From: Michael Tremer Date: Thu, 1 May 2025 14:58:46 +0000 (+0000) Subject: downloads: Add document for the Raspberry Pi Imager X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bb86abb372366bc3293e7c2121a5b2ec6ea3b413;p=ipfire.org.git downloads: Add document for the Raspberry Pi Imager Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 097bbd8d..fae05e8a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1105,6 +1105,7 @@ static_img_DATA = \ 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 \ diff --git a/src/backend/releases.py b/src/backend/releases.py index 895c6ca3..5990c4f6 100644 --- a/src/backend/releases.py +++ b/src/backend/releases.py @@ -264,10 +264,17 @@ class Release(Object): 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) @@ -354,6 +361,37 @@ class Release(Object): 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: diff --git a/src/static/img/ipfire-tux-40x40.png b/src/static/img/ipfire-tux-40x40.png new file mode 100644 index 00000000..44541162 Binary files /dev/null and b/src/static/img/ipfire-tux-40x40.png differ diff --git a/src/web/__init__.py b/src/web/__init__.py index 52a1fe36..94df8310 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -169,6 +169,8 @@ class Application(tornado.web.Application): (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), diff --git a/src/web/downloads.py b/src/web/downloads.py index 05f95994..623d0974 100644 --- a/src/web/downloads.py +++ b/src/web/downloads.py @@ -84,3 +84,30 @@ class FileHandler(base.AnalyticsMixin, base.BaseHandler): 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)