Coverage for webapp/snapcraft/views.py: 45%
84 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-14 22:07 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-14 22:07 +0000
1import flask
3from webapp.snapcraft import logic
6def snapcraft_blueprint():
7 snapcraft = flask.Blueprint("snapcraft", __name__)
9 @snapcraft.route("/")
10 def homepage():
11 nps = flask.request.args.get("nps")
13 livestream = logic.get_livestreams()
15 return flask.render_template(
16 "index.html", nps=nps, livestream=livestream
17 )
19 @snapcraft.route("/account.json")
20 def get_account_json():
21 """
22 A JSON endpoint to request login status
23 """
24 try:
25 publisher = None
27 if "publisher" in flask.session:
28 publisher = flask.session["publisher"]
30 response = {"publisher": publisher}
31 response = flask.make_response(response)
33 # Unset the last_login_method cookie to avoid forcing
34 response.set_cookie("last_login_method", "", expires=0)
36 response.headers["Cache-Control"] = "no-store"
38 return response
39 except Exception:
40 response = {"error": "Error fetching account information"}
41 response = flask.make_response(response)
42 response.headers["Cache-Control"] = "no-store"
43 return response, 502
45 @snapcraft.route("/iot")
46 def iot():
47 status_code = 200
49 icon_host = "https://dashboard.snapcraft.io/site_media/appmedia"
50 assets_host = "https://assets.ubuntu.com/v1"
52 devices = [
53 {
54 "package_name": "ubuntu-frame-osk",
55 "icon_url": "/".join([icon_host, "2023/03/icon_2_Frame.png"]),
56 "title": "Ubuntu Frame",
57 "developer_name": "Canonical",
58 "developer_link": "/publisher/canonical",
59 "developer_validation": "verified",
60 },
61 {
62 "package_name": "mir-kiosk",
63 "icon_url": "/".join(
64 [icon_host, "2021/06/mir-sqr-stacked-orng.png"]
65 ),
66 "title": "mir-kiosk",
67 "developer_name": "Canonical",
68 "developer_link": "/publisher/canonical",
69 "developer_validation": "verified",
70 },
71 {
72 "package_name": "edgexfoundry",
73 "icon_url": "/".join([icon_host, "2018/12/icon_Hx6IyH0.png"]),
74 "title": "Edgexfoundry",
75 "developer_name": "Canonical",
76 "developer_link": "/publisher/canonical",
77 "developer_validation": "verified",
78 },
79 {
80 "package_name": "node-red",
81 "icon_url": "/".join([icon_host, "2017/01/nr-hex_1.png"]),
82 "title": "Node-Red",
83 "developer_name": "Node-RED-Team (noderedteam)",
84 "developer_link": "/publisher/noderedteam",
85 "developer_validation": "verified",
86 },
87 {
88 "package_name": "bluez",
89 "icon_url": "/".join(
90 [icon_host, "2020/05/bluez-logo-2.jpg.png"]
91 ),
92 "title": "bluez",
93 "developer_name": "Canonical",
94 "developer_link": "/publisher/canonical",
95 "developer_validation": "verified",
96 },
97 {
98 "package_name": "zwave-js-ui",
99 "icon_url": "/".join(
100 [icon_host, "2022/10/app_logo-svg_2.svg.png"]
101 ),
102 "title": "Zwave JS UI",
103 "developer_name": "Giaever.online (giaever-online)",
104 "developer_link": "/publisher/giaever-online",
105 },
106 {
107 "package_name": "ubports-installer",
108 "icon_url": "/".join(
109 [icon_host, "2017/09/256x256_h3aYso1.png"]
110 ),
111 "title": "ubports-installer",
112 "developer_name": "UBports",
113 "developer_link": "/publisher/ubports",
114 },
115 {
116 "package_name": "librepcb",
117 "icon_url": "/".join([icon_host, "2022/10/librepcb.png"]),
118 "title": "LibrePCB",
119 "developer_name": "librepcb",
120 "developer_link": "/publisher/librepcb",
121 "developer_validation": "verified",
122 },
123 {
124 "package_name": "ammp-edge",
125 "icon_url": "/".join(
126 [icon_host, "2020/12/glyph-rounder-square-180px.png"]
127 ),
128 "title": "ammp-edge",
129 "developer_name": "AMMP Technologies (ammp)",
130 "developer_link": "/publisher/ammp",
131 },
132 {
133 "package_name": "pi-bluetooth",
134 "icon_url": "/".join(
135 [assets_host, "be6eb412-snapcraft-missing-icon.svg"]
136 ),
137 "title": "pi-bluetooth",
138 "developer_name": "Dave Jones (waveform)",
139 "developer_link": "/publisher/waveform",
140 },
141 ]
143 robotics = [
144 {
145 "package_name": "arduino",
146 "icon_url": "/".join([icon_host, "2020/02/icon_s4HbwJl.png"]),
147 "title": "Arduino IDE",
148 "developer_name": "Snapcrafters",
149 "developer_link": "/publisher/snapcrafters",
150 "developer_validation": "starred",
151 },
152 {
153 "package_name": "rosbot-xl",
154 "icon_url": "/".join([icon_host, "2024/06/rosbot-xl.png"]),
155 "title": "ROSbot XL",
156 "developer_name": "Husarion",
157 "developer_link": "/publisher/husarion",
158 "developer_validation": "verified",
159 },
160 {
161 "package_name": "rosbot-xl-teleop",
162 "icon_url": "/".join(
163 [icon_host, "2023/10/popr512x512px_rosbot_xl_teleop.png"]
164 ),
165 "title": "ROSbot XL: teleop",
166 "developer_name": "Husarion",
167 "developer_link": "/publisher/husarion",
168 "developer_validation": "verified",
169 },
170 {
171 "package_name": "webots",
172 "icon_url": "/".join([icon_host, "2019/08/webots.png"]),
173 "title": "Webots",
174 "developer_name": "Cyberbotics",
175 "developer_link": "/publisher/cyberbotics",
176 },
177 {
178 "package_name": "gazebo",
179 "icon_url": "/".join([icon_host, "2022/05/icon.svg.png"]),
180 "title": "gazebo",
181 "developer_name": (
182 "Ubuntu Robotics Community (ubuntu-robotics-community)"
183 ),
184 "developer_link": "/publisher/ubuntu-robotics-community",
185 "developer_validation": "verified",
186 },
187 {
188 "package_name": "ros2-cli",
189 "icon_url": "/".join(
190 [icon_host, "2023/02/ros2-cli_icon_1.png"]
191 ),
192 "title": "ros2-cli",
193 "developer_name": (
194 "Ubuntu Robotics Community (ubuntu-robotics-community)"
195 ),
196 "developer_link": "/publisher/ubuntu-robotics-community",
197 "developer_validation": "verified",
198 },
199 {
200 "package_name": "vulcanexus-router",
201 "icon_url": "/".join([icon_host, "2023/05/V-DDSRouter.png"]),
202 "title": "Vulcanexus Router",
203 "developer_name": "eProsima",
204 "developer_link": "/publisher/eprosima",
205 },
206 {
207 "package_name": "bow-webots",
208 "icon_url": "/".join(
209 [assets_host, "be6eb412-snapcraft-missing-icon.svg"]
210 ),
211 "title": "BOW Webots",
212 "developer_name": "Daniel Camilleri (bow-robotics)",
213 "developer_link": "/publisher/bow-robotics",
214 },
215 {
216 "package_name": "foxglove-studio",
217 "icon_url": "/".join([icon_host, "2022/07/fs-icon.svg.png"]),
218 "title": "foxglove-studio",
219 "developer_name": "Roman Shtylman (roman-foxglove)",
220 "developer_link": "/publisher/roman-foxglove",
221 },
222 {
223 "package_name": "husarion-ouster",
224 "icon_url": "/".join(
225 [icon_host, "2023/10/husarion-ouster.png"]
226 ),
227 "title": "husarion-ouster",
228 "developer_name": "Husarion",
229 "developer_link": "/publisher/husarion",
230 "developer_validation": "verified",
231 },
232 ]
234 smart_home = [
235 {
236 "package_name": "openhab",
237 "icon_url": "/".join([icon_host, "2017/11/favicon.png"]),
238 "title": "openhab",
239 "developer_name": "openHAB Foundation e.V. (openhab)",
240 "developer_link": "/publisher/openhab",
241 },
242 {
243 "package_name": "homebridge",
244 "icon_url": "/".join([icon_host, "2018/10/Logo2x.png"]),
245 "title": "homebridge",
246 "developer_name": "Ondrej Kubik (ondra)",
247 },
248 {
249 "package_name": "home-assistant-snap",
250 "icon_url": "/".join(
251 [icon_host, "2020/07/favicon-192x192.png"]
252 ),
253 "title": "Home Assistant",
254 "developer_name": "Giaever.online (giaever-online)",
255 "developer_link": "/publisher/giaever-online",
256 },
257 {
258 "package_name": "security-bear",
259 "icon_url": "/".join(
260 [icon_host, "2020/11/security-bear_Logo.png"]
261 ),
262 "title": "security-bear",
263 "developer_name": "CyBear Jinni (cybearjinni)",
264 "developer_link": "/publisher/cybearjinni",
265 },
266 {
267 "package_name": "chip-tool",
268 "icon_url": "/".join([icon_host, "2023/01/1F3E0_color.png"]),
269 "title": "chip-tool",
270 "developer_name": "Canonical IoT Labs (canonical-iot-labs)",
271 "developer_link": "/publisher/canonical-iot-labs",
272 },
273 {
274 "package_name": "openthread-border-router",
275 "icon_url": "/".join(
276 [icon_host, "2023/09/ThreadLogo-stort-1.png"]
277 ),
278 "title": "openthread-border-router",
279 "developer_name": "Canonical IoT Labs (canonical-iot-labs)",
280 "developer_link": "/publisher/canonical-iot-labs",
281 },
282 {
283 "package_name": "matter-bridge-tapo-lighting",
284 "icon_url": "/".join(
285 [icon_host, "2023/01/1F3E0_color_8tMXOjP.png"]
286 ),
287 "title": "matter-bridge-tapo-lighting",
288 "developer_name": "Canonical IoT Labs (canonical-iot-labs)",
289 "developer_link": "/publisher/canonical-iot-labs",
290 },
291 {
292 "package_name": "matter-pi-gpio-commander",
293 "icon_url": "/".join([icon_host, "2023/03/E1C7_color.png"]),
294 "title": "matter-pi-gpio-commander",
295 "developer_name": "Canonical IoT Labs (canonical-iot-labs)",
296 "developer_link": "/publisher/canonical-iot-labs",
297 },
298 ]
300 networking = [
301 {
302 "package_name": "mosquitto",
303 "icon_url": "/".join(
304 [icon_host, "2018/08/mosquitto-logo-only.svg.png"]
305 ),
306 "title": "mosquitto",
307 "developer_name": "Mosquitto Team (mosquitto)",
308 "developer_link": "/publisher/mosquitto",
309 "developer_validation": "verified",
310 },
311 {
312 "package_name": "domotzpro-agent-publicstore",
313 "icon_url": "/".join(
314 [icon_host, "2019/03/new_domotz_icon.png"]
315 ),
316 "title": "Domotz Pro Agent",
317 "developer_name": "Domotz (domotzpublicstore)",
318 "developer_link": "/publisher/domotzpublicstore",
319 "developer_validation": "verified",
320 },
321 {
322 "package_name": "adguard-home",
323 "icon_url": "/".join([icon_host, "2020/04/256.png"]),
324 "title": "AdGuard Home",
325 "developer_name": "AdGuard (ameshkov)",
326 "developer_link": "/publisher/ameshkov",
327 "developer_validation": "verified",
328 },
329 {
330 "package_name": "flexran",
331 "icon_url": "/".join([icon_host, "2018/04/m5g-flexran.png"]),
332 "title": "flexran",
333 "developer_name": "Mosaic 5G (mosaic-5g)",
334 "developer_link": "/publisher/mosaic-5g",
335 },
336 {
337 "package_name": "modem-manager",
338 "icon_url": "/".join([icon_host, "2020/05/mm-logo.png"]),
339 "title": "modem-manager",
340 "developer_name": "Canonical",
341 "developer_link": "/publisher/canonical",
342 "developer_validation": "verified",
343 },
344 {
345 "package_name": "snap-store-proxy",
346 "icon_url": "/".join(
347 [icon_host, "2018/09/Snapcraft_Proxy_Aubergine-256.png"]
348 ),
349 "title": "snap-store-proxy",
350 "developer_name": "Canonical",
351 "developer_link": "/publisher/canonical",
352 "developer_validation": "verified",
353 },
354 ]
356 board_images = [
357 {
358 "package_name": "pc",
359 "icon_url": "/".join([icon_host, "2016/07/icon_30.png"]),
360 "title": "PC",
361 "developer_name": "Canonical",
362 "developer_link": "/publisher/canonical",
363 "developer_validation": "verified",
364 },
365 {
366 "package_name": "rpi-imager",
367 "icon_url": "/".join([icon_host, "2020/03/rpi-imager.png"]),
368 "title": "rpi-imager",
369 "developer_name": "Dave Jones (waveform)",
370 "developer_link": "/publisher/waveform",
371 },
372 {
373 "package_name": "pi-desktop",
374 "icon_url": "/".join(
375 [assets_host, "be6eb412-snapcraft-missing-icon.svg"]
376 ),
377 "title": "pi-desktop",
378 "developer_name": "Canonical",
379 "developer_link": "/publisher/canonical",
380 "develper_validation": "verified",
381 },
382 {
383 "package_name": "pi",
384 "icon_url": "/".join(
385 [assets_host, "be6eb412-snapcraft-missing-icon.svg"]
386 ),
387 "title": "pi",
388 "developer_name": "Canonical",
389 "developer_link": "/publisher/canonical",
390 "developer_validation": "verified",
391 },
392 {
393 "package_name": "pi2",
394 "icon_url": "/".join([icon_host, "2015/04/berry.jpg.png"]),
395 "title": "pi2",
396 "developer_name": "Canonical",
397 "developer_link": "/publisher/canonical",
398 "developer_validation": "verified",
399 },
400 {
401 "package_name": "pi3",
402 "icon_url": "/".join(
403 [assets_host, "be6eb412-snapcraft-missing-icon.svg"]
404 ),
405 "title": "pi3",
406 "developer_name": "Canonical",
407 "developer_link": "/publisher/canonical",
408 "developer_validation": "verified",
409 },
410 ]
412 context = {
413 "devices": devices,
414 "robotics": robotics,
415 "smart_home": smart_home,
416 "networking": networking,
417 "board_images": board_images,
418 }
420 return (
421 flask.render_template("store/categories/iot.html", **context),
422 status_code,
423 )
425 @snapcraft.route("/about")
426 def about():
427 return flask.render_template("about/index.html")
429 @snapcraft.route("/about/publish")
430 def about_publish():
431 return flask.render_template("about/publish.html")
433 @snapcraft.route("/about/listing")
434 def about_listing():
435 return flask.render_template("about/listing.html")
437 @snapcraft.route("/about/release")
438 def about_release():
439 return flask.render_template("about/release.html")
441 @snapcraft.route("/about/publicise")
442 def about_publicise():
443 return flask.render_template("about/publicise.html")
445 @snapcraft.route("/about/contact-us")
446 def about_contact():
447 return flask.render_template("contact-us.html")
449 @snapcraft.route("/about/thank-you")
450 def about_thankyou():
451 return flask.render_template("thank-you.html")
453 @snapcraft.route("/community")
454 def community_redirect():
455 return flask.redirect("/")
457 @snapcraft.route("/create")
458 def create_redirect():
459 return flask.redirect("https://docs.snapcraft.io/build-snaps")
461 @snapcraft.route("/build")
462 def build():
463 status_code = 200
465 return flask.render_template("snapcraft/build.html"), status_code
467 @snapcraft.route("/sitemap.xml")
468 def sitemap():
469 xml_sitemap = flask.render_template(
470 "sitemap/sitemap-index.xml",
471 base_url="https://snapcraft.io",
472 )
473 response = flask.make_response(xml_sitemap)
474 response.headers["Content-Type"] = "application/xml"
476 return response
478 @snapcraft.route("/sitemap-links.xml")
479 def sitemap_links():
480 base_url = "https://snapcraft.io"
481 links = [
482 {"url": f"{base_url}/about"},
483 {"url": f"{base_url}/about/publish"},
484 {"url": f"{base_url}/about/listing"},
485 {"url": f"{base_url}/about/release"},
486 {"url": f"{base_url}/about/publicise"},
487 {"url": f"{base_url}/iot"},
488 ]
490 xml_sitemap = flask.render_template(
491 "sitemap/sitemap.xml",
492 base_url="https://snapcraft.io",
493 links=links,
494 )
495 response = flask.make_response(xml_sitemap)
496 response.headers["Content-Type"] = "application/xml"
497 response.headers["Cache-Control"] = "public, max-age=43200"
499 return response
501 return snapcraft