From 360c503a93ec9f327a3b36a0b11dc13c31450769 Mon Sep 17 00:00:00 2001 From: Arun Prasad Date: Sat, 8 Apr 2023 18:41:19 -0700 Subject: [PATCH] [proofing] Add more project metadata columns As requested by Suhas. - Add a `Genre` table for project genres. - Add the following columns to `Project`: `page_title` (`title` renamed to `display_title`), `worldcat_link`, `notes`, `genre_id` - Add admin forms for `Genre` - Update the project metadata form to include these new fields and add fieldset headers Test plan: unit tests --- ambuda/admin.py | 7 +- ambuda/enums.py | 2 +- ambuda/models/proofing.py | 33 ++- ambuda/queries.py | 5 + ambuda/tasks/projects.py | 24 +- ambuda/templates/blog/edit-post.html | 2 +- ambuda/templates/macros/proofing.html | 10 +- ambuda/templates/proofing/index.html | 4 +- ambuda/templates/proofing/pages/edit.html | 2 +- .../proofing/pages/editor-components.html | 2 +- ambuda/templates/proofing/pages/history.html | 2 +- ambuda/templates/proofing/pages/revision.html | 2 +- .../templates/proofing/projects/activity.html | 2 +- ambuda/templates/proofing/projects/admin.html | 2 +- .../proofing/projects/batch-ocr-post.html | 2 +- .../proofing/projects/batch-ocr.html | 2 +- .../proofing/projects/confirm_changes.html | 4 +- .../templates/proofing/projects/download.html | 2 +- ambuda/templates/proofing/projects/edit.html | 44 +++- .../templates/proofing/projects/replace.html | 4 +- .../templates/proofing/projects/search.html | 4 +- ambuda/templates/proofing/projects/stats.html | 2 +- .../templates/proofing/projects/summary.html | 6 +- ambuda/templates/proofing/talk.html | 2 +- ambuda/templates/proofing/talk/board.html | 2 +- .../templates/proofing/talk/create-post.html | 2 +- .../proofing/talk/create-thread.html | 4 +- ambuda/templates/proofing/talk/edit-post.html | 2 +- ambuda/views/proofing/main.py | 4 +- ambuda/views/proofing/project.py | 39 ++- .../f208e1844a36_add_more_project_metadata.py | 61 +++++ poetry.lock | 243 +++++++++--------- pyproject.toml | 4 +- requirements.txt | 3 +- test/ambuda/conftest.py | 4 +- test/ambuda/tasks/test_projects_tasks.py | 2 +- test/ambuda/views/proofing/test_project.py | 4 +- 37 files changed, 345 insertions(+), 200 deletions(-) create mode 100644 migrations/versions/f208e1844a36_add_more_project_metadata.py diff --git a/ambuda/admin.py b/ambuda/admin.py index 53828bc8..dd2077e0 100644 --- a/ambuda/admin.py +++ b/ambuda/admin.py @@ -58,7 +58,7 @@ class TextView(BaseView): class ProjectView(BaseView): - column_list = ["slug", "title", "creator"] + column_list = ["slug", "display_title", "creator"] form_excluded_columns = ["creator", "board", "pages", "created_at", "updated_at"] @@ -66,6 +66,10 @@ class DictionaryView(BaseView): column_list = form_columns = ["slug", "title"] +class GenreView(ModeratorBaseView): + pass + + class SponsorshipView(ModeratorBaseView): column_labels = dict( sa_title="Sanskrit title", @@ -100,6 +104,7 @@ def create_admin_manager(app): admin.add_view(TextBlockView(db.TextBlock, session)) admin.add_view(TextView(db.Text, session)) admin.add_view(UserView(db.User, session)) + admin.add_view(GenreView(db.Genre, session)) admin.add_view(SponsorshipView(db.ProjectSponsorship, session)) admin.add_view(ContributorInfoView(db.ContributorInfo, session)) diff --git a/ambuda/enums.py b/ambuda/enums.py index f940e451..9c23656f 100644 --- a/ambuda/enums.py +++ b/ambuda/enums.py @@ -2,7 +2,7 @@ class SiteRole(str, Enum): - """Defines user roles on Ambuda.""" + """Defines user roles.""" #: Basic proofer. Can mark pages as yellow and upload simple projects. P1 = "p1" diff --git a/ambuda/models/proofing.py b/ambuda/models/proofing.py index e2dfebcd..4571cd28 100644 --- a/ambuda/models/proofing.py +++ b/ambuda/models/proofing.py @@ -19,6 +19,24 @@ def text(): return Column(Text_, nullable=False, default="") +class Genre(Base): + """A text genre. + + We use genre to help proofers sort through different projects and select + one to work on. + """ + + __tablename__ = "genres" + + #: Primary key. + id = pk() + #: The name of this genre. + name = Column(String, unique=True, nullable=False) + + def __str__(self): + return self.name + + class Project(Base): """A proofreading project. @@ -32,9 +50,11 @@ class Project(Base): id = pk() #: Human-readable ID, which we display in the URL. slug = Column(String, unique=True, nullable=False) - #: Human-readable title, which we show on the page. - title = Column(String, nullable=False) + #: Human-readable title, which we show on the page. + display_title = Column(String, nullable=False) + #: The full book title as it appears in print. + print_title = string() #: The document's author. author = string() #: The document's editor. @@ -43,9 +63,13 @@ class Project(Base): publisher = string() #: The document's publication year. publication_year = string() + #: A link to the book's WorldCat entry, if available. + worldcat_link = string() #: Markdown for this project (to entice contributors, etc.) description = text() + #: Notes about the project, for internal and scholarly use. + notes = text() #: Defines page numbers (e.g. "x", "vii", ...) page_numbers = text() @@ -59,9 +83,12 @@ class Project(Base): #: Creator of this project. #: FIXME: make non-nullable once we manually migrate the production setup. creator_id = Column(Integer, ForeignKey("users.id"), index=True) + #: The genre of this project. + genre_id = Column(Integer, ForeignKey("genres.id"), index=True) creator = relationship("User") board = relationship("Board", cascade="delete") + genre = relationship("Genre") #: An ordered list of pages belonging to this project. pages = relationship( @@ -126,7 +153,7 @@ class PageStatus(Base): #: Primary key. id = pk() - #: Short human-readable label for this status. + #: A short human-readable label for this status. name = Column(String, nullable=False, unique=True) diff --git a/ambuda/queries.py b/ambuda/queries.py index 8e01fc00..35b69cf0 100644 --- a/ambuda/queries.py +++ b/ambuda/queries.py @@ -253,3 +253,8 @@ def project_sponsorships() -> list[db.ProjectSponsorship]: def contributor_info() -> list[db.ContributorInfo]: session = get_session() return session.query(db.ContributorInfo).order_by(db.ContributorInfo.name).all() + + +def genres() -> list[db.Genre]: + session = get_session() + return session.query(db.Genre).all() diff --git a/ambuda/tasks/projects.py b/ambuda/tasks/projects.py index 68f4e874..9c617c56 100644 --- a/ambuda/tasks/projects.py +++ b/ambuda/tasks/projects.py @@ -36,10 +36,12 @@ def _split_pdf_into_pages( return doc.page_count -def _add_project_to_database(title: str, slug: str, num_pages: int, creator_id: int): +def _add_project_to_database( + display_title: str, slug: str, num_pages: int, creator_id: int +): """Create a project on the database. - :param title: the project title + :param display_title: the project title :param num_pages: the number of pages in the project """ @@ -49,7 +51,7 @@ def _add_project_to_database(title: str, slug: str, num_pages: int, creator_id: session.add(board) session.flush() - project = db.Project(slug=slug, title=title, creator_id=creator_id) + project = db.Project(slug=slug, display_title=display_title, creator_id=creator_id) project.board_id = board.id session.add(project) session.flush() @@ -72,7 +74,7 @@ def _add_project_to_database(title: str, slug: str, num_pages: int, creator_id: def create_project_inner( *, - title: str, + display_title: str, pdf_path: str, output_dir: str, app_environment: str, @@ -84,25 +86,25 @@ def create_project_inner( We separate this function from `create_project` so that we can run this function in a non-Celery context (for example, in `cli.py`). - :param title: the project title. + :param display_title: the project's title. :param pdf_path: local path to the source PDF. :param output_dir: local path where page images will be stored. :param app_environment: the app environment, e.g. `"development"`. :param creator_id: the user that created this project. :param task_status: tracks progress on the task. """ - logging.info(f'Received upload task "{title}" for path {pdf_path}.') + logging.info(f'Received upload task "{display_title}" for path {pdf_path}.') # Tasks must be idempotent. Exit if the project already exists. app = create_config_only_app(app_environment) with app.app_context(): session = q.get_session() - slug = slugify(title) + slug = slugify(display_title) project = session.query(db.Project).filter_by(slug=slug).first() if project: raise ValueError( - f'Project "{title}" already exists. Please choose a different title.' + f'Project "{display_title}" already exists. Please choose a different title.' ) pdf_path = Path(pdf_path) @@ -111,7 +113,7 @@ def create_project_inner( num_pages = _split_pdf_into_pages(Path(pdf_path), Path(pages_dir), task_status) with app.app_context(): _add_project_to_database( - title=title, + display_title=display_title, slug=slug, num_pages=num_pages, creator_id=creator_id, @@ -124,7 +126,7 @@ def create_project_inner( def create_project( self, *, - title: str, + display_title: str, pdf_path: str, output_dir: str, app_environment: str, @@ -136,7 +138,7 @@ def create_project( """ task_status = CeleryTaskStatus(self) create_project_inner( - title=title, + display_title=display_title, pdf_path=pdf_path, output_dir=output_dir, app_environment=app_environment, diff --git a/ambuda/templates/blog/edit-post.html b/ambuda/templates/blog/edit-post.html index a35395b5..87c0f012 100644 --- a/ambuda/templates/blog/edit-post.html +++ b/ambuda/templates/blog/edit-post.html @@ -3,7 +3,7 @@ {% import 'macros/forms.html' as mf %} -{% block title %}{{ mc.title('Edit post: {}'.format(post.title)) }}{% endblock %} +{% block title %}{{ mc.title('Edit post: {}'.format(post.display_title)) }}{% endblock %} {% block content %} diff --git a/ambuda/templates/macros/proofing.html b/ambuda/templates/macros/proofing.html index 81282923..f0c88ef9 100644 --- a/ambuda/templates/macros/proofing.html +++ b/ambuda/templates/macros/proofing.html @@ -12,7 +12,7 @@

{{ title|safe }}

{% macro project_header_nested(label, project) %} {% set url = url_for("proofing.project.summary", slug=project.slug) %} -{{ nested_header(label, project.title, url) }} +{{ nested_header(label, project.display_title, url) }} {% endmacro %} @@ -113,7 +113,7 @@

{{ _('Contribute') }}

- {{ project.title }} + {{ project.display_title }} /{{ cur.slug }}

@@ -141,7 +141,7 @@

project_slug=r.project.slug, page_slug=r.page.slug) %} {% set author_url = url_for('proofing.user.summary', username=r.author.username) %} - {% set page_title = r.project.title + "/" + r.page.slug %} + {% set page_title = r.project.display_title + "/" + r.page.slug %} {% set author = r.author.username %} @@ -158,7 +158,7 @@

{% macro project_li(p) %}
  • {% set project_url = url_for('proofing.project.summary', slug=p.slug) %} - {% set title = p.title %} + {% set title = p.display_title %} {% set creator = p.creator.username %} {% set creator_url = url_for('proofing.user.summary', username=creator) %}
    @@ -202,7 +202,7 @@

    project_slug=r.project.slug, page_slug=r.page.slug) %} {% set author_url = url_for('proofing.user.summary', username=r.author.username) %} - {% set page_title = r.project.title + "/" + r.page.slug %} + {% set page_title = r.project.display_title + "/" + r.page.slug %} {% set author = r.author.username %} diff --git a/ambuda/templates/proofing/index.html b/ambuda/templates/proofing/index.html index dfa21fef..97378e09 100644 --- a/ambuda/templates/proofing/index.html +++ b/ambuda/templates/proofing/index.html @@ -53,12 +53,12 @@

    {{ _('Ongoing projects') }}

      {% for p in projects %}
    • - {{ p.title }} + {{ p.display_title }} {% set count = pages_per_project[p.id] %} {{ ngettext('%(num)d page', '%(num)d pages', count) }} diff --git a/ambuda/templates/proofing/pages/edit.html b/ambuda/templates/proofing/pages/edit.html index 3d7e167a..adabac22 100644 --- a/ambuda/templates/proofing/pages/edit.html +++ b/ambuda/templates/proofing/pages/edit.html @@ -17,7 +17,7 @@ {% endmacro %} -{% block title %}Edit: {{ project.title }}/{{ cur.slug }} | Ambuda{% endblock %} +{% block title %}Edit: {{ project.display_title }}/{{ cur.slug }} | Ambuda{% endblock %} {% block main %} diff --git a/ambuda/templates/proofing/pages/editor-components.html b/ambuda/templates/proofing/pages/editor-components.html index 8057096f..daa96948 100644 --- a/ambuda/templates/proofing/pages/editor-components.html +++ b/ambuda/templates/proofing/pages/editor-components.html @@ -56,7 +56,7 @@

      - {{ project.title }} / {{ image_number }} + {{ project.display_title }} / {{ image_number }} Image {{ image_number }} of {{ num_images }} {% if image_title != page_number %} diff --git a/ambuda/templates/proofing/pages/history.html b/ambuda/templates/proofing/pages/history.html index df62dbe2..b95d0ff5 100644 --- a/ambuda/templates/proofing/pages/history.html +++ b/ambuda/templates/proofing/pages/history.html @@ -1,7 +1,7 @@ {% extends 'proofing/base.html' %} {% import "macros/proofing.html" as m %} -{% block title %}History: {{ project.title }}/{{ cur.slug }} | Ambuda{% endblock %} +{% block title %}History: {{ project.display_title }}/{{ cur.slug }} | Ambuda{% endblock %} {% block content %} {{ m.page_header(project, cur=cur, prev=prev, next=next) }} diff --git a/ambuda/templates/proofing/pages/revision.html b/ambuda/templates/proofing/pages/revision.html index ca10fb01..3151b682 100644 --- a/ambuda/templates/proofing/pages/revision.html +++ b/ambuda/templates/proofing/pages/revision.html @@ -1,7 +1,7 @@ {% extends 'proofing/base.html' %} {% import "macros/proofing.html" as m %} -{% block title %}Revision: {{ project.title }}/{{ cur.slug }} | Ambuda{% endblock %} +{% block title %}Revision: {{ project.display_title }}/{{ cur.slug }} | Ambuda{% endblock %} {% block content %}
      diff --git a/ambuda/templates/proofing/projects/activity.html b/ambuda/templates/proofing/projects/activity.html index f2199157..de2e4d8d 100644 --- a/ambuda/templates/proofing/projects/activity.html +++ b/ambuda/templates/proofing/projects/activity.html @@ -4,7 +4,7 @@ {% import "macros/proofing.html" as m %} -{% block title %}Activity: {{ project.title }} | Ambuda{% endblock %} +{% block title %}Activity: {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} diff --git a/ambuda/templates/proofing/projects/admin.html b/ambuda/templates/proofing/projects/admin.html index a358bea3..554ff64f 100644 --- a/ambuda/templates/proofing/projects/admin.html +++ b/ambuda/templates/proofing/projects/admin.html @@ -4,7 +4,7 @@ {% import "macros/proofing.html" as m %} -{% block title %}Admin: {{ project.title }} | Ambuda{% endblock %} +{% block title %}Admin: {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} diff --git a/ambuda/templates/proofing/projects/batch-ocr-post.html b/ambuda/templates/proofing/projects/batch-ocr-post.html index bd803796..a1043cdf 100644 --- a/ambuda/templates/proofing/projects/batch-ocr-post.html +++ b/ambuda/templates/proofing/projects/batch-ocr-post.html @@ -3,7 +3,7 @@ {% import "macros/proofing.html" as m %} -{% block title %}OCR {{ project.title }} | Ambuda{% endblock %} +{% block title %}OCR: {{ project.display_title }} | Ambuda{% endblock %} {% block content %} diff --git a/ambuda/templates/proofing/projects/batch-ocr.html b/ambuda/templates/proofing/projects/batch-ocr.html index 371eee8d..3a70effc 100644 --- a/ambuda/templates/proofing/projects/batch-ocr.html +++ b/ambuda/templates/proofing/projects/batch-ocr.html @@ -4,7 +4,7 @@ {% import "macros/proofing.html" as m %} -{% block title %}OCR {{ project.title }} | Ambuda{% endblock %} +{% block title %}OCR {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} diff --git a/ambuda/templates/proofing/projects/confirm_changes.html b/ambuda/templates/proofing/projects/confirm_changes.html index 86ef4339..a8c07d38 100644 --- a/ambuda/templates/proofing/projects/confirm_changes.html +++ b/ambuda/templates/proofing/projects/confirm_changes.html @@ -2,7 +2,7 @@ {% from "macros/forms.html" import field %} {% import "macros/proofing.html" as m %} -{% block title %} Search and Replace | {{ project.title }}{% endblock %} +{% block title %} Search and Replace | {{ project.display_title }}{% endblock %} {% block content %} @@ -28,7 +28,7 @@

      Confirm Changes

      {% set matches = result.matches %} {% for match in matches %}
      -

      Page {{ project.title }}/{{ page.slug }}: Line {{ match.line_num }}

      +

      Page {{ project.display_title }}/{{ page.slug }}: Line {{ match.line_num }}


      diff --git a/ambuda/templates/proofing/projects/download.html b/ambuda/templates/proofing/projects/download.html index b4670786..d97e3f15 100644 --- a/ambuda/templates/proofing/projects/download.html +++ b/ambuda/templates/proofing/projects/download.html @@ -2,7 +2,7 @@ {% import "macros/proofing.html" as m %} -{% block title %}Download: {{ project.title }} | Ambuda{% endblock %} +{% block title %}Download: {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} diff --git a/ambuda/templates/proofing/projects/edit.html b/ambuda/templates/proofing/projects/edit.html index 4c9ac8f5..726917c3 100644 --- a/ambuda/templates/proofing/projects/edit.html +++ b/ambuda/templates/proofing/projects/edit.html @@ -4,7 +4,7 @@ {% import "macros/proofing.html" as m %} -{% block title %}Edit: {{ project.title }} | Ambuda{% endblock %} +{% block title %}Edit: {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} @@ -29,17 +29,39 @@ {{ components.flash_messages() }} {{ mf.show_errors_if_any(form.errors) }} -
      + {{ form.csrf_token }} - {{ mf.markdown_field(form.description) }} - {{ mf.field(form.page_numbers) }} - {{ mf.field(form.title) }} - {{ mf.field(form.author) }} - {{ mf.field(form.editor) }} - {{ mf.field(form.publisher) }} - {{ mf.field(form.publication_year) }} - - + +
      + Basic information +
      + {{ mf.field(form.display_title) }} + {{ mf.field(form.genre) }} + {{ mf.markdown_field(form.description) }} + {{ mf.field(form.page_numbers) }} +
      +
      + +
      + Book metadata +
      + {{ mf.field(form.print_title) }} + {{ mf.field(form.author) }} + {{ mf.field(form.editor) }} + {{ mf.field(form.publisher) }} + {{ mf.field(form.publication_year) }} + {{ mf.field(form.worldcat_link) }} +
      +
      + +
      + Internal notes +
      + {{ mf.field(form.notes) }} +
      +
      + +
      {% endblock %} diff --git a/ambuda/templates/proofing/projects/replace.html b/ambuda/templates/proofing/projects/replace.html index f2ca2491..0a93dce5 100644 --- a/ambuda/templates/proofing/projects/replace.html +++ b/ambuda/templates/proofing/projects/replace.html @@ -15,7 +15,7 @@

      - {{ project.title }}, page {{ page.slug }}, + {{ project.display_title }}, page {{ page.slug }}, line {{ match.line_num }}

      @@ -29,7 +29,7 @@ {% endmacro %} -{% block title %}Search and Replace {{ project.title }} | Ambuda{% endblock %} +{% block title %}Search and Replace {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} diff --git a/ambuda/templates/proofing/projects/search.html b/ambuda/templates/proofing/projects/search.html index bf93180b..23267d23 100644 --- a/ambuda/templates/proofing/projects/search.html +++ b/ambuda/templates/proofing/projects/search.html @@ -3,7 +3,7 @@ {% import "macros/proofing.html" as m %} -{% block title %}Search {{ project.title }} | Ambuda{% endblock %} +{% block title %}Search: {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} @@ -34,7 +34,7 @@ {% for page in results %} {% set page_url = url_for("proofing.page.edit", project_slug=project.slug, page_slug=page.slug) %}
    • - {{ project.title }}/{{ page.slug }} + {{ project.display_title }}/{{ page.slug }}
      {% for match in page.matches %}
      {{ match.text }}
      diff --git a/ambuda/templates/proofing/projects/stats.html b/ambuda/templates/proofing/projects/stats.html index 80116e05..03b7356d 100644 --- a/ambuda/templates/proofing/projects/stats.html +++ b/ambuda/templates/proofing/projects/stats.html @@ -2,7 +2,7 @@ {% import "macros/proofing.html" as m %} -{% block title %}Stats: {{ project.title }} | Ambuda{% endblock %} +{% block title %}Stats: {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} diff --git a/ambuda/templates/proofing/projects/summary.html b/ambuda/templates/proofing/projects/summary.html index f051e750..4bef6b3f 100644 --- a/ambuda/templates/proofing/projects/summary.html +++ b/ambuda/templates/proofing/projects/summary.html @@ -4,14 +4,14 @@ {% import "macros/proofing.html" as m %} -{% block title %}{{ project.title }} | Ambuda{% endblock %} +{% block title %}{{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('projects', current_user=current_user) }}{% endblock %} {% block content %} -

      {{ project.title }}

      +

      {{ project.display_title }}

      {{ m.project_tabs(project=project, active='summary', is_mod=current_user.is_moderator) }} {% if project.description %} @@ -45,7 +45,7 @@

      {{ pgettext("project", "About") }}

      - + diff --git a/ambuda/templates/proofing/talk.html b/ambuda/templates/proofing/talk.html index 7d741c18..46f75e0d 100644 --- a/ambuda/templates/proofing/talk.html +++ b/ambuda/templates/proofing/talk.html @@ -21,7 +21,7 @@ diff --git a/ambuda/templates/proofing/talk/board.html b/ambuda/templates/proofing/talk/board.html index 8c648f08..dcfca8ae 100644 --- a/ambuda/templates/proofing/talk/board.html +++ b/ambuda/templates/proofing/talk/board.html @@ -4,7 +4,7 @@ {% from "macros/forms.html" import field %} -{% block title %}Talk: {{ project.title }} | Ambuda{% endblock %} +{% block title %}Talk: {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('talk', current_user=current_user) }}{% endblock %} diff --git a/ambuda/templates/proofing/talk/create-post.html b/ambuda/templates/proofing/talk/create-post.html index a632f2d8..f2e47725 100644 --- a/ambuda/templates/proofing/talk/create-post.html +++ b/ambuda/templates/proofing/talk/create-post.html @@ -4,7 +4,7 @@ {% import "macros/forms.html" as mf %} -{% block title %}Create post on {{ project.title }} | Ambuda{% endblock %} +{% block title %}Create post on {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('talk', current_user=current_user) }}{% endblock %} diff --git a/ambuda/templates/proofing/talk/create-thread.html b/ambuda/templates/proofing/talk/create-thread.html index 7a4b1c06..c4599f84 100644 --- a/ambuda/templates/proofing/talk/create-thread.html +++ b/ambuda/templates/proofing/talk/create-thread.html @@ -4,7 +4,7 @@ {% import "macros/talk.html" as m_talk %} -{% block title %}Create thread on {{ project.title }} | Ambuda{% endblock %} +{% block title %}Create thread on {{ project.display_title }} | Ambuda{% endblock %} {% block sidebar %}{{ m.main_nav('talk', current_user=current_user) }}{% endblock %} @@ -12,7 +12,7 @@ {% block content %}
      -

      {{ project.title }} — create thread

      +

      {{ project.display_title }} — create thread

      {{ mf.show_errors_if_any(form.errors) }} diff --git a/ambuda/templates/proofing/talk/edit-post.html b/ambuda/templates/proofing/talk/edit-post.html index 5cd2ab9b..432f1b65 100644 --- a/ambuda/templates/proofing/talk/edit-post.html +++ b/ambuda/templates/proofing/talk/edit-post.html @@ -3,7 +3,7 @@ {% import "macros/talk.html" as m_talk %} {% from "macros/forms.html" import field, show_errors_if_any %} -{% block title %}Create thread on {{ project.title }} | Ambuda{% endblock %} +{% block title %}Create thread on {{ project.display_title }} | Ambuda{% endblock %} {% block content %} {% set url = url_for('proofing.talk.thread', project_slug=project.slug, thread_id=thread.id) %} diff --git a/ambuda/views/proofing/main.py b/ambuda/views/proofing/main.py index 39b2f135..87c6f635 100644 --- a/ambuda/views/proofing/main.py +++ b/ambuda/views/proofing/main.py @@ -137,7 +137,7 @@ def index(): statuses_per_project[project.id] = project_counts pages_per_project[project.id] = num_pages - projects.sort(key=lambda x: x.title) + projects.sort(key=lambda x: x.display_title) return render_template( "proofing/index.html", projects=projects, @@ -196,7 +196,7 @@ def create_project(): form.local_file.data.save(pdf_path) task = project_tasks.create_project.delay( - title=title, + display_title=title, pdf_path=str(pdf_path), output_dir=str(page_image_dir), app_environment=current_app.config["AMBUDA_ENVIRONMENT"], diff --git a/ambuda/views/proofing/project.py b/ambuda/views/proofing/project.py index e8110ce5..d8977110 100644 --- a/ambuda/views/proofing/project.py +++ b/ambuda/views/proofing/project.py @@ -29,6 +29,7 @@ ) from wtforms.validators import DataRequired, ValidationError from wtforms.widgets import TextArea +from wtforms_sqlalchemy.fields import QuerySelectField from ambuda import database as db from ambuda import queries as q @@ -51,6 +52,13 @@ def _is_valid_page_number_spec(_, field): class EditMetadataForm(FlaskForm): + display_title = StringField( + _l("Display title"), + render_kw={ + "placeholder": _l("e.g. Avantisundarīkathā"), + }, + validators=[DataRequired()], + ) description = StringField( _l("Description (optional)"), widget=TextArea(), @@ -68,7 +76,18 @@ class EditMetadataForm(FlaskForm): "placeholder": "Coming soon.", }, ) - title = StringField(_l("Title"), validators=[DataRequired()]) + genre = QuerySelectField( + query_factory=q.genres, allow_blank=True, blank_text=_l("(none)") + ) + + print_title = StringField( + _l("Print title"), + render_kw={ + "placeholder": _l( + "e.g. Śrīdaṇḍimahākaviviracitam avantisundarīkathā nāma gadyakāvyam" + ), + }, + ) author = StringField( _l("Author"), render_kw={ @@ -79,7 +98,7 @@ class EditMetadataForm(FlaskForm): _l("Editor"), render_kw={ "placeholder": _l( - "The person or organization that created this edition of the text." + "The person or organization that created this edition, e.g. M.R. Kale." ), }, ) @@ -91,6 +110,12 @@ class EditMetadataForm(FlaskForm): ), }, ) + worldcat_link = StringField( + _l("Worldcat link"), + render_kw={ + "placeholder": _l("A link to this book's entry on worldcat.org."), + }, + ) publication_year = StringField( _l("Publication year"), render_kw={ @@ -98,6 +123,14 @@ class EditMetadataForm(FlaskForm): }, ) + notes = StringField( + _l("Notes (optional)"), + widget=TextArea(), + render_kw={ + "placeholder": _l("Internal notes for scholars and other proofreaders."), + }, + ) + class MatchForm(Form): selected = BooleanField() @@ -259,7 +292,7 @@ def download_as_xml(slug): abort(404) project_meta = { - "title": project_.title, + "title": project_.display_title, "author": project_.author, "publication_year": project_.publication_year, "publisher": project_.publisher, diff --git a/migrations/versions/f208e1844a36_add_more_project_metadata.py b/migrations/versions/f208e1844a36_add_more_project_metadata.py new file mode 100644 index 00000000..310c2371 --- /dev/null +++ b/migrations/versions/f208e1844a36_add_more_project_metadata.py @@ -0,0 +1,61 @@ +"""Add Project metadata fields + +Revision ID: f208e1844a36 +Revises: ed1c7e4af52d +Create Date: 2023-04-07 19:15:04.082171 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = "f208e1844a36" +down_revision = "ed1c7e4af52d" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.create_table( + "genres", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("name"), + ) + + with op.batch_alter_table("proof_projects") as batch_op: + batch_op.alter_column("title", new_column_name="display_title") + batch_op.create_foreign_key( + "fk_proof_projects_genre_id", "proof_projects", ["genre_id"], ["id"] + ) + + op.add_column( + "proof_projects", + sa.Column("print_title", sa.String(), nullable=False, server_default=""), + ) + op.add_column( + "proof_projects", + sa.Column("worldcat_link", sa.String(), nullable=False, server_default=""), + ) + op.add_column( + "proof_projects", + sa.Column("notes", sa.Text(), nullable=False, server_default=""), + ) + op.add_column("proof_projects", sa.Column("genre_id", sa.Integer(), nullable=True)) + op.create_index( + op.f("ix_proof_projects_genre_id"), "proof_projects", ["genre_id"], unique=False + ) + + +def downgrade() -> None: + op.drop_index(op.f("ix_proof_projects_genre_id"), table_name="proof_projects") + op.drop_column("proof_projects", "notes") + op.drop_column("proof_projects", "worldcat_link") + op.drop_column("proof_projects", "print_title") + op.drop_column("proof_projects", "genre_id") + + with op.batch_alter_table("proof_projects") as batch_op: + batch_op.alter_column("display_title", new_column_name="title") + + op.drop_table("genres") diff --git a/poetry.lock b/poetry.lock index e013cef7..5e790d14 100644 --- a/poetry.lock +++ b/poetry.lock @@ -214,16 +214,19 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "blinker" -version = "1.5" +version = "1.6" description = "Fast, simple object-to-object and broadcast signaling" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" files = [ - {file = "blinker-1.5-py2.py3-none-any.whl", hash = "sha256:1eb563df6fdbc39eeddc177d953203f99f097e9bf0e2b8f9f3cf18b6ca425e36"}, - {file = "blinker-1.5.tar.gz", hash = "sha256:923e5e2f69c155f2cc42dafbbd70e16e3fde24d2d4aa2ab72fbe386238892462"}, + {file = "blinker-1.6-py3-none-any.whl", hash = "sha256:eeebd5dfc782e1817fe4261ce79936c8c8cefb90d685caf50cec458029f773c1"}, + {file = "blinker-1.6.tar.gz", hash = "sha256:5874afe21df4bae8885d31a0a6c4b5861910a575eae6176f051fbb9a6571481b"}, ] +[package.dependencies] +typing-extensions = "*" + [[package]] name = "cachetools" version = "5.3.0" @@ -486,63 +489,63 @@ files = [ [[package]] name = "coverage" -version = "7.2.2" +version = "7.2.3" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "coverage-7.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c90e73bdecb7b0d1cea65a08cb41e9d672ac6d7995603d6465ed4914b98b9ad7"}, - {file = "coverage-7.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e2926b8abedf750c2ecf5035c07515770944acf02e1c46ab08f6348d24c5f94d"}, - {file = "coverage-7.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57b77b9099f172804e695a40ebaa374f79e4fb8b92f3e167f66facbf92e8e7f5"}, - {file = "coverage-7.2.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efe1c0adad110bf0ad7fb59f833880e489a61e39d699d37249bdf42f80590169"}, - {file = "coverage-7.2.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2199988e0bc8325d941b209f4fd1c6fa007024b1442c5576f1a32ca2e48941e6"}, - {file = "coverage-7.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:81f63e0fb74effd5be736cfe07d710307cc0a3ccb8f4741f7f053c057615a137"}, - {file = "coverage-7.2.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:186e0fc9cf497365036d51d4d2ab76113fb74f729bd25da0975daab2e107fd90"}, - {file = "coverage-7.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:420f94a35e3e00a2b43ad5740f935358e24478354ce41c99407cddd283be00d2"}, - {file = "coverage-7.2.2-cp310-cp310-win32.whl", hash = "sha256:38004671848b5745bb05d4d621526fca30cee164db42a1f185615f39dc997292"}, - {file = "coverage-7.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:0ce383d5f56d0729d2dd40e53fe3afeb8f2237244b0975e1427bfb2cf0d32bab"}, - {file = "coverage-7.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3eb55b7b26389dd4f8ae911ba9bc8c027411163839dea4c8b8be54c4ee9ae10b"}, - {file = "coverage-7.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d2b96123a453a2d7f3995ddb9f28d01fd112319a7a4d5ca99796a7ff43f02af5"}, - {file = "coverage-7.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:299bc75cb2a41e6741b5e470b8c9fb78d931edbd0cd009c58e5c84de57c06731"}, - {file = "coverage-7.2.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e1df45c23d4230e3d56d04414f9057eba501f78db60d4eeecfcb940501b08fd"}, - {file = "coverage-7.2.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:006ed5582e9cbc8115d2e22d6d2144a0725db542f654d9d4fda86793832f873d"}, - {file = "coverage-7.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d683d230b5774816e7d784d7ed8444f2a40e7a450e5720d58af593cb0b94a212"}, - {file = "coverage-7.2.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8efb48fa743d1c1a65ee8787b5b552681610f06c40a40b7ef94a5b517d885c54"}, - {file = "coverage-7.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c752d5264053a7cf2fe81c9e14f8a4fb261370a7bb344c2a011836a96fb3f57"}, - {file = "coverage-7.2.2-cp311-cp311-win32.whl", hash = "sha256:55272f33da9a5d7cccd3774aeca7a01e500a614eaea2a77091e9be000ecd401d"}, - {file = "coverage-7.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:92ebc1619650409da324d001b3a36f14f63644c7f0a588e331f3b0f67491f512"}, - {file = "coverage-7.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5afdad4cc4cc199fdf3e18088812edcf8f4c5a3c8e6cb69127513ad4cb7471a9"}, - {file = "coverage-7.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0484d9dd1e6f481b24070c87561c8d7151bdd8b044c93ac99faafd01f695c78e"}, - {file = "coverage-7.2.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d530191aa9c66ab4f190be8ac8cc7cfd8f4f3217da379606f3dd4e3d83feba69"}, - {file = "coverage-7.2.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac0f522c3b6109c4b764ffec71bf04ebc0523e926ca7cbe6c5ac88f84faced0"}, - {file = "coverage-7.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ba279aae162b20444881fc3ed4e4f934c1cf8620f3dab3b531480cf602c76b7f"}, - {file = "coverage-7.2.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:53d0fd4c17175aded9c633e319360d41a1f3c6e352ba94edcb0fa5167e2bad67"}, - {file = "coverage-7.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c99cb7c26a3039a8a4ee3ca1efdde471e61b4837108847fb7d5be7789ed8fd9"}, - {file = "coverage-7.2.2-cp37-cp37m-win32.whl", hash = "sha256:5cc0783844c84af2522e3a99b9b761a979a3ef10fb87fc4048d1ee174e18a7d8"}, - {file = "coverage-7.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:817295f06eacdc8623dc4df7d8b49cea65925030d4e1e2a7c7218380c0072c25"}, - {file = "coverage-7.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6146910231ece63facfc5984234ad1b06a36cecc9fd0c028e59ac7c9b18c38c6"}, - {file = "coverage-7.2.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:387fb46cb8e53ba7304d80aadca5dca84a2fbf6fe3faf6951d8cf2d46485d1e5"}, - {file = "coverage-7.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:046936ab032a2810dcaafd39cc4ef6dd295df1a7cbead08fe996d4765fca9fe4"}, - {file = "coverage-7.2.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e627dee428a176ffb13697a2c4318d3f60b2ccdde3acdc9b3f304206ec130ccd"}, - {file = "coverage-7.2.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fa54fb483decc45f94011898727802309a109d89446a3c76387d016057d2c84"}, - {file = "coverage-7.2.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3668291b50b69a0c1ef9f462c7df2c235da3c4073f49543b01e7eb1dee7dd540"}, - {file = "coverage-7.2.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7c20b731211261dc9739bbe080c579a1835b0c2d9b274e5fcd903c3a7821cf88"}, - {file = "coverage-7.2.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5764e1f7471cb8f64b8cda0554f3d4c4085ae4b417bfeab236799863703e5de2"}, - {file = "coverage-7.2.2-cp38-cp38-win32.whl", hash = "sha256:4f01911c010122f49a3e9bdc730eccc66f9b72bd410a3a9d3cb8448bb50d65d3"}, - {file = "coverage-7.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:c448b5c9e3df5448a362208b8d4b9ed85305528313fca1b479f14f9fe0d873b8"}, - {file = "coverage-7.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bfe7085783cda55e53510482fa7b5efc761fad1abe4d653b32710eb548ebdd2d"}, - {file = "coverage-7.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9d22e94e6dc86de981b1b684b342bec5e331401599ce652900ec59db52940005"}, - {file = "coverage-7.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:507e4720791977934bba016101579b8c500fb21c5fa3cd4cf256477331ddd988"}, - {file = "coverage-7.2.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc4803779f0e4b06a2361f666e76f5c2e3715e8e379889d02251ec911befd149"}, - {file = "coverage-7.2.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db8c2c5ace167fd25ab5dd732714c51d4633f58bac21fb0ff63b0349f62755a8"}, - {file = "coverage-7.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4f68ee32d7c4164f1e2c8797535a6d0a3733355f5861e0f667e37df2d4b07140"}, - {file = "coverage-7.2.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d52f0a114b6a58305b11a5cdecd42b2e7f1ec77eb20e2b33969d702feafdd016"}, - {file = "coverage-7.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:797aad79e7b6182cb49c08cc5d2f7aa7b2128133b0926060d0a8889ac43843be"}, - {file = "coverage-7.2.2-cp39-cp39-win32.whl", hash = "sha256:db45eec1dfccdadb179b0f9ca616872c6f700d23945ecc8f21bb105d74b1c5fc"}, - {file = "coverage-7.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:8dbe2647bf58d2c5a6c5bcc685f23b5f371909a5624e9f5cd51436d6a9f6c6ef"}, - {file = "coverage-7.2.2-pp37.pp38.pp39-none-any.whl", hash = "sha256:872d6ce1f5be73f05bea4df498c140b9e7ee5418bfa2cc8204e7f9b817caa968"}, - {file = "coverage-7.2.2.tar.gz", hash = "sha256:36dd42da34fe94ed98c39887b86db9d06777b1c8f860520e21126a75507024f2"}, + {file = "coverage-7.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e58c0d41d336569d63d1b113bd573db8363bc4146f39444125b7f8060e4e04f5"}, + {file = "coverage-7.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:344e714bd0fe921fc72d97404ebbdbf9127bac0ca1ff66d7b79efc143cf7c0c4"}, + {file = "coverage-7.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974bc90d6f6c1e59ceb1516ab00cf1cdfbb2e555795d49fa9571d611f449bcb2"}, + {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0743b0035d4b0e32bc1df5de70fba3059662ace5b9a2a86a9f894cfe66569013"}, + {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d0391fb4cfc171ce40437f67eb050a340fdbd0f9f49d6353a387f1b7f9dd4fa"}, + {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a42e1eff0ca9a7cb7dc9ecda41dfc7cbc17cb1d02117214be0561bd1134772b"}, + {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be19931a8dcbe6ab464f3339966856996b12a00f9fe53f346ab3be872d03e257"}, + {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72fcae5bcac3333a4cf3b8f34eec99cea1187acd55af723bcbd559adfdcb5535"}, + {file = "coverage-7.2.3-cp310-cp310-win32.whl", hash = "sha256:aeae2aa38395b18106e552833f2a50c27ea0000122bde421c31d11ed7e6f9c91"}, + {file = "coverage-7.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:83957d349838a636e768251c7e9979e899a569794b44c3728eaebd11d848e58e"}, + {file = "coverage-7.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfd393094cd82ceb9b40df4c77976015a314b267d498268a076e940fe7be6b79"}, + {file = "coverage-7.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:182eb9ac3f2b4874a1f41b78b87db20b66da6b9cdc32737fbbf4fea0c35b23fc"}, + {file = "coverage-7.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bb1e77a9a311346294621be905ea8a2c30d3ad371fc15bb72e98bfcfae532df"}, + {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca0f34363e2634deffd390a0fef1aa99168ae9ed2af01af4a1f5865e362f8623"}, + {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55416d7385774285b6e2a5feca0af9652f7f444a4fa3d29d8ab052fafef9d00d"}, + {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:06ddd9c0249a0546997fdda5a30fbcb40f23926df0a874a60a8a185bc3a87d93"}, + {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fff5aaa6becf2c6a1699ae6a39e2e6fb0672c2d42eca8eb0cafa91cf2e9bd312"}, + {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ea53151d87c52e98133eb8ac78f1206498c015849662ca8dc246255265d9c3c4"}, + {file = "coverage-7.2.3-cp311-cp311-win32.whl", hash = "sha256:8f6c930fd70d91ddee53194e93029e3ef2aabe26725aa3c2753df057e296b925"}, + {file = "coverage-7.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:fa546d66639d69aa967bf08156eb8c9d0cd6f6de84be9e8c9819f52ad499c910"}, + {file = "coverage-7.2.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2317d5ed777bf5a033e83d4f1389fd4ef045763141d8f10eb09a7035cee774c"}, + {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be9824c1c874b73b96288c6d3de793bf7f3a597770205068c6163ea1f326e8b9"}, + {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3b2803e730dc2797a017335827e9da6da0e84c745ce0f552e66400abdfb9a1"}, + {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f69770f5ca1994cb32c38965e95f57504d3aea96b6c024624fdd5bb1aa494a1"}, + {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1127b16220f7bfb3f1049ed4a62d26d81970a723544e8252db0efde853268e21"}, + {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa784405f0c640940595fa0f14064d8e84aff0b0f762fa18393e2760a2cf5841"}, + {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3146b8e16fa60427e03884301bf8209221f5761ac754ee6b267642a2fd354c48"}, + {file = "coverage-7.2.3-cp37-cp37m-win32.whl", hash = "sha256:1fd78b911aea9cec3b7e1e2622c8018d51c0d2bbcf8faaf53c2497eb114911c1"}, + {file = "coverage-7.2.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f3736a5d34e091b0a611964c6262fd68ca4363df56185902528f0b75dbb9c1f"}, + {file = "coverage-7.2.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:981b4df72c93e3bc04478153df516d385317628bd9c10be699c93c26ddcca8ab"}, + {file = "coverage-7.2.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0045f8f23a5fb30b2eb3b8a83664d8dc4fb58faddf8155d7109166adb9f2040"}, + {file = "coverage-7.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f760073fcf8f3d6933178d67754f4f2d4e924e321f4bb0dcef0424ca0215eba1"}, + {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c86bd45d1659b1ae3d0ba1909326b03598affbc9ed71520e0ff8c31a993ad911"}, + {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:172db976ae6327ed4728e2507daf8a4de73c7cc89796483e0a9198fd2e47b462"}, + {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d2a3a6146fe9319926e1d477842ca2a63fe99af5ae690b1f5c11e6af074a6b5c"}, + {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f649dd53833b495c3ebd04d6eec58479454a1784987af8afb77540d6c1767abd"}, + {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c4ed4e9f3b123aa403ab424430b426a1992e6f4c8fd3cb56ea520446e04d152"}, + {file = "coverage-7.2.3-cp38-cp38-win32.whl", hash = "sha256:eb0edc3ce9760d2f21637766c3aa04822030e7451981ce569a1b3456b7053f22"}, + {file = "coverage-7.2.3-cp38-cp38-win_amd64.whl", hash = "sha256:63cdeaac4ae85a179a8d6bc09b77b564c096250d759eed343a89d91bce8b6367"}, + {file = "coverage-7.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20d1a2a76bb4eb00e4d36b9699f9b7aba93271c9c29220ad4c6a9581a0320235"}, + {file = "coverage-7.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ea748802cc0de4de92ef8244dd84ffd793bd2e7be784cd8394d557a3c751e21"}, + {file = "coverage-7.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b154aba06df42e4b96fc915512ab39595105f6c483991287021ed95776d934"}, + {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd214917cabdd6f673a29d708574e9fbdb892cb77eb426d0eae3490d95ca7859"}, + {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2e58e45fe53fab81f85474e5d4d226eeab0f27b45aa062856c89389da2f0d9"}, + {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87ecc7c9a1a9f912e306997ffee020297ccb5ea388421fe62a2a02747e4d5539"}, + {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:387065e420aed3c71b61af7e82c7b6bc1c592f7e3c7a66e9f78dd178699da4fe"}, + {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ea3f5bc91d7d457da7d48c7a732beaf79d0c8131df3ab278e6bba6297e23c6c4"}, + {file = "coverage-7.2.3-cp39-cp39-win32.whl", hash = "sha256:ae7863a1d8db6a014b6f2ff9c1582ab1aad55a6d25bac19710a8df68921b6e30"}, + {file = "coverage-7.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f04becd4fcda03c0160d0da9c8f0c246bc78f2f7af0feea1ec0930e7c93fa4a"}, + {file = "coverage-7.2.3-pp37.pp38.pp39-none-any.whl", hash = "sha256:965ee3e782c7892befc25575fa171b521d33798132692df428a09efacaffe8d0"}, + {file = "coverage-7.2.3.tar.gz", hash = "sha256:d298c2815fa4891edd9abe5ad6e6cb4207104c7dd9fd13aea3fdebf6f9b91259"}, ] [package.dependencies] @@ -696,23 +699,6 @@ pathlib2 = "*" pytest = ["mock (>=2.0.0,<3.0)", "pytest (>=3.2.5,<4.0)"] testing = ["mock (>=2.0.0,<3.0)"] -[[package]] -name = "flake8" -version = "5.0.4" -description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" -optional = false -python-versions = ">=3.6.1" -files = [ - {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, - {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.9.0,<2.10.0" -pyflakes = ">=2.5.0,<2.6.0" - [[package]] name = "flask" version = "2.1.2" @@ -1200,24 +1186,6 @@ files = [ {file = "invoke-1.7.3.tar.gz", hash = "sha256:41b428342d466a82135d5ab37119685a989713742be46e42a3a399d685579314"}, ] -[[package]] -name = "isort" -version = "5.12.0" -description = "A Python utility / library to sort Python imports." -category = "dev" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] - -[package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] - [[package]] name = "itsdangerous" version = "2.1.2" @@ -1602,18 +1570,6 @@ files = [ {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - [[package]] name = "mdurl" version = "0.1.2" @@ -1881,18 +1837,6 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.5.0" -[[package]] -name = "pycodestyle" -version = "2.9.1" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, - {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, -] - [[package]] name = "pycparser" version = "2.21" @@ -1905,18 +1849,6 @@ files = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] -[[package]] -name = "pyflakes" -version = "2.5.0" -description = "passive checker of Python programs" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, - {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, -] - [[package]] name = "pygments" version = "2.14.0" @@ -2331,6 +2263,33 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" +[[package]] +name = "ruff" +version = "0.0.260" +description = "An extremely fast Python linter, written in Rust." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.0.260-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:c559650b623f3fbdc39c7ed1bcb064765c666a53ee738c53d1461afbf3f23db2"}, + {file = "ruff-0.0.260-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:90ff1479e292a84c388a8a035d223247ddeea5f6760752a9142b88b6d59ac334"}, + {file = "ruff-0.0.260-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25584d1b9f445fde72651caab97e7430a4c5bfd2a0ce9af39868753826cba10d"}, + {file = "ruff-0.0.260-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8032e35357384a29791c75194a71e314031171eb0731fcaa872dfaf4c1f4470a"}, + {file = "ruff-0.0.260-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e4fa7293f97c021825b3b72f2bf53f0eb4f59625608a889678c1fc6660f412d"}, + {file = "ruff-0.0.260-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8bec0271e2c8cd36bcf915cb9f6a93e40797a3ff3d2cda4ca87b7bed9e598472"}, + {file = "ruff-0.0.260-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e075a61aaff8ebe56172217f0ac14c5df9637b289bf161ac697445a9003d5c2"}, + {file = "ruff-0.0.260-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8678f54eb2696481618902a10c3cb28325f3323799af99997ad6f06005ea4f5"}, + {file = "ruff-0.0.260-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57d9f0bfdef739b76aa3112b9182a214f0f34589a2659f88353492c7670fe2fe"}, + {file = "ruff-0.0.260-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ec1f77219ba5adaa194289cb82ba924ff2ed931fd00b8541d66a1724c89fbc9"}, + {file = "ruff-0.0.260-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:aae2170a7ec6f7fc4a73db30aa7aa7fce936176bf66bf85f77f69ddd1dd4a665"}, + {file = "ruff-0.0.260-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5f847b72ef994ab88e9da250c7eb5cbb3f1555b92a9f22c5ed1c27a44b7e98d6"}, + {file = "ruff-0.0.260-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6dd705d4eff405c2b70513188fbff520f49db6df91f0d5e8258c5d469efa58bc"}, + {file = "ruff-0.0.260-py3-none-win32.whl", hash = "sha256:3866a96b2ef92c7d837ba6bf8fc9dd125a67886f1c5512ad6fa5d5fefaceff87"}, + {file = "ruff-0.0.260-py3-none-win_amd64.whl", hash = "sha256:0733d524946decbd4f1e63f7dc26820f5c1e6c31da529ba20fb995057f8e79b1"}, + {file = "ruff-0.0.260-py3-none-win_arm64.whl", hash = "sha256:12542a26f189a5a10c719bfa14d415d0511ac05e5c9ff5e79cc9d5cc50b81bc8"}, + {file = "ruff-0.0.260.tar.gz", hash = "sha256:ea8f94262f33b81c47ee9d81f455b144e94776f5c925748cb0c561a12206eae1"}, +] + [[package]] name = "selenium" version = "4.8.3" @@ -2763,6 +2722,18 @@ dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2 doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +[[package]] +name = "typing-extensions" +version = "4.5.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, +] + [[package]] name = "uc-micro-py" version = "1.0.1" @@ -3020,7 +2991,23 @@ MarkupSafe = "*" [package.extras] email = ["email-validator"] +[[package]] +name = "wtforms-sqlalchemy" +version = "0.3" +description = "SQLAlchemy tools for WTForms" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "WTForms-SQLAlchemy-0.3.tar.gz", hash = "sha256:7ca42824ad7c453a036f502b42d9c17d4ad8398ff9248a62ed538d1ce0bc41c3"}, + {file = "WTForms_SQLAlchemy-0.3-py3-none-any.whl", hash = "sha256:90195d7592bf256d82498c42c79d416832e4a4e6fbca4f1e745a018f66d26c47"}, +] + +[package.dependencies] +SQLAlchemy = ">=0.7.10" +WTForms = ">=1.0.5" + [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "dc3b049d936c1e9079613c8eba5505f0f1eba46f7d9403c6a417fd5da61bb897" +content-hash = "e373d87d556335540868b01d435fe1cc6ae083f00f6f4dce75df8075fb8a391b" diff --git a/pyproject.toml b/pyproject.toml index 110101cf..3cbea747 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,6 +58,7 @@ sentry-sdk = "1.6.0" SQLAlchemy = "1.4.37" Werkzeug = "2.1.2" WTForms = "3.0.1" +wtforms-sqlalchemy = "^0.3" [tool.poetry.dev-dependencies] @@ -66,8 +67,7 @@ pytest = "^7.1.2" pytest-cov = "4.0.0" # Linting / formatting black = "^22.3.0" -flake8 = "5.0.4" -isort = "^5.10.1" +ruff = "0.0.260" # Documentation Sphinx = "5.0.2" sphinx-rtd-theme = "1.0.0" diff --git a/requirements.txt b/requirements.txt index ef22509b..ffb68c72 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,6 @@ cryptography==38.0.1 docutils==0.17.1 email-validator==1.2.1 fabric==2.7.0 -flake8==5.0.4 flask-admin==1.6.0 flask-babel==3.0.1 flask-bcrypt==1.0.1 @@ -46,6 +45,7 @@ pytz==2022.7 redis==4.3.4 regex==2022.6.2 requests==2.27.1 +ruff==0.0.260 sentry-sdk==1.6.0 sphinx-rtd-theme==1.0.0 sphinx==5.0.2 @@ -58,3 +58,4 @@ sphinxcontrib-serializinghtml==1.1.5 sqlalchemy==1.4.37 werkzeug==2.1.2 wtforms==3.0.1 +wtforms-sqlalchemy==0.3 diff --git a/test/ambuda/conftest.py b/test/ambuda/conftest.py index 4924abb6..f8f683b6 100644 --- a/test/ambuda/conftest.py +++ b/test/ambuda/conftest.py @@ -149,7 +149,9 @@ def initialize_test_db(): post.thread = thread board.threads = [thread] - project = db.Project(slug="test-project", title="Test Project", board_id=board.id) + project = db.Project( + slug="test-project", display_title="Test Project", board_id=board.id + ) session.add(project) session.flush() diff --git a/test/ambuda/tasks/test_projects_tasks.py b/test/ambuda/tasks/test_projects_tasks.py index d178ef3b..698f871b 100644 --- a/test/ambuda/tasks/test_projects_tasks.py +++ b/test/ambuda/tasks/test_projects_tasks.py @@ -26,7 +26,7 @@ def test_create_project_inner(flask_app): _create_sample_pdf(f.name, num_pages=10) projects.create_project_inner( - title="Cool project", + display_title="Cool project", pdf_path=f.name, output_dir=flask_app.config["UPLOAD_FOLDER"], app_environment=flask_app.config["AMBUDA_ENVIRONMENT"], diff --git a/test/ambuda/views/proofing/test_project.py b/test/ambuda/views/proofing/test_project.py index 350dbd6c..9ff71be2 100644 --- a/test/ambuda/views/proofing/test_project.py +++ b/test/ambuda/views/proofing/test_project.py @@ -185,7 +185,7 @@ def test_confirm_unauth(client): def test_admin(moderator_client): session = q.get_session() - project = Project(slug="project-123", title="Dummy project", board_id=0) + project = Project(slug="project-123", display_title="Dummy project", board_id=0) session.add(project) session.commit() @@ -202,7 +202,7 @@ def test_admin(moderator_client): def test_admin__slug_mismatch(moderator_client): session = q.get_session() - project = Project(slug="project-1234", title="Dummy project", board_id=0) + project = Project(slug="project-1234", display_title="Dummy project", board_id=0) session.add(project) session.commit()
      {{ _('Title') }}{{ project.title or _("(none)") }}{{ project.display_title or _("(none)") }}
      {{ _('Author') }}