From 983bb8e2d7bf2da260d11a4b84dd05b75adba22f Mon Sep 17 00:00:00 2001 From: Adam Coldrick Date: Fri, 11 Sep 2020 00:31:14 +0100 Subject: [PATCH] Unpin webob and hacking to fix compatibility issues The pinned versions of webob and hacking weren't functioning properly with modern Python, so they are unpinned. Unpinning hacking brought a number of extra rules into use, so this commit also contains a number of code style fixes. There was also an incompatibility in the test_setup.sh script, which meant it doesn't work with MySQL 8.0 (which is in Ubuntu 20.04). This is also fixed in this commit. Change-Id: I0889bc35f8babfeec42f6f577d302bb5fbce1c95 --- requirements.txt | 2 +- storyboard/api/app.py | 1 + storyboard/api/auth/oauth_validator.py | 1 + storyboard/api/auth/openid_client.py | 6 +- storyboard/api/middleware/cors_middleware.py | 6 +- storyboard/api/v1/storage/swift_impl.py | 2 +- storyboard/api/v1/stories.py | 8 +- storyboard/api/v1/tasks.py | 78 +++++++++---------- storyboard/api/v1/wmodels.py | 1 + storyboard/db/api/boards.py | 6 +- storyboard/db/api/worklists.py | 6 +- .../alembic_migrations/script.py.mako | 9 ++- .../versions/001_initial_version.py | 9 +-- ...049_add_tables_for_worklists_and_boards.py | 9 ++- ...add_detailed_permissions_to_boards_and_.py | 9 ++- .../051_add_story_title_event_info.py | 8 +- .../versions/052_add_column_for_task_links.py | 9 ++- ...053_add_due_dates_for_tasks_and_stories.py | 9 ++- .../054_add_archived_field_to_cards.py | 8 +- ..._allow_comments_to_be_replies_to_other_.py | 9 ++- ...use_filters_with_multiple_criteria_for_.py | 9 ++- ...057_allow_stories_and_tasks_to_be_made_.py | 9 ++- .../058_allow_subscription_to_worklists.py | 9 ++- .../059_add_a_table_for_comment_history.py | 9 ++- ...allow_timeline_events_to_be_related_to_.py | 9 ++- ...extends_project_name_and_project_group_.py | 9 ++- .../062_convert_to_charset_utf8mb4.py | 9 ++- .../versions/063_index_story_storytags.py | 7 +- .../064_add_a_security_flag_to_teams.py | 9 ++- ..._associate_multiple_projects_with_teams.py | 9 ++- .../066_add_a_security_flag_to_stories.py | 9 ++- .../versions/067_add_an_attachments_table.py | 9 ++- storyboard/db/models.py | 3 + storyboard/migrate/cli.py | 2 +- storyboard/migrate/launchpad/loader.py | 4 +- storyboard/notifications/notification_hook.py | 4 +- storyboard/plugin/email/workers.py | 2 +- storyboard/plugin/subscription/base.py | 4 +- storyboard/tests/api/test_stories.py | 8 +- storyboard/tests/api/test_subscriptions.py | 22 +++--- storyboard/tests/api/test_user_tokens.py | 15 ++-- storyboard/tests/base.py | 1 + storyboard/tests/mock_smtp.py | 1 + test-requirements.txt | 2 +- tools/openid_server.py | 1 + tools/test-setup.sh | 4 +- tox.ini | 3 +- 47 files changed, 205 insertions(+), 173 deletions(-) diff --git a/requirements.txt b/requirements.txt index 11ac6f2e..8de4d878 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ PyYAML>=3.1.0 requests>=1.1 six>=1.7.0 SQLAlchemy -webob==1.7.4 +webob WSME>=0.6,<0.8 SQLAlchemy-FullText-Search>=0.2.3 stevedore>=1.3.0 diff --git a/storyboard/api/app.py b/storyboard/api/app.py index 7ea87eea..86012106 100644 --- a/storyboard/api/app.py +++ b/storyboard/api/app.py @@ -165,5 +165,6 @@ def start(): srv.serve_forever() + if __name__ == '__main__': start() diff --git a/storyboard/api/auth/oauth_validator.py b/storyboard/api/auth/oauth_validator.py index 4056b5d7..26b6e13a 100644 --- a/storyboard/api/auth/oauth_validator.py +++ b/storyboard/api/auth/oauth_validator.py @@ -298,5 +298,6 @@ class OpenIdConnectServer(WebApplicationServer): request_validator, token_expires_in=access_token_ttl) + validator = SkeletonValidator() SERVER = OpenIdConnectServer(validator) diff --git a/storyboard/api/auth/openid_client.py b/storyboard/api/auth/openid_client.py index 714a4e5a..42c6729a 100644 --- a/storyboard/api/auth/openid_client.py +++ b/storyboard/api/auth/openid_client.py @@ -66,9 +66,9 @@ class OpenIdClient(object): message=e_msg.NO_CLIENT_ID) oauth_client_is_invalid = True for valid_oauth_client in CONF.oauth.valid_oauth_clients: - if ((valid_oauth_client == client_id) or - (valid_oauth_client.startswith('^') and - re.match(valid_oauth_client, client_id))): + if ((valid_oauth_client == client_id) + or (valid_oauth_client.startswith('^') + and re.match(valid_oauth_client, client_id))): oauth_client_is_invalid = False break if oauth_client_is_invalid: diff --git a/storyboard/api/middleware/cors_middleware.py b/storyboard/api/middleware/cors_middleware.py index deac94cd..e8bad451 100644 --- a/storyboard/api/middleware/cors_middleware.py +++ b/storyboard/api/middleware/cors_middleware.py @@ -100,9 +100,9 @@ class CORSMiddleware(object): # Does this request match one of our origin domains? for allowed_origin in self.allowed_origins: - if ((allowed_origin == origin) or - (allowed_origin.startswith('^') and - re.match(allowed_origin, origin))): + if ((allowed_origin == origin) + or (allowed_origin.startswith('^') + and re.match(allowed_origin, origin))): # Is this an OPTIONS request? if method == 'OPTIONS': diff --git a/storyboard/api/v1/storage/swift_impl.py b/storyboard/api/v1/storage/swift_impl.py index e1cb1511..22076741 100644 --- a/storyboard/api/v1/storage/swift_impl.py +++ b/storyboard/api/v1/storage/swift_impl.py @@ -88,7 +88,7 @@ class SwiftStorageImpl(StorageBackend): conn.object_store.create_container(CONF.swift.container) conn.object_store.set_container_temp_url_key( CONF.swift.container, CONF.swift.temp_url_key) - container = conn.object_store.set_container_metadata( + conn.object_store.set_container_metadata( CONF.swift.container, read_ACL=".r:*") def get_upload_url(self): diff --git a/storyboard/api/v1/stories.py b/storyboard/api/v1/stories.py index 0e8f61b3..7a5ffc1c 100644 --- a/storyboard/api/v1/stories.py +++ b/storyboard/api/v1/stories.py @@ -323,8 +323,8 @@ class StoriesController(rest.RestController): """ # Reject private story types while ACL is not created. - if (story.story_type_id and - (story.story_type_id == 3 or story.story_type_id == 4)): + if (story.story_type_id + and (story.story_type_id == 3 or story.story_type_id == 4)): abort(400, _("Now you can't add story with type %s.") % story.story_type_id) @@ -393,8 +393,8 @@ class StoriesController(rest.RestController): user_id = request.current_user_id # Reject private story types while ACL is not created. - if (story.story_type_id and - (story.story_type_id == 3 or story.story_type_id == 4)): + if (story.story_type_id + and (story.story_type_id == 3 or story.story_type_id == 4)): abort(400, _("Now you can't change story type to %s.") % story.story_type_id) diff --git a/storyboard/api/v1/tasks.py b/storyboard/api/v1/tasks.py index 0d9b96eb..df06685b 100644 --- a/storyboard/api/v1/tasks.py +++ b/storyboard/api/v1/tasks.py @@ -179,8 +179,8 @@ def task_is_valid_put(task, original_task): abort(400, _("Milestones can only be associated with merged tasks")) - if (original_task.status == 'merged' and - task.status and task.status != 'merged'): + if (original_task.status == 'merged' + and task.status and task.status != 'merged'): abort(400, _("Milestones can only be associated with merged tasks")) elif 'milestone_id' in task.as_dict(omit_unset=True): @@ -201,48 +201,48 @@ def task_is_valid_put(task, original_task): def post_timeline_events(original_task, updated_task): - # If both the assignee_id and the status were changed there will be - # two separate comments in the activity log. + # If both the assignee_id and the status were changed there will be + # two separate comments in the activity log. - author_id = request.current_user_id - specific_change = False + author_id = request.current_user_id + specific_change = False - if original_task.status != updated_task.status: - events_api.task_status_changed_event( - story_id=original_task.story_id, - task_id=original_task.id, - task_title=original_task.title, - author_id=author_id, - old_status=original_task.status, - new_status=updated_task.status) - specific_change = True + if original_task.status != updated_task.status: + events_api.task_status_changed_event( + story_id=original_task.story_id, + task_id=original_task.id, + task_title=original_task.title, + author_id=author_id, + old_status=original_task.status, + new_status=updated_task.status) + specific_change = True - if original_task.priority != updated_task.priority: - events_api.task_priority_changed_event( - story_id=original_task.story_id, - task_id=original_task.id, - task_title=original_task.title, - author_id=author_id, - old_priority=original_task.priority, - new_priority=updated_task.priority) - specific_change = True + if original_task.priority != updated_task.priority: + events_api.task_priority_changed_event( + story_id=original_task.story_id, + task_id=original_task.id, + task_title=original_task.title, + author_id=author_id, + old_priority=original_task.priority, + new_priority=updated_task.priority) + specific_change = True - if original_task.assignee_id != updated_task.assignee_id: - events_api.task_assignee_changed_event( - story_id=original_task.story_id, - task_id=original_task.id, - task_title=original_task.title, - author_id=author_id, - old_assignee_id=original_task.assignee_id, - new_assignee_id=updated_task.assignee_id) - specific_change = True + if original_task.assignee_id != updated_task.assignee_id: + events_api.task_assignee_changed_event( + story_id=original_task.story_id, + task_id=original_task.id, + task_title=original_task.title, + author_id=author_id, + old_assignee_id=original_task.assignee_id, + new_assignee_id=updated_task.assignee_id) + specific_change = True - if not specific_change: - events_api.task_details_changed_event( - story_id=original_task.story_id, - task_id=original_task.id, - task_title=original_task.title, - author_id=author_id) + if not specific_change: + events_api.task_details_changed_event( + story_id=original_task.story_id, + task_id=original_task.id, + task_title=original_task.title, + author_id=author_id) class TasksPrimaryController(rest.RestController): diff --git a/storyboard/api/v1/wmodels.py b/storyboard/api/v1/wmodels.py index cacff53e..6a92b5f1 100644 --- a/storyboard/api/v1/wmodels.py +++ b/storyboard/api/v1/wmodels.py @@ -142,6 +142,7 @@ class ProjectGroup(base.APIBase): name="Infra", title="Awesome projects") + TaskStatuses = wtypes.Enum(wtypes.text, 'todo', 'inprogress', 'invalid', 'review', 'merged') diff --git a/storyboard/db/api/boards.py b/storyboard/db/api/boards.py index 3375a427..3ca82fa9 100644 --- a/storyboard/db/api/boards.py +++ b/storyboard/db/api/boards.py @@ -199,9 +199,9 @@ def get_from_lane(worklist): def get_card(board, item_type, item_id, archived=False): for lane in board.lanes: for card in lane.worklist.items: - if (card.item_type == item_type and - card.item_id == item_id and - card.archived == archived): + if (card.item_type == item_type + and card.item_id == item_id + and card.archived == archived): return card diff --git a/storyboard/db/api/worklists.py b/storyboard/db/api/worklists.py index 1dc35bcf..2fede56d 100644 --- a/storyboard/db/api/worklists.py +++ b/storyboard/db/api/worklists.py @@ -308,9 +308,9 @@ def move_item(item_id, new_pos, new_list_id=None): old_pos = modified_card.list_position # If the item hasn't actually moved, we don't need to move it. - if (old_pos == new_pos and - (new_list_id == modified_card.list_id or - new_list_id is None)): + if (old_pos == new_pos + and (new_list_id == modified_card.list_id + or new_list_id is None)): return modified_card # "old_list" is the list the item is moving from, and "new_list" is diff --git a/storyboard/db/migration/alembic_migrations/script.py.mako b/storyboard/db/migration/alembic_migrations/script.py.mako index ee0e3aca..0a2e5e0e 100644 --- a/storyboard/db/migration/alembic_migrations/script.py.mako +++ b/storyboard/db/migration/alembic_migrations/script.py.mako @@ -19,16 +19,17 @@ Create Date: ${create_date} """ -# revision identifiers, used by Alembic. -revision = ${repr(up_revision)} -down_revision = ${repr(down_revision)} - from alembic import op import sqlalchemy as sa ${imports if imports else ""} +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} + + def upgrade(active_plugins=None, options=None): ${upgrades if upgrades else "pass"} diff --git a/storyboard/db/migration/alembic_migrations/versions/001_initial_version.py b/storyboard/db/migration/alembic_migrations/versions/001_initial_version.py index 81992cb8..2ceaa7b9 100644 --- a/storyboard/db/migration/alembic_migrations/versions/001_initial_version.py +++ b/storyboard/db/migration/alembic_migrations/versions/001_initial_version.py @@ -19,11 +19,6 @@ Create Date: 2013-12-10 00:35:55.327593 """ -# revision identifiers, used by Alembic. -revision = '001' -down_revision = None - - from alembic import op from oslo_log import log import sqlalchemy as sa @@ -36,6 +31,10 @@ LOG = log.getLogger(__name__) MYSQL_ENGINE = 'InnoDB' MYSQL_CHARSET = 'utf8' +# revision identifiers, used by Alembic. +revision = '001' +down_revision = None + def _define_enums(): pref_type = sa.Enum('string', 'int', 'bool', 'float') diff --git a/storyboard/db/migration/alembic_migrations/versions/049_add_tables_for_worklists_and_boards.py b/storyboard/db/migration/alembic_migrations/versions/049_add_tables_for_worklists_and_boards.py index f297f3ce..a8441532 100644 --- a/storyboard/db/migration/alembic_migrations/versions/049_add_tables_for_worklists_and_boards.py +++ b/storyboard/db/migration/alembic_migrations/versions/049_add_tables_for_worklists_and_boards.py @@ -19,10 +19,6 @@ Create Date: 2015-08-17 12:17:35.629353 """ -# revision identifiers, used by Alembic. -revision = '049' -down_revision = '001' - from alembic import op import sqlalchemy as sa @@ -30,6 +26,11 @@ import sqlalchemy as sa import storyboard +# revision identifiers, used by Alembic. +revision = '049' +down_revision = '001' + + def upgrade(active_plugins=None, options=None): op.create_table('worklists', sa.Column('id', sa.Integer(), nullable=False), diff --git a/storyboard/db/migration/alembic_migrations/versions/050_add_detailed_permissions_to_boards_and_.py b/storyboard/db/migration/alembic_migrations/versions/050_add_detailed_permissions_to_boards_and_.py index c653d044..a76511d0 100644 --- a/storyboard/db/migration/alembic_migrations/versions/050_add_detailed_permissions_to_boards_and_.py +++ b/storyboard/db/migration/alembic_migrations/versions/050_add_detailed_permissions_to_boards_and_.py @@ -19,10 +19,6 @@ Create Date: 2015-10-09 10:25:47.338906 """ -# revision identifiers, used by Alembic. -revision = '050' -down_revision = '049' - from alembic import op import sqlalchemy as sa @@ -34,6 +30,11 @@ from storyboard.db.api import worklists from storyboard.db import models +# revision identifiers, used by Alembic. +revision = '050' +down_revision = '049' + + def upgrade(active_plugins=None, options=None): op.create_table('board_permissions', sa.Column('board_id', sa.Integer(), nullable=True), diff --git a/storyboard/db/migration/alembic_migrations/versions/051_add_story_title_event_info.py b/storyboard/db/migration/alembic_migrations/versions/051_add_story_title_event_info.py index 0b127034..24cbf5ad 100644 --- a/storyboard/db/migration/alembic_migrations/versions/051_add_story_title_event_info.py +++ b/storyboard/db/migration/alembic_migrations/versions/051_add_story_title_event_info.py @@ -20,10 +20,6 @@ Create Date: 2015-12-03 12:00:00 """ -# revision identifiers, used by Alembic. - -revision = '051' -down_revision = '050' from alembic import op import json @@ -32,6 +28,10 @@ from sqlalchemy.sql import column from sqlalchemy.sql.expression import table +# revision identifiers, used by Alembic. +revision = '051' +down_revision = '050' + subs_events_table = table( 'subscription_events', sa.Column('id', sa.Integer(), nullable=False), diff --git a/storyboard/db/migration/alembic_migrations/versions/052_add_column_for_task_links.py b/storyboard/db/migration/alembic_migrations/versions/052_add_column_for_task_links.py index 4f410650..bc91a79e 100644 --- a/storyboard/db/migration/alembic_migrations/versions/052_add_column_for_task_links.py +++ b/storyboard/db/migration/alembic_migrations/versions/052_add_column_for_task_links.py @@ -19,15 +19,16 @@ Create Date: 2016-02-08 15:58:59.451550 """ -# revision identifiers, used by Alembic. -revision = '052' -down_revision = '051' - from alembic import op import sqlalchemy as sa +# revision identifiers, used by Alembic. +revision = '052' +down_revision = '051' + + def upgrade(active_plugins=None, options=None): op.add_column('tasks', sa.Column('link', sa.UnicodeText(), nullable=True)) diff --git a/storyboard/db/migration/alembic_migrations/versions/053_add_due_dates_for_tasks_and_stories.py b/storyboard/db/migration/alembic_migrations/versions/053_add_due_dates_for_tasks_and_stories.py index 8ee20dc5..07fafbcf 100644 --- a/storyboard/db/migration/alembic_migrations/versions/053_add_due_dates_for_tasks_and_stories.py +++ b/storyboard/db/migration/alembic_migrations/versions/053_add_due_dates_for_tasks_and_stories.py @@ -19,10 +19,6 @@ Create Date: 2016-02-04 11:27:55.607256 """ -# revision identifiers, used by Alembic. -revision = '053' -down_revision = '052' - from alembic import op import sqlalchemy as sa @@ -30,6 +26,11 @@ import sqlalchemy as sa from storyboard.db.decorators import UTCDateTime +# revision identifiers, used by Alembic. +revision = '053' +down_revision = '052' + + def upgrade(active_plugins=None, options=None): op.create_table( 'due_dates', diff --git a/storyboard/db/migration/alembic_migrations/versions/054_add_archived_field_to_cards.py b/storyboard/db/migration/alembic_migrations/versions/054_add_archived_field_to_cards.py index 5ead6708..fed735a0 100644 --- a/storyboard/db/migration/alembic_migrations/versions/054_add_archived_field_to_cards.py +++ b/storyboard/db/migration/alembic_migrations/versions/054_add_archived_field_to_cards.py @@ -19,15 +19,15 @@ Create Date: 2016-02-25 19:15:29.464877 """ +from alembic import op +import sqlalchemy as sa + + # revision identifiers, used by Alembic. revision = '054' down_revision = '053' -from alembic import op -import sqlalchemy as sa - - def upgrade(active_plugins=None, options=None): op.add_column( 'worklist_items', sa.Column('archived', sa.Boolean(), nullable=True)) diff --git a/storyboard/db/migration/alembic_migrations/versions/055_allow_comments_to_be_replies_to_other_.py b/storyboard/db/migration/alembic_migrations/versions/055_allow_comments_to_be_replies_to_other_.py index 6898b56c..1186ab81 100644 --- a/storyboard/db/migration/alembic_migrations/versions/055_allow_comments_to_be_replies_to_other_.py +++ b/storyboard/db/migration/alembic_migrations/versions/055_allow_comments_to_be_replies_to_other_.py @@ -19,15 +19,16 @@ Create Date: 2016-03-05 23:35:40.379333 """ -# revision identifiers, used by Alembic. -revision = '055' -down_revision = '054' - from alembic import op import sqlalchemy as sa +# revision identifiers, used by Alembic. +revision = '055' +down_revision = '054' + + def upgrade(active_plugins=None, options=None): op.add_column( 'comments', sa.Column('in_reply_to', sa.Integer(), nullable=True)) diff --git a/storyboard/db/migration/alembic_migrations/versions/056_use_filters_with_multiple_criteria_for_.py b/storyboard/db/migration/alembic_migrations/versions/056_use_filters_with_multiple_criteria_for_.py index 17b36ab3..67b0dc6e 100644 --- a/storyboard/db/migration/alembic_migrations/versions/056_use_filters_with_multiple_criteria_for_.py +++ b/storyboard/db/migration/alembic_migrations/versions/056_use_filters_with_multiple_criteria_for_.py @@ -19,10 +19,6 @@ Create Date: 2016-03-04 13:31:01.600372 """ -# revision identifiers, used by Alembic. -revision = '056' -down_revision = '055' - from alembic import op import sqlalchemy as sa @@ -31,6 +27,11 @@ from sqlalchemy.dialects import mysql import storyboard +# revision identifiers, used by Alembic. +revision = '056' +down_revision = '055' + + def upgrade(active_plugins=None, options=None): op.create_table( 'worklist_filters', diff --git a/storyboard/db/migration/alembic_migrations/versions/057_allow_stories_and_tasks_to_be_made_.py b/storyboard/db/migration/alembic_migrations/versions/057_allow_stories_and_tasks_to_be_made_.py index 1e2367c0..9d6959d6 100644 --- a/storyboard/db/migration/alembic_migrations/versions/057_allow_stories_and_tasks_to_be_made_.py +++ b/storyboard/db/migration/alembic_migrations/versions/057_allow_stories_and_tasks_to_be_made_.py @@ -28,16 +28,17 @@ Create Date: 2016-04-27 15:45:51.646556 """ -# revision identifiers, used by Alembic. -revision = '057' -down_revision = '056' - from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import mysql +# revision identifiers, used by Alembic. +revision = '057' +down_revision = '056' + + def upgrade(active_plugins=None, options=None): op.create_table( 'story_permissions', diff --git a/storyboard/db/migration/alembic_migrations/versions/058_allow_subscription_to_worklists.py b/storyboard/db/migration/alembic_migrations/versions/058_allow_subscription_to_worklists.py index 23fd7ede..2f750e3a 100644 --- a/storyboard/db/migration/alembic_migrations/versions/058_allow_subscription_to_worklists.py +++ b/storyboard/db/migration/alembic_migrations/versions/058_allow_subscription_to_worklists.py @@ -19,14 +19,15 @@ Create Date: 2016-06-01 13:28:19.033906 """ -# revision identifiers, used by Alembic. -revision = '058' -down_revision = '057' - from alembic import op import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = '058' +down_revision = '057' + old_type_enum = sa.Enum('task', 'story', 'project', 'project_group') new_type_enum = sa.Enum( 'task', 'story', 'project', 'project_group', 'worklist') diff --git a/storyboard/db/migration/alembic_migrations/versions/059_add_a_table_for_comment_history.py b/storyboard/db/migration/alembic_migrations/versions/059_add_a_table_for_comment_history.py index 388c0393..15f39d2a 100644 --- a/storyboard/db/migration/alembic_migrations/versions/059_add_a_table_for_comment_history.py +++ b/storyboard/db/migration/alembic_migrations/versions/059_add_a_table_for_comment_history.py @@ -19,10 +19,6 @@ Create Date: 2016-06-21 14:00:20.515139 """ -# revision identifiers, used by Alembic. -revision = '059' -down_revision = '058' - from alembic import op import sqlalchemy as sa @@ -31,6 +27,11 @@ from storyboard.db.decorators import UTCDateTime from storyboard.db.models import MYSQL_MEDIUM_TEXT +# revision identifiers, used by Alembic. +revision = '059' +down_revision = '058' + + def upgrade(active_plugins=None, options=None): op.create_table( 'comments_history', diff --git a/storyboard/db/migration/alembic_migrations/versions/060_allow_timeline_events_to_be_related_to_.py b/storyboard/db/migration/alembic_migrations/versions/060_allow_timeline_events_to_be_related_to_.py index ad685ad4..3768a035 100644 --- a/storyboard/db/migration/alembic_migrations/versions/060_allow_timeline_events_to_be_related_to_.py +++ b/storyboard/db/migration/alembic_migrations/versions/060_allow_timeline_events_to_be_related_to_.py @@ -19,15 +19,16 @@ Create Date: 2016-07-14 15:05:12.369072 """ -# revision identifiers, used by Alembic. -revision = '060' -down_revision = '059' - from alembic import op import sqlalchemy as sa +# revision identifiers, used by Alembic. +revision = '060' +down_revision = '059' + + def upgrade(active_plugins=None, options=None): op.add_column( 'events', sa.Column('board_id', sa.Integer(), nullable=True)) diff --git a/storyboard/db/migration/alembic_migrations/versions/061_extends_project_name_and_project_group_.py b/storyboard/db/migration/alembic_migrations/versions/061_extends_project_name_and_project_group_.py index 668bcfa5..0ddace8b 100644 --- a/storyboard/db/migration/alembic_migrations/versions/061_extends_project_name_and_project_group_.py +++ b/storyboard/db/migration/alembic_migrations/versions/061_extends_project_name_and_project_group_.py @@ -19,15 +19,16 @@ Create Date: 2017-03-17 10:28:24.567704 """ -# revision identifiers, used by Alembic. -revision = '061' -down_revision = '060' - from alembic import op import sqlalchemy as sa +# revision identifiers, used by Alembic. +revision = '061' +down_revision = '060' + + def upgrade(active_plugins=None, options=None): dialect = op.get_bind().engine.dialect if dialect.supports_alter: diff --git a/storyboard/db/migration/alembic_migrations/versions/062_convert_to_charset_utf8mb4.py b/storyboard/db/migration/alembic_migrations/versions/062_convert_to_charset_utf8mb4.py index d4894701..9c7484e0 100644 --- a/storyboard/db/migration/alembic_migrations/versions/062_convert_to_charset_utf8mb4.py +++ b/storyboard/db/migration/alembic_migrations/versions/062_convert_to_charset_utf8mb4.py @@ -19,15 +19,16 @@ Create Date: 2018-03-23 14:34:55.656531 """ -# revision identifiers, used by Alembic. -revision = '062' -down_revision = '061' - from alembic import op import sqlalchemy as sa +# revision identifiers, used by Alembic. +revision = '062' +down_revision = '061' + + def upgrade(active_plugins=None, options=None): dialect = op.get_bind().engine.dialect if dialect.supports_alter: diff --git a/storyboard/db/migration/alembic_migrations/versions/063_index_story_storytags.py b/storyboard/db/migration/alembic_migrations/versions/063_index_story_storytags.py index 08fbfe85..c8cdff36 100644 --- a/storyboard/db/migration/alembic_migrations/versions/063_index_story_storytags.py +++ b/storyboard/db/migration/alembic_migrations/versions/063_index_story_storytags.py @@ -19,14 +19,15 @@ Create Date: 2018-06-25 17:13:43.992561 """ + +from alembic import op + + # revision identifiers, used by Alembic. revision = '063' down_revision = '062' -from alembic import op - - def upgrade(active_plugins=None, options=None): op.create_index('story_storytags_idx', 'story_storytags', ['story_id']) diff --git a/storyboard/db/migration/alembic_migrations/versions/064_add_a_security_flag_to_teams.py b/storyboard/db/migration/alembic_migrations/versions/064_add_a_security_flag_to_teams.py index 53b35228..7c03f8aa 100644 --- a/storyboard/db/migration/alembic_migrations/versions/064_add_a_security_flag_to_teams.py +++ b/storyboard/db/migration/alembic_migrations/versions/064_add_a_security_flag_to_teams.py @@ -19,15 +19,16 @@ Create Date: 2019-03-04 16:24:44.264120 """ -# revision identifiers, used by Alembic. -revision = '064' -down_revision = '063' - from alembic import op import sqlalchemy as sa +# revision identifiers, used by Alembic. +revision = '064' +down_revision = '063' + + def upgrade(active_plugins=None, options=None): op.add_column('teams', sa.Column('security', sa.Boolean(), nullable=True)) diff --git a/storyboard/db/migration/alembic_migrations/versions/065_associate_multiple_projects_with_teams.py b/storyboard/db/migration/alembic_migrations/versions/065_associate_multiple_projects_with_teams.py index d66a5c70..de5c15d9 100644 --- a/storyboard/db/migration/alembic_migrations/versions/065_associate_multiple_projects_with_teams.py +++ b/storyboard/db/migration/alembic_migrations/versions/065_associate_multiple_projects_with_teams.py @@ -19,15 +19,16 @@ Create Date: 2019-03-07 11:25:31.308033 """ -# revision identifiers, used by Alembic. -revision = '065' -down_revision = '064' - from alembic import op import sqlalchemy as sa +# revision identifiers, used by Alembic. +revision = '065' +down_revision = '064' + + def upgrade(active_plugins=None, options=None): op.create_table('project_teams', sa.Column('project_id', sa.Integer(), nullable=False), diff --git a/storyboard/db/migration/alembic_migrations/versions/066_add_a_security_flag_to_stories.py b/storyboard/db/migration/alembic_migrations/versions/066_add_a_security_flag_to_stories.py index 33c01fd3..17aba7bc 100644 --- a/storyboard/db/migration/alembic_migrations/versions/066_add_a_security_flag_to_stories.py +++ b/storyboard/db/migration/alembic_migrations/versions/066_add_a_security_flag_to_stories.py @@ -19,15 +19,16 @@ Create Date: 2019-03-08 08:57:44.497977 """ -# revision identifiers, used by Alembic. -revision = '066' -down_revision = '065' - from alembic import op import sqlalchemy as sa +# revision identifiers, used by Alembic. +revision = '066' +down_revision = '065' + + def upgrade(active_plugins=None, options=None): op.add_column('stories', sa.Column('security', sa.Boolean())) diff --git a/storyboard/db/migration/alembic_migrations/versions/067_add_an_attachments_table.py b/storyboard/db/migration/alembic_migrations/versions/067_add_an_attachments_table.py index 80e4c5a3..67a5d62f 100644 --- a/storyboard/db/migration/alembic_migrations/versions/067_add_an_attachments_table.py +++ b/storyboard/db/migration/alembic_migrations/versions/067_add_an_attachments_table.py @@ -19,10 +19,6 @@ Create Date: 2019-01-27 16:07:04.427155 """ -# revision identifiers, used by Alembic. -revision = '067' -down_revision = '066' - from alembic import op from oslo_log import log @@ -30,6 +26,11 @@ import sqlalchemy as sa import storyboard + +# revision identifiers, used by Alembic. +revision = '067' +down_revision = '066' + LOG = log.getLogger(__name__) diff --git a/storyboard/db/models.py b/storyboard/db/models.py index 4dbacc03..736bd22a 100644 --- a/storyboard/db/models.py +++ b/storyboard/db/models.py @@ -58,6 +58,7 @@ def table_args(): 'mysql_charset': "utf8mb4"} return None + # # CUSTOM TYPES # A mysql medium text type. @@ -664,6 +665,7 @@ class Board(FullText, ModelBuilder, Base): _public_fields = ["id", "title", "description", "creator_id", "project_id", "permission_id", "private", "archived"] + board_permissions = Table( 'board_permissions', Base.metadata, Column('board_id', Integer, ForeignKey('boards.id')), @@ -701,6 +703,7 @@ class DueDate(FullText, ModelBuilder, Base): secondary='worklist_due_dates', backref='due_dates') + due_date_permissions = Table( 'due_date_permissions', Base.metadata, Column('due_date_id', Integer, ForeignKey('due_dates.id')), diff --git a/storyboard/migrate/cli.py b/storyboard/migrate/cli.py index 8e6321cc..618709d3 100644 --- a/storyboard/migrate/cli.py +++ b/storyboard/migrate/cli.py @@ -72,7 +72,7 @@ def main(): session.execute('ALTER TABLE stories AUTO_INCREMENT = %d;' % (auto_increment,)) - if CONF.origin is 'launchpad': + if CONF.origin == 'launchpad': loader = LaunchpadLoader(CONF.from_project, CONF.to_project, set(CONF.only_tags), set(CONF.exclude_tags)) loader.run() diff --git a/storyboard/migrate/launchpad/loader.py b/storyboard/migrate/launchpad/loader.py index 65d20a53..dbee9957 100644 --- a/storyboard/migrate/launchpad/loader.py +++ b/storyboard/migrate/launchpad/loader.py @@ -79,8 +79,8 @@ class LaunchpadLoader(object): branch_name = url_parts[-1].lower() project_name = url_parts[-2] - if (branch_name in releases and - project_name == self.reader.project_name): + if (branch_name in releases + and project_name == self.reader.project_name): branches.append(branch_name) elif branch_name == self.reader.project_name: branches.append('master') diff --git a/storyboard/notifications/notification_hook.py b/storyboard/notifications/notification_hook.py index 152292fb..55b50863 100644 --- a/storyboard/notifications/notification_hook.py +++ b/storyboard/notifications/notification_hook.py @@ -140,8 +140,8 @@ class NotificationHook(hooks.PecanHook): return None def parse(self, s): - url_pattern = re.match("^(\/api)?\/v1\/([a-z_]+)\/?([0-9]+)?" - "\/?([a-z]+)?\/?([0-9]+)?$", s) + url_pattern = re.match(r"^(/api)?/v1/([a-z_]+)/?([0-9]+)?" + r"/?([a-z]+)?/?([0-9]+)?$", s) if not url_pattern or url_pattern.groups()[1] == "openid": return None, None, None, None diff --git a/storyboard/plugin/email/workers.py b/storyboard/plugin/email/workers.py index 646c76b1..c9699dba 100644 --- a/storyboard/plugin/email/workers.py +++ b/storyboard/plugin/email/workers.py @@ -400,7 +400,7 @@ class SubscriptionEmailWorker(EmailWorkerBase): /{{resource_name}}/{{subresource_name}}/{{method}}.txt /{{resource_name}}/{{subresource_name}}/{{method}}.html (optional) """ - ## TODO(krotscheck): Templates can also resolve by user language. + # TODO(krotscheck): Templates can also resolve by user language. if sub_resource_name: base_template = os.path.join(resource_name, sub_resource_name) diff --git a/storyboard/plugin/subscription/base.py b/storyboard/plugin/subscription/base.py index ee05f1b5..59e24976 100644 --- a/storyboard/plugin/subscription/base.py +++ b/storyboard/plugin/subscription/base.py @@ -107,8 +107,8 @@ class Subscription(WorkerTaskBase): user = db_api.entity_get(models.User, user_id, session=session) send_notification = get_preference( 'receive_notifications_worklists', user) - if (send_notification != 'true' and - resource.get('worklist_id') is not None): + if (send_notification != 'true' + and resource.get('worklist_id') is not None): continue if resource['event_type'] == 'user_comment': diff --git a/storyboard/tests/api/test_stories.py b/storyboard/tests/api/test_stories.py index 7702ac35..8311640c 100644 --- a/storyboard/tests/api/test_stories.py +++ b/storyboard/tests/api/test_stories.py @@ -146,8 +146,8 @@ class TestStories(base.FunctionalTest): story_types = [2, 1] for story_type_id in story_types: - response = self.put_json(self.resource + - ('/%s' % created_story["id"]), + response = self.put_json(self.resource + + ('/%s' % created_story["id"]), {'story_type_id': story_type_id}) self.assertEqual(story_type_id, response.json['story_type_id']) @@ -164,8 +164,8 @@ class TestStories(base.FunctionalTest): self.assertEqual(story['private'], created_story['private']) - response = self.put_json(self.resource + - ('/%s' % created_story['id']), + response = self.put_json(self.resource + + ('/%s' % created_story['id']), {'private': False}) updated_story = response.json self.assertFalse(updated_story['private']) diff --git a/storyboard/tests/api/test_subscriptions.py b/storyboard/tests/api/test_subscriptions.py index 7312d819..28ac2d16 100644 --- a/storyboard/tests/api/test_subscriptions.py +++ b/storyboard/tests/api/test_subscriptions.py @@ -74,8 +74,9 @@ class TestSubscriptionsAsUser(base.FunctionalTest): search_response_1 = self.get_json(self.resource) self.assertEqual(1, len(search_response_1)) - response2 = self.delete(self.resource + '/' + - six.text_type(subscription['id']), + response2 = self.delete(self.resource + + '/' + + six.text_type(subscription['id']), expect_errors=True) self.assertEqual(204, response2.status_code) @@ -106,16 +107,16 @@ class TestSubscriptionsAsUser(base.FunctionalTest): response = self.get_json(self.resource) self.assertEqual(1, len(response)) - response = self.get_json(self.resource + - '?target_type=project') + response = self.get_json(self.resource + + '?target_type=project') self.assertEqual(1, len(response)) - response = self.get_json(self.resource + - '?target_type=project&target_id=1') + response = self.get_json(self.resource + + '?target_type=project&target_id=1') self.assertEqual(1, len(response)) - response = self.get_json(self.resource + - '?target_type=story&target_id=1') + response = self.get_json(self.resource + + '?target_type=story&target_id=1') self.assertEqual(0, len(response)) def test_create_subscription_for_invalid_resource(self): @@ -216,8 +217,9 @@ class TestSubscriptionsAsSuperuser(base.FunctionalTest): search_response_1 = self.get_json(self.resource + '?user_id=3') self.assertEqual(2, len(search_response_1)) - response2 = self.delete(self.resource + '/' + - six.text_type(subscription['id']), + response2 = self.delete(self.resource + + '/' + + six.text_type(subscription['id']), expect_errors=True) self.assertEqual(204, response2.status_code) diff --git a/storyboard/tests/api/test_user_tokens.py b/storyboard/tests/api/test_user_tokens.py index 779e9f40..2d90e4e0 100644 --- a/storyboard/tests/api/test_user_tokens.py +++ b/storyboard/tests/api/test_user_tokens.py @@ -56,8 +56,9 @@ class TestUserTokensAsUser(base.FunctionalTest): self.assertEqual(response.json['access_token'], 'test_token') self.assertIsNotNone(response.json['id']) - read_response = self.get_json(self.resource + '/' + - six.text_type(response.json['id'])) + read_response = self.get_json(self.resource + + '/' + + six.text_type(response.json['id'])) self.assertEqual(response.json['user_id'], read_response['user_id']) @@ -124,8 +125,9 @@ class TestUserTokensAsUser(base.FunctionalTest): new_record['expires_in'] = 3601 - updated = self.put_json(self.resource + '/' + - six.text_type(response.json['id']), + updated = self.put_json(self.resource + + '/' + + six.text_type(response.json['id']), new_record, expect_errors=True) self.assertEqual(updated.json['expires_in'], 3601) @@ -142,8 +144,9 @@ class TestUserTokensAsUser(base.FunctionalTest): self.assertIsNotNone(response.json['access_token']) self.assertIsNotNone(response.json['id']) - response = self.delete(self.resource + '/' + - six.text_type(response.json['id']), + response = self.delete(self.resource + + '/' + + six.text_type(response.json['id']), expect_errors=True) self.assertEqual(204, response.status_code) diff --git a/storyboard/tests/base.py b/storyboard/tests/base.py index abf402d6..60273ad3 100644 --- a/storyboard/tests/base.py +++ b/storyboard/tests/base.py @@ -214,6 +214,7 @@ class DbTestCase(WorkingDirTestCase): cls.db_name, err) db_api_base.cleanup() + PATH_PREFIX = '/v1' diff --git a/storyboard/tests/mock_smtp.py b/storyboard/tests/mock_smtp.py index 78be2c3e..9ccb0016 100644 --- a/storyboard/tests/mock_smtp.py +++ b/storyboard/tests/mock_smtp.py @@ -70,6 +70,7 @@ class DummySMTP_SSL(DummySMTP): def _get_socket(self, host, port, timeout): return None + # Monkeypatch our SMTP Instances. smtplib.SMTP = DummySMTP smtplib.SMTP_SSL = DummySMTP_SSL diff --git a/test-requirements.txt b/test-requirements.txt index c58bee30..310333cc 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,4 @@ -hacking>=1.0.0,<1.1.0 +hacking>=1.0.0 coverage!=4.4,>=4.0 # Apache-2.0 fixtures>=3.0.0 # Apache-2.0/BSD diff --git a/tools/openid_server.py b/tools/openid_server.py index 01da6fa6..ef66b8c2 100644 --- a/tools/openid_server.py +++ b/tools/openid_server.py @@ -93,5 +93,6 @@ def start(): srv = simple_server.make_server('0.0.0.0', 8088, api_root) srv.serve_forever() + if __name__ == '__main__': start() diff --git a/tools/test-setup.sh b/tools/test-setup.sh index a5bb6b8d..75ba0ec0 100755 --- a/tools/test-setup.sh +++ b/tools/test-setup.sh @@ -26,8 +26,8 @@ DB_PW=openstack_citest sudo -H mysql -u root -p$DB_ROOT_PW -h localhost -e " DELETE FROM mysql.user WHERE User=''; FLUSH PRIVILEGES; - GRANT ALL PRIVILEGES ON *.* - TO '$DB_USER'@'%' identified by '$DB_PW' WITH GRANT OPTION;" + CREATE USER '$DB_USER'@'%' IDENTIFIED BY '$DB_PW'; + GRANT ALL PRIVILEGES ON *.* TO '$DB_USER'@'%' WITH GRANT OPTION;" # Now create our database. mysql -u $DB_USER -p$DB_PW -h 127.0.0.1 -e " diff --git a/tox.ini b/tox.ini index d8ff4b6a..00b9d984 100644 --- a/tox.ini +++ b/tox.ini @@ -50,11 +50,12 @@ commands = [flake8] # E125 and E128 are ignored on purpose, they are invalid pep8 +# W503 is ignored on purpose, it is no longer valid pep8 # The following rules should either be addressed or determined to be # skippable long term. # E265 is ignored to make switch to newer hacking easier # H405 is ignored to make switch to newer hacking easier -ignore = E125,E128,E265,H405 +ignore = E125,E128,E265,H405,W503 builtins = _ show-source = True exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build