]>
git.ipfire.org Git - people/shoehn/ipfire.org.git/blob - webapp/backend/planet.py
5 import tornado
.database
8 from accounts
import Accounts
9 from databases
import Databases
11 from misc
import Object
13 class PlanetEntry(Object
):
14 def __init__(self
, backend
, data
):
15 Object
.__init
__(self
, backend
)
29 return self
.data
.title
33 return "http://planet.ipfire.org/post/%s" % self
.slug
37 return self
.data
.published
41 return self
.published
.year
45 return self
.published
.month
49 return self
.data
.updated
53 return self
.data
.markdown
58 return self
.data
.markup
60 return self
.render(self
.markdown
)
64 return self
.render(self
.markdown
, 400)
66 def render(self
, text
, limit
=0):
67 return self
.planet
.render(text
, limit
)
76 if not hasattr(self
, "__author"):
77 self
.__author
= self
.accounts
.search(self
.data
.author_id
)
84 if not hasattr(self
, "__tags"):
85 res
= self
.db
.query("SELECT tag FROM planet_tags \
86 WHERE post_id = %s ORDER BY tag", self
.id)
89 self
.__tags
.append(row
.tag
)
93 def set_tags(self
, tags
):
94 # Delete all existing tags.
95 self
.db
.execute("DELETE FROM planet_tags WHERE post_id = %s", self
.id)
97 self
.db
.executemany("INSERT INTO planet_tags(post_id, tag) VALUES(%s, %s)",
98 ((self
.id, tag
) for tag
in tags
))
104 tags
= property(get_tags
, set_tags
)
107 class Planet(Object
):
108 def get_authors(self
):
110 for author
in self
.db
.query("SELECT DISTINCT author_id FROM planet WHERE status = %s", "published"):
111 author
= self
.accounts
.search(author
.author_id
)
113 authors
.append(author
)
115 return sorted(authors
)
118 res
= self
.db
.query("SELECT DISTINCT YEAR(published) AS year \
119 FROM planet WHERE status = %s ORDER BY year DESC", "published")
121 return [row
.year
for row
in res
]
123 def get_entry_by_slug(self
, slug
):
124 entry
= self
.db
.get("SELECT * FROM planet WHERE slug = %s", slug
)
126 return PlanetEntry(self
.backend
, entry
)
128 def get_entry_by_id(self
, id):
129 entry
= self
.db
.get("SELECT * FROM planet WHERE id = %s", id)
131 return PlanetEntry(self
.backend
, entry
)
133 def _limit_and_offset_query(self
, limit
=None, offset
=None):
138 query
+= "LIMIT %d,%d" % (offset
, limit
)
140 query
+= "LIMIT %d" % limit
144 def get_entries(self
, limit
=3, offset
=None, status
="published", author_id
=None):
145 query
= "SELECT * FROM planet"
146 args
, clauses
= [], []
149 clauses
.append("status = %s")
153 clauses
.append("author_id = %s")
154 args
.append(author_id
)
157 query
+= " WHERE %s" % " AND ".join(clauses
)
159 query
+= " ORDER BY published DESC"
161 # Respect limit and offset
164 query
+= " LIMIT %s,%s"
165 args
+= [offset
, limit
,]
171 for entry
in self
.db
.query(query
, *args
):
172 entry
= PlanetEntry(self
.backend
, entry
)
173 entries
.append(entry
)
177 def get_entries_by_author(self
, author_id
, limit
=None, offset
=None):
178 return self
.get_entries(limit
=limit
, offset
=offset
, author_id
=author_id
)
180 def get_entries_by_year(self
, year
):
181 entries
= self
.db
.query("SELECT * FROM planet \
182 WHERE status = %s AND YEAR(published) = %s ORDER BY published DESC",
185 return [PlanetEntry(self
.backend
, e
) for e
in entries
]
187 def render(self
, text
, limit
=0):
188 if limit
and len(text
) >= limit
:
189 text
= text
[:limit
] + "..."
191 return textile
.textile(text
)
193 def _generate_slug(self
, title
):
194 slug
= unicodedata
.normalize("NFKD", title
).encode("ascii", "ignore")
195 slug
= re
.sub(r
"[^\w]+", " ", slug
)
196 slug
= "-".join(slug
.lower().strip().split())
202 e
= self
.db
.get("SELECT * FROM planet WHERE slug = %s", slug
)
209 def update_entry(self
, entry
):
210 self
.db
.execute("UPDATE planet SET title = %s, markdown = %s WHERE id = %s",
211 entry
.title
, entry
.markdown
, entry
.id)
213 def save_entry(self
, entry
):
214 slug
= self
._generate
_slug
(entry
.title
)
216 id = self
.db
.execute("INSERT INTO planet(author_id, title, slug, markdown, published) "
217 "VALUES(%s, %s, %s, %s, UTC_TIMESTAMP())", entry
.author
.uid
, entry
.title
,
218 slug
, entry
.markdown
)
222 def search(self
, what
):
226 query
= "SELECT planet.* FROM planet INNER JOIN ( \
227 SELECT post_id FROM planet_tags \
228 INNER JOIN planet ON planet_tags.post_id = planet.id \
229 WHERE %s GROUP BY post_id HAVING COUNT(post_id) = %%s \
230 ) pt ON planet.id = pt.post_id ORDER BY published DESC"
232 args
= (tags
, len(tags
))
234 clauses
, args
= [], tags
236 clauses
.append("planet_tags.tag = %s")
237 args
.append(len(tags
))
239 entries
= self
.db
.query(query
% " OR ".join(clauses
), *args
)
240 return [PlanetEntry(self
.backend
, e
) for e
in entries
]
242 def search_autocomplete(self
, what
):
244 last_tag
= tags
.pop()
246 res
= self
.db
.query("SELECT tag, COUNT(tag) AS count FROM planet_tags \
247 WHERE tag LIKE %s GROUP BY tag ORDER BY count DESC", "%s%%" % last_tag
)
250 return ["%s %s" % (" ".join(tags
), row
.tag
) for row
in res
]
252 return [row
.tag
for row
in res
]