From 3d3c2fae86149ea2e5c7d7e4fb971fc84ce2c52a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C5=81ukasz=20Rekucki?= Date: Sat, 26 Sep 2009 20:57:01 +0200 Subject: [PATCH] Pull requests. --- apps/api/forms.py | 2 +- apps/api/handlers/library_handlers.py | 53 +++++++++++-------- .../management/commands/upload_document.py | 42 --------------- apps/api/resources.py | 14 +++-- apps/api/urls.py | 13 +++-- apps/api/utils.py | 2 +- apps/explorer/models.py | 4 +- lib/wlrepo/mercurial_backend/document.py | 4 +- 8 files changed, 55 insertions(+), 79 deletions(-) delete mode 100644 apps/api/management/commands/upload_document.py diff --git a/apps/api/forms.py b/apps/api/forms.py index 3c393a87..af1b6b5a 100644 --- a/apps/api/forms.py +++ b/apps/api/forms.py @@ -10,7 +10,7 @@ from django import forms class MergeRequestForm(forms.Form): # should the target document revision be updated or shared - type = forms.ChoiceField(choices=('update', 'share')) + type = forms.ChoiceField(choices=(('update', 'Update'), ('share', 'Share')) ) # which revision to update/share target_revision = forms.RegexField('[0-9a-f]{40}') diff --git a/apps/api/handlers/library_handlers.py b/apps/api/handlers/library_handlers.py index 5f844dba..6fd7786f 100644 --- a/apps/api/handlers/library_handlers.py +++ b/apps/api/handlers/library_handlers.py @@ -70,6 +70,8 @@ class LibraryHandler(BaseHandler): try: lock = lib.lock() try: + print "DOCID", docid + doc = lib.document_create(docid) # document created, but no content yet @@ -226,11 +228,10 @@ class DocumentTextHandler(BaseHandler): "updated_revision": ndoc.revision } except Exception, e: - lib.rollback() - raise e - - except (RevisionNotFound, KeyError): - return response.EntityNotFound().django_response() + lib._rollback() + raise e + except RevisionNotFound, e: + return response.EntityNotFound().django_response(e) # # Dublin Core handlers @@ -245,9 +246,9 @@ class DocumentDublinCoreHandler(BaseHandler): """Read document as raw text""" try: if revision == 'latest': - document = lib.document(docid) + doc = lib.document(docid) else: - document = lib.document_for_rev(revision) + doc = lib.document_for_rev(revision) bookinfo = dcparser.BookInfo.from_string(doc.data('xml')) return bookinfo.serialize() @@ -280,20 +281,24 @@ class DocumentDublinCoreHandler(BaseHandler): document.serialize().encode('utf-8'),\ message=msg, user=request.user.username) - return { - "document": ndoc.id, - "subview": "xml", - "previous_revision": prev, - "updated_revision": ndoc.revision - } - except (RevisionNotFound, KeyError): + try: + # return the new revision number + return { + "document": ndoc.id, + "subview": "dc", + "previous_revision": current.revision, + "updated_revision": ndoc.revision + } + except Exception, e: + lib._rollback() + raise e + except RevisionNotFound: return response.EntityNotFound().django_response() - class MergeHandler(BaseHandler): allowed_methods = ('POST',) - @validate_form(forms.MergeRequestForm) + @validate_form(forms.MergeRequestForm, 'POST') @hglibrary def create(self, request, form, docid, lib): """Create a new document revision from the information provided by user""" @@ -306,7 +311,7 @@ class MergeHandler(BaseHandler): if target_rev == 'latest': target_rev = udoc.revision - if udoc.revision != target_rev: + if str(udoc.revision) != target_rev: # user think doesn't know he has an old version # of his own branch. @@ -328,22 +333,24 @@ class MergeHandler(BaseHandler): # update his internal state. return response.EntityConflict().django_response({ "reason": "out-of-date", - "provided": target_revision, + "provided": target_rev, "latest": udoc.revision }) - if not request.user.has_permission('explorer.pull_request.can_add'): + if not request.user.has_perm('explorer.book.can_share'): # User is not permitted to make a merge, right away # So we instead create a pull request in the database prq = PullRequest( - commiter=request.uset.username, + comitter=request.user, document=docid, - source_revision = udoc.revision, + source_revision = str(udoc.revision), status="N", - comment = form.cleaned_data['comment'] + comment = form.cleaned_data['comment'] or '$AUTO$ Document shared.' ) prq.save() - return response.RequestAccepted() + return response.RequestAccepted().django_response(\ + ticket_status=prq.status, \ + ticket_uri=reverse("pullrequest_view", args=[prq.id]) ) if form.cleanded_data['type'] == 'update': # update is always performed from the file branch diff --git a/apps/api/management/commands/upload_document.py b/apps/api/management/commands/upload_document.py deleted file mode 100644 index 66ef9243..00000000 --- a/apps/api/management/commands/upload_document.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python -# -*- conding: utf-8 -*- -__author__="lreqc" -__date__ ="$2009-09-08 14:31:26$" - -from django.core.management.base import BaseCommand -from django.utils import simplejson as json -from django.test.client import Client -from django.core.urlresolvers import reverse - -from optparse import make_option - -class Command(BaseCommand): - - option_list = BaseCommand.option_list + ( - make_option('-u', '--user', action='store', dest='username'), - make_option('-p', '--password', action='store', dest='password'), - make_option('-d', '--dublin-core', action='store_true', dest='dc'), - ) - - def handle(self, *args, **options): - client = Client() - if not options['username'] or not options['password']: - raise CommandError("You must provide login data") - - client.login(username=options['username'], \ - password=options['password']) - - print options['username'], options['password'] - - filename = args[0] - bookname = args[1] - - print "Uploading '%s' as document '%s'" % (filename, bookname) - print "Wth DC template" if options['dc'] else "" - - print client.post( reverse("document_list_view"),\ - { - 'bookname': bookname, - 'ocr_file': open(filename), - 'generate_dc': options['dc'] } ) - diff --git a/apps/api/resources.py b/apps/api/resources.py index 113d4b6d..2d097877 100644 --- a/apps/api/resources.py +++ b/apps/api/resources.py @@ -7,9 +7,6 @@ __doc__ = "Module documentation." from piston.resource import Resource from api.utils import DjangoAuth - - - authdata = {'authentication': DjangoAuth()} # @@ -24,6 +21,11 @@ document_html_resource = Resource(dh.DocumentHTMLHandler, **authdata) document_dc_resource = Resource(dh.DocumentDublinCoreHandler, **authdata) document_merge = Resource(dh.MergeHandler, **authdata) +import api.handlers.manage_handlers as mh + +pullrequest_collection = Resource(mh.PullRequestListHandler, **authdata) +pullrequest_rsrc = Resource(mh.PullRequestHandler, **authdata) + # # Toolbar resources # @@ -31,6 +33,8 @@ import api.handlers.toolbar_handlers as th toolbar_buttons = Resource(th.ToolbarHandler, **authdata) scriptlets = Resource(th.ScriptletsHandler, **authdata) + + __all__ = [ 'library_resource', 'document_resource', @@ -38,5 +42,7 @@ __all__ = [ 'document_dc_resource', 'document_merge', 'toolbar_buttons', - 'scriptlets' + 'scriptlets', + 'pullrequest_collection', + 'pullrequest_rsrc', ] \ No newline at end of file diff --git a/apps/api/urls.py b/apps/api/urls.py index b36cbe30..8c47e830 100644 --- a/apps/api/urls.py +++ b/apps/api/urls.py @@ -18,10 +18,15 @@ urlpatterns = patterns('', # url(r'^hello\.(?P.+)$', hello_resource), # Toolbar - url(r'^toolbar/buttons$', toolbar_buttons, {'emitter_format': 'json'}), - - # Toolbar + url(r'^toolbar/buttons$', toolbar_buttons, {'emitter_format': 'json'}), url(r'^toolbar/scriptlets$', scriptlets, {'emitter_format': 'json'}), + + # Pull requests + url(r"^pull-requests$", pullrequest_collection, + {'emitter_format': 'json'} ), + + url(r"^pull-requests/(?P\d+)$", pullrequest_rsrc, + {'emitter_format': 'json'}, name="pullrequest_view" ), # Documents url(r'^documents$', library_resource, @@ -53,7 +58,7 @@ urlpatterns = patterns('', document_dc_resource, {'emitter_format': 'json'}, name="docdc_view"), - url(urlpath(r'documents', DOC, 'revision'), + url(urlpath(r'documents', DOC, 'revision', format=False), document_merge, {'emitter_format': 'json'}, name="docmerge_view") # url(r'^documents/(?P[^/]+)/parts$', diff --git a/apps/api/utils.py b/apps/api/utils.py index d8177ab0..a52e555b 100644 --- a/apps/api/utils.py +++ b/apps/api/utils.py @@ -39,7 +39,7 @@ def validate_form(formclass, source='GET'): form = formclass(getattr(request, source), request.FILES) if not form.is_valid(): - errorlist = [{'field': k, 'errors': e} for k, e in form.errors.items()] + errorlist = [{'field': k, 'errors': str(e)} for k, e in form.errors.items()] return api.response.BadRequest().django_response(errorlist) kwargs['form'] = form diff --git a/apps/explorer/models.py b/apps/explorer/models.py index 0a3a252d..f2dc8f4a 100644 --- a/apps/explorer/models.py +++ b/apps/explorer/models.py @@ -56,8 +56,8 @@ class EditorPanel(models.Model): class Book(models.Model): class Meta: - permissions = ( - ("can_add_files", "Can do hg add."), + permissions = ( + ("can_share", "Can share documents without pull requests."), ) abstract=True pass diff --git a/lib/wlrepo/mercurial_backend/document.py b/lib/wlrepo/mercurial_backend/document.py index 6cf8a5bf..523e330a 100644 --- a/lib/wlrepo/mercurial_backend/document.py +++ b/lib/wlrepo/mercurial_backend/document.py @@ -32,7 +32,7 @@ class MercurialDocument(wlrepo.Document): f.close() l._fileadd(r(entry)) - return self.invoke_and_commit(write, lambda d: (msg, user)) + return self.invoke_and_commit(write, lambda d: (msg, self.owner)) def invoke_and_commit(self, ops, before_commit, rollback=False): @@ -50,7 +50,7 @@ class MercurialDocument(wlrepo.Document): return self._library.document(docid=self.id, user=user) except Exception, e: # rollback the last commit - self._library.rollback() + self._library._rollback() raise e finally: lock.release() -- 2.20.1