From 5d2daa12441de9070dfe11322e6c4319359f2406 Mon Sep 17 00:00:00 2001 From: Martin Zimmermann Date: Sun, 20 Apr 2014 15:39:43 +0200 Subject: [PATCH 1/6] add db migration, part of #79 --- isso/db/__init__.py | 27 ++++++++++++++++++++- isso/tests/test_db.py | 56 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/isso/db/__init__.py b/isso/db/__init__.py index 7a10a74..cac31ee 100644 --- a/isso/db/__init__.py +++ b/isso/db/__init__.py @@ -2,8 +2,11 @@ import sqlite3 import logging +import operator import os.path +from collections import defaultdict + logger = logging.getLogger("isso") from isso.db.comments import Comments @@ -19,7 +22,7 @@ class SQLite3: a trigger for automated orphan removal. """ - MAX_VERSION = 2 + MAX_VERSION = 3 def __init__(self, path, conf): @@ -89,3 +92,25 @@ class SQLite3: con.execute('PRAGMA user_version = 2') logger.info("%i rows changed", con.total_changes) + + # limit max. nesting level to 1 + if self.version == 2: + + first = lambda rv: list(map(operator.itemgetter(0), rv)) + + with sqlite3.connect(self.path) as con: + top = first(con.execute("SELECT id FROM comments WHERE parent IS NULL").fetchall()) + flattened = defaultdict(set) + + for id in top: + + ids = [id, ] + + while ids: + rv = first(con.execute("SELECT id FROM comments WHERE parent=?", (ids.pop(), ))) + ids.extend(rv) + flattened[id].update(set(rv)) + + for id in flattened.keys(): + for n in flattened[id]: + con.execute("UPDATE comments SET parent=? WHERE id=?", (id, n)) diff --git a/isso/tests/test_db.py b/isso/tests/test_db.py index be354e4..0b5db33 100644 --- a/isso/tests/test_db.py +++ b/isso/tests/test_db.py @@ -9,8 +9,11 @@ import sqlite3 import tempfile from isso.db import SQLite3 +from isso.db.comments import Comments from isso.core import Config +from isso.compat import iteritems + class TestDBMigration(unittest.TestCase): @@ -49,3 +52,56 @@ class TestDBMigration(unittest.TestCase): self.assertEqual(db.version, SQLite3.MAX_VERSION) self.assertEqual(db.preferences.get("session-key"), "supersecretkey") + + def test_limit_nested_comments(self): + + tree = { + 1: None, + 2: None, + 3: 2, + 4: 3, + 7: 3, + 5: 2, + 6: None + } + + with sqlite3.connect(self.path) as con: + con.execute("PRAGMA user_version = 2") + con.execute("CREATE TABLE threads (" + " id INTEGER PRIMARY KEY," + " uri VARCHAR UNIQUE," + " title VARCHAR)") + con.execute("CREATE TABLE comments (" + " tid REFERENCES threads(id)," + " id INTEGER PRIMARY KEY," + " parent INTEGER," + " created FLOAT NOT NULL, modified FLOAT," + " text VARCHAR, email VARCHAR, website VARCHAR," + " mode INTEGER," + " remote_addr VARCHAR," + " likes INTEGER DEFAULT 0," + " dislikes INTEGER DEFAULT 0," + " voters BLOB)") + + con.execute("INSERT INTO threads (uri, title) VALUES (?, ?)", ("/", "Test")) + for (id, parent) in iteritems(tree): + con.execute("INSERT INTO comments (" + " tid, parent, created)" + "VALUEs (?, ?, ?)", (id, parent, id)) + + conf = Config.load(None) + db = SQLite3(self.path, conf) + + flattened = [ + (1, None), + (2, None), + (3, 2), + (4, 2), + (5, 2), + (6, None), + (7, 2) + ] + + with sqlite3.connect(self.path) as con: + rv = con.execute("SELECT id, parent FROM comments ORDER BY created").fetchall() + self.assertEqual(flattened, rv) From 9ee0a1a2ebec3c25a0b5c8ae9c57fc13611ba091 Mon Sep 17 00:00:00 2001 From: Martin Zimmermann Date: Sun, 20 Apr 2014 16:30:18 +0200 Subject: [PATCH 2/6] reply to comment now nests to max. level of 1, part of #79 --- isso/js/app/isso.js | 29 +++-------------------------- isso/js/app/text/comment.html | 7 ------- isso/tests/test_db.py | 1 - 3 files changed, 3 insertions(+), 34 deletions(-) diff --git a/isso/js/app/isso.js b/isso/js/app/isso.js index 0bec02e..e903b6a 100644 --- a/isso/js/app/isso.js +++ b/isso/js/app/isso.js @@ -75,7 +75,6 @@ define(["app/text/html", "app/dom", "app/utils", "app/config", "app/api", "app/m if (parent !== null) { el.onsuccess(); - el.remove(); } }); }); @@ -85,16 +84,8 @@ define(["app/text/html", "app/dom", "app/utils", "app/config", "app/api", "app/m return el; }; - // lookup table for responses (to link to the parent) - var map = {id: {}, name: {}}; - var insert = function(comment, scrollIntoView) { - map.name[comment.id] = comment.author; - if (comment.parent) { - comment["replyto"] = map.name[comment.parent]; - } - var el = $.htmlify(Mark.up(templates["comment"], comment)); // update datetime every 60 seconds @@ -113,12 +104,7 @@ define(["app/text/html", "app/dom", "app/utils", "app/config", "app/api", "app/m if (comment.parent === null) { entrypoint = $("#isso-root"); } else { - var key = comment.parent; - while (key in map.id) { - key = map.id[key]; - } - map.id[comment.id] = comment.parent; - entrypoint = $("#isso-" + key + " > .text-wrapper > .isso-follow-up"); + entrypoint = $("#isso-" + comment.parent + " > .text-wrapper > .isso-follow-up"); } entrypoint.append(el); @@ -134,26 +120,17 @@ define(["app/text/html", "app/dom", "app/utils", "app/config", "app/api", "app/m var form = null; // XXX: probably a good place for a closure $("a.reply", footer).toggle("click", function(toggler) { - form = footer.insertAfter(new Postbox(comment.id)); + form = footer.insertAfter(new Postbox(comment.parent === null ? comment.id : comment.parent)); form.onsuccess = function() { toggler.next(); }; $(".textarea", form).focus(); $("a.reply", footer).textContent = msgs["comment-close"]; }, function() { - form.remove(); + form.remove() $("a.reply", footer).textContent = msgs["comment-reply"]; } ); - if (comment.parent !== null) { - $("a.parent", header).on("mouseover", function() { - $("#isso-" + comment.parent).classList.add("parent-highlight"); - }); - $("a.parent", header).on("mouseout", function() { - $("#isso-" + comment.parent).classList.remove("parent-highlight"); - }); - } - // update vote counter, but hide if votes sum to 0 var votes = function(value) { var span = $("span.votes", footer); diff --git a/isso/js/app/text/comment.html b/isso/js/app/text/comment.html index e2431f2..e9cc1e1 100644 --- a/isso/js/app/text/comment.html +++ b/isso/js/app/text/comment.html @@ -14,13 +14,6 @@ {{ /if }} - {{ if parent }} - - - {{ svg-forward }}{{ replyto | blank: `i18n-comment-anonymous` }} - - {{ /if }} -