From 2c8c97b2a88f1335d8bd4e5fe14f5fa6e14ee0db Mon Sep 17 00:00:00 2001 From: posativ Date: Thu, 18 Oct 2012 15:39:04 +0200 Subject: [PATCH] add db.activate function and use UNIX-style permission bits for normal/activated/deleted comments --- isso/db.py | 22 ++++++++++++++++------ isso/models.py | 13 ++++++++----- specs/test_db.py | 25 +++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/isso/db.py b/isso/db.py index f408443..bdb5152 100644 --- a/isso/db.py +++ b/isso/db.py @@ -19,10 +19,15 @@ class Abstract: return @abc.abstractmethod - def add(path, comment): + def add(self, path, comment): """Add a new comment to the database. Returns a Comment object.""" return + @abc.abstractmethod + def activate(self, path, id): + """Activate comment id if pending and return comment for (path, id).""" + return + @abc.abstractmethod def update(self, path, id, comment): """ @@ -64,7 +69,7 @@ class SQLite(Abstract): def __init__(self, app): self.dbpath = app.SQLITE - self.mode = 1 if app.MODERATION else 0 + self.mode = 2 if app.MODERATION else 1 with sqlite3.connect(self.dbpath) as con: sql = ('main.comments (id INTEGER NOT NULL, path VARCHAR(255) NOT NULL,' @@ -104,6 +109,11 @@ class SQLite(Abstract): return self.query2comment( con.execute('SELECT *, MAX(id) FROM comments;').fetchone()) + def activate(self, path, id): + with sqlite3.connect(self.dbpath) as con: + con.execute("UPDATE comments SET mode=1 WHERE path=? AND id=? AND mode=2", (path, id)) + return self.get(path, id) + def update(self, path, id, comment): with sqlite3.connect(self.dbpath) as con: for field, value in comment.iteritems(False): @@ -129,16 +139,16 @@ class SQLite(Abstract): return None con.execute('UPDATE comments SET text=? WHERE path=? AND id=?', ('', path, id)) - con.execute('UPDATE comments SET mode=? WHERE path=? AND id=?', (2, path, id)) + con.execute('UPDATE comments SET mode=? WHERE path=? AND id=?', (4, path, id)) for field in set(Comment.fields) - set(['text', 'parent']): con.execute('UPDATE comments SET %s=? WHERE path=? AND id=?' % field, (None, path, id)) return self.get(path, id) - def retrieve(self, path, limit=20, mode=None): + def retrieve(self, path, limit=20, mode=1): with sqlite3.connect(self.dbpath) as con: - rv = con.execute("SELECT * FROM comments WHERE path = ?" \ - + " ORDER BY id DESC LIMIT ?;", (path, limit)).fetchall() + rv = con.execute("SELECT * FROM comments WHERE path=? AND (? | mode) = ?" \ + + " ORDER BY id DESC LIMIT ?;", (path, mode, mode, limit)).fetchall() for item in rv: yield self.query2comment(item) diff --git a/isso/models.py b/isso/models.py index 65141a1..dfffd3e 100644 --- a/isso/models.py +++ b/isso/models.py @@ -13,9 +13,12 @@ class Comment(object): The field `mode` has a special meaning: - 0: normal - 1: in moderation queue - 2: deleted + 1: normal + 2: in moderation queue + 4: deleted + + You can query for them like with UNIX permission bits, so you get both + normal and queued using MODE=3. """ protected = ['id', 'mode', 'created', 'modified'] @@ -48,8 +51,8 @@ class Comment(object): @property def pending(self): - return self.mode == 1 + return self.mode == 2 @property def deleted(self): - return self.mode == 2 + return self.mode == 4 diff --git a/specs/test_db.py b/specs/test_db.py index a6ae17e..e5bb52d 100644 --- a/specs/test_db.py +++ b/specs/test_db.py @@ -65,3 +65,28 @@ class TestSQLite(unittest.TestCase): def tearDown(self): os.unlink(self.path) + + +class TestSQLitePending(unittest.TestCase): + + def setUp(self): + + fd, self.path = tempfile.mkstemp() + self.db = SQLite(isso.Isso({'SQLITE': self.path, 'MODERATION': True})) + + def test_retrieve(self): + + self.db.add('/', comment(text='Foo')) + assert len(list(self.db.retrieve('/'))) == 0 + + def test_activate(self): + + self.db.add('/', comment(text='Foo')) + self.db.add('/', comment(text='Bar')) + self.db.activate('/', 2) + + assert len(list(self.db.retrieve('/'))) == 1 + assert len(list(self.db.retrieve('/', mode=3))) == 2 + + def tearDown(self): + os.unlink(self.path)