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