blob: 58dca738ab2acd89dc9124c9e6636e07dbb40b04 [file] [log] [blame]
# 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