# HG changeset patch # User raph # Date 1279203055 -7200 # Node ID 2c52e4453bf761b9fad3bf095b16990ad2b97250 # Parent 3442202aff1ab92148221d53069c859d54bffb9f api update (incl. doc) diff -r 3442202aff1a -r 2c52e4453bf7 src/cm/api/handlers.py --- a/src/cm/api/handlers.py Thu Jul 15 16:10:29 2010 +0200 +++ b/src/cm/api/handlers.py Thu Jul 15 16:10:55 2010 +0200 @@ -1,7 +1,7 @@ from piston.handler import AnonymousBaseHandler, BaseHandler from piston.utils import rc -from cm.models import Text,TextVersion, Role, UserRole +from cm.models import Text,TextVersion, Role, UserRole, Comment from cm.views import get_keys_from_dict, get_textversion_by_keys_or_404, get_text_by_keys_or_404, get_textversion_by_keys_or_404, redirect from cm.security import get_texts_with_perm, has_perm, get_viewable_comments, \ has_perm_on_text_api @@ -69,9 +69,18 @@ class TextVersionHandler(BaseHandler): type = "Text methods" anonymous = AnonymousTextVersionHandler - allowed_methods = ('GET',) + fields = ('key', 'title', 'format', 'content', 'created', 'modified', 'nb_comments',) + allowed_methods = ('GET', ) + model = Text no_display = True + @has_perm_on_text_api('can_view_text') + def read(self, request, key, version_key): + text_version = get_textversion_by_keys_or_404(version_key, key=key) + setattr(text_version,'nb_comments',len(get_viewable_comments(request, text_version.comment_set.all(), text_version.text))) + + return text_version + class AnonymousTextListHandler(AnonymousBaseHandler): title = "List texts" type = "Text methods" @@ -93,6 +102,8 @@ title = "Create text" type = "Text methods" allowed_methods = ('GET', 'POST') + fields = ('key', 'title', 'created', 'modified', 'nb_comments', 'nb_versions',) + model = Text anonymous = AnonymousTextListHandler desc = "Create a text with the provided parameters." args = """
@@ -213,7 +224,51 @@ type = "Text methods" anonymous = AnonymousTextFeedHandler allowed_methods = ('GET',) - no_display = True + no_display = True + + def read(self, request, key): + return text_feed(request, key=key) + +class TextVersionRevertHandler(BaseHandler): + allowed_methods = ('POST', ) + type = "Text methods" + title = "Revert to specific text version" + desc = "Revert to a text version (i.e. copy this text_version which becomes the last text_version)." + args = """
+`key`: text's key
+`version_key`: key of the version to revert to
+ """ + + @staticmethod + def endpoint(): + return URL_PREFIX + '/text/{key}/{version_key}/revert/' + + + def create(self, request, key, version_key): + text_version = get_textversion_by_keys_or_404(version_key, key=key) + new_text_version = text_version.text.revert_to_version(version_key) + return {'version_key' : new_text_version.key , 'created': new_text_version.created} + +class TextVersionDeleteHandler(BaseHandler): + allowed_methods = ('POST', ) + type = "Text methods" + title = "Delete a specific text version" + desc = "Delete a text version." + args = """
+`key`: text's key
+`version_key`: key of the version to delete
+ """ + + @staticmethod + def endpoint(): + return URL_PREFIX + '/text/{key}/{version_key}/delete/' + + + def create(self, request, key, version_key): + text_version = get_textversion_by_keys_or_404(version_key, key=key) + text_version.delete() + return rc.ALL_OK + ## client methods class AnonymousClientHandler(AnonymousBaseHandler): @@ -243,6 +298,7 @@ ## embed methods from django.views.i18n import javascript_catalog +from cm.urls import js_info_dict class JSI18NHandler(AnonymousBaseHandler): allowed_methods = ('GET',) @@ -256,7 +312,7 @@ return URL_PREFIX + '/jsi18n/' def read(self, request): - return javascript_catalog(request) + return javascript_catalog(request, **js_info_dict) class AnonymousCommentFrameHandler(AnonymousBaseHandler): @@ -331,36 +387,59 @@ def create(self, request, key, format, download, whichcomments, withcolor): return text_export(request, key, format, download, whichcomments, withcolor, adminkey=None) -## user methods - -class SetUserHandler(AnonymousBaseHandler): - allowed_methods = ('POST',) - type = "User methods" - title = "Set username and email" - desc = "Set username and email to use when commenting." +class AnonymousCommentsHandler(AnonymousBaseHandler): + allowed_methods = ('GET',) + type = "Comment methods" + fields = ('id_key', 'title', 'format', 'content', 'created', 'name', ('text_version' , ('key', ('text', ('key',))) )) + model = Comment + title = "Get comments" + desc = "Get comments from the workspace, most recent first." args = """
-`user_name`: user's name
-`user_email`: user's email
+`keys`: (optional) comma separated keys : limit comments from these texts only
+`name`: (optional) limit comments from this user only +`limit`: (optional) limit number of comments returned """ @staticmethod def endpoint(): - return URL_PREFIX + '/setuser/' + return URL_PREFIX + '/comments/' - def create(self, request): - user_name = request.POST.get('user_name', None) - user_email = request.POST.get('user_email', None) - if user_name and user_email: - response = rc.ALL_OK - response.set_cookie('user_name', user_name) - response.set_cookie('user_email', user_email) - return response - else: - return rc.BAD_REQUEST - + def read(self, request): + name = request.GET.get('name', None) + limit = request.GET.get('limit', None) + keys = request.GET.get('keys', None) + query = Comment.objects.all() + if keys: + query = query.filter(text_version__text__key__in=keys.split(',')) + if name: + query = query.filter(name=name) + query = query.order_by('-created') + if limit: + query = query[:int(limit)] + return query +class CommentsHandler(BaseHandler): + type = "Comment methods" + anonymous = AnonymousCommentsHandler + allowed_methods = ('GET',) + fields = ('id_key', 'title', 'format', 'content', 'created', 'name', ('text_version' , ('key', ('text', ('key',))) )) + model = Comment + no_display = True - + def read(self, request): + name = request.GET.get('name', None) + limit = request.GET.get('limit', None) + keys = request.GET.get('keys', None) + query = Comment.objects.all() + if keys: + query = query.filter(text_version__text__key__in=keys.split(',')) + if name: + query = query.filter(name=name) + query = query.order_by('-created') + if limit: + query = query[:int(limit)] + return query + from piston.doc import documentation_view from piston.handler import handler_tracker diff -r 3442202aff1a -r 2c52e4453bf7 src/cm/api/urls.py --- a/src/cm/api/urls.py Thu Jul 15 16:10:29 2010 +0200 +++ b/src/cm/api/urls.py Thu Jul 15 16:10:55 2010 +0200 @@ -12,17 +12,43 @@ text_delete_handler = Resource(handler=TextDeleteHandler, authentication=auth) text_pre_edit_handler = Resource(handler=TextPreEditHandler, authentication=auth) text_edit_handler = Resource(handler=TextEditHandler, authentication=auth) -setuser_handler = Resource(handler=SetUserHandler, authentication=None) +text_feed_handler = Resource(handler=TextFeedHandler, authentication=auth) + +tv_revert_handler = Resource(handler=TextVersionRevertHandler, authentication=auth) +tv_delete_handler = Resource(handler=TextVersionDeleteHandler, authentication=auth) + +text_export_handler = Resource(handler=TextExportHandler, authentication=auth) + +comments_handler = Resource(handler=CommentsHandler, authentication=auth) + +client_handler = Resource(handler=ClientHandler, authentication=auth) + +jsi8n_handler = Resource(handler=JSI18NHandler, authentication=None) + +comment_frame_handler = Resource(handler=CommentFrameHandler, authentication=auth) +comment_handler = Resource(handler=CommentHandler, authentication=auth) #doc_handler = Resource(handler=DocHandler) urlpatterns = patterns('', url(r'^text/(?P\w*)/$', text_handler), url(r'^text/$', text_list_handler), + + url(r'^text/(?P\w*)/(?P\w*)/revert/$', tv_revert_handler), + url(r'^text/(?P\w*)/(?P\w*)/delete/$', tv_delete_handler), + + url(r'^text/(?P\w*)/comments_frame/$', comment_frame_handler), + url(r'^text/(?P\w*)/comments/(?P\w*)/$', comment_handler), + + url(r'^text/(?P\w*)/export/(?P\w*)/(?P\w*)/(?P\w*)/(?P\w*)/$', text_export_handler), + + url(r'^text/(?P\w*)/feed/$', text_feed_handler), url(r'^text/(?P\w*)/delete/$', text_delete_handler), url(r'^text/(?P\w*)/pre_edit/$', text_pre_edit_handler), url(r'^text/(?P\w*)/edit/$', text_edit_handler), url(r'^text/(?P\w*)/(?P\w*)/$', textversion_handler), - url(r'^setuser/$', setuser_handler), + url(r'^comments/$', comments_handler), + url(r'^client/$', client_handler), + url(r'^jsi18n/$', jsi8n_handler), url(r'^doc/$', documentation), ) diff -r 3442202aff1a -r 2c52e4453bf7 src/cm/fixtures/test_content.yaml --- a/src/cm/fixtures/test_content.yaml Thu Jul 15 16:10:29 2010 +0200 +++ b/src/cm/fixtures/test_content.yaml Thu Jul 15 16:10:55 2010 +0200 @@ -121,6 +121,19 @@ mod_posteriori: True key: "textversion_key_1" adminkey: "tv_adminkey_1" + +- model : cm.textversion + pk: 0 + fields: + created: "2009-01-14 04:01:12" + modified: "2009-01-14 04:01:12" + title: 'title 1, aposteriori moderation' + format: 'markdown' + content: 'zzz hhhh aaa bbb ccc ddd eee fff ggg' + text: 1 + mod_posteriori: True + key: "textversion_key_0" + adminkey: "tv_adminkey_0" - model : cm.text pk: 1 diff -r 3442202aff1a -r 2c52e4453bf7 src/cm/tests/test_api.py --- a/src/cm/tests/test_api.py Thu Jul 15 16:10:29 2010 +0200 +++ b/src/cm/tests/test_api.py Thu Jul 15 16:10:55 2010 +0200 @@ -135,10 +135,10 @@ user = User.objects.get(pk=1) setattr(request, 'user' , user) request.method = 'POST' - setattr(request, 'POST' , {'key':'text_key_3'}) + setattr(request, 'POST' , {}) setattr(request, 'flash' , {}) - response = resource(request, emitter_format='json') + response = resource(request, key='text_key_3', emitter_format='json') self.assertEquals(204, response.status_code) # one text deleted @@ -155,10 +155,10 @@ user = User.objects.get(pk=3) setattr(request, 'user' , user) request.method = 'POST' - setattr(request, 'POST' , {'key':'text_key_3'}) + setattr(request, 'POST' , {}) setattr(request, 'flash' , {}) - response = resource(request, emitter_format='json') + response = resource(request, key='text_key_3', emitter_format='json') self.assertEquals(401, response.status_code) # no text deleted @@ -180,28 +180,51 @@ response = resource(request, key='text_key_2', emitter_format='json') self.assertEquals(response.content, '{"nb_removed": 3}') - def xtest_edit(self): + def test_edit(self): """ Edit text """ resource = Resource(TextEditHandler) request = HttpRequest() - setattr(request,'session',None) + session = {} + setattr(request,'session',{}) + user = User.objects.get(pk=1) setattr(request, 'user' , user) request.method = 'POST' - setattr(request, 'POST' , {'new_format' : 'markdown', 'new_content' : u'ggg'}) - setattr(request, 'flash' , {}) + setattr(request, 'POST' , {'format' : 'markdown', 'content' : u'ggg', 'keep_comments' : True, 'new_version' : True, 'title' : 'new title'}) + #setattr(request, 'flash' , {}) response = resource(request, key='text_key_2', emitter_format='json') self.assertEquals(Text.objects.get(pk=2).last_text_version.content , u'ggg') - - def test_setuser(self): + def test_text_version(self): """ - Set username/email for commenting + Text version operation """ from django.test.client import Client c = Client() - response = c.post('/setuser/', {'username': 'my_username', 'email': 'my_email'}) + + # revert to text version + self.assertEquals(Text.objects.get(pk=1).get_versions_number() , 2) + + resource = Resource(TextVersionRevertHandler) + request = HttpRequest() + request.method = 'POST' + setattr(request, 'POST' , {}) + + response = resource(request, key='text_key_1', version_key='textversion_key_0', emitter_format='json') + + self.assertEquals(Text.objects.get(pk=1).get_versions_number() , 3) + + # delete text version + + resource = Resource(TextVersionDeleteHandler) + request = HttpRequest() + request.method = 'POST' + setattr(request, 'POST' , {}) + response = resource(request, key='text_key_1', version_key='textversion_key_0', emitter_format='json') + + + self.assertEquals(Text.objects.get(pk=1).get_versions_number() , 2)