Coverage for webapp/snapcraft/views.py : 47%

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