From 5d23bff409d8000985e6e099550df67effdc3418 Mon Sep 17 00:00:00 2001 From: posativ Date: Tue, 16 Oct 2012 22:49:43 +0200 Subject: [PATCH] clean json fuckup and add create and get views --- isso/__init__.py | 19 ++++++++++---- isso/comment.py | 21 +++++++++++++++ isso/comments.py | 7 ----- isso/db.py | 2 +- isso/models.py | 6 +---- isso/utils.py | 22 ++++++++++++++++ setup.py | 2 +- specs/test_comment.py | 59 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 119 insertions(+), 19 deletions(-) create mode 100644 isso/comment.py delete mode 100644 isso/comments.py create mode 100644 isso/utils.py create mode 100644 specs/test_comment.py diff --git a/isso/__init__.py b/isso/__init__.py index 55f9684..c33723c 100644 --- a/isso/__init__.py +++ b/isso/__init__.py @@ -21,21 +21,30 @@ __version__ = '0.1' +import json + from werkzeug.routing import Map, Rule from werkzeug.serving import run_simple from werkzeug.wrappers import Request, Response from werkzeug.exceptions import HTTPException, NotFound, NotImplemented, InternalServerError -from isso import admin, comments, db +from isso import admin, comment, db, utils + + +_dumps = json.dumps +setattr(json, 'dumps', lambda obj: _dumps(obj, cls=utils.IssoEncoder)) + url_map = Map([ # moderation panel Rule('/', endpoint='admin.index', methods=['GET', 'POST']), # comments API - Rule('/comment//', endpoint='comments.comment', methods=['POST']), - Rule('/comment//', endpoint='comments.comment', - methods=['GET', 'PUT', 'DELETE']), + Rule('/comment//', endpoint='comment.get'), + Rule('/comment//new', endpoint='comment.create', methods=['POST']), + Rule('/comment//', endpoint='comment.get'), + Rule('/comment//', endpoint='comment.modify', + methods=['PUT', 'DELETE']), ]) @@ -70,5 +79,5 @@ class Isso: def main(): - app = Isso(123) + app = Isso({'SQLITE': '/tmp/sqlite.db'}) run_simple('127.0.0.1', 8080, app) diff --git a/isso/comment.py b/isso/comment.py new file mode 100644 index 0000000..200fa33 --- /dev/null +++ b/isso/comment.py @@ -0,0 +1,21 @@ + +from werkzeug.wrappers import Response +from werkzeug.exceptions import abort + +from isso import json, models + + +def create(app, environ, request, path): + + try: + rv = app.db.add(path, models.Comment.fromjson(request.data)) + except ValueError as e: + return Response(unicode(e), 400) + + return Response(json.dumps(app.db.get(*rv)), 201, content_type='application/json') + + +def get(app, environ, request, path, id=None): + + rv = list(app.db.retrieve(path)) if id is None else app.db.get(path, id) + return Response(json.dumps(rv), 200, content_type='application/json') diff --git a/isso/comments.py b/isso/comments.py deleted file mode 100644 index b39a802..0000000 --- a/isso/comments.py +++ /dev/null @@ -1,7 +0,0 @@ - -from werkzeug.wrappers import Response -from werkzeug.exceptions import abort - - -def comment(app, environ, request, path, id=None): - return Response('', 200) diff --git a/isso/db.py b/isso/db.py index 7c692cf..dcbabe2 100644 --- a/isso/db.py +++ b/isso/db.py @@ -90,7 +90,7 @@ class SQLite(Abstract): def update(self, path, id, comment): with sqlite3.connect(self.dbpath) as con: - for field, value in comment.iteritems(): + for field, value in comment.iteritems(False): con.execute('UPDATE comments SET %s=? WHERE path=? AND id=?;' % field, (value, id, path)) diff --git a/isso/models.py b/isso/models.py index be72633..5d84ef9 100644 --- a/isso/models.py +++ b/isso/models.py @@ -22,7 +22,7 @@ class Comment(object): for field in self.protected + self.fields: self.__dict__[field] = kw.get(field) - def iteritems(self, protected=False): + def iteritems(self, protected=True): for field in self.fields: yield field, getattr(self, field) if protected: @@ -42,10 +42,6 @@ class Comment(object): return comment - @property - def json(self): - return '' - @property def pending(self): return self.mode == 1 diff --git a/isso/utils.py b/isso/utils.py new file mode 100644 index 0000000..273d823 --- /dev/null +++ b/isso/utils.py @@ -0,0 +1,22 @@ + +import json +from isso.models import Comment + +# def prove(f): + +# def dec(app, env, req, *args, **kwargs): + +# pass + + +# def sign(response): +# pass + + +class IssoEncoder(json.JSONEncoder): + + def default(self, obj): + if isinstance(obj, Comment): + return dict((field, value) for field, value in obj.iteritems()) + + return json.JSONEncoder.default(self, obj) diff --git a/setup.py b/setup.py index f8aba95..99e8d47 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ setup( "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7" ], - install_requires=['werkzeug'], + install_requires=['werkzeug', 'itsdangerous'], entry_points={ 'console_scripts': ['isso = isso:main'], diff --git a/specs/test_comment.py b/specs/test_comment.py new file mode 100644 index 0000000..713b51b --- /dev/null +++ b/specs/test_comment.py @@ -0,0 +1,59 @@ + +import tempfile +import unittest + +from werkzeug.test import Client +from werkzeug.wrappers import Response + +from isso import Isso, json +from isso.models import Comment + + +def comment(**kw): + return Comment.fromjson(json.dumps(kw)) + + +class TestComments(unittest.TestCase): + + get = lambda self, *x, **z: Client(self.app, Response).get(*x, **z) + put = lambda self, *x, **z: Client(self.app, Response).put(*x, **z) + post = lambda self, *x, **z: Client(self.app, Response).post(*x, **z) + + def setUp(self): + fd, self.path = tempfile.mkstemp() + self.app = Isso({'SQLITE': self.path}) + + def testGet(self): + + self.post('/comment/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) + r = self.get('/comment/path/1') + assert r.status_code == 200 + + rv = json.loads(r.data) + + assert rv['id'] == 1 + assert rv['text'] == 'Lorem ipsum ...' + + def testCreate(self): + + rv = self.post('/comment/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) + + assert rv.status_code == 201 + # XXX assert cookie + + c = Comment.fromjson(rv.data) + + assert not c.pending + assert not c.deleted + assert c.text == 'Lorem ipsum ...' + + def testCreateAndGetMultiple(self): + + for i in range(100): + self.post('/comment/path/new', data=json.dumps(comment(text='Spam'))) + + r = self.get('/comment/path/') + assert r.status_code == 200 + + rv = json.loads(r.data) + assert len(rv) == 20