add db.activate function and use UNIX-style permission bits for normal/activated/deleted comments
This commit is contained in:
parent
f1fb80f5ef
commit
2c8c97b2a8
22
isso/db.py
22
isso/db.py
@ -19,10 +19,15 @@ class Abstract:
|
|||||||
return
|
return
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def add(path, comment):
|
def add(self, path, comment):
|
||||||
"""Add a new comment to the database. Returns a Comment object."""
|
"""Add a new comment to the database. Returns a Comment object."""
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def activate(self, path, id):
|
||||||
|
"""Activate comment id if pending and return comment for (path, id)."""
|
||||||
|
return
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def update(self, path, id, comment):
|
def update(self, path, id, comment):
|
||||||
"""
|
"""
|
||||||
@ -64,7 +69,7 @@ class SQLite(Abstract):
|
|||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
|
|
||||||
self.dbpath = app.SQLITE
|
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:
|
with sqlite3.connect(self.dbpath) as con:
|
||||||
sql = ('main.comments (id INTEGER NOT NULL, path VARCHAR(255) NOT NULL,'
|
sql = ('main.comments (id INTEGER NOT NULL, path VARCHAR(255) NOT NULL,'
|
||||||
@ -104,6 +109,11 @@ class SQLite(Abstract):
|
|||||||
return self.query2comment(
|
return self.query2comment(
|
||||||
con.execute('SELECT *, MAX(id) FROM comments;').fetchone())
|
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):
|
def update(self, path, id, comment):
|
||||||
with sqlite3.connect(self.dbpath) as con:
|
with sqlite3.connect(self.dbpath) as con:
|
||||||
for field, value in comment.iteritems(False):
|
for field, value in comment.iteritems(False):
|
||||||
@ -129,16 +139,16 @@ class SQLite(Abstract):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
con.execute('UPDATE comments SET text=? WHERE path=? AND id=?', ('', path, id))
|
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']):
|
for field in set(Comment.fields) - set(['text', 'parent']):
|
||||||
con.execute('UPDATE comments SET %s=? WHERE path=? AND id=?' % field,
|
con.execute('UPDATE comments SET %s=? WHERE path=? AND id=?' % field,
|
||||||
(None, path, id))
|
(None, path, id))
|
||||||
return self.get(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:
|
with sqlite3.connect(self.dbpath) as con:
|
||||||
rv = con.execute("SELECT * FROM comments WHERE path = ?" \
|
rv = con.execute("SELECT * FROM comments WHERE path=? AND (? | mode) = ?" \
|
||||||
+ " ORDER BY id DESC LIMIT ?;", (path, limit)).fetchall()
|
+ " ORDER BY id DESC LIMIT ?;", (path, mode, mode, limit)).fetchall()
|
||||||
|
|
||||||
for item in rv:
|
for item in rv:
|
||||||
yield self.query2comment(item)
|
yield self.query2comment(item)
|
||||||
|
@ -13,9 +13,12 @@ class Comment(object):
|
|||||||
|
|
||||||
The field `mode` has a special meaning:
|
The field `mode` has a special meaning:
|
||||||
|
|
||||||
0: normal
|
1: normal
|
||||||
1: in moderation queue
|
2: in moderation queue
|
||||||
2: deleted
|
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']
|
protected = ['id', 'mode', 'created', 'modified']
|
||||||
@ -48,8 +51,8 @@ class Comment(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def pending(self):
|
def pending(self):
|
||||||
return self.mode == 1
|
return self.mode == 2
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def deleted(self):
|
def deleted(self):
|
||||||
return self.mode == 2
|
return self.mode == 4
|
||||||
|
@ -65,3 +65,28 @@ class TestSQLite(unittest.TestCase):
|
|||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
os.unlink(self.path)
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user