def test_removerequest(self): results = [] def on_db_return(success, db_results): assert success results.extend(db_results.fetchall()) with nested( mock.patch.dict(db.Settings, T.MockedSettings), mock.patch.object( RemoveRequestServlet, "get_current_user", return_value="testuser" ) ): results = [] db.execute_cb(db.push_pushcontents.select(), on_db_return) num_results_before = len(results) uri = "/removerequest?request=1&push=1" response = self.fetch(uri) T.assert_equal(response.error, None) results = [] db.execute_cb(db.push_pushcontents.select(), on_db_return) num_results_after = len(results) T.assert_equal(num_results_after, num_results_before - 1, "Request removal failed.")
def test_process_queue_successful(self): """Update the request with its sha""" with nested( mock.patch("%s.core.git.GitQueue.update_request_failure" % __name__), mock.patch("%s.core.git.GitQueue.update_request_successful" % __name__), self.mocked_update_request(self.fake_request)): # Successful call to update_request should trigger update_request_successful T.assert_equal(core.git.GitQueue.update_request_failure.call_count, 0) T.assert_equal( core.git.GitQueue.update_request_successful.call_count, 1) result = [None] def on_db_return(success, db_results): assert success, "Database error" result[0] = db_results.first() request_info_query = db.push_requests.select().where( db.push_requests.c.id == self.fake_request['id']) db.execute_cb(request_info_query, on_db_return) T.assert_equal(result[0][5], self.fake_request['revision'])
def get(self): if not self.current_user: return self.send_error(403) self.pushid = core.util.get_int_arg(self.request, 'id') self.pushmaster = core.util.get_int_arg(self.request, 'pushmaster') c = db.push_checklist.c r = db.push_requests.c query = SA.select([ c.target, c.type, c.complete, c.id, c.request, r.title, r.repo, r.branch, r.user, ]).where( SA.and_( r.id == c.request, r.state != 'pickme', c.request == db.push_pushcontents.c.request, db.push_pushcontents.c.push == self.pushid, )) db.execute_cb(query, self.on_db_complete)
def get(self): pushid = core.util.get_int_arg(self.request, 'push') ping_action = core.util.get_str_arg(self.request, 'action') response = yield tornado.gen.Task( self.async_api_call, "push", {"id": pushid} ) push = self.get_api_results(response) if not push: self.send_error() pings = set(x for x in (push['extra_pings'] or "").split(',') if x) if ping_action == 'set': pings.add(self.current_user) else: pings.discard(self.current_user) # This is not atomic, so we could theoretically # run into race conditions here, but since we're # working at machine speed on human input triggers # it should be okay for now. query = db.push_pushes.update().where( db.push_pushes.c.id == pushid, ).values({ 'extra_pings': ','.join(pings), }) db.execute_cb(query, self.on_update_complete)
def get(self): pushid = core.util.get_int_arg(self.request, 'push') ping_action = core.util.get_str_arg(self.request, 'action') response = yield tornado.gen.Task(self.async_api_call, "push", {"id": pushid}) push = self.get_api_results(response) if not push: self.send_error() pings = set(x for x in (push['extra_pings'] or "").split(',') if x) if ping_action == 'set': pings.add(self.current_user) else: pings.discard(self.current_user) # This is not atomic, so we could theoretically # run into race conditions here, but since we're # working at machine speed on human input triggers # it should be okay for now. query = db.push_pushes.update().where( db.push_pushes.c.id == pushid, ).values({ 'extra_pings': ','.join(pings), }) db.execute_cb(query, self.on_update_complete)
def post(self): if not self.current_user: return self.send_error(403) self.requestid = self._arg('request-id') self.tag_list = [x for x in TAGS_RE.findall(self._arg('request-tags')) if x] reviewid = self._arg('request-review') if reviewid: try: reviewid = int(reviewid) except (ValueError, TypeError): return self.send_error(500) watchers = ','.join(map(str.strip, self._arg('request-watchers').split(','))) if self.requestid != '': self.requestid = int(self.requestid) updated_values = { 'title': self._arg('request-title'), 'tags': ','.join(self.tag_list), 'reviewid': reviewid or None, 'repo': self._arg('request-repo'), 'branch': self._arg('request-branch'), 'comments': self._arg('request-comments'), 'description': self._arg('request-description'), 'watchers': watchers, 'modified': time.time(), 'revision': '0'*40, } if len(self._arg('request-takeover')): updated_values.update({'user': self.current_user}) self.request_user = self.current_user else: self.request_user = self._arg('request-user') query = db.push_requests.update().where( db.push_requests.c.id == self.requestid ).values(updated_values) else: query = db.push_requests.insert({ 'title': self._arg('request-title'), 'user': self.current_user, 'tags': ','.join(self.tag_list), 'reviewid': self._arg('request-review') or None, 'repo': self._arg('request-repo'), 'branch': self._arg('request-branch'), 'comments': self._arg('request-comments'), 'description': self._arg('request-description'), 'watchers': watchers, 'created': time.time(), 'modified': time.time(), 'state': 'requested', 'revision': '0'*40, }) self.request_user = self.current_user db.execute_cb(query, self.on_request_upsert_complete)
def get_requests(self): requests = [None] def on_select_return(success, db_results): assert success requests[0] = db_results.fetchall() db.execute_cb(db.push_requests.select(), on_select_return) return requests[0]
def get_pushes(self): pushes = [None] def on_select_return(success, db_results): assert success pushes[0] = db_results.fetchall() db.execute_cb(db.push_pushes.select(), on_select_return) return pushes[0]
def _api_PUSH(self): """Returns a JSON representation of a push.""" push_id = util.get_int_arg(self.request, 'id') if not push_id: return self.send_error(404) query = db.push_pushes.select(db.push_pushes.c.id == push_id) db.execute_cb(query, self._on_PUSH_db_response)
def post(self): if not self.current_user: return self.send_error(403) self.pushid = core.util.get_int_arg(self.request, 'push') self.request_ids = self.request.arguments.get('request', []) db.execute_cb(db.push_pushes.select().where(db.push_pushes.c.id == self.pushid), self.on_push_select)
def _api_REQUEST(self): """Returns a JSON representation of a push request.""" request_id = util.get_int_arg(self.request, 'id') if not request_id: return self.send_error(404) query = db.push_requests.select(db.push_requests.c.id == request_id) db.execute_cb(query, self._on_REQUEST_db_response)
def on_request_upsert_complete(self, success, db_results): self.check_db_results(success, db_results) if not self.requestid: self.requestid = db_results.lastrowid query = db.push_checklist.select().where(db.push_checklist.c.request == self.requestid) db.execute_cb(query, self.on_existing_checklist_retrieved)
def on_request_upsert_complete(self, success, db_results): self.check_db_results(success, db_results) if not self.requestid: self.requestid = db_results.lastrowid query = db.push_checklist.select().where( db.push_checklist.c.request == self.requestid) db.execute_cb(query, self.on_existing_checklist_retrieved)
def post(self): if not self.current_user: return self.send_error(403) self.checklist = core.util.get_int_arg(self.request, 'id') new_value = core.util.get_int_arg(self.request, 'complete') query = db.push_checklist.update().where( db.push_checklist.c.id == self.checklist).values({'complete': new_value}) db.execute_cb(query, lambda _, __:self.finish())
def _api_PUSHCONTENTS(self): """Returns a set of JSON representations of requests in a given push.""" push_id = util.get_int_arg(self.request, "id") if not push_id: return self.send_error(404) query = db.push_requests.select( SA.and_(db.push_requests.c.id == db.push_pushcontents.c.request, db.push_pushcontents.c.push == push_id) ) db.execute_cb(query, self._on_PUSHCONTENTS_db_response)
def post(self): if not self.current_user: return self.send_error(403) self.pushid = core.util.get_int_arg(self.request, 'push') self.request_ids = self.request.arguments.get('request', []) db.execute_cb( db.push_pushes.select().where(db.push_pushes.c.id == self.pushid), self.on_push_select)
def get_push_for_request(self, requestid): pushid = [None] def on_select_return(success, db_results): assert success _, pushid[0] = db_results.fetchone() # check if we have a push in with request first_pushcontent_query = db.push_pushcontents.select(db.push_pushcontents.c.request == requestid) db.execute_cb(first_pushcontent_query, on_select_return) return pushid[0]
def test_newrequest(self): results = [] def on_db_return(success, db_results): assert success results.extend(db_results.fetchall()) with nested( mock.patch.dict(db.Settings, T.MockedSettings), mock.patch.object(NewRequestServlet, "redirect"), mock.patch.object( NewRequestServlet, "get_current_user", return_value="testuser" ) ): results = [] db.execute_cb(db.push_requests.select(), on_db_return) num_results_before = len(results) request = { 'request-title': 'Test Push Request Title', 'request-tags': 'super-safe,logs', 'request-review': 1, 'request-repo': 'testuser', 'request-branch': 'super_safe_fix', 'request-comments': 'No comment', 'request-description': 'I approve this fix!', 'request-watchers': 'testuser2,testuser3', } response = self.fetch( "/newrequest", method="POST", body=urllib.urlencode(request) ) T.assert_equal(response.error, None) results = [] db.execute_cb(db.push_requests.select(), on_db_return) num_results_after = len(results) T.assert_equal(num_results_after, num_results_before + 1) last_req = self.get_requests()[-1] T.assert_equal(len(results), last_req['id']) T.assert_equal('testuser', last_req['user']) T.assert_equal(request['request-repo'], last_req['repo']) T.assert_equal(request['request-branch'], last_req['branch']) T.assert_equal(request['request-tags'], last_req['tags']) T.assert_equal(request['request-comments'], last_req['comments']) T.assert_equal(request['request-description'], last_req['description']) T.assert_equal(request['request-watchers'], last_req['watchers'])
def _api_PUSHBYREQUEST(self): """Returns a JSON representation of a PUSH given a request id.""" request_id = util.get_int_arg(self.request, 'id') if not request_id: return self.send_error(404) query = db.push_pushes.select(SA.and_( db.push_pushes.c.state != "discarded", db.push_pushcontents.c.push == db.push_pushes.c.id, db.push_pushcontents.c.request == request_id, )) db.execute_cb(query, self._on_PUSHBYREQUEST_db_response)
def _api_PUSHCONTENTS(self): """Returns a set of JSON representations of requests in a given push.""" push_id = util.get_int_arg(self.request, 'id') if not push_id: return self.send_error(404) query = db.push_requests.select( SA.and_( db.push_requests.c.id == db.push_pushcontents.c.request, db.push_pushcontents.c.push == push_id, )) db.execute_cb(query, self._on_PUSHCONTENTS_db_response)
def get_push_for_request(self, requestid): pushid = [None] def on_select_return(success, db_results): assert success _, pushid[0] = db_results.fetchone() # check if we have a push in with request first_pushcontent_query = db.push_pushcontents.select( db.push_pushcontents.c.request == requestid ) db.execute_cb(first_pushcontent_query, on_select_return) return pushid[0]
def _api_PUSHBYREQUEST(self): """Returns a JSON representation of a PUSH given a request id.""" request_id = util.get_int_arg(self.request, 'id') if not request_id: return self.send_error(404) query = db.push_pushes.select( SA.and_( db.push_pushes.c.state != "discarded", db.push_pushcontents.c.push == db.push_pushes.c.id, db.push_pushcontents.c.request == request_id, )) db.execute_cb(query, self._on_PUSHBYREQUEST_db_response)
def get(self): query = db.push_pushes.select(SA.and_( db.push_pushes.c.state == 'accepting', SA.exists([1], SA.and_( db.push_pushcontents.c.push == db.push_pushes.c.id, db.push_pushcontents.c.request == db.push_requests.c.id, db.push_requests.c.user == self.current_user, ), ), ), order_by=db.push_pushes.c.created.asc(), ) db.execute_cb(query, self.on_db_response)
def get_checklists(self, requestid): checklists = [None] def on_select_return(success, db_results): assert success checklists[0] = db_results.fetchall() select_query = db.push_checklist.select().where( db.push_checklist.c.request == requestid) db.execute_cb(select_query, on_select_return) # id, *request*, *type*, complete, *target* simple_checklists = [(cl[1], cl[2], cl[4]) for cl in checklists[0]] return simple_checklists
def test_newrequest(self): results = [] def on_db_return(success, db_results): assert success results.extend(db_results.fetchall()) with nested( mock.patch.dict(db.Settings, T.MockedSettings), mock.patch.object(NewRequestServlet, "redirect"), mock.patch.object(NewRequestServlet, "get_current_user", return_value="testuser")): results = [] db.execute_cb(db.push_requests.select(), on_db_return) num_results_before = len(results) request = { 'request-title': 'Test Push Request Title', 'request-tags': 'super-safe,logs', 'request-review': 1, 'request-repo': 'testuser', 'request-branch': 'super_safe_fix', 'request-comments': 'No comment', 'request-description': 'I approve this fix!', 'request-watchers': 'testuser2,testuser3', } response = self.fetch("/newrequest", method="POST", body=urllib.urlencode(request)) T.assert_equal(response.error, None) results = [] db.execute_cb(db.push_requests.select(), on_db_return) num_results_after = len(results) T.assert_equal(num_results_after, num_results_before + 1) last_req = self.get_requests()[-1] T.assert_equal(len(results), last_req['id']) T.assert_equal('testuser', last_req['user']) T.assert_equal(request['request-repo'], last_req['repo']) T.assert_equal(request['request-branch'], last_req['branch']) T.assert_equal(request['request-tags'], last_req['tags']) T.assert_equal(request['request-comments'], last_req['comments']) T.assert_equal(request['request-description'], last_req['description']) T.assert_equal(request['request-watchers'], last_req['watchers'])
def test_add_new_request(self): db.execute_cb(db.push_pushcontents.select(), self.record_pushcontents) num_results_before = len(self.results) request = { 'request': 2, 'push': 1 } response = self.fetch( '/addrequest', method='POST', body=urllib.urlencode(request) ) T.assert_equal(response.error, None) db.execute_cb(db.push_pushcontents.select(), self.record_pushcontents) num_results_after = len(self.results) T.assert_equal(num_results_after, num_results_before + 1, "Add new request failed.")
def post(self): if not self.current_user: return self.send_error(403) self.pushid = core.util.get_int_arg(self.request, 'id') query = db.push_pushes.update().where(db.push_pushes.c.id == self.pushid).values(**{ 'title': self._arg('push-title'), 'user': self.current_user, 'branch': self._arg('push-branch'), 'revision': "0"*40, 'modified': time.time(), }) db.execute_cb( query, lambda _, __: self.redirect("/push?id=%d" % self.pushid) )
def _api_PUSHITEMS(self): """Returns a JSON representation of a list of requests given a push id""" push_id = util.get_int_arg(self.request, 'push_id') if not push_id: return self.send_error(404) query = db.push_requests.select( SA.and_( db.push_requests.c.id == db.push_pushcontents.c.request, db.push_requests.c.state != 'pickme', db.push_pushcontents.c.push == push_id, ), order_by=(db.push_requests.c.user, db.push_requests.c.title), ) db.execute_cb(query, self._on_PUSHITEMS_db_response)
def test_newpush(self): pushes = [] def on_db_return(success, db_results): assert success pushes.extend(db_results.fetchall()) with nested( mock.patch.dict(db.Settings, T.MockedSettings), mock.patch.object(NewPushServlet, "get_current_user", return_value = "jblack"), mock.patch.object(NewPushServlet, "redirect"), mock.patch.object(MailQueue, "enqueue_user_email"), ): with mock.patch("%s.servlets.newpush.subprocess.call" % __name__) as mocked_call: title = "BestPushInTheWorld" branch = "jblack" push_type = "regular" uri = "/newpush?push-title=%s&branch=%s&push-type=%s" % ( title, branch, push_type ) pushes = [] db.execute_cb(db.push_pushes.select(), on_db_return) num_pushes_before = len(pushes) response = self.fetch(uri) assert response.error == None pushes = [] db.execute_cb(db.push_pushes.select(), on_db_return) num_pushes_after = len(pushes) T.assert_equal(num_pushes_before + 1, num_pushes_after) # There should be one call to nodebot after a push is created T.assert_equal(servlets.newpush.subprocess.call.call_count, 1) # Verify that we have a valid call to # subprocess.call. Getting the arguments involves ugly # mock magic mocked_call.assert_called_once_with([ '/nail/sys/bin/nodebot', '-i', mock.ANY, # nickname mock.ANY, # channel mock.ANY, # msg ])
def get(self): query = db.push_pushes.select( SA.and_( db.push_pushes.c.state == 'accepting', SA.exists( [1], SA.and_( db.push_pushcontents.c.push == db.push_pushes.c.id, db.push_pushcontents.c.request == db.push_requests.c.id, db.push_requests.c.user == self.current_user, ), ), ), order_by=db.push_pushes.c.created.asc(), ) db.execute_cb(query, self.on_db_response)
def test_newpush(self): pushes = [] def on_db_return(success, db_results): assert success pushes.extend(db_results.fetchall()) with nested( mock.patch.dict(db.Settings, T.MockedSettings), mock.patch.object(NewPushServlet, "get_current_user", return_value = "jblack"), mock.patch.object(NewPushServlet, "redirect"), ): with mock.patch("%s.servlets.newpush.subprocess.call" % __name__) as mocked_call: title = "BestPushInTheWorld" branch = "jblack" push_type = "regular" uri = "/newpush?push-title=%s&branch=%s&push-type=%s" % ( title, branch, push_type ) pushes = [] db.execute_cb(db.push_pushes.select(), on_db_return) num_pushes_before = len(pushes) response = self.fetch(uri) assert response.error == None pushes = [] db.execute_cb(db.push_pushes.select(), on_db_return) num_pushes_after = len(pushes) T.assert_equal(num_pushes_before + 1, num_pushes_after) # There should be one call to nodebot after a push is created T.assert_equal(servlets.newpush.subprocess.call.call_count, 1) # Verify that we have a valid call to # subprocess.call. Getting the arguments involves ugly # mock magic call = mocked_call.call_args args = call[0][0] last_arg = args[-1] T.assert_in("regular push starting! https://", last_arg)
def get(self): if not self.current_user: return self.send_error(403) self.pushid = core.util.get_int_arg(self.request, 'id') self.pushmaster = core.util.get_int_arg(self.request, 'pushmaster') c = db.push_checklist.c r = db.push_requests.c query = SA.select([ c.target, c.type, c.complete, c.id, c.request, r.title, r.repo, r.branch, r.user, ]).where(SA.and_( r.id == c.request, r.state != 'pickme', c.request == db.push_pushcontents.c.request, db.push_pushcontents.c.push == self.pushid, )) db.execute_cb(query, self.on_db_complete)
def test_process_queue_successful(self): """Update the request with its sha""" with nested( mock.patch("%s.core.git.GitQueue.update_request_failure" % __name__), mock.patch("%s.core.git.GitQueue.update_request_successful" % __name__), self.mocked_update_request(self.fake_request) ): # Successful call to update_request should trigger update_request_successful T.assert_equal(core.git.GitQueue.update_request_failure.call_count, 0) T.assert_equal(core.git.GitQueue.update_request_successful.call_count, 1) result = [None] def on_db_return(success, db_results): assert success, "Database error" result[0] = db_results.first() request_info_query = db.push_requests.select().where( db.push_requests.c.id == self.fake_request['id'] ) db.execute_cb(request_info_query, on_db_return) T.assert_equal(result[0][5], self.fake_request['revision'])
def test_pickmerequest(self): push_contents = [] def on_db_return(success, db_results): assert success push_contents.extend(db_results.fetchall()) with self.fake_pickme_request(): pushid = 1 requestid = 2 push_contents = [] db.execute_cb(db.push_pushcontents.select(), on_db_return) num_contents_before = len(push_contents) uri = "/pickmerequest?push=%d&request=%d" % (pushid, requestid) response = self.fetch(uri) T.assert_equal(response.error, None) push_contents = [] db.execute_cb(db.push_pushcontents.select(), on_db_return) num_contents_after = len(push_contents) T.assert_equal(num_contents_before + 1, num_contents_after)
def test_checklist_toggle_post(self): complete = 0 checklist_item = [None] def check_toggle(success, db_results): assert success checklist_item[0] = db_results.fetchone() T.assert_equal(checklist_item[0]['complete'], complete) with fake_checklist_request(): # insert fake data from FakeDataMixin self.insert_requests() test_request1 = self.get_requests_by_user('testuser1')[0] # insert fake checklist data checklist_query = db.push_checklist.insert({ 'request': test_request1['id'], 'type': 'search', 'target': 'prod' }) db.execute_cb(checklist_query, on_db_return) checklist_toggle_query = db.push_checklist.select( db.push_checklist.c.request == test_request1['id']) complete = 0 db.execute_cb(checklist_toggle_query, check_toggle) complete = 1 response = self.fetch("/checklisttoggle", method="POST", body=urllib.urlencode({ 'id': checklist_item[0]['id'], 'complete': complete })) T.assert_equal(response.error, None) db.execute_cb(checklist_toggle_query, check_toggle)
def test_checklist_toggle_post(self): complete = 0 checklist_item = [None] def check_toggle(success, db_results): assert success checklist_item[0] = db_results.fetchone() T.assert_equal(checklist_item[0]['complete'], complete) with fake_checklist_request(): # insert fake data from FakeDataMixin self.insert_requests() test_request1 = self.get_requests_by_user('testuser1')[0] # insert fake checklist data checklist_query = db.push_checklist.insert({ 'request': test_request1['id'], 'type': 'search', 'target': 'prod' }) db.execute_cb(checklist_query, on_db_return) checklist_toggle_query = db.push_checklist.select( db.push_checklist.c.request == test_request1['id'] ) complete = 0 db.execute_cb(checklist_toggle_query, check_toggle) complete = 1 response = self.fetch( "/checklisttoggle", method="POST", body=urllib.urlencode({'id': checklist_item[0]['id'], 'complete': complete}) ) T.assert_equal(response.error, None) db.execute_cb(checklist_toggle_query, check_toggle)
def insert_pushcontent(self, requestid, pushid): db.execute_cb( db.push_pushcontents.insert({'request': requestid, 'push': pushid}), self.on_db_return )
def test_convert_cleanup_type(self): rename_checklist_type.convert_checklist('search', 'not_search') cb = partial(self.verify_type_rename, 'search', 'not_search') db.execute_cb(db.push_checklist.select(), cb)
def _api_REQUESTSEARCH(self): """Returns a list of requests matching a the specified filter(s).""" filters = [] # Tag constraint for tag in self.request.arguments.get('tag', []): filters.append( db.push_requests.c.tags.op('regexp')('[[:<:]]' + tag + '[[:>:]]')) # Timestamp constraint mbefore = util.get_int_arg(self.request, 'mbefore') mafter = util.get_int_arg(self.request, 'mafter') if mbefore: filters.append(db.push_requests.c.modified < mbefore) if mafter: filters.append(db.push_requests.c.modified > mafter) cbefore = util.get_int_arg(self.request, 'cbefore') cafter = util.get_int_arg(self.request, 'cafter') if cbefore: filters.append(db.push_requests.c.created < cbefore) if cafter: filters.append(db.push_requests.c.created > cafter) # State constraint states = self.request.arguments.get('state', []) if states: filters.append(db.push_requests.c.state.in_(states)) # User constraint users = self.request.arguments.get('user', []) if users: filters.append(db.push_requests.c.user.in_(users)) # Repository constraint repos = self.request.arguments.get('repo', []) if repos: filters.append(db.push_requests.c.repo.in_(repos)) # Branch constraint branches = self.request.arguments.get('branch', []) if branches: filters.append(db.push_requests.c.branch.in_(branches)) # Revision constraint revisions = self.request.arguments.get('rev', []) if revisions: filters.append(db.push_requests.c.revision.in_(revisions)) # Review constraint reviews = self.request.arguments.get('review', []) if reviews: filters.append(db.push_requests.c.reviewid.in_(reviews)) # Title constraint for title in self.request.arguments.get('title', []): filters.append(db.push_requests.c.title.like('%' + title + '%')) # Only allow searches with at least one constraint (to avoid # accidental dumps of the entire table) if not filters: return self.send_error(409) query = db.push_requests.select(SA.and_(*filters)) query = query.order_by(db.push_requests.c.id.desc()) limit = util.get_int_arg(self.request, 'limit') if limit > 0: limit = max(min(1000, limit), 1) query = query.limit(limit) db.execute_cb(query, self._on_REQUESTSEARCH_db_response)
def _api_USERLIST(self): """Returns a JSON list of users who used PushManager for a request at least once.""" query = db.push_requests.select(group_by=db.push_requests.c.user, ) db.execute_cb(query, self._on_USERLIST_db_response)
def test_convert_notype(self): rename_checklist_type.convert_checklist('nonexistent', 'random') cb = partial(self.verify_database_state, self.checklist_data) db.execute_cb(db.push_checklist.select(), cb)
def _api_USERLIST(self): """Returns a JSON list of users who used PushManager for a request at least once.""" query = db.push_requests.select( group_by=db.push_requests.c.user, ) db.execute_cb(query, self._on_USERLIST_db_response)
def _api_REQUESTSEARCH(self): """Returns a list of requests matching a the specified filter(s).""" filters = [] # Tag constraint for tag in self.request.arguments.get('tag', []): filters.append(db.push_requests.c.tags.op('regexp')('[[:<:]]' + tag + '[[:>:]]')) # Timestamp constraint mbefore = util.get_int_arg(self.request, 'mbefore') mafter = util.get_int_arg(self.request, 'mafter') if mbefore: filters.append(db.push_requests.c.modified < mbefore) if mafter: filters.append(db.push_requests.c.modified > mafter) cbefore = util.get_int_arg(self.request, 'cbefore') cafter = util.get_int_arg(self.request, 'cafter') if cbefore: filters.append(db.push_requests.c.created < cbefore) if cafter: filters.append(db.push_requests.c.created > cafter) # State constraint states = self.request.arguments.get('state', []) if states: filters.append(db.push_requests.c.state.in_(states)) # User constraint users = self.request.arguments.get('user', []) if users: filters.append(db.push_requests.c.user.in_(users)) # Repository constraint repos = self.request.arguments.get('repo', []) if repos: filters.append(db.push_requests.c.repo.in_(repos)) # Branch constraint branches = self.request.arguments.get('branch', []) if branches: filters.append(db.push_requests.c.branch.in_(branches)) # Revision constraint revisions = self.request.arguments.get('rev', []) if revisions: filters.append(db.push_requests.c.revision.in_(revisions)) # Review constraint reviews = self.request.arguments.get('review', []) if reviews: filters.append(db.push_requests.c.reviewid.in_(reviews)) # Title constraint for title in self.request.arguments.get('title', []): filters.append(db.push_requests.c.title.like('%' + title + '%')) # Only allow searches with at least one constraint (to avoid # accidental dumps of the entire table) if not filters: return self.send_error(409) query = db.push_requests.select(SA.and_(*filters)) query = query.order_by(db.push_requests.c.id.desc()) limit = util.get_int_arg(self.request, 'limit') if limit > 0: limit = max(min(1000, limit), 1) query = query.limit(limit) db.execute_cb(query, self._on_REQUESTSEARCH_db_response)
def post(self): if not self.current_user: return self.send_error(403) self.requestid = self._arg('request-id') self.tag_list = [ x for x in TAGS_RE.findall(self._arg('request-tags')) if x ] reviewid = self._arg('request-review') if reviewid: try: reviewid = int(reviewid) except (ValueError, TypeError): return self.send_error(500) if self.requestid != '': self.requestid = int(self.requestid) query = db.push_requests.update().where( db.push_requests.c.id == self.requestid).values({ 'title': self._arg('request-title'), 'user': self.current_user, 'tags': ','.join(self.tag_list), 'reviewid': reviewid or None, 'repo': self._arg('request-repo'), 'branch': self._arg('request-branch'), 'comments': self._arg('request-comments'), 'description': self._arg('request-description'), 'modified': time.time(), 'revision': '0' * 40, }) else: query = db.push_requests.insert({ 'title': self._arg('request-title'), 'user': self.current_user, 'tags': ','.join(self.tag_list), 'reviewid': self._arg('request-review') or None, 'repo': self._arg('request-repo'), 'branch': self._arg('request-branch'), 'comments': self._arg('request-comments'), 'description': self._arg('request-description'), 'created': time.time(), 'modified': time.time(), 'state': 'requested', 'revision': '0' * 40, }) db.execute_cb(query, self.on_request_upsert_complete)