Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
commit 42bdee5b1752ada33eb2f8b6af4bdc396d311201 Author: Bohuslav Kabrda bkabrda@redhat.com Date: Fri Mar 29 12:20:57 2013 +0100
Generalize Action to be usable for different scenarios
- rename backend_message to message - add ended_on column
.../versions/451e9507b866_generalize_action.py | 30 ++++++++++++++++++++ coprs_frontend/coprs/logic/builds_logic.py | 2 +- coprs_frontend/coprs/logic/coprs_logic.py | 15 ++++++---- coprs_frontend/coprs/models.py | 8 +++-- .../coprs/views/backend_ns/backend_general.py | 5 ++- .../coprs/views/coprs_ns/coprs_general.py | 5 +++ .../test_backend_ns/test_backend_general.py | 21 +++++++++---- 7 files changed, 67 insertions(+), 19 deletions(-)
diff --git a/coprs_frontend/alembic/versions/451e9507b866_generalize_action.py b/coprs_frontend/alembic/versions/451e9507b866_generalize_action.py new file mode 100644 index 0000000..203f4cc --- /dev/null +++ b/coprs_frontend/alembic/versions/451e9507b866_generalize_action.py @@ -0,0 +1,30 @@ +"""generalize_action + +Revision ID: 451e9507b866 +Revises: 2a75f0a06d90 +Create Date: 2013-03-29 12:13:33.303584 + +""" + +# revision identifiers, used by Alembic. +revision = '451e9507b866' +down_revision = '2a75f0a06d90' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.add_column('action', sa.Column('message', sa.Text(), nullable=True)) + op.add_column('action', sa.Column('ended_on', sa.Integer(), nullable=True)) + op.drop_column('action', u'backend_message') + ### end Alembic commands ### + + +def downgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.add_column('action', sa.Column(u'backend_message', sa.TEXT(), nullable=True)) + op.drop_column('action', 'ended_on') + op.drop_column('action', 'message') + ### end Alembic commands ### diff --git a/coprs_frontend/coprs/logic/builds_logic.py b/coprs_frontend/coprs/logic/builds_logic.py index 834217d..bbcd639 100644 --- a/coprs_frontend/coprs/logic/builds_logic.py +++ b/coprs_frontend/coprs/logic/builds_logic.py @@ -58,7 +58,7 @@ class BuildsLogic(object):
@classmethod def add(cls, user, pkgs, copr): - coprs_logic.CoprsLogic.raise_if_unfinished_action(user, copr, + coprs_logic.CoprsLogic.raise_if_unfinished_blocking_action(user, copr, 'Can't build while there is an operation in progress: {action}') users_logic.UsersLogic.raise_if_cant_build_in_copr(user, copr, 'You don't have permissions to build in this copr.') diff --git a/coprs_frontend/coprs/logic/coprs_logic.py b/coprs_frontend/coprs/logic/coprs_logic.py index 663c5cd..e768ae0 100644 --- a/coprs_frontend/coprs/logic/coprs_logic.py +++ b/coprs_frontend/coprs/logic/coprs_logic.py @@ -93,7 +93,7 @@ class CoprsLogic(object):
@classmethod def update(cls, user, copr, check_for_duplicates = True): - cls.raise_if_unfinished_action(user, copr, + cls.raise_if_unfinished_blocking_action(user, copr, 'Can't change this Copr name, another operation is in progress: {action}') users_logic.UsersLogic.raise_if_cant_update_copr(user, copr, 'Only owners and admins may update their Coprs.') @@ -120,7 +120,7 @@ class CoprsLogic(object): if not copr.owner == user: raise exceptions.InsufficientRightsException('Only owners may delete their Coprs.') # TODO: do we want to dump the information somewhere, so that we can search it in future? - cls.raise_if_unfinished_action(user, copr, + cls.raise_if_unfinished_blocking_action(user, copr, 'Can't delete this Copr, another operation is in progress: {action}') action = models.Action(action_type=helpers.ActionTypeEnum('delete'), object_type='copr', @@ -147,19 +147,22 @@ class CoprsLogic(object): update({models.Copr.build_count: models.Copr.build_count + 1})
@classmethod - def unfinished_actions_for(cls, user, copr): + def unfinished_blocking_actions_for(cls, user, copr): + blocking_actions = [helpers.ActionTypeEnum('rename'), + helpers.ActionTypeEnum('delete')] actions = models.Action.query.filter(models.Action.object_type=='copr').\ filter(models.Action.object_id==copr.id).\ - filter(models.Action.backend_result==helpers.BackendResultEnum('waiting')) + filter(models.Action.backend_result==helpers.BackendResultEnum('waiting')).\ + filter(models.Action.action_type.in_(blocking_actions))
return actions
@classmethod - def raise_if_unfinished_action(cls, user, copr, message): + def raise_if_unfinished_blocking_action(cls, user, copr, message): """This method raises ActionInProgressException if given copr has an unfinished action. Returns None otherwise. """ - unfinished_actions = cls.unfinished_actions_for(user, copr).all() + unfinished_actions = cls.unfinished_blocking_actions_for(user, copr).all() if unfinished_actions: raise exceptions.ActionInProgressException(message, unfinished_actions[0])
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py index 22e8efe..c092e53 100644 --- a/coprs_frontend/coprs/models.py +++ b/coprs_frontend/coprs/models.py @@ -269,7 +269,7 @@ class CoprChroot(db.Model, Serializer): cascade='all,delete,delete-orphan'))
class Action(db.Model, Serializer): - """Representation of a custom action that needs backends cooperation""" + """Representation of a custom action that needs backends cooperation/admin attention/...""" id = db.Column(db.Integer, primary_key=True) # delete, rename, ...; see helpers.ActionTypeEnum action_type = db.Column(db.Integer, nullable=False) @@ -282,10 +282,12 @@ class Action(db.Model, Serializer): new_value = db.Column(db.String(255)) # backend result, see helpers.BackendResultEnum backend_result = db.Column(db.Integer, default=helpers.BackendResultEnum('waiting')) - # optional message from the backend - backend_message = db.Column(db.Text) + # optional message from the backend/whatever + message = db.Column(db.Text) # time created as returned by int(time.time()) created_on = db.Column(db.Integer) + # time ended as returned by int(time.time()) + ended_on = db.Column(db.Integer)
def __str__(self): return self.__unicode__() diff --git a/coprs_frontend/coprs/views/backend_ns/backend_general.py b/coprs_frontend/coprs/views/backend_ns/backend_general.py index 7be60a2..1f9c4f1 100644 --- a/coprs_frontend/coprs/views/backend_ns/backend_general.py +++ b/coprs_frontend/coprs/views/backend_ns/backend_general.py @@ -46,7 +46,7 @@ def update_builds(): def waiting_actions(): actions = models.Action.query.filter(models.Action.backend_result==helpers.BackendResultEnum('waiting')).all()
- return flask.jsonify({'actions': [action.to_dict(options={'__columns_except__': ['backend_result', 'backend_message']}) for action in actions]}) + return flask.jsonify({'actions': [action.to_dict(options={'__columns_except__': ['backend_result', 'message', 'ended_on']}) for action in actions]})
# TODO: this is very similar to update_builds, we should pull out the common functionality into a single function @backend_ns.route('/update_actions/', methods=['POST', 'PUT']) @@ -67,7 +67,8 @@ def update_actions():
for i, action in existing.items(): existing[i].backend_result = to_update[i]['backend_result'] - existing[i].backend_message = to_update[i]['backend_message'] + existing[i].message = to_update[i]['message'] + existing[i].ended_on = to_update[i]['ended_on']
db.session.commit()
diff --git a/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/coprs_frontend/coprs/views/coprs_ns/coprs_general.py index f5d84fe..cce699a 100644 --- a/coprs_frontend/coprs/views/coprs_ns/coprs_general.py +++ b/coprs_frontend/coprs/views/coprs_ns/coprs_general.py @@ -255,3 +255,8 @@ def copr_delete(username, coprname): return flask.redirect(flask.url_for('coprs_ns.coprs_by_owner', username=username)) else: return flask.render_template('coprs/detail/delete.html', form=form, copr=copr) + +@coprs_ns.route('/detail/<username>/<coprname>/legal_flag/') +@login_required +def copr_legal_flag(username, coprname): + pass diff --git a/coprs_frontend/tests/test_views/test_backend_ns/test_backend_general.py b/coprs_frontend/tests/test_views/test_backend_ns/test_backend_general.py index 5b021d8..2d3270c 100644 --- a/coprs_frontend/tests/test_views/test_backend_ns/test_backend_general.py +++ b/coprs_frontend/tests/test_views/test_backend_ns/test_backend_general.py @@ -143,7 +143,8 @@ class TestUpdateActions(CoprsTestCase): { "id": 1, "backend_result": 1, - "backend_message": "no problem" + "message": "no problem", + "ended_on": 123 } ] }""" @@ -153,17 +154,20 @@ class TestUpdateActions(CoprsTestCase): { "id": 1, "backend_result": 1, - "backend_message": null + "message": null, + "ended_on": 1234 }, { "id": 2, "backend_result": 2, - "backend_message": "problem!" + "message": "problem!", + "ended_on": 12345 }, { "id": 100, "backend_result": 123, - "backend_message": "wheeeee!" + "message": "wheeeee!", + "ended_on": 123456 } ] }""" @@ -178,7 +182,8 @@ class TestUpdateActions(CoprsTestCase):
updated = self.models.Action.query.filter(self.models.Action.id==1).first() assert updated.backend_result == 1 - assert updated.backend_message == "no problem" + assert updated.message == "no problem" + assert updated.ended_on == 123
def test_update_more_existent_and_non_existent_builds(self, f_users, f_coprs, f_actions, f_db): r = self.tc.post('/backend/update_actions/', @@ -190,8 +195,10 @@ class TestUpdateActions(CoprsTestCase):
updated = self.models.Action.query.filter(self.models.Action.id==1).first() assert updated.backend_result == 1 - assert updated.backend_message == None + assert updated.message == None + assert updated.ended_on == 1234
updated2 = self.models.Action.query.filter(self.models.Action.id==2).first() assert updated2.backend_result == 2 - assert updated2.backend_message == "problem!" + assert updated2.message == "problem!" + assert updated2.ended_on == 12345
copr-devel@lists.fedorahosted.org