1 # -*- encoding: utf-8 -*-
4 log = logging.getLogger('platforma.api.manage')
6 __author__= "Łukasz Rekucki"
7 __date__ = "$2009-09-25 15:49:50$"
8 __doc__ = "Module documentation."
10 from piston.handler import BaseHandler
11 from wlrepo import UpdateException
13 from api.utils import hglibrary
14 from api.models import PullRequest
15 from api.response import *
18 class PullRequestListHandler(BaseHandler):
19 allowed_methods = ('GET',)
21 def read(self, request):
22 if request.user.has_perm('change_pullrequest'):
23 return PullRequest.objects.all()
25 return PullRequest.objects.filter(commiter=request.user)
28 class PullRequestHandler(BaseHandler):
29 allowed_methods = ('GET', 'PUT')
31 def read(self, request, prq_id):
32 return PullRequest.objects.get(id=prq_id)
34 def update(self, request, prq_id):
35 """Change the status of request"""
37 if not request.user.has_perm('change_pullrequest'):
38 return AccessDenied().django_response("Insufficient priviliges")
40 prq = PullRequest.objects.get(id=prq_id)
43 return EntityNotFound().django_response()
45 action = request.PUT.get('action', None)
47 if action == 'accept':
48 return self.accept_merge(request.user, prq)
49 elif action == 'reject' and prq.status in ['N', 'R']:
50 return self.reject_merge(request.user, prq)
52 return BadRequest().django_response()
56 def accept_merge(self, user, prq, lib):
57 if prq.status not in ['N', 'E']:
58 return BadRequest().django_response({
59 'reason': 'invalid-state',
60 'message': "This pull request is alredy resolved. Can't accept."
63 src_doc = lib.document_for_revision( prq.source_revision )
67 if not src_doc.up_to_date():
68 # This revision is no longer up to date, thus
69 # it needs to be updated, before push:
71 # Q: where to put the updated revision ?
72 # A: create a special user branch named prq-#prqid
73 prq_doc = src_doc.take("$prq-%d" % prq.id)
75 # This could be not the first time we try this,
76 # so the prq_doc could already be there
80 prq_doc = prq_doc.update(user.username)
81 prq.source_revision = str(prq_doc.revision)
83 except UpdateException, e:
84 # this can happen only if the merge program
85 # is misconfigured - try returning an entity conflict
86 # TODO: put some useful infor here
89 return EntityConflict().django_response({
90 'reason': 'update-failed',
91 'message': e.message })
93 # check if there are conflicts
94 if src_doc.has_conflict_marks():
97 # Now, the user must resolve the conflict
98 return EntityConflict().django_response({
99 "reason": "unresolved-conflicts",
100 "message": "There are conflict in the document. Resolve the conflicts retry accepting."
103 # So, we have an up-to-date, non-conflicting document
104 changed = src_doc.share(prq.comment)
107 # this is actually very bad, but not critical
108 log.error("Unsynched pull request: %d" % prq.id)
110 # sync state with repository
112 prq.merged_revision = str(src_doc.shared().revision)
113 prq.merged_timestamp = datetime.datetime.now()
116 return SuccessAllOk().django_response({
117 'status': prq.status,
118 'merged_into': prq.merged_revision,
119 'merged_at': prq.merged_timestamp
124 def reject_merge(self, prq, lib):
128 return SuccessAllOk().django_response({