Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : matrix
---------------------------------------------------------------
commit 8b1cdec0f539fd52e1025aa90daf588a5653c3d8
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Wed Nov 13 16:11:57 2013 +0100
[frontend] rewrite backend view to use Build <-> Chroot relation
Fix BuildsLogic to update status of chroot objects
instead of Build directly, drop some unused parameters.
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
---------------------------------------------------------------
coprs_frontend/coprs/logic/builds_logic.py | 33 +++++-
.../coprs/views/backend_ns/backend_general.py | 117 +++++++++----------
2 files changed, 81 insertions(+), 69 deletions(-)
diff --git a/coprs_frontend/coprs/logic/builds_logic.py
b/coprs_frontend/coprs/logic/builds_logic.py
index 406f94e..f198e5a 100644
--- a/coprs_frontend/coprs/logic/builds_logic.py
+++ b/coprs_frontend/coprs/logic/builds_logic.py
@@ -10,7 +10,7 @@ from coprs.logic import users_logic
class BuildsLogic(object):
@classmethod
- def get(cls, user, build_id):
+ def get(cls, build_id):
query = models.Build.query.filter(models.Build.id == build_id)
return query
@@ -38,7 +38,7 @@ class BuildsLogic(object):
return query
@classmethod
- def get_waiting_builds(cls, user):
+ def get_waiting(cls):
# return builds that aren't both started and finished (if build start
submission
# fails, we still want to mark the build as non-waiting, if it ended)
# this has very different goal then get_multiple, so implement it alone
@@ -53,7 +53,7 @@ class BuildsLogic(object):
return query
@classmethod
- def get_by_ids(cls, user, ids):
+ def get_by_ids(cls, ids):
return models.Build.query.filter(models.Build.id.in_(ids))
@classmethod
@@ -91,14 +91,33 @@ class BuildsLogic(object):
db.session.add(buildchroot)
@classmethod
- def update_state_from_dict(cls, user, build, upd_dict):
- for attr in ['results', 'started_on', 'ended_on',
'status']:
+ def update_state_from_dict(cls, build, upd_dict):
+ if 'chroot' in upd_dict:
+ # update respective chroot status
+ for build_chroot in build.build_chroots:
+ if build_chroot.mock_chroot.chroot_name == upd_dict['chroot']:
+ build_chroot.status = upd_dict['status']
+
+ db.session.add(build_chroot)
+
+ for attr in ['results', 'started_on', 'ended_on']:
value = upd_dict.get(attr, None)
- if value != None:
- setattr(build, attr, value)
+ if value:
+ # only update started_on once
+ if attr == 'started_on' and build.started_on:
+ continue
+
+ # only update ended_on and results
+ # when there are no pending builds
+ if (attr in ['ended_on', 'results'] and
+ build.has_pending_chroot):
+ continue
+
if attr == 'ended_on':
signals.build_finished.send(cls, build=build)
+ setattr(build, attr, value)
+
db.session.add(build)
@classmethod
diff --git a/coprs_frontend/coprs/views/backend_ns/backend_general.py
b/coprs_frontend/coprs/views/backend_ns/backend_general.py
index ca7a3dd..fbc009a 100644
--- a/coprs_frontend/coprs/views/backend_ns/backend_general.py
+++ b/coprs_frontend/coprs/views/backend_ns/backend_general.py
@@ -1,81 +1,74 @@
-import json
-
import flask
from coprs import db
-from coprs import helpers
-from coprs import models
-
+from coprs.logic import actions_logic
from coprs.logic import builds_logic
from coprs.views import misc
from coprs.views.backend_ns import backend_ns
-(a)backend_ns.route('/waiting_builds/')
-def waiting_builds():
- query = builds_logic.BuildsLogic.get_waiting_builds(None)
-
- builds = query[0:10]
- return flask.jsonify({'builds': [build.to_dict(options = {'copr':
{'owner': {},
-
'__columns_only__': ['id', 'name'],
-
'__included_ids__': False},
- '__included_ids__':
False}) for build in builds]})
-
-
-(a)backend_ns.route('/update_builds/', methods = ['POST', 'PUT'])
+(a)backend_ns.route('/waiting/')
@misc.backend_authenticated
-def update_builds():
- to_update = {}
- for build in flask.request.json['builds']: # first get ids of sent builds
- to_update[build['id']] = build
-
- if not to_update:
- return json.dumps({'warning': 'No parsed builds'})
-
- existing = {} # create a dict of existing builds {build.id: build, ...}
- for build in builds_logic.BuildsLogic.get_by_ids(None, to_update.keys()).all():
- existing[build.id] = build
-
- non_existing_ids = list(set(to_update.keys()) - set(existing.keys()))
-
- for i, build in existing.items(): # actually update existing builds
- builds_logic.BuildsLogic.update_state_from_dict(None, build, to_update[i])
-
- db.session.commit()
-
- return flask.jsonify({'updated_builds_ids': list(existing.keys()),
'non_existing_builds_ids': non_existing_ids})
-
-
-(a)backend_ns.route('/waiting_actions/')
-def waiting_actions():
- actions =
models.Action.query.filter(models.Action.result==helpers.BackendResultEnum('waiting')).all()
+def waiting():
+ """
+ Return list of waiting actions and builds.
+ """
+
+ # models.Actions
+ actions_list = [action.to_dict(
+ options={'__columns_except__': ['result', 'message',
'ended_on']})
+ for action in actions_logic.ActionsLogic.get_waiting()
+ ]
+
+ # models.Builds
+ builds_list = []
+
+ for build in builds_logic.BuildsLogic.get_waiting():
+ build_dict = build.to_dict(
+ options={'copr': {'owner': {},
+ '__columns_only__': ['id',
'name'],
+ '__included_ids__': False
+ },
+ '__included_ids__': False})
+
+ # return separate build for each chroot this build
+ # is assigned with
+ for chroot in build.chroots:
+ build_dict_copy = build_dict.copy()
+ build_dict_copy['chroot'] = chroot.chroot_name
+ builds_list.append(build_dict_copy)
+
+ return flask.jsonify({'actions': actions_list, 'builds':
builds_list})
+
+
+(a)backend_ns.route('/update/', methods=['POST', 'PUT'])
+(a)misc.backend_authenticated
+def update():
+ result = {}
- return flask.jsonify({'actions':
[action.to_dict(options={'__columns_except__': ['result',
'message', 'ended_on']}) for action in actions]})
+ for typ, logic_cls in [('actions', actions_logic.ActionsLogic),
+ ('builds', builds_logic.BuildsLogic)]:
+ if typ not in flask.request.json:
+ continue
-# TODO: this is very similar to update_builds, we should pull out the common
functionality into a single function
-(a)backend_ns.route('/update_actions/', methods=['POST', 'PUT'])
-(a)misc.backend_authenticated
-def update_actions():
- to_update = {}
- for action in flask.request.json['actions']:
- to_update[action['id']] = action
+ to_update = {}
+ for obj in flask.request.json[typ]:
+ to_update[obj['id']] = obj
- if not to_update:
- return json.dumps({'warning': 'No parsed actions'})
+ existing = {}
+ for obj in logic_cls.get_by_ids(to_update.keys()).all():
+ existing[obj.id] = obj
- existing = {}
- for action in
models.Action.query.filter(models.Action.id.in_(to_update.keys())).all():
- existing[action.id] = action
+ non_existing_ids = list(set(to_update.keys()) - set(existing.keys()))
- non_existing_ids = list(set(to_update.keys()) - set(existing.keys()))
+ for i, obj in existing.items():
+ logic_cls.update_state_from_dict(obj, to_update[i])
- for i, action in existing.items():
- existing[i].result = to_update[i]['result']
- existing[i].message = to_update[i]['message']
- existing[i].ended_on = to_update[i]['ended_on']
+ db.session.commit()
- db.session.commit()
+ result.update({'updated_{0}_ids'.format(typ): list(existing.keys()),
+ 'non_existing_{0}_ids'.format(typ): non_existing_ids})
- return flask.jsonify({'updated_actions_ids': list(existing.keys()),
'non_existing_actions_ids': non_existing_ids})
+ return flask.jsonify(result)