]>
git.ipfire.org Git - ipfire.org.git/blob - src/backend/blog.py
980cc676265115c41d4865d096d3675250c39a66
10 class Blog(misc
.Object
):
11 def _get_post(self
, query
, *args
):
12 res
= self
.db
.get(query
, *args
)
15 return Post(self
.backend
, res
.id, data
=res
)
17 def _get_posts(self
, query
, *args
):
18 res
= self
.db
.query(query
, *args
)
21 yield Post(self
.backend
, row
.id, data
=row
)
23 def get_by_id(self
, id):
24 return self
._get
_post
("SELECT * FROM blog \
27 def get_by_slug(self
, slug
):
28 return self
._get
_post
("SELECT * FROM blog \
29 WHERE slug = %s AND published_at <= NOW()", slug
)
31 def get_newest(self
, limit
=None):
32 return self
._get
_posts
("SELECT * FROM blog \
33 WHERE published_at IS NOT NULL \
34 AND published_at <= NOW() \
35 ORDER BY published_at DESC LIMIT %s", limit
)
37 def get_by_tag(self
, tag
, limit
=None):
38 return self
._get
_posts
("SELECT * FROM blog \
39 WHERE published_at IS NOT NULL \
40 AND published_at <= NOW() \
42 ORDER BY published_at DESC LIMIT %s", tag
, limit
)
44 def get_by_author(self
, author
, limit
=None):
45 return self
._get
_posts
("SELECT * FROM blog \
46 WHERE (author = %s OR author_uid = %s) \
47 AND published_at IS NOT NULL \
48 AND published_at <= NOW() \
49 ORDER BY published_at DESC LIMIT %s",
50 author
.name
, author
.uid
, limit
)
52 def get_by_year(self
, year
):
53 return self
._get
_posts
("SELECT * FROM blog \
54 WHERE EXTRACT(year FROM published_at) = %s \
55 AND published_at IS NOT NULL \
56 AND published_at <= NOW() \
57 ORDER BY published_at DESC", year
)
59 def search(self
, query
, limit
=None):
60 return self
._get
_posts
("SELECT blog.* FROM blog \
61 LEFT JOIN blog_search_index search_index ON blog.id = search_index.post_id \
62 WHERE search_index.document @@ to_tsquery('english', %s) \
63 ORDER BY ts_rank(search_index.document, to_tsquery('english', %s)) DESC \
64 LIMIT %s", query
, query
, limit
)
66 def _make_slug(self
, s
):
67 # Remove any non-ASCII characters
69 s
= unicodedata
.normalize("NFKD", s
)
73 # Remove excessive whitespace
74 s
= re
.sub(r
"[^\w]+", " ", s
)
76 slug
= "-".join(s
.split()).lower()
79 e
= self
.db
.get("SELECT 1 FROM blog WHERE slug = %s", slug
)
89 Needs to be called after a post has been changed
90 and updates the search index.
92 self
.db
.execute("REFRESH MATERIALIZED VIEW blog_search_index")
96 res
= self
.db
.query("SELECT DISTINCT EXTRACT(year FROM published_at)::integer AS year \
97 FROM blog WHERE published_at IS NOT NULL AND published_at <= NOW() \
103 def update_feeds(self
):
105 Updates all enabled feeds
107 for feed
in self
.db
.query("SELECT * FROM blog_feeds WHERE enabled IS TRUE"):
109 f
= feedparser
.parse(feed
.url
)
110 except Exception as e
:
113 with self
.db
.transaction():
115 self
.db
.execute("UPDATE blog_feeds SET name = %s \
116 WHERE id = %s", f
.feed
.title
, feed
.id)
118 # Walk through all entries
119 for entry
in f
.entries
:
120 # Skip everything without the "blog.ipfire.org" tag
122 tags
= list((t
.term
for t
in entry
.tags
))
124 if not "blog.ipfire.org" in tags
:
126 except AttributeError:
129 # Get link to the posting site
130 link
= entry
.links
[0].href
132 # Check if the entry has already been imported
133 res
= self
.db
.get("SELECT id, (updated_at < %s) AS needs_update \
134 FROM blog WHERE feed_id = %s AND foreign_id = %s",
135 entry
.updated
, feed
.id, entry
.id)
137 # If the post needs to be updated, we do so
139 self
.db
.execute("UPDATE blog SET title = %s, author = %s, \
140 published_at = %s, updated_at = %s, html = %s, link = %s, \
141 tags = %s WHERE id = %s", entry
.title
, entry
.author
,
142 entry
.published
, entry
.updated
, entry
.summary
, link
,
143 feed
.tags
+ tags
, res
.id)
148 # Insert the new post
149 self
.db
.execute("INSERT INTO blog(title, slug, author, \
150 published_at, html, link, tags, updated_at, feed_id, foreign_id) \
151 VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
152 entry
.title
, self
._make
_slug
(entry
.title
), entry
.author
,
153 entry
.published
, entry
.summary
, link
, feed
.tags
+ tags
,
154 entry
.updated
, feed
.id, entry
.id)
156 # Mark feed as updated
157 self
.db
.execute("UPDATE blog_feeds SET last_updated_at = CURRENT_TIMESTAMP \
158 WHERE id = %s" % feed
.id)
160 # Refresh the search index
161 with self
.db
.transaction():
165 class Post(misc
.Object
):
166 def init(self
, id, data
=None):
172 return self
.data
.title
176 return self
.data
.slug
181 if self
.data
.author_uid
:
182 return self
.backend
.accounts
.get_by_uid(self
.data
.author_uid
)
184 return self
.data
.author
187 def created_at(self
):
188 return self
.data
.created_at
191 def published_at(self
):
192 return self
.data
.published_at
196 return self
.data
.markdown
201 Returns this post as rendered HTML
203 return self
.data
.html
or textile
.textile(self
.markdown
.decode("utf-8"))
207 return self
.data
.tags
211 return self
.data
.link
216 return self
.backend
.releases
._get
_release
("SELECT * FROM releases \
217 WHERE published IS NOT NULL AND published <= NOW() AND blog_id = %s", self
.id)