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 }}
{{ match.query }}
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) }}
-
{% 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") }}
{{ _('Title') }}
- {{ project.title or _("(none)") }}
+ {{ project.display_title or _("(none)") }}
{{ _('Author') }}
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()