]>
git.ipfire.org Git - people/shoehn/ipfire.org.git/blob - webapp/backend/planet.py
c34898f0fe097191217cafd4b3ff09a2ab5c03a7
6 import tornado
.database
9 from accounts
import Accounts
10 from databases
import Databases
12 from misc
import Object
14 class PlanetEntry(Object
):
15 def __init__(self
, backend
, data
):
16 Object
.__init
__(self
, backend
)
28 def set_title(self
, title
):
29 if self
.title
== title
:
32 self
.db
.execute("UPDATE planet SET title = %s WHERE id = %s", title
, self
.id)
33 self
.data
["title"] = title
35 title
= property(lambda s
: s
.data
.title
, set_title
)
39 return "http://planet.ipfire.org/post/%s" % self
.slug
41 def set_published(self
, published
):
42 if self
.published
== published
:
45 self
.db
.execute("UPDATE planet SET published = %s WHERE id = %s",
47 self
.data
["published"] = published
49 published
= property(lambda s
: s
.data
.published
, set_published
)
53 return self
.published
.year
57 return self
.published
.month
61 return self
.data
.updated
63 def get_markdown(self
):
64 return self
.data
.markdown
66 def set_markdown(self
, markdown
):
67 if self
.markdown
== markdown
:
70 markup
= self
.render(markdown
)
71 self
.db
.execute("UPDATE planet SET markdown = %s, markup = %s WHERE id = %s",
72 markdown
, markup
, self
.id)
75 "markdown" : markdown
,
79 markdown
= property(get_markdown
, set_markdown
)
84 return self
.data
.markup
86 return self
.render(self
.markdown
)
90 return self
.render(self
.markdown
, 400)
92 def render(self
, text
, limit
=0):
93 return self
.planet
.render(text
, limit
)
102 if not hasattr(self
, "__author"):
103 self
.__author
= self
.accounts
.search(self
.data
.author_id
)
107 def set_status(self
, status
):
108 if self
.status
== status
:
111 self
.db
.execute("UPDATE planet SET status = %s WHERE id = %s", status
, self
.id)
112 self
.data
["status"] = status
114 status
= property(lambda s
: s
.data
.status
, set_status
)
117 return self
.status
== "draft"
119 def is_published(self
):
120 return self
.status
== "published"
125 if not hasattr(self
, "__tags"):
126 res
= self
.db
.query("SELECT tag FROM planet_tags \
127 WHERE post_id = %s ORDER BY tag", self
.id)
130 self
.__tags
.append(row
.tag
)
134 def set_tags(self
, tags
):
135 # Delete all existing tags.
136 self
.db
.execute("DELETE FROM planet_tags WHERE post_id = %s", self
.id)
138 self
.db
.executemany("INSERT INTO planet_tags(post_id, tag) VALUES(%s, %s)",
139 ((self
.id, tag
) for tag
in tags
))
145 tags
= property(get_tags
, set_tags
)
148 class Planet(Object
):
149 def get_authors(self
):
151 for author
in self
.db
.query("SELECT DISTINCT author_id FROM planet WHERE status = %s", "published"):
152 author
= self
.accounts
.search(author
.author_id
)
154 authors
.append(author
)
156 return sorted(authors
)
159 res
= self
.db
.query("SELECT DISTINCT YEAR(published) AS year \
160 FROM planet WHERE status = %s ORDER BY year DESC", "published")
162 return [row
.year
for row
in res
]
164 def get_entry_by_slug(self
, slug
):
165 entry
= self
.db
.get("SELECT * FROM planet WHERE slug = %s", slug
)
167 return PlanetEntry(self
.backend
, entry
)
169 def get_entry_by_id(self
, id):
170 entry
= self
.db
.get("SELECT * FROM planet WHERE id = %s", id)
172 return PlanetEntry(self
.backend
, entry
)
174 def _limit_and_offset_query(self
, limit
=None, offset
=None):
179 query
+= "LIMIT %d,%d" % (offset
, limit
)
181 query
+= "LIMIT %d" % limit
185 def get_entries(self
, limit
=3, offset
=None, status
="published", author_id
=None):
186 query
= "SELECT * FROM planet"
187 args
, clauses
= [], []
190 clauses
.append("status = %s")
194 clauses
.append("author_id = %s")
195 args
.append(author_id
)
198 query
+= " WHERE %s" % " AND ".join(clauses
)
200 query
+= " ORDER BY published DESC"
202 # Respect limit and offset
205 query
+= " LIMIT %s,%s"
206 args
+= [offset
, limit
,]
212 for entry
in self
.db
.query(query
, *args
):
213 entry
= PlanetEntry(self
.backend
, entry
)
214 entries
.append(entry
)
218 def get_entries_by_author(self
, author_id
, limit
=None, offset
=None):
219 return self
.get_entries(limit
=limit
, offset
=offset
, author_id
=author_id
)
221 def get_entries_by_year(self
, year
):
222 entries
= self
.db
.query("SELECT * FROM planet \
223 WHERE status = %s AND YEAR(published) = %s ORDER BY published DESC",
226 return [PlanetEntry(self
.backend
, e
) for e
in entries
]
228 def render(self
, text
, limit
=0):
229 if limit
and len(text
) >= limit
:
230 text
= text
[:limit
] + "..."
232 return textile
.textile(text
)
234 def _generate_slug(self
, title
):
235 slug
= unicodedata
.normalize("NFKD", title
).encode("ascii", "ignore")
236 slug
= re
.sub(r
"[^\w]+", " ", slug
)
237 slug
= "-".join(slug
.lower().strip().split())
243 e
= self
.db
.get("SELECT * FROM planet WHERE slug = %s", slug
)
250 def create(self
, title
, markdown
, author
, status
="published", tags
=None, published
=None):
251 slug
= self
._generate
_slug
(title
)
252 markup
= self
.render(markdown
)
254 if published
is None:
255 published
= datetime
.datetime
.utcnow()
257 id = self
.db
.execute("INSERT INTO planet(author_id, slug, title, status, \
258 markdown, markup, published) VALUES(%s, %s, %s, %s, %s, %s, %s)",
259 author
.uid
, slug
, title
, status
, markdown
, markup
, published
)
261 entry
= self
.get_entry_by_id(id)
268 def update_entry(self
, entry
):
269 self
.db
.execute("UPDATE planet SET title = %s, markdown = %s WHERE id = %s",
270 entry
.title
, entry
.markdown
, entry
.id)
272 def save_entry(self
, entry
):
273 slug
= self
._generate
_slug
(entry
.title
)
275 id = self
.db
.execute("INSERT INTO planet(author_id, title, slug, markdown, published) "
276 "VALUES(%s, %s, %s, %s, UTC_TIMESTAMP())", entry
.author
.uid
, entry
.title
,
277 slug
, entry
.markdown
)
281 def search(self
, what
):
285 query
= "SELECT planet.* FROM planet INNER JOIN ( \
286 SELECT post_id FROM planet_tags \
287 INNER JOIN planet ON planet_tags.post_id = planet.id \
288 WHERE %s GROUP BY post_id HAVING COUNT(post_id) = %%s \
289 ) pt ON planet.id = pt.post_id ORDER BY published DESC"
291 args
= (tags
, len(tags
))
293 clauses
, args
= [], tags
295 clauses
.append("planet_tags.tag = %s")
296 args
.append(len(tags
))
298 entries
= self
.db
.query(query
% " OR ".join(clauses
), *args
)
299 return [PlanetEntry(self
.backend
, e
) for e
in entries
]
301 def search_autocomplete(self
, what
):
303 last_tag
= tags
.pop()
305 res
= self
.db
.query("SELECT tag, COUNT(tag) AS count FROM planet_tags \
306 WHERE tag LIKE %s GROUP BY tag ORDER BY count DESC", "%s%%" % last_tag
)
309 return ["%s %s" % (" ".join(tags
), row
.tag
) for row
in res
]
311 return [row
.tag
for row
in res
]