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

1import flask 

2import talisker 

3 

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 

13 

14 

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 ) 

30 

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 

37 

38 blog_articles = None 

39 articles = [] 

40 

41 if blog_tags: 

42 snapcraft_tag = blog_api.get_tag_by_slug("snapcraft.io") 

43 

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 = [] 

52 

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 

66 

67 url = f"/blog/{article['slug']}" 

68 

69 if snapcraft_tag["id"] not in article["tags"]: 

70 url = f"https://ubuntu.com{url}" 

71 

72 articles.append( 

73 { 

74 "slug": url, 

75 "title": article["title"]["rendered"], 

76 "image": featured_media, 

77 } 

78 ) 

79 

80 return flask.jsonify(articles) 

81 

82 @blog.route("/api/series/<series>") 

83 def snap_series(series): 

84 blog_articles = None 

85 articles = [] 

86 

87 try: 

88 blog_articles, total_pages = blog_api.get_articles(series) 

89 except RequestException: 

90 blog_articles = [] 

91 

92 for article in blog_articles: 

93 articles.append( 

94 { 

95 "slug": article["slug"], 

96 "title": article["title"]["rendered"], 

97 } 

98 ) 

99 

100 return flask.jsonify(articles) 

101 

102 @blog.context_processor 

103 def add_newsletter(): 

104 newsletter_subscribed = flask.request.args.get( 

105 "newsletter", default=False, type=bool 

106 ) 

107 

108 return {"newsletter_subscribed": newsletter_subscribed} 

109 

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 ) 

121 

122 response = session.get(url) 

123 if response.status_code == 400: 

124 break 

125 

126 try: 

127 blog_response = response.json() 

128 except Exception: 

129 continue 

130 

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 

146 

147 page = page + 1 

148 

149 xml_sitemap = flask.render_template( 

150 "sitemap/sitemap.xml", 

151 base_url=base_url, 

152 links=links, 

153 ) 

154 

155 response = flask.make_response(xml_sitemap) 

156 response.headers["Content-Type"] = "application/xml" 

157 response.headers["Cache-Control"] = "public, max-age=43200" 

158 

159 return response 

160 

161 app.register_blueprint(blog, url_prefix=url_prefix)