Coverage for webapp/first_snap/views.py: 91%
114 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-28 22:05 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-28 22:05 +0000
1import os
2import re
3from io import StringIO
5import flask
6from webapp import helpers
8YAML_KEY_REGEXP = re.compile(r"([^\s:]*)(:.*)")
9FSF_FLOW = "first-snap"
12first_snap = flask.Blueprint(
13 "fist_snap_flow",
14 __name__,
15 template_folder="/templates",
16 static_folder="/static",
17)
20def transform_snapcraft_yaml(snapcraft_yaml):
21 """
22 Transforms a snapcraft.yaml dict top-level key
23 values into renderable HTML.
25 Keyword arguments:
26 snapcraft_yaml -- content of a snapcraft.yaml file
27 """
28 for key in snapcraft_yaml:
29 stream = StringIO()
30 data = {}
31 data[key] = snapcraft_yaml[key]
32 helpers.dump_yaml(data, stream, typ="rt")
33 stream = stream.getvalue()
35 # Assuming content starts with yaml key name, wrap it in <b>
36 # for some code highligthing in HTML
37 content = re.sub(YAML_KEY_REGEXP, r"<b>\1</b>\2", stream)
38 snapcraft_yaml[key] = content
40 return snapcraft_yaml
43def directory_exists(file):
44 return os.path.isdir(os.path.join(flask.current_app.root_path, file))
47@first_snap.route("/")
48def get_pick_language():
49 return flask.render_template("first-snap/language.html")
52@first_snap.route("/<language>")
53def get_language(language):
54 filename = f"first_snap/content/{language}"
55 if not directory_exists(filename):
56 return flask.abort(404)
58 context = {"language": language, "fsf_flow": FSF_FLOW}
59 return flask.render_template(
60 "first-snap/install-snapcraft.html", **context
61 )
64@first_snap.route("/<language>/snapcraft.yaml")
65def get_language_snapcraft_yaml(language):
66 filename = f"first_snap/content/{language}/package.yaml"
67 snapcraft_yaml_filename = f"first_snap/content/{language}/snapcraft.yaml"
68 snap_name_cookie = f"fsf_snap_name_{language}"
69 steps = helpers.get_yaml(filename, typ="rt")
71 if not steps:
72 return flask.abort(404)
74 snap_name = steps["name"]
76 if snap_name_cookie in flask.request.cookies:
77 snap_name = flask.request.cookies.get(snap_name_cookie)
79 snapcraft_yaml = helpers.get_file(
80 snapcraft_yaml_filename, {"${name}": snap_name}
81 )
83 if not snapcraft_yaml:
84 return flask.abort(404)
86 return flask.Response(
87 snapcraft_yaml,
88 mimetype="text/yaml",
89 headers={"Content-Disposition": "attachment;filename=snapcraft.yaml"},
90 )
93@first_snap.route("/<language>/<operating_system>/package")
94def get_package(language, operating_system):
95 filename = f"first_snap/content/{language}/package.yaml"
96 snapcraft_yaml_filename = f"first_snap/content/{language}/snapcraft.yaml"
97 annotations_filename = "first_snap/content/snapcraft_yaml_annotations.yaml"
99 snap_name_cookie = f"fsf_snap_name_{language}"
100 steps = helpers.get_yaml(filename, typ="rt")
102 if not steps:
103 return flask.abort(404)
105 snap_name = steps["name"]
106 has_user_chosen_name = False
108 if "publisher" in flask.session:
109 user_name = flask.session["publisher"]["nickname"]
110 snap_name = snap_name.replace("{name}", user_name)
112 if snap_name_cookie in flask.request.cookies:
113 snap_name = flask.request.cookies.get(snap_name_cookie)
114 has_user_chosen_name = True
116 context = {
117 "language": language,
118 "os": operating_system,
119 "steps": steps,
120 "snap_name": snap_name,
121 "has_user_chosen_name": has_user_chosen_name,
122 "fsf_flow": FSF_FLOW,
123 }
125 snapcraft_yaml = helpers.get_yaml(
126 snapcraft_yaml_filename, typ="rt", replaces={"${name}": snap_name}
127 )
128 annotations = helpers.get_yaml(annotations_filename, typ="rt")
130 if snapcraft_yaml:
131 context["snapcraft_yaml"] = transform_snapcraft_yaml(snapcraft_yaml)
132 context["annotations"] = annotations
133 return flask.render_template("first-snap/package.html", **context)
134 else:
135 return flask.abort(404)
138@first_snap.route("/<language>/<operating_system>/build-and-test")
139def get_build(language, operating_system):
140 build_filename = f"first_snap/content/{language}/build.yaml"
141 test_filename = f"first_snap/content/{language}/test.yaml"
142 snap_name_cookie = f"fsf_snap_name_{language}"
143 build_steps = helpers.get_yaml(build_filename, typ="rt")
144 test_steps = helpers.get_yaml(test_filename, typ="rt")
145 operating_system_parts = operating_system.split("-")
147 operating_system_only = operating_system_parts[0]
148 install_type = (
149 operating_system_parts[1]
150 if len(operating_system_parts) == 2
151 else "auto"
152 )
154 if (
155 (not (build_steps and test_steps))
156 or (
157 (operating_system_only not in build_steps)
158 and (operating_system_only not in test_steps)
159 )
160 or (install_type not in build_steps[operating_system_only])
161 ):
162 return flask.abort(404)
164 snap_name = build_steps["name"]
166 if "publisher" in flask.session:
167 user_name = flask.session["publisher"]["nickname"]
168 snap_name = snap_name.replace("{name}", user_name)
170 if snap_name_cookie in flask.request.cookies:
171 snap_name = flask.request.cookies.get(snap_name_cookie)
173 context = {
174 "language": language,
175 "os": operating_system,
176 "build_steps": build_steps[operating_system_only][install_type],
177 "test_steps": test_steps[operating_system_only],
178 "snap_name": snap_name,
179 "fsf_flow": FSF_FLOW,
180 }
182 return flask.render_template("first-snap/build-and-test.html", **context)
185@first_snap.route("/<language>/<operating_system>/push")
186def get_push(language, operating_system):
187 return flask.redirect(f"/first-snap/{language}/{operating_system}/upload")
190@first_snap.route("/<language>/<operating_system>/upload")
191def get_upload(language, operating_system):
192 filename = f"first_snap/content/{language}/package.yaml"
193 snap_name_cookie = f"fsf_snap_name_{language}"
195 data = helpers.get_yaml(filename, typ="rt")
197 if not data:
198 return flask.abort(404)
200 snap_name = data["name"]
201 has_user_chosen_name = False
203 if "publisher" in flask.session:
204 user_name = flask.session["publisher"]["nickname"]
205 snap_name = snap_name.replace("{name}", user_name)
207 if snap_name_cookie in flask.request.cookies:
208 snap_name = flask.request.cookies.get(snap_name_cookie)
209 has_user_chosen_name = True
211 flask_user = flask.session.get("publisher", {})
213 if "nickname" in flask_user:
214 user = {
215 "image": flask_user["image"],
216 "username": flask_user["nickname"],
217 "display_name": flask_user["fullname"],
218 "email": flask_user["email"],
219 }
220 else:
221 user = None
223 context = {
224 "language": language,
225 "os": operating_system,
226 "user": user,
227 "snap_name": snap_name,
228 "has_user_chosen_name": has_user_chosen_name,
229 "fsf_flow": FSF_FLOW,
230 }
232 return flask.render_template("first-snap/upload.html", **context)