]> TLD Linux GIT Repositories - tld-builder.git/blob - TLD_Builder/bqueue.py
f95f0f394816a4a4a1749333544af9ff10b4c9c7
[tld-builder.git] / TLD_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 # TLD_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="//www.tld-linux.org/favicon.ico"/>
44         <title>TLD builder queue</title>
45         <link rel="stylesheet" type="text/css" charset="utf-8" media="all" href="style.css">
46         <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
47         <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.4.3/jquery.timeago.min.js"></script>
48         <script type="text/javascript" src="script.js"></script>
49     </head>
50 <body>
51 <div id="header">
52     <div id="requesters-filter">Filter by requesters:<br></div>
53 </div>
54 <div id="content">
55 """
56         )
57         self.requests.reverse()
58         for r in self.requests:
59             r.dump_html(f)
60         self.requests.reverse()
61         f.write("</div></body></html>\n")
62         f.flush()
63         os.fsync(f.fileno())
64         f.close()
65         os.chmod(tmpfname, 0644)
66         os.rename(tmpfname, fname)
67
68     # read possibly compressed, signed queue
69     def read_signed(self):
70         if re.search(r"\.gz$", self.name):
71             f = gzip.open(self.name)
72         else:
73             f = open(self.name)
74         (signers, body) = gpg.verify_sig(f.read())
75         self.signers = signers
76         self.requests = request.parse_requests(body)
77
78     def _open(self):
79         if self.fd == None:
80             if os.access(self.name, os.F_OK):
81                 self.fd = open(self.name, "r+")
82             else:
83                 self.fd = open(self.name, "w+")
84
85     def read(self):
86         self._open()
87         self.signers = []
88         body = self.fd.read()
89         if string.strip(body) == "":
90             # empty file, don't choke
91             self.requests = []
92             return
93         try:
94             self.requests = request.parse_requests(body)
95         except Exception, e:
96             log.panic("error parsing %s: %s" % (self.name, e))
97             pass
98
99     def _write_to(self, f):
100         f.write("<queue>\n")
101         for r in self.requests:
102             r.write_to(f)
103         f.write("</queue>\n")
104
105     def write(self):
106         self._open()
107         self.fd.seek(0)
108         self.fd.truncate(0)
109         self._write_to(self.fd)
110         self.fd.flush()
111
112     def lock(self, no_block):
113         self._open()
114         op = fcntl.LOCK_EX
115         if no_block:
116             op = op + fcntl.LOCK_NB
117         try:
118             fcntl.flock(self.fd, op)
119             return 1
120         except IOError:
121             return 0
122
123     def unlock(self):
124         fcntl.flock(self.fd, fcntl.LOCK_UN)
125
126     def write_signed(self, name):
127         sio = StringIO.StringIO()
128         self._write_to(sio)
129         sio.seek(0)
130         sio.write(gpg.sign(sio.read()))
131         sio.seek(0)
132         (fdno, tmpname) = tempfile.mkstemp(dir=os.path.dirname(name))
133         f = os.fdopen(fdno, "w")
134         if re.search(r"\.gz$", name):
135             fgz = gzip.GzipFile(filename=name, mode="w", compresslevel=6, fileobj=f)
136             util.sendfile(sio, fgz)
137             fgz.close()
138         else:
139             util.sendfile(sio, f)
140         f.flush()
141         os.fsync(f.fileno())
142         f.close()
143         os.chmod(tmpname, 0644)
144         os.rename(tmpname, name)
145
146     def add(self, req):
147         self.requests.append(req)
148
149     def value(self):
150         return self.requests