]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blobdiff - webapp/backend/planet.py
planet: Add proper tag search function.
[people/shoehn/ipfire.org.git] / webapp / backend / planet.py
index 3bc5f846d1645dc283e8fc0d0be433c8b671b945..a1ea61e1b4760611e1b4079770b9044b400fd449 100644 (file)
@@ -11,7 +11,9 @@ from databases import Databases
 from misc import Singleton
 
 class PlanetEntry(object):
-       def __init__(self, entry=None):
+       def __init__(self, db, entry=None):
+               self.db = db
+
                if entry:
                        self.__entry = entry
                else:
@@ -19,6 +21,7 @@ class PlanetEntry(object):
                                "id" : None,
                                "title" : "",
                                "markdown" : "",
+                               "tags" : [],
                        })
 
        def set(self, key, val):
@@ -75,6 +78,31 @@ class PlanetEntry(object):
        def author(self):
                return Accounts().search(self.__entry.author_id)
 
+       # Tags
+
+       def get_tags(self):
+               if not hasattr(self, "__tags"):
+                       res = self.db.query("SELECT tag FROM planet_tags \
+                               WHERE post_id = %s ORDER BY tag", self.id)
+                       self.__tags = []
+                       for row in res:
+                               self.__tags.append(row.tag)
+
+               return self.__tags
+
+       def set_tags(self, tags):
+               # Delete all existing tags.
+               self.db.execute("DELETE FROM planet_tags WHERE post_id = %s", self.id)
+
+               self.db.executemany("INSERT INTO planet_tags(post_id, tag) VALUES(%s, %s)",
+                       ((self.id, tag) for tag in tags))
+
+               # Update cache.
+               self.__tags = tags
+               self.__tags.sort()
+
+       tags = property(get_tags, set_tags)
+
 
 class Planet(object):
        __metaclass__ = Singleton
@@ -101,12 +129,12 @@ class Planet(object):
        def get_entry_by_slug(self, slug):
                entry = self.db.get("SELECT * FROM planet WHERE slug = %s", slug)
                if entry:
-                       return PlanetEntry(entry)
+                       return PlanetEntry(self.db, entry)
 
        def get_entry_by_id(self, id):
                entry = self.db.get("SELECT * FROM planet WHERE id = %s", id)
                if entry:
-                       return PlanetEntry(entry)
+                       return PlanetEntry(self.db, entry)
 
        def _limit_and_offset_query(self, limit=None, offset=None):
                query = " "
@@ -127,7 +155,7 @@ class Planet(object):
 
                entries = []
                for entry in self.db.query(query):
-                       entries.append(PlanetEntry(entry))
+                       entries.append(PlanetEntry(self.db, entry))
 
                return entries
 
@@ -140,13 +168,13 @@ class Planet(object):
 
                entries = self.db.query(query)
 
-               return [PlanetEntry(e) for e in entries]
+               return [PlanetEntry(self.db, e) for e in entries]
 
        def get_entries_by_year(self, year):
                entries = self.db.query("SELECT * FROM planet \
                        WHERE YEAR(published) = %s ORDER BY published DESC", year)
 
-               return [PlanetEntry(e) for e in entries]
+               return [PlanetEntry(self.db, e) for e in entries]
 
        def render(self, text, limit=0):
                if limit and len(text) >= limit:
@@ -184,22 +212,21 @@ class Planet(object):
                # Split tags.
                tags = what.split()
 
-               query = "SELECT * FROM planet WHERE id IN ( \
-                       SELECT DISTINCT post_id FROM planet_tags"
+               query = "SELECT planet.* FROM planet INNER JOIN ( \
+                               SELECT post_id FROM planet_tags \
+                               INNER JOIN planet ON planet_tags.post_id = planet.id \
+                               WHERE %s GROUP BY post_id HAVING COUNT(post_id) = %%s \
+                       ) pt ON planet.id = pt.post_id ORDER BY published DESC"
 
-               clauses = []
-               args = []
+               args = (tags, len(tags))
 
+               clauses, args = [], tags
                for tag in tags:
-                       clauses.append("tag = %s")
-                       args.append(tag)
-
-               query += " WHERE %s" % " OR ".join(clauses)
-               query += " ORDER BY COUNT(*) DESC)"
-
-               entries = self.db.query(query, *args)
+                       clauses.append("planet_tags.tag = %s")
+               args.append(len(tags))
 
-               return [PlanetEntry(e) for e in entries]
+               entries = self.db.query(query % " OR ".join(clauses), *args)
+               return [PlanetEntry(self.db, e) for e in entries]
 
        def search_autocomplete(self, what):
                tags = what.split()