Handle genres and authors casing
This commit is contained in:
@@ -380,7 +380,7 @@ def list_books(
|
||||
click.echo("-" * 75)
|
||||
|
||||
for book in books:
|
||||
authors_str = ", ".join(a.name for a in book.authors)[:22]
|
||||
authors_str = ", ".join(a.name.title() for a in book.authors)[:22]
|
||||
if len(authors_str) == 22:
|
||||
authors_str += "..."
|
||||
owner_str = book.owner.username if book.owner else ""
|
||||
@@ -459,7 +459,7 @@ def search_books(
|
||||
click.echo("-" * 72)
|
||||
|
||||
for book in books:
|
||||
authors_str = ", ".join(a.name for a in book.authors)[:27]
|
||||
authors_str = ", ".join(a.name.title() for a in book.authors)[:27]
|
||||
if len(authors_str) == 27:
|
||||
authors_str += "..."
|
||||
click.echo(f"{book.id:<4} {book.title[:32]:<35} {authors_str:<30}")
|
||||
@@ -502,7 +502,7 @@ def import_book(
|
||||
fetch_cover=not no_cover,
|
||||
)
|
||||
click.echo(
|
||||
f"Imported book: {book.title} by {', '.join(a.name for a in book.authors)} (ID: {book.id})"
|
||||
f"Imported book: {book.title} by {', '.join(a.name.title() for a in book.authors)} (ID: {book.id})"
|
||||
)
|
||||
except Exception as e:
|
||||
click.echo(f"Error importing book: {e}", err=True)
|
||||
|
||||
@@ -645,13 +645,14 @@ def get_books_by_location(
|
||||
|
||||
|
||||
def _get_or_create_author(name: str) -> Author:
|
||||
"""Get existing author or create a new one."""
|
||||
"""Get existing author or create a new one. Always store as lowercase."""
|
||||
normalized = name.strip().lower()
|
||||
author = db.session.execute(
|
||||
select(Author).filter(Author.name == name)
|
||||
select(Author).filter(Author.name == normalized)
|
||||
).scalar_one_or_none()
|
||||
|
||||
if author is None:
|
||||
author = Author(name=name)
|
||||
author = Author(name=normalized)
|
||||
db.session.add(author)
|
||||
# Don't commit here - let the caller handle the transaction
|
||||
|
||||
@@ -659,13 +660,14 @@ def _get_or_create_author(name: str) -> Author:
|
||||
|
||||
|
||||
def _get_or_create_genre(name: str) -> Genre:
|
||||
"""Get existing genre or create a new one."""
|
||||
"""Get existing genre or create a new one. Always store as lowercase."""
|
||||
normalized = name.strip().lower()
|
||||
genre = db.session.execute(
|
||||
select(Genre).filter(Genre.name == name)
|
||||
select(Genre).filter(Genre.name == normalized)
|
||||
).scalar_one_or_none()
|
||||
|
||||
if genre is None:
|
||||
genre = Genre(name=name)
|
||||
genre = Genre(name=normalized)
|
||||
db.session.add(genre)
|
||||
# Don't commit here - let the caller handle the transaction
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<div class="bg-light p-3 rounded mb-4">
|
||||
<h6 class="fw-bold">{{ book.title }}</h6>
|
||||
{% if book.authors %}
|
||||
<p class="text-muted small mb-1">by {{ book.authors | join(', ') }}</p>
|
||||
<p class="text-muted small mb-1">by {{ book.authors | map('title') | join(', ') }}</p>
|
||||
{% endif %}
|
||||
{% if book.isbn %}
|
||||
<p class="text-muted small mb-0">ISBN: {{ book.isbn }}</p>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
{% if book.authors %}
|
||||
<p class="card-text text-muted small text-truncate mb-2">
|
||||
by {{ book.authors | join(', ') }}
|
||||
by {{ book.authors | map('title') | join(', ') }}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
{% if book.genres %}
|
||||
<div class="mt-1">
|
||||
{% for genre in book.genres[:2] %}
|
||||
<span class="badge bg-light text-dark small me-1">{{ genre }}</span>
|
||||
<span class="badge bg-light text-dark small me-1">{{ genre|title }}</span>
|
||||
{% endfor %}
|
||||
{% if book.genres|length > 2 %}
|
||||
<span class="badge bg-light text-dark small">+{{ book.genres|length - 2 }}</span>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
<div class="col-md-6">
|
||||
<label for="authors" class="form-label">Authors</label>
|
||||
<textarea class="form-control" id="authors" name="authors" rows="2"
|
||||
placeholder="One author per line">{% if book and book.authors %}{{ book.authors | join('\n') }}{% endif %}</textarea>
|
||||
placeholder="One author per line">{% if book and book.authors %}{{ book.authors | map('title') | join('\n') }}{% endif %}</textarea>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="genres" class="form-label">Genres</label>
|
||||
<textarea class="form-control" id="genres" name="genres" rows="2"
|
||||
placeholder="One genre per line">{% if book and book.genres %}{{ book.genres | join('\n') }}{% endif %}</textarea>
|
||||
placeholder="One genre per line">{% if book and book.genres %}{{ book.genres | map('title') | join('\n') }}{% endif %}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -155,12 +155,12 @@
|
||||
};
|
||||
new Tagify(document.querySelector('#genres'), {
|
||||
...commmon_settings,
|
||||
whitelist: {{ genres | map(attribute = 'name') | list | pprint }},
|
||||
whitelist: {{ genres | map(attribute = 'name') | map('title') | list | pprint }},
|
||||
dropdown: { enabled: 0, closeOnSelect: false }
|
||||
});
|
||||
new Tagify(document.querySelector('#authors'), {
|
||||
...commmon_settings,
|
||||
whitelist: {{ authors | map(attribute = 'name') | list | pprint }},
|
||||
whitelist: {{ authors | map(attribute = 'name') | map('title') | list | pprint }},
|
||||
dropdown: { enabled: 0, closeOnSelect: false }
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user