summaryrefslogtreecommitdiffstats
path: root/webapp/codereview/review_service.py
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/codereview/review_service.py')
-rw-r--r--webapp/codereview/review_service.py125
1 files changed, 125 insertions, 0 deletions
diff --git a/webapp/codereview/review_service.py b/webapp/codereview/review_service.py
new file mode 100644
index 0000000000..58dca738ab
--- /dev/null
+++ b/webapp/codereview/review_service.py
@@ -0,0 +1,125 @@
+# Copyright 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+
+from google.appengine.api import users
+from google.appengine.ext import db
+
+from models import gql, Project, Branch, Account
+import git_models
+
+from review_pb2 import *
+from upload_bundle_pb2 import *
+from internal.util import automatic_retry
+
+class ReviewServiceImp(ReviewService):
+ """
+ Implements the review_service API for developer clients.
+ """
+
+ @automatic_retry
+ def UploadBundle(self, rpc_controller, req, done):
+ """
+ Receives an uploaded Git style bundle and queues it for processing.
+ """
+ rsp = UploadBundleResponse()
+
+ # can't get here if there isn't a current user
+ current_user = users.get_current_user()
+
+ if not Account.get_account_for_user(current_user).cla_verified:
+ rsp.status_code = UploadBundleResponse.UNAUTHORIZED_USER
+ done(rsp)
+ return
+
+ if not req.dest_project:
+ rsp.status_code = UploadBundleResponse.UNKNOWN_PROJECT
+ done(rsp)
+ return
+
+ proj = req.dest_project
+ if proj.endswith(".git"):
+ proj = proj[0 : len(proj) - 4]
+
+ proj = Project.get_project_for_name(proj)
+ if not proj:
+ rsp.status_code = UploadBundleResponse.UNKNOWN_PROJECT
+ done(rsp)
+ return
+
+ if not req.dest_branch:
+ rsp.status_code = UploadBundleResponse.UNKNOWN_BRANCH
+ done(rsp)
+
+ brch = Branch.get_branch_for_name(proj, req.dest_branch)
+ if not brch:
+ rsp.status_code = UploadBundleResponse.UNKNOWN_BRANCH
+ done(rsp)
+ return
+
+ rb = git_models.ReceivedBundle(
+ dest_project = proj,
+ dest_branch = brch,
+ owner = current_user,
+ state = git_models.ReceivedBundle.STATE_UPLOADING,
+ contained_objects = list(req.contained_object))
+ rb.put()
+
+ rsp.bundle_id = str(rb.key().id())
+ self._store_segment(req, rsp, rb, 1)
+ done(rsp)
+
+ @automatic_retry
+ def ContinueBundle(self, rpc_controller, req, done):
+ rsp = UploadBundleResponse()
+ rsp.bundle_id = req.bundle_id
+
+ rb = git_models.ReceivedBundle.get_by_id(int(req.bundle_id))
+ if rb is None:
+ rsp.status_code = UploadBundleResponse.UNKNOWN_BUNDLE
+ done(rsp)
+ return
+
+ if rb.owner != users.get_current_user():
+ rsp.status_code = UploadBundleResponse.NOT_BUNDLE_OWNER
+ done(rsp)
+ return
+
+ self._store_segment(req, rsp, rb, req.segment_id)
+ done(rsp)
+
+ def _store_segment(self, req, rsp, rb, segment_id):
+ rb.set_segment(segment_id, req.bundle_data)
+ def trans():
+ b = db.get(rb.key())
+ if b.state != git_models.ReceivedBundle.STATE_UPLOADING:
+ return False
+
+ if b.n_segments < segment_id:
+ b.n_segments = segment_id
+ if not req.partial_upload:
+ b.state = git_models.ReceivedBundle.STATE_NEW
+ b.put()
+ return True
+
+ if db.run_in_transaction(trans):
+ if req.partial_upload:
+ rsp.status_code = UploadBundleResponse.CONTINUE
+ else:
+ rb.ready()
+ rsp.status_code = UploadBundleResponse.RECEIVED
+ else:
+ rsp.status_code = UploadBundleResponse.BUNDLE_CLOSED
+