]> git.ipfire.org Git - people/shoehn/ipfire.org.git/commitdiff
planet: Add proper tag search function.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 4 May 2013 17:24:13 +0000 (19:24 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 4 May 2013 17:24:13 +0000 (19:24 +0200)
static/js/site.js
templates/admin-planet-compose.html
templates/planet/posting.html
webapp/__init__.py
webapp/backend/planet.py
webapp/handlers_admin.py

index f8e535ccf98acc5a84b4a871d3a3381474a156fe..83c3bb30ed2104f926437d66698750f0174d68a5 100644 (file)
@@ -48,7 +48,7 @@ if (/.*download-splash.*/i.test(window.location.href)) {
 
 $(".planet-search-autocomplete").typeahead({
        source: function(query, process) {
-               $.get("http://planet.ipfire.org/api/search/autocomplete", { q: query }, function(data) {
+               $.get("/api/planet/search/autocomplete", { q: query }, function(data) {
                        if (data.query == query) {
                                process(data.results);
                        }
index 04fe68cd6c19b17d3660bb71214fb672e128048c..edf8fab8114dac0f608c0631092bd6cd6c00ef80 100644 (file)
@@ -1,41 +1,54 @@
 {% extends "admin-base.html" %}
 
-{% block bodyA %}
-       <div class="post">
-               <h3>{{ _("Compose new entry") }}</h3>
-               <form name="entry" method="post">
-                       {% raw xsrf_form_html() %}
-                       {% if entry.id %}
-                               <input type="hidden" name="id" value="{{ entry.id }}">
-                       {% end %}
-
-                       <table>
-                               <tr>
-                                       <td>{{ _("Title") }}</td>
-                                       <td><input type="text" name="title" value="{{ entry.title }}"
-                                               size="50" /></td>
-                               </tr>
-                               <tr>
-                                       <td>&nbsp;</td>
-                                       <td>
-                                               <textarea id="markdown" name="markdown" rows="20" cols="80">{{ entry.markdown }}</textarea>
-                                       </td>
-                               </tr>
-                               <tr>
-                                       <td colspan="2">
-                                               <input type="button" onClick="preview()" value="{{ _("Preview") }}" />
-                                               <input type="submit" value="{{ _("Save") }}" />
-                                       </td>
-                               </tr>
-                       </table>
-               </form>
+{% block body %}
+       <div class="page-header">
+               <h2>{{ _("Compose new entry") }}</h2>
        </div>
 
+       <form class="form-horizontal" action="" method="POST" name="entry">
+               {% raw xsrf_form_html() %}
+
+               {% if entry.id %}
+                       <input type="hidden" name="id" value="{{ entry.id }}">
+               {% end %}
+
+               <div class="control-group">
+                       <label class="control-label" for="inputTitle">{{ _("Title") }}</label>
+                       <div class="controls">
+                               <input class="input-block-level" type="text" name="title" id="inputTitle"
+                                       value="{{ entry.title }}" placeholder="{{ _("Title") }}">
+                       </div>
+               </div>
+
+               <div class="control-group">
+                       <div class="controls">
+                               <textarea class="input-block-level" name="markdown" rows="12" id="inputMarkdown"
+                                       placeholder="{{ _("Content") }}">{{ entry.markdown }}</textarea>
+                       </div>
+               </div>
+
+               <hr>
+
+               <div class="control-group">
+                       <label class="control-label" for="inputTags">{{ _("Tags") }}</label>
+                       <div class="controls">
+                               <input class="input-block-level planet-search-autocomplete" type="text"
+                                       name="tags" id="inputTags" value="{{ " ".join(entry.tags) }}"
+                                       placeholder="{{ _("Tags") }}" autocomplete="off">
+                       </div>
+               </div>
+               <div class="form-actions">
+                       <button type="submit" class="btn btn-primary">{{ _("Save") }}</button>
+                       <a class="btn" href="javascript:preview();">{{ _("Preview") }}</a>
+                       <a class="btn" href="/planet">{{ _("Cancel") }}</a>
+               </div>
+       </form>
+
        <div id="preview"></div>
 
        <script type="text/javascript">
                preview = function() {
-                       $.postJSON("/api/planet/render", { text : $("#markdown").val() },
+                       $.postJSON("/api/planet/render", { text : $("#inputMarkdown").val() },
                                function(data) {
                                        $("#preview").html(data.html);
                                }
index c4e972425c3113c1ea438ca7545210582e866261..4d769e0c1e223cba252f88733f3dd8926dba6ac8 100644 (file)
                </div>
 
                <p class="pull-right" style="clear: both;">
+                       {% if entry.tags %}
+                               {{ _("Tags") }}:
+                               {% for tag in entry.tags %}
+                                       <a href="/search?q={{ tag }}">{{ tag }}</a>
+                               {% end %} &bull;
+                       {% end %}
                        {{ _("Posted by") }} <a href="/user/{{ entry.author.uid }}">{{ entry.author.cn }}</a>
                        {{ _("on") }} {{ locale.format_date(entry.published, shorter=True) }}
                </p>
index d24fbd8e2c849d22a783d48c82327030ee1472df..ea7a420742703d70571377d5ce11432ae954b4b7 100644 (file)
@@ -129,7 +129,7 @@ class Application(tornado.web.Application):
                        (r"/year/(\d+)", PlanetYearHandler),
 
                        # API
-                       (r"/api/search/autocomplete", PlanetAPISearchAutocomplete),
+                       (r"/api/planet/search/autocomplete", PlanetAPISearchAutocomplete),
 
                        # RSS
                        (r"/rss", RSSPlanetAllHandler),
@@ -229,6 +229,7 @@ class Application(tornado.web.Application):
                        (r"/downloads", AdminDownloadsHandler),
                        (r"/downloads/mirrors", AdminDownloadsMirrorsHandler),
                        # API
+                       (r"/api/planet/search/autocomplete", PlanetAPISearchAutocomplete),
                        (r"/api/planet/render", AdminApiPlanetRenderMarkupHandler)
                ] + static_handlers)
 
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()
index 7c4cb1a1be8866e11f79db1a0a2d34bece46fb73..c5ac79473ec9c36c7855df05ce5e8512d5cfb9d9 100644 (file)
@@ -76,7 +76,7 @@ class AdminPlanetHandler(AdminBaseHandler):
 class AdminPlanetComposeHandler(AdminBaseHandler):
        @tornado.web.authenticated
        def get(self, id=None):
-               entry = backend.PlanetEntry()
+               entry = backend.PlanetEntry(self.planet.db)
 
                if id:
                        entry = self.planet.get_entry_by_id(id)
@@ -87,7 +87,7 @@ class AdminPlanetComposeHandler(AdminBaseHandler):
        def post(self, id=None):
                id = self.get_argument("id", id)
 
-               entry = backend.PlanetEntry()
+               entry = backend.PlanetEntry(self.planet.db)
 
                if id:
                        entry = self.planet.get_entry_by_id(id)
@@ -96,6 +96,9 @@ class AdminPlanetComposeHandler(AdminBaseHandler):
                entry.set("markdown", self.get_argument("markdown"))
                entry.set("author_id", self.current_user)
 
+               tags = self.get_argument("tags", "")
+               entry.tags = tags.split()
+
                if id:
                        self.planet.update_entry(entry)
                else: