]>
git.ipfire.org Git - people/shoehn/ipfire.org.git/blob - www/webapp/backend/releases.py
12 from databases
import Databases
13 from misc
import Singleton
14 from settings
import Settings
17 def __init__(self
, release
, id):
19 self
._release
= release
21 # get all data from database
26 return Databases().webapp
30 return self
.release
.tracker
34 if self
.__data
is None:
35 self
.__data
= self
.db
.get("SELECT * FROM files WHERE id = %s", self
.id)
43 release_id
= self
.data
.get("releases")
44 self
._release
= Release(release_id
)
50 filename
= self
.filename
52 if filename
.endswith(".iso"):
55 elif filename
.endswith(".torrent"):
58 elif "xen" in filename
:
61 elif "sources" in filename
:
64 elif "usb-fdd" in filename
:
67 elif "usb-hdd" in filename
:
70 elif "armv5tel" in filename
and "scon" in filename
:
71 return "armv5tel-scon"
73 elif "armv5tel" in filename
:
76 elif "scon" in filename
:
79 elif filename
.endswith(".img.gz"):
87 baseurl
= Settings().get("download_url")
89 return urlparse
.urljoin(baseurl
, self
.filename
)
96 "armv5tel" : _("Image for the armv5tel architecture"),
97 "armv5tel-scon" : _("armv5tel image for boards with serial console"),
98 "iso" : _("Installable CD image"),
99 "torrent" : _("Torrent file"),
100 "flash" : _("Flash image"),
101 "alix" : _("Alix image"),
102 "usbfdd" : _("USB FDD Image"),
103 "usbhdd" : _("USB HDD Image"),
104 "xen" : _("Pregenerated Xen image"),
108 return descriptions
[self
.type]
110 return _("Unknown image type")
122 "armv5tel-scon" : 41,
127 return priorities
[self
.type]
136 "armv5tel" : _("This image runs on many ARM-based boards"),
137 "armv5tel-scon" : _("This image runs on ARM boards with a serial console"),
138 "iso" : _("Use this image to burn a CD and install IPFire from it."),
139 "torrent" : _("Download the CD image from the torrent network."),
140 "flash" : _("An image that is meant to run on embedded devices."),
141 "alix" : _("Flash image where a serial console is enabled by default."),
142 "usbfdd" : _("Install IPFire from a floppy-formated USB key."),
143 "usbhdd" : _("If the floppy image doesn't work, use this image instead."),
144 "xen" : _("A ready-to-run image for Xen."),
148 return remarks
[self
.type]
150 return _("Unknown image type")
154 return self
.data
.get("sha1")
158 return self
.data
.get("filename")
162 return os
.path
.basename(self
.filename
)
166 return self
.data
.get("filesize")
170 known_arches
= ("i586", "arm")
172 for arch
in known_arches
:
173 if arch
in self
.basename
:
179 def torrent_hash(self
):
180 return self
.data
.get("torrent_hash", None)
183 def magnet_link(self
):
184 # Don't return anything if we have no torrent hash.
185 if self
.torrent_hash
is None:
188 s
= "magnet:?xt=urn:btih:%s" % self
.torrent_hash
190 #s += "&xl=%d" % self.size
191 s
+= "&dn=%s" % urllib
.quote(self
.basename
)
194 s
+= "&tr=http://tracker.ipfire.org:6969/announce"
200 if not self
.torrent_hash
:
203 return self
.tracker
.get_seeds(self
.torrent_hash
)
207 if not self
.torrent_hash
:
210 return self
.tracker
.get_peers(self
.torrent_hash
)
214 if not self
.torrent_hash
:
217 return self
.tracker
.complete(self
.torrent_hash
)
220 class Release(object):
227 return tracker
.Tracker()
229 def __init__(self
, id):
232 # get all data from database
234 self
.db
.get("SELECT * FROM releases WHERE id = %s", self
.id)
240 return "<%s %s>" % (self
.__class
__.__name
__, self
.name
)
245 files
= self
.db
.query("SELECT id, filename FROM files WHERE releases = %s \
246 AND loadable = 'Y' AND NOT filename LIKE '%%.torrent'", self
.id)
248 self
.__files
= [File(self
, f
.id) for f
in files
]
249 self
.__files
.sort(lambda a
, b
: cmp(a
.prio
, b
.prio
))
257 for file in self
.files
:
258 if not file.torrent_hash
:
261 torrents
.append(file)
267 return self
.__data
.get("name")
271 return self
.__data
.get("stable") == "Y"
275 return self
.__data
.get("published") == "Y"
279 return self
.__data
.get("date")
283 return self
.__data
.get("path")
285 def get_file(self
, type):
286 for file in self
.files
:
287 if file.type == type:
290 def __file_hash(self
, filename
):
291 sha1
= hashlib
.sha1()
293 with
open(filename
) as f
:
295 buf
= f
.read(buf_size
)
298 buf
= f
.read(buf_size
)
300 return sha1
.hexdigest()
302 def scan_files(self
, basepath
="/srv/mirror0"):
306 path
= os
.path
.join(basepath
, self
.path
)
307 if not os
.path
.exists(path
):
310 files
= self
.db
.query("SELECT filename FROM files WHERE releases = %s", self
.id)
311 files
= [f
.filename
for f
in files
]
313 # Make files that do not exists not loadable.
314 for filename
in files
:
315 _filename
= os
.path
.join(basepath
, filename
)
316 if not os
.path
.exists(_filename
):
317 self
.db
.execute("UPDATE files SET loadable='N' WHERE filename = %s", filename
)
319 for filename
in os
.listdir(path
):
320 filename
= os
.path
.join(path
, filename
)
322 if os
.path
.isdir(filename
):
325 _filename
= re
.match(".*(releases/.*)", filename
).group(1)
326 if _filename
in files
:
329 if filename
.endswith(".md5"):
332 filehash
= self
.__file
_hash
(filename
)
333 filesize
= os
.path
.getsize(filename
)
335 # Check if there is a torrent download available for this file:
337 torrent_file
= "%s.torrent" % filename
338 if os
.path
.exists(torrent_file
):
339 torrent_hash
= self
.torrent_read_hash(torrent_file
)
341 self
.db
.execute("INSERT INTO files(releases, filename, filesize, \
342 sha1, torrent_hash) VALUES(%s, %s, %s, %s, %s)",
343 self
.id, _filename
, filesize
, filehash
, torrent_hash
)
345 # Search for all files that miss a torrent hash.
346 files
= self
.db
.query("SELECT id, filename FROM files \
347 WHERE releases = %s AND torrent_hash IS NULL", self
.id)
350 path
= os
.path
.join(basepath
, file.filename
)
352 torrent_file
= "%s.torrent" % path
353 if os
.path
.exists(torrent_file
):
354 torrent_hash
= self
.torrent_read_hash(torrent_file
)
356 self
.db
.execute("UPDATE files SET torrent_hash = %s WHERE id = %s",
357 torrent_hash
, file.id)
359 def torrent_read_hash(self
, filename
):
362 f
= open(filename
, "rb")
364 metainfo
= tracker
.bdecode(f
.read())
365 metainfo
= tracker
.bencode(metainfo
["info"])
367 hash = hashlib
.sha1()
368 hash.update(metainfo
)
370 return hash.hexdigest()
377 class Releases(object):
378 __metaclass__
= Singleton
382 return Databases().webapp
385 return [Release(r
.id) for r
in self
.db
.query("SELECT id FROM releases ORDER BY date DESC")]
387 def get_by_id(self
, id):
389 if id in [r
.id for r
in self
.db
.query("SELECT id FROM releases")]:
392 def get_latest(self
, stable
=1):
393 query
= "SELECT id FROM releases WHERE published='Y' AND"
395 query
+= " stable='Y'"
397 query
+= " stable='N'"
399 query
+= " ORDER BY date DESC LIMIT 1"
401 release
= self
.db
.get(query
)
403 return Release(release
.id)
405 def get_stable(self
):
406 releases
= self
.db
.query("""SELECT id FROM releases
407 WHERE published='Y' AND stable='Y'
408 ORDER BY date DESC""")
410 return [Release(r
.id) for r
in releases
]
412 def get_unstable(self
):
413 releases
= self
.db
.query("""SELECT id FROM releases
414 WHERE published='Y' AND stable='N'
415 ORDER BY date DESC""")
417 return [Release(r
.id) for r
in releases
]
420 releases
= self
.db
.query("""SELECT id FROM releases
421 WHERE published='Y' ORDER BY date DESC""")
423 return [Release(r
.id) for r
in releases
]
425 def get_file_for_torrent_hash(self
, torrent_hash
):
426 file = self
.db
.get("SELECT id, releases FROM files WHERE torrent_hash = %s LIMIT 1",
432 release
= Release(file.releases
)
433 file = File(release
, file.id)
438 if __name__
== "__main__":
441 for release
in r
.get_all():