]>
Commit | Line | Data |
---|---|---|
940227cb MT |
1 | #!/usr/bin/python |
2 | ||
27066195 | 3 | import re |
940227cb | 4 | import textile |
27066195 MT |
5 | import tornado.database |
6 | import unicodedata | |
940227cb MT |
7 | |
8 | from accounts import Accounts | |
9 | from databases import Databases | |
10 | ||
11 | from misc import Singleton | |
12 | ||
13 | class PlanetEntry(object): | |
27066195 MT |
14 | def __init__(self, entry=None): |
15 | if entry: | |
16 | self.__entry = entry | |
17 | else: | |
18 | self.__entry = tornado.database.Row({ | |
19 | "id" : None, | |
20 | "title" : "", | |
21 | "markdown" : "", | |
22 | }) | |
23 | ||
24 | def set(self, key, val): | |
25 | self.__entry[key] = val | |
26 | ||
27 | @property | |
28 | def planet(self): | |
29 | return Planet() | |
940227cb MT |
30 | |
31 | @property | |
32 | def id(self): | |
33 | return self.__entry.id | |
34 | ||
35 | @property | |
36 | def slug(self): | |
37 | return self.__entry.slug | |
38 | ||
39 | @property | |
40 | def title(self): | |
41 | return self.__entry.title | |
42 | ||
43 | @property | |
44 | def published(self): | |
45 | return self.__entry.published | |
46 | ||
47 | @property | |
48 | def updated(self): | |
49 | return self.__entry.updated | |
50 | ||
51 | @property | |
52 | def markdown(self): | |
53 | return self.__entry.markdown | |
54 | ||
55 | @property | |
56 | def abstract(self): | |
57 | return self.render(self.markdown, 400) | |
58 | ||
59 | def render(self, text, limit=0): | |
27066195 | 60 | return self.planet.render(text, limit) |
940227cb MT |
61 | |
62 | @property | |
63 | def text(self): | |
64 | return self.render(self.markdown) | |
65 | ||
66 | @property | |
67 | def author(self): | |
68 | return Accounts().search(self.__entry.author_id) | |
69 | ||
70 | ||
71 | class Planet(object): | |
72 | __metaclass__ = Singleton | |
73 | ||
74 | @property | |
75 | def db(self): | |
76 | return Databases().webapp | |
77 | ||
78 | def get_authors(self): | |
79 | authors = [] | |
80 | for author in self.db.query("SELECT DISTINCT author_id FROM planet"): | |
81 | author = Accounts().search(author.author_id) | |
82 | if author: | |
83 | authors.append(author) | |
84 | ||
27066195 | 85 | return sorted(authors) |
940227cb MT |
86 | |
87 | def get_entry_by_slug(self, slug): | |
88 | entry = self.db.get("SELECT * FROM planet WHERE slug = %s", slug) | |
89 | if entry: | |
90 | return PlanetEntry(entry) | |
91 | ||
27066195 MT |
92 | def get_entry_by_id(self, id): |
93 | entry = self.db.get("SELECT * FROM planet WHERE id = %s", id) | |
94 | if entry: | |
95 | return PlanetEntry(entry) | |
96 | ||
940227cb MT |
97 | def _limit_and_offset_query(self, limit=None, offset=None): |
98 | query = " " | |
99 | ||
100 | if limit: | |
101 | if offset: | |
102 | query += "LIMIT %d,%d" % (offset, limit) | |
103 | else: | |
104 | query += "LIMIT %d" % limit | |
105 | ||
106 | return query | |
107 | ||
108 | def get_entries(self, limit=3, offset=None): | |
14624b27 | 109 | query = "SELECT * FROM planet WHERE acknowledged='Y' ORDER BY published DESC" |
940227cb MT |
110 | |
111 | # Respect limit and offset | |
112 | query += self._limit_and_offset_query(limit=limit, offset=offset) | |
113 | ||
114 | entries = [] | |
115 | for entry in self.db.query(query): | |
116 | entries.append(PlanetEntry(entry)) | |
117 | ||
118 | return entries | |
119 | ||
120 | def get_entries_by_author(self, author_id, limit=None, offset=None): | |
121 | query = "SELECT * FROM planet WHERE author_id = '%s'" % author_id | |
14624b27 | 122 | query += " AND acknowledged='Y' ORDER BY published DESC" |
940227cb MT |
123 | |
124 | # Respect limit and offset | |
125 | query += self._limit_and_offset_query(limit=limit, offset=offset) | |
126 | ||
940227cb MT |
127 | entries = self.db.query(query) |
128 | ||
129 | return [PlanetEntry(e) for e in entries] | |
27066195 MT |
130 | |
131 | def render(self, text, limit=0): | |
132 | if limit and len(text) >= limit: | |
133 | text = text[:limit] + "..." | |
134 | return textile.textile(text) | |
135 | ||
136 | def _generate_slug(self, title): | |
137 | slug = unicodedata.normalize("NFKD", title).encode("ascii", "ignore") | |
138 | slug = re.sub(r"[^\w]+", " ", slug) | |
139 | slug = "-".join(slug.lower().strip().split()) | |
140 | ||
141 | if not slug: | |
142 | slug = "entry" | |
143 | ||
144 | while True: | |
145 | e = self.db.get("SELECT * FROM planet WHERE slug = %s", slug) | |
146 | if not e: | |
147 | break | |
148 | slug += "-" | |
149 | ||
150 | return slug | |
151 | ||
152 | def update_entry(self, entry): | |
153 | self.db.execute("UPDATE planet SET title = %s, markdown = %s WHERE id = %s", | |
154 | entry.title, entry.markdown, entry.id) | |
155 | ||
156 | def save_entry(self, entry): | |
157 | slug = self._generate_slug(entry.title) | |
158 | ||
159 | self.db.execute("INSERT INTO planet(author_id, title, slug, markdown, published) " | |
160 | "VALUES(%s, %s, %s, %s, UTC_TIMESTAMP())", entry.author.uid, entry.title, | |
161 | slug, entry.markdown) | |
162 |