]> TLD Linux GIT Repositories - TLD.git/blob - pld-builder.new/PLD_Builder/bqueue.py
aff32e90b50b042eae8f02a044cb990ce477d6d2
[TLD.git] / pld-builder.new / PLD_Builder / bqueue.py
1 # vi: encoding=utf-8 ts=8 sts=4 sw=4 et
2
3 import re
4 import gzip
5 import time
6 import StringIO
7 import os
8 import fcntl
9 import string
10 import tempfile
11
12 # PLD_Builder:
13 import gpg
14 import request
15 import util
16 import log
17
18 class B_Queue:
19     def __init__(self, filename):
20         self.name = filename
21         self.requests = []
22         self.fd = None
23
24     def dump(self, fname):
25         (fdno, tmpfname) = tempfile.mkstemp(dir=os.path.dirname(fname))
26         f = os.fdopen(fdno, "w")
27         self.requests.reverse()
28         for r in self.requests:
29             r.dump(f)
30         self.requests.reverse()
31         f.flush()
32         os.fsync(f.fileno())
33         f.close()
34         os.chmod(tmpfname, 0644)
35         os.rename(tmpfname, fname)
36
37     def dump_html(self, fname):
38         (fdno, tmpfname) = tempfile.mkstemp(dir=os.path.dirname(fname))
39         f = os.fdopen(fdno, "w")
40         f.write("""
41 <html>
42     <head>
43     <link rel="Shortcut Icon" href="http://www.pld-linux.org/favicon.ico"/>
44         <title>PLD builder queue</title>
45         <link rel="stylesheet" type="text/css" charset="utf-8" media="all" href="style.css">
46         <script type="text/javascript" src="script.js"></script>
47     </head>
48 <body>\n"""
49         )
50         self.requests.reverse()
51         for r in self.requests:
52             r.dump_html(f)
53         self.requests.reverse()
54         f.write("</body></html>\n")
55         f.flush()
56         os.fsync(f.fileno())
57         f.close()
58         os.chmod(tmpfname, 0644)
59         os.rename(tmpfname, fname)
60
61     # read possibly compressed, signed queue
62     def read_signed(self):
63         if re.search(r"\.gz$", self.name):
64             f = gzip.open(self.name)
65         else:
66             f = open(self.name)
67         (signers, body) = gpg.verify_sig(f.read())
68         self.signers = signers
69         self.requests = request.parse_requests(body)
70
71     def _open(self):
72         if self.fd == None:
73             if os.access(self.name, os.F_OK):
74                 self.fd = open(self.name, "r+")
75             else:
76                 self.fd = open(self.name, "w+")
77
78     def read(self):
79         self._open()
80         self.signers = []
81         body = self.fd.read()
82         if string.strip(body) == "":
83             # empty file, don't choke
84             self.requests = []
85             return
86         try:
87             self.requests = request.parse_requests(body)
88         except Exception, e:
89             log.panic("error parsing %s: %s" % (self.name, e))
90             pass
91
92     def _write_to(self, f):
93         f.write("<queue>\n")
94         for r in self.requests:
95             r.write_to(f)
96         f.write("</queue>\n")
97
98     def write(self):
99         self._open()
100         self.fd.seek(0)
101         self.fd.truncate(0)
102         self._write_to(self.fd)
103         self.fd.flush()
104
105     def lock(self, no_block):
106         self._open()
107         op = fcntl.LOCK_EX
108         if no_block:
109             op = op + fcntl.LOCK_NB
110         try:
111             fcntl.flock(self.fd, op)
112             return 1
113         except IOError:
114             return 0
115
116     def unlock(self):
117         fcntl.flock(self.fd, fcntl.LOCK_UN)
118
119     def write_signed(self, name):
120         sio = StringIO.StringIO()
121         self._write_to(sio)
122         sio.seek(0)
123         sio.write(gpg.sign(sio.read()))
124         sio.seek(0)
125         (fdno, tmpname) = tempfile.mkstemp(dir=os.path.dirname(name))
126         f = os.fdopen(fdno, "w")
127         if re.search(r"\.gz$", name):
128             fgz = gzip.GzipFile(filename=name, mode="w", compresslevel=6, fileobj=f)
129             util.sendfile(sio, fgz)
130             fgz.close()
131         else:
132             util.sendfile(sio, f)
133         f.flush()
134         os.fsync(f.fileno())
135         f.close()
136         os.chmod(tmpname, 0644)
137         os.rename(tmpname, name)
138
139     def add(self, req):
140         self.requests.append(req)
141
142     def value(self):
143         return self.requests