src/static/img/default-avatar.jpg \
src/static/img/fdroid-logo.svg \
src/static/img/ipfire-tux.png \
+ src/static/img/ipfire-tux-40x40.png \
src/static/img/iuse-not-found.png \
src/static/img/kyberio-logo.svg \
src/static/img/lightningwirelabs-logo.svg \
def path(self):
return self.__data.path
- def get_file(self, type):
+ def get_file(self, type, arch=None):
for file in self.files:
- if file.type == type:
- return file
+ # Skip anything where the type does not match
+ if not file.type == type:
+ continue
+
+ # Optionally skip the architecture
+ if arch and not file.arch == arch:
+ continue
+
+ return file
def __file_hash(self, filename, algo="sha256"):
h = hashlib.new(algo)
def netboot_args(self, arch, platform):
return ""
+ # OS List (For Raspberry Pi Imager)
+
+ def make_os_list(self, arch):
+ """
+ Returns an object according to this spec:
+
+ https://github.com/raspberrypi/rpi-imager/blob/qml/doc/json-schema/os-list-schema.json
+ https://github.com/raspberrypi/rpi-imager/blob/qml/doc/os-sublist-example.json
+ """
+ # Fetch the flash image
+ file = self.get_file(type="flash", arch=arch)
+
+ # Return an empty object if we could not find the image file
+ if not file:
+ return {}
+
+ # Make the document
+ return {
+ "name" : self.name,
+ "description" : "The Open Source Linux-based Firewall Operating System"
+ " with a Comprehensive Feature Set",
+ "url" : file.url,
+ "icon" : "https://www.ipfire.org/static/img/ipfire-tux-40x40.png",
+ "website" : "https://www.ipfire.org/",
+ "release_date" : self.published.strftime("%Y-%m-%d"),
+
+ # Image Metadata
+ "image_download_size" : file.size,
+ "image_download_sha256" : file.sha256,
+ }
+
@property
def post(self):
if self.__data.blog_id:
(r"/downloads/mirrors", downloads.MirrorsHandler),
(r"/downloads/thank-you", downloads.ThankYouHandler),
(r"/downloads/([0-9a-z\-\.]+)", downloads.ReleaseHandler),
+ (r"/downloads/latest/os\-list\.json", downloads.LatestOSListHandler),
+ (r"/downloads/([0-9a-z\-\.]+)/os\-list\.json", downloads.OSListHandler),
# Donate
(r"/donate", donate.DonateHandler),
we will have to redirect the user back to the main page
"""
self.redirect("https://www.ipfire.org/error/%s" % status_code)
+
+
+class LatestOSListHandler(base.AnalyticsMixin, base.BaseHandler):
+ def get(self):
+ release = self.backend.releases.get_latest()
+ if not release:
+ raise tornado.web.HTTPError(404)
+
+ # Redirect to latest release
+ self.redirect("/downloads/%s/os-list.json" % release.slug)
+
+
+class OSListHandler(base.AnalyticsMixin, base.BaseHandler):
+ def get(self, slug):
+ release = self.backend.releases.get_by_sname(slug)
+ if not release:
+ raise tornado.web.HTTPError(404)
+
+ # Create the document
+ json = release.make_os_list(arch="aarch64")
+
+ # Fail if there was no image
+ if not json:
+ raise tornado.web.HTTPError(404, "Empty document")
+
+ # Send the document to the client
+ self.finish(json)