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