Coverage for webapp/blog/views.py: 25%
75 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 flask
2import talisker
4from canonicalwebteam import image_template
5from canonicalwebteam.blog import (
6 BlogViews,
7 BlogAPI,
8 build_blueprint,
9 NotFoundError,
10)
11from dateutil import parser
12from requests.exceptions import RequestException
15def init_blog(app, url_prefix):
16 session = talisker.requests.get_session()
17 blog_api = BlogAPI(
18 session=session,
19 thumbnail_width=354,
20 thumbnail_height=199,
21 )
22 blog = build_blueprint(
23 BlogViews(
24 api=blog_api,
25 blog_title="Snapcraft Blog",
26 tag_ids=[2996],
27 excluded_tags=[3184, 3265, 3408],
28 )
29 )
31 @blog.route("/api/snap-posts/<snap>")
32 def snap_posts(snap):
33 try:
34 blog_tags = blog_api.get_tag_by_slug(f"sc:snap:{snap}")
35 except NotFoundError:
36 blog_tags = None
38 blog_articles = None
39 articles = []
41 if blog_tags:
42 snapcraft_tag = blog_api.get_tag_by_slug("snapcraft.io")
44 try:
45 blog_articles, total_pages = blog_api.get_articles(
46 tags=blog_tags["id"],
47 tags_exclude=[3184, 3265, 3408],
48 per_page=3 - len(articles),
49 )
50 except RequestException:
51 blog_articles = []
53 for article in blog_articles:
54 if article["image"]:
55 featured_media = image_template(
56 url=article["image"]["source_url"],
57 alt="",
58 width="346",
59 height="231",
60 fill=True,
61 hi_def=True,
62 loading="auto",
63 )
64 else:
65 featured_media = None
67 url = f"/blog/{article['slug']}"
69 if snapcraft_tag["id"] not in article["tags"]:
70 url = f"https://ubuntu.com{url}"
72 articles.append(
73 {
74 "slug": url,
75 "title": article["title"]["rendered"],
76 "image": featured_media,
77 }
78 )
80 return flask.jsonify(articles)
82 @blog.route("/api/series/<series>")
83 def snap_series(series):
84 blog_articles = None
85 articles = []
87 try:
88 blog_articles, total_pages = blog_api.get_articles(series)
89 except RequestException:
90 blog_articles = []
92 for article in blog_articles:
93 articles.append(
94 {
95 "slug": article["slug"],
96 "title": article["title"]["rendered"],
97 }
98 )
100 return flask.jsonify(articles)
102 @blog.context_processor
103 def add_newsletter():
104 newsletter_subscribed = flask.request.args.get(
105 "newsletter", default=False, type=bool
106 )
108 return {"newsletter_subscribed": newsletter_subscribed}
110 @blog.route("/sitemap.xml")
111 def sitemap():
112 base_url = "https://snapcraft.io/blog"
113 links = []
114 page = 1
115 while True:
116 url = (
117 f"https://ubuntu.com/blog/wp-json/wp/v2/posts?"
118 f"tags=2996&per_page=100&page={page}"
119 f"&tags_exclude=3184%2C3265%2C3408"
120 )
122 response = session.get(url)
123 if response.status_code == 400:
124 break
126 try:
127 blog_response = response.json()
128 except Exception:
129 continue
131 for post in blog_response:
132 try:
133 date = (
134 parser.parse(post["date"])
135 .replace(tzinfo=None)
136 .strftime("%Y-%m-%d")
137 )
138 links.append(
139 {
140 "url": base_url + "/" + post["slug"],
141 "last_udpated": date,
142 }
143 )
144 except Exception:
145 continue
147 page = page + 1
149 xml_sitemap = flask.render_template(
150 "sitemap/sitemap.xml",
151 base_url=base_url,
152 links=links,
153 )
155 response = flask.make_response(xml_sitemap)
156 response.headers["Content-Type"] = "application/xml"
157 response.headers["Cache-Control"] = "public, max-age=43200"
159 return response
161 app.register_blueprint(blog, url_prefix=url_prefix)