Coverage for webapp / blog / views.py: 23%
86 statements
« prev ^ index » next coverage.py v7.13.1, created at 2025-12-29 22:06 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2025-12-29 22:06 +0000
1import flask
2import requests
4from canonicalwebteam import image_template
5from canonicalwebteam.blog import (
6 BlogViews,
7 BlogAPI,
8 build_blueprint,
9 NotFoundError,
10)
11from cache.cache_utility import redis_cache
12from dateutil import parser
13from requests.exceptions import RequestException
16def init_blog(app, url_prefix):
17 session = requests.Session()
18 blog_api = BlogAPI(
19 session=session,
20 thumbnail_width=354,
21 thumbnail_height=199,
22 )
23 blog = build_blueprint(
24 BlogViews(
25 api=blog_api,
26 blog_title="Snapcraft Blog",
27 tag_ids=[2996],
28 excluded_tags=[3184, 3265, 3408],
29 )
30 )
32 @blog.route("/api/snap-posts/<snap>")
33 def snap_posts(snap):
34 cached_articles_key = f"snap_posts:{snap}"
35 cached_articles = redis_cache.get(
36 cached_articles_key, expected_type=list
37 )
38 if cached_articles:
39 return flask.jsonify(cached_articles)
41 try:
42 blog_tags = blog_api.get_tag_by_slug(f"sc:snap:{snap}")
43 except NotFoundError:
44 blog_tags = None
46 blog_articles = None
47 articles = []
49 if blog_tags:
50 snapcraft_tag = blog_api.get_tag_by_slug("snapcraft.io")
52 try:
53 blog_articles, total_pages = blog_api.get_articles(
54 tags=blog_tags["id"],
55 tags_exclude=[3184, 3265, 3408],
56 per_page=3 - len(articles),
57 )
58 except RequestException:
59 blog_articles = []
61 for article in blog_articles:
62 if article["image"]:
63 featured_media = image_template(
64 url=article["image"]["source_url"],
65 alt="",
66 width="346",
67 height="231",
68 fill=True,
69 hi_def=True,
70 loading="auto",
71 )
72 else:
73 featured_media = None
75 url = f"/blog/{article['slug']}"
77 if snapcraft_tag["id"] not in article["tags"]:
78 url = f"https://ubuntu.com{url}"
80 articles.append(
81 {
82 "slug": url,
83 "title": article["title"]["rendered"],
84 "image": featured_media,
85 }
86 )
87 redis_cache.set(cached_articles_key, articles, ttl=3600)
88 return flask.jsonify(articles)
90 @blog.route("/api/series/<series>")
91 def snap_series(series):
92 cached_articles_key = f"snap_series:{series}"
93 cached_articles = redis_cache.get(
94 cached_articles_key, expected_type=list
95 )
96 if cached_articles:
97 return flask.jsonify(cached_articles)
99 blog_articles = None
100 articles = []
102 try:
103 blog_articles, total_pages = blog_api.get_articles(series)
104 except RequestException:
105 blog_articles = []
107 for article in blog_articles:
108 articles.append(
109 {
110 "slug": article["slug"],
111 "title": article["title"]["rendered"],
112 }
113 )
114 redis_cache.set(cached_articles_key, articles, ttl=3600)
115 return flask.jsonify(articles)
117 @blog.context_processor
118 def add_newsletter():
119 newsletter_subscribed = flask.request.args.get(
120 "newsletter", default=False, type=bool
121 )
123 return {"newsletter_subscribed": newsletter_subscribed}
125 @blog.route("/sitemap.xml")
126 def sitemap():
127 base_url = "https://snapcraft.io/blog"
128 links = []
129 page = 1
130 while True:
131 url = (
132 f"https://ubuntu.com/blog/wp-json/wp/v2/posts?"
133 f"tags=2996&per_page=100&page={page}"
134 f"&tags_exclude=3184%2C3265%2C3408"
135 )
137 response = session.get(url)
138 if response.status_code == 400:
139 break
141 try:
142 blog_response = response.json()
143 except Exception:
144 continue
146 for post in blog_response:
147 try:
148 date = (
149 parser.parse(post["date"])
150 .replace(tzinfo=None)
151 .strftime("%Y-%m-%d")
152 )
153 links.append(
154 {
155 "url": base_url + "/" + post["slug"],
156 "last_udpated": date,
157 }
158 )
159 except Exception:
160 continue
162 page = page + 1
164 xml_sitemap = flask.render_template(
165 "sitemap/sitemap.xml",
166 base_url=base_url,
167 links=links,
168 )
170 response = flask.make_response(xml_sitemap)
171 response.headers["Content-Type"] = "application/xml"
172 response.headers["Cache-Control"] = "public, max-age=43200"
174 return response
176 app.register_blueprint(blog, url_prefix=url_prefix)