]>
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
:
73 elif "scon" in filename
:
76 elif filename
.endswith(".img.gz"):
84 baseurl
= Settings().get("download_url")
86 return urlparse
.urljoin(baseurl
, self
.filename
)
93 "armv5tel" : _("Image for the armv5tel architecture"),
94 "iso" : _("Installable CD image"),
95 "torrent" : _("Torrent file"),
96 "flash" : _("Flash image"),
97 "alix" : _("Alix image"),
98 "usbfdd" : _("USB FDD Image"),
99 "usbhdd" : _("USB HDD Image"),
100 "xen" : _("Pregenerated Xen image"),
104 return descriptions
[self
.type]
106 return _("Unknown image type")
122 return priorities
[self
.type]
131 "armv5tel" : _("This image runs on many ARM-based boards"),
132 "iso" : _("Use this image to burn a CD and install IPFire from it."),
133 "torrent" : _("Download the CD image from the torrent network."),
134 "flash" : _("An image that is meant to run on embedded devices."),
135 "alix" : _("Flash image where a serial console is enabled by default."),
136 "usbfdd" : _("Install IPFire from a floppy-formated USB key."),
137 "usbhdd" : _("If the floppy image doesn't work, use this image instead."),
138 "xen" : _("A ready-to-run image for Xen."),
142 return remarks
[self
.type]
144 return _("Unknown image type")
148 return self
.data
.get("sha1")
152 return self
.data
.get("filename")
156 return os
.path
.basename(self
.filename
)
160 return self
.data
.get("filesize")
164 known_arches
= ("i586", "arm")
166 for arch
in known_arches
:
167 if arch
in self
.basename
:
173 def torrent_hash(self
):
174 return self
.data
.get("torrent_hash", None)
177 def magnet_link(self
):
178 # Don't return anything if we have no torrent hash.
179 if self
.torrent_hash
is None:
182 s
= "magnet:?xt=urn:btih:%s" % self
.torrent_hash
184 #s += "&xl=%d" % self.size
185 s
+= "&dn=%s" % urllib
.quote(self
.basename
)
188 s
+= "&tr=http://tracker.ipfire.org:6969/announce"
194 if not self
.torrent_hash
:
197 return self
.tracker
.get_seeds(self
.torrent_hash
)
201 if not self
.torrent_hash
:
204 return self
.tracker
.get_peers(self
.torrent_hash
)
208 if not self
.torrent_hash
:
211 return self
.tracker
.complete(self
.torrent_hash
)
214 class Release(object):
221 return tracker
.Tracker()
223 def __init__(self
, id):
226 # get all data from database
228 self
.db
.get("SELECT * FROM releases WHERE id = %s", self
.id)
234 return "<%s %s>" % (self
.__class
__.__name
__, self
.name
)
239 files
= self
.db
.query("SELECT id, filename FROM files WHERE releases = %s \
240 AND loadable = 'Y' AND NOT filename LIKE '%%.torrent'", self
.id)
242 self
.__files
= [File(self
, f
.id) for f
in files
]
243 self
.__files
.sort(lambda a
, b
: cmp(a
.prio
, b
.prio
))
251 for file in self
.files
:
252 if not file.torrent_hash
:
255 torrents
.append(file)
261 return self
.__data
.get("name")
265 return self
.__data
.get("stable") == "Y"
269 return self
.__data
.get("published") == "Y"
273 return self
.__data
.get("date")
277 return self
.__data
.get("path")
279 def get_file(self
, type):
280 for file in self
.files
:
281 if file.type == type:
284 def __file_hash(self
, filename
):
285 sha1
= hashlib
.sha1()
287 with
open(filename
) as f
:
289 buf
= f
.read(buf_size
)
292 buf
= f
.read(buf_size
)
294 return sha1
.hexdigest()
296 def scan_files(self
, basepath
="/srv/mirror0"):
300 path
= os
.path
.join(basepath
, self
.path
)
301 if not os
.path
.exists(path
):
304 files
= self
.db
.query("SELECT filename FROM files WHERE releases = %s", self
.id)
305 files
= [f
.filename
for f
in files
]
307 # Make files that do not exists not loadable.
308 for filename
in files
:
309 _filename
= os
.path
.join(basepath
, filename
)
310 if not os
.path
.exists(_filename
):
311 self
.db
.execute("UPDATE files SET loadable='N' WHERE filename = %s", filename
)
313 for filename
in os
.listdir(path
):
314 filename
= os
.path
.join(path
, filename
)
316 if os
.path
.isdir(filename
):
319 _filename
= re
.match(".*(releases/.*)", filename
).group(1)
320 if _filename
in files
:
323 if filename
.endswith(".md5"):
326 filehash
= self
.__file
_hash
(filename
)
327 filesize
= os
.path
.getsize(filename
)
329 # Check if there is a torrent download available for this file:
331 torrent_file
= "%s.torrent" % filename
332 if os
.path
.exists(torrent_file
):
333 torrent_hash
= self
.torrent_read_hash(torrent_file
)
335 self
.db
.execute("INSERT INTO files(releases, filename, filesize, \
336 sha1, torrent_hash) VALUES(%s, %s, %s, %s, %s)",
337 self
.id, _filename
, filesize
, filehash
, torrent_hash
)
339 # Search for all files that miss a torrent hash.
340 files
= self
.db
.query("SELECT id, filename FROM files \
341 WHERE releases = %s AND torrent_hash IS NULL", self
.id)
344 path
= os
.path
.join(basepath
, file.filename
)
346 torrent_file
= "%s.torrent" % path
347 if os
.path
.exists(torrent_file
):
348 torrent_hash
= self
.torrent_read_hash(torrent_file
)
350 self
.db
.execute("UPDATE files SET torrent_hash = %s WHERE id = %s",
351 torrent_hash
, file.id)
353 def torrent_read_hash(self
, filename
):
356 f
= open(filename
, "rb")
358 metainfo
= tracker
.bdecode(f
.read())
359 metainfo
= tracker
.bencode(metainfo
["info"])
361 hash = hashlib
.sha1()
362 hash.update(metainfo
)
364 return hash.hexdigest()
371 class Releases(object):
372 __metaclass__
= Singleton
376 return Databases().webapp
379 return [Release(r
.id) for r
in self
.db
.query("SELECT id FROM releases ORDER BY date DESC")]
381 def get_by_id(self
, id):
383 if id in [r
.id for r
in self
.db
.query("SELECT id FROM releases")]:
386 def get_latest(self
, stable
=1):
387 query
= "SELECT id FROM releases WHERE published='Y' AND"
389 query
+= " stable='Y'"
391 query
+= " stable='N'"
393 query
+= " ORDER BY date DESC LIMIT 1"
395 release
= self
.db
.get(query
)
397 return Release(release
.id)
399 def get_stable(self
):
400 releases
= self
.db
.query("""SELECT id FROM releases
401 WHERE published='Y' AND stable='Y'
402 ORDER BY date DESC""")
404 return [Release(r
.id) for r
in releases
]
406 def get_unstable(self
):
407 releases
= self
.db
.query("""SELECT id FROM releases
408 WHERE published='Y' AND stable='N'
409 ORDER BY date DESC""")
411 return [Release(r
.id) for r
in releases
]
414 releases
= self
.db
.query("""SELECT id FROM releases
415 WHERE published='Y' ORDER BY date DESC""")
417 return [Release(r
.id) for r
in releases
]
419 def get_file_for_torrent_hash(self
, torrent_hash
):
420 file = self
.db
.get("SELECT id, releases FROM files WHERE torrent_hash = %s LIMIT 1",
426 release
= Release(file.releases
)
427 file = File(release
, file.id)
432 if __name__
== "__main__":
435 for release
in r
.get_all():