Added pagination.

Pagination has been added so that the amount of items on each page is a reasonable amount.
This commit is contained in:
Matthew Welch 2019-07-25 00:02:54 -07:00
parent 308b1e1791
commit 2cd339f731
32 changed files with 369 additions and 76 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
/.idea
/__pycache__
__pycache__

View File

@ -17,16 +17,30 @@ MOBILE_DEVICES = ["android", "blackberry", "ipad", "iphone"]
@login_required
def index():
try:
return render_template("comics/index.html", title="Comics", publishers=database.get_publishers())
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publishers = database.get_publishers()
start = (max_items*(page-1))
end = len(publishers) if len(publishers) < max_items*page else max_items*page
return render_template("comics/index.html", title="Comics", publishers=publishers, page=page, max_items=max_items, start=start, end=end, item_count=len(publishers))
except Exception as e:
print(e)
return str(e)
print(type(e), e)
return str(type(e)) + " " + str(e)
@Comics.route("/comics/search")
@login_required
def search():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publisher_end = 0
series_end = 0
comics_end = 0
publisher_start = 0
series_start = 0
comics_start = 0
item_count = 0
query = request.args.get("q")
results = {
"publisher": [],
@ -35,8 +49,23 @@ def search():
}
if query:
results = database.db_search_comics(query)
return render_template("comics/search.html", title="Comics: Search",
publishers=results["publisher"], publisher_series=results["series"], comics=results["comics"])
item_count = len(results["publisher"]) + len(results["series"]) + len(results["comics"])
for temp_page in range(1, page+1):
publisher_start = publisher_end
series_start = series_end
comics_start = comics_end
items = 0
publisher_end = len(results["publisher"]) if len(results["publisher"]) < max_items*temp_page else max_items*temp_page
items += publisher_end - publisher_start
if items < max_items:
series_end = len(results["series"]) if len(results["series"]) < (max_items*temp_page)-items else (max_items*temp_page)-items
items += series_end-series_start
if items < max_items:
comics_end = len(results["comics"]) if len(results["comics"]) < (max_items*temp_page)-series_end-publisher_end else (max_items*temp_page)-series_end-publisher_end
return render_template("comics/search.html", title="Comics: Search", publishers=results["publisher"], publisher_series=results["series"],
comics=results["comics"], page=page, max_items=max_items, item_count=item_count,
publisher_start=publisher_start, series_start=series_start, comics_start=comics_start,
publisher_end=publisher_end, series_end=series_end, comics_end=comics_end)
except Exception as e:
print(type(e), e)
return str(type(e))+" "+str(e)
@ -45,20 +74,32 @@ def search():
@Comics.route("/comics/<publisher>")
@login_required
def comics_publisher(publisher):
publisher = parse.unquote(publisher)
series = request.args.get("series")
series_year = request.args.get("seriesYear")
issue = request.args.get("issue")
page_number = request.args.get("pageNumber")
if series:
if issue:
if page_number:
return comic_viewer(publisher, series, series_year, issue)
return comic_gallery(publisher, series, series_year, issue)
return render_template("comics/seriesView.html", title="Comics",
comics=database.db_get_comics_in_series(series, publisher, series_year))
return render_template("comics/publisherSeriesView.html", title="Comics",
publisher_series=database.db_get_series_by_publisher(publisher))
try:
publisher = parse.unquote(publisher)
series = request.args.get("series")
series_year = request.args.get("seriesYear")
issue = request.args.get("issue")
page_number = request.args.get("pageNumber")
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publisher_series = database.db_get_series_by_publisher(publisher)
start = (max_items*(page-1))
end = len(publisher_series) if len(publisher_series) < max_items*page else max_items*page
if series:
comics = database.db_get_comics_in_series(series, publisher, series_year)
start = (max_items * (page - 1))
end = len(comics) if len(comics) < max_items * page else max_items * page
if issue:
if page_number:
return comic_viewer(publisher, series, series_year, issue)
return comic_gallery(publisher, series, series_year, issue)
return render_template("comics/seriesView.html", title="Comics", comics=comics,
start=start, end=end, page=page, max_items=max_items, item_count=len(comics))
return render_template("comics/publisherSeriesView.html", title="Comics", publisher_series=publisher_series,
start=start, end=end, page=page, max_items=max_items, item_count=len(publisher_series))
except Exception as e:
print(type(e), e)
return str(type(e)) + " " + str(e)
def comic_viewer(publisher, series, series_year, issue):
@ -83,17 +124,21 @@ def comic_viewer(publisher, series, series_year, issue):
title = "Comics: "+meta["series"]+": #"+meta["issueText"]+" "+(meta["title"] or "")
return render_template("comics/comicView.html", title=title, on_mobile=on_mobile, prev_url=prev_url, next_url=next_url, comic=meta, page_number=page_number)
except Exception as e:
print(e)
return str(e)
print(type(e), e)
return str(type(e)) + " " + str(e)
def comic_gallery(publisher, series, series_year, issue):
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
meta = database.db_get_comic(publisher, series, series_year, issue)
return render_template("comics/comicGallery.html", title="Comics", comic=meta)
start = (max_items*(page-1))
end = meta["pageCount"] if meta["pageCount"] < max_items*page else max_items*page
return render_template("comics/comicGallery.html", title="Comics", comic=meta, start=start, end=end, page=page, max_items=max_items, item_count=meta["pageCount"])
except Exception as e:
print(e)
return str(e)
print(type(e), e)
return str(type(e)) + " " + str(e)
@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>")

View File

@ -1,10 +1,10 @@
{% for comic in publisher_series %}
{% for i in range(start, end) %}
<div class="col-3" style="padding: 10px">
<a href="/comics/{{ comic["publisher"]|urlencode }}?series={{ comic["series"]|urlencode }}&seriesYear={{ comic["seriesYear"] }}">
<a href="/comics/{{ publisher_series[i]["publisher"]|urlencode }}?series={{ publisher_series[i]["series"]|urlencode }}&seriesYear={{ publisher_series[i]["seriesYear"] }}">
<div class="card">
<img class="card-img" src="/comics/get_comic/{{ comic['id'] }}/0/thumbnail">
<img class="card-img" src="/comics/get_comic/{{ publisher_series[i]['id'] }}/0/thumbnail">
<div class="card-body">
{{ comic["series"] }} {{ comic["seriesYear"] }}
{{ publisher_series[i]["series"] }} {{ publisher_series[i]["seriesYear"] }}
</div>
</div>
</a>

View File

@ -1,9 +1,12 @@
{% extends "base.html" %}
{% block content %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div style="text-align: center">
<div class="comic-grid">
{% for page_number in range(comic["pageCount"]|int) %}
{% for page_number in range(start, end) %}
<div style="margin: auto" class="comic-thumbnail card bg-dark text-white">
<a href="/comics/{{ comic["publisher"]|urlencode }}?series={{ comic["series"]|urlencode }}&seriesYear={{ comic["seriesYear"] }}&issue={{ comic["issue"]|urlencode }}&pageNumber={{ page_number }}">
<img src="/comics/get_comic/{{ comic["id"] }}/{{ page_number }}/thumbnail" alt="" style="display: inline">
@ -13,4 +16,7 @@
{% endfor %}
</div>
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}

View File

@ -36,3 +36,5 @@
</script>
{% endblock %}
{% block footer %}{% endblock %}

View File

@ -5,9 +5,15 @@
{% endblock %}
{% block content %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-7">
<div class="row justify-content-start">
{% include "comics/publisherList.html" %}
</div>
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}

View File

@ -1,10 +1,10 @@
{% for publisher in publishers %}
{% for i in range(start, end) %}
<div class="col-4" style="padding: 10px">
<a href="/comics/{{ publisher }}">
<a href="/comics/{{ publishers[i] }}">
<div class="card">
<img class="card-img" src="/static/images/{{ publisher }}.png">
<img class="card-img" src="/static/images/{{ publishers[i] }}.png">
<div class="card-body">
{{ publisher }}
{{ publishers[i] }}
</div>
</div>
</a>

View File

@ -1,9 +1,15 @@
{% extends "base.html" %}
{% block content %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-7">
<div class="row justify-content-start">
{% include "comics/PublisherSeriesList.html" %}
</div>
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}

View File

@ -13,24 +13,42 @@
{% endblock %}
{% block content %}
<div class="container col-7">
{% if publishers != [] %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-7">
{% with %}
{% set end=publisher_end %}
{% set start=publisher_start %}
{% if publishers != [] and start != end %}
<h1>Publishers</h1>
<div class="row justify-content-start">
{% include "comics/publisherList.html" %}
</div>
{% endif %}
{% if publisher_series != [] %}
<div class="row justify-content-start">
{% include "comics/publisherList.html" %}
</div>
{% endif %}
{% endwith %}
{% with %}
{% set end=series_end %}
{% set start=series_start %}
{% if publisher_series != [] and start != end %}
<h1>Series</h1>
<div class="row justify-content-start">
{% include "comics/PublisherSeriesList.html" %}
</div>
{% endif %}
{% if comics != [] %}
<div class="row justify-content-start">
{% include "comics/PublisherSeriesList.html" %}
</div>
{% endif %}
{% endwith %}
{% with %}
{% set end=comics_end %}
{% set start=comics_start %}
{% if comics != [] and start != end %}
<h1>Comics</h1>
<div class="row justify-content-start">
{% include "comics/seriesList.html" %}
</div>
{% endif %}
<div class="row justify-content-start">
{% include "comics/seriesList.html" %}
</div>
{% endif %}
{% endwith %}
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}

View File

@ -1,10 +1,10 @@
{% for comic in comics %}
{% for i in range(start, end) %}
<div class="col-3" style="padding: 10px">
<a href="/comics/{{ comic["publisher"]|urlencode }}?series={{ comic["series"]|urlencode }}&seriesYear={{ comic["seriesYear"] }}&issue={{ comic["issue"]|urlencode }}">
<a href="/comics/{{ comics[i]["publisher"]|urlencode }}?series={{ comics[i]["series"]|urlencode }}&seriesYear={{ comics[i]["seriesYear"] }}&issue={{ comics[i]["issue"]|urlencode }}">
<div class="card">
<img class="card-img" src="/comics/get_comic/{{ comic['id'] }}/0/thumbnail">
<img class="card-img" src="/comics/get_comic/{{ comics[i]['id'] }}/0/thumbnail">
<div class="card-body">
{{ comic["series"] }} {% if comic["issue"] > 0 %}{{ "#{0:g}".format(comic["issue"]) }}{% endif %} {% if comic["title"] != None %}{{ comic["title"] }} {% endif %}
{{ comics[i]["series"] }} {% if comics[i]["issue"] > 0 %}{{ "#{0:g}".format(comics[i]["issue"]) }}{% endif %} {% if comics[i]["title"] != None %}{{ comics[i]["title"] }} {% endif %}
</div>
</div>
</a>

View File

@ -1,9 +1,15 @@
{% extends "base.html" %}
{% block content %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-7">
<div class="row justify-content-start">
{% include "comics/seriesList.html" %}
</div>
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}

View File

@ -14,7 +14,36 @@ Movies = Blueprint("movies", __name__, template_folder="templates")
@Movies.route("/movies")
@login_required
def index():
return render_template("movies/index.html", title="Movies", movies=database.db_get_all_movies())
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
movies = database.db_get_all_movies()
start = (max_items*(page-1))
end = len(movies) if len(movies) < max_items*page else max_items*page
return render_template("movies/index.html", title="Movies", movies=movies, page=page, max_items=max_items, start=start, end=end, item_count=len(movies))
except Exception as e:
print(type(e), e)
return str(type(e)) + " " + str(e)
@Movies.route("/movies/search")
@login_required
def search():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
start = 0
end = 0
query = request.args.get("q")
results = []
if query:
results = database.db_search_movies(query)
start = (max_items*(page-1))
end = len(results) if len(results) < max_items*page else max_items*page
return render_template("movies/search.html", title="Movies", movies=results, page=page, max_items=max_items, start=start, end=end, item_count=len(results))
except Exception as e:
print(type(e), e)
return str(type(e)) + " " + str(e)
@Movies.route("/movies/<imdb_id>")
@ -24,8 +53,8 @@ def movie_view(imdb_id):
movie_data = database.db_get_movie_by_imdb_id(imdb_id)
return render_template("movies/movieViewer.html", title="Movies: " + movie_data["title"], movie=movie_data)
except Exception as e:
print(e)
return str(e)
print(type(e), e)
return str(type(e)) + " " + str(e)
@Movies.route("/movies/<imdb_id>/extended")
@ -35,8 +64,8 @@ def movie_view_extended(imdb_id):
movie_data = database.db_get_movie_by_imdb_id(imdb_id, extended=1)
return render_template("movies/movieViewer.html", title="Movies: " + movie_data["title"], movie=movie_data)
except Exception as e:
print(e)
return str(e)
print(type(e), e)
return str(type(e)) + " " + str(e)
@Movies.route("/movies/<imdb_id>/directors_cut")
@ -46,8 +75,8 @@ def movie_view_directors_cut(imdb_id):
movie_data = database.db_get_movie_by_imdb_id(imdb_id, directors_cut=1)
return render_template("movies/movieViewer.html", title="Movies: " + movie_data["title"], movie=movie_data)
except Exception as e:
print(e)
return str(e)
print(type(e), e)
return str(type(e)) + " " + str(e)
@Movies.route("/movies/get_movie/<imdb_id>")

View File

@ -1,16 +1,26 @@
{% extends "base.html" %}
{% block nav %}
<a class="btn btn-primary" href="{{ url_for("movies.search") }}" style="position: fixed; margin: 5px; right: 10px">Search</a>
{% endblock %}
{% block content %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-7">
<div class="row justify-content-start">
{% include "movies/moviesList.html" %}
</div>
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}
{% block footer %}
{% block footer_content %}
<div class="container">
<img src="/static/svg/tmdb.svg" alt="" style="height: 40px;">
<p>This product uses the TMDb API but is not endorsed or certified by TMDb.</p>
</div>
{% endblock %}
{% endblock footer_content %}

View File

@ -14,3 +14,10 @@
<p style="text-align: left">{{ movie["description"] }}</p>
</div>
{% endblock %}
{% block footer_content %}
<div class="container">
<img src="/static/svg/tmdb.svg" alt="" style="height: 40px;">
<p>This product uses the TMDb API but is not endorsed or certified by TMDb.</p>
</div>
{% endblock footer_content %}

View File

@ -1,10 +1,10 @@
{% for movie in movies %}
{% for i in range(start, end) %}
<div class="col-4" style="padding: 10px">
<a href="/movies/{{ movie["imdb_id"] }}{% if movie["extended"] == 1 %}/extended{% endif %}{% if movie["directors_cut"]==1 %}/directors_cut{% endif %}">
<a href="/movies/{{ movies[i]["imdb_id"] }}{% if movies[i]["extended"] == 1 %}/extended{% endif %}{% if movies[i]["directors_cut"]==1 %}/directors_cut{% endif %}">
<div class="card">
<img class="card-img" src="https://image.tmdb.org/t/p/original{{ movie["poster_path"] }}" alt="">
<img class="card-img" src="https://image.tmdb.org/t/p/original{{ movies[i]["poster_path"] }}" alt="">
<div class="card-body">
{{ movie["title"] }}
{{ movies[i]["title"] }} ({{ movies[i]["year"] }})
</div>
</div>
</a>

View File

@ -0,0 +1,38 @@
{% extends "base.html" %}
{% block nav %}
<nav class="navbar navbar-expand">
<ul class="navbar-nav mr-auto"></ul>
<form class="form-inline" method="get" action="">
<div class="form-group mx-2">
<input type="text" class="form-control" minlength="3" name="q">
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
</nav>
{% endblock %}
{% block content %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-7">
{% if movies != [] %}
<div class="row justify-content-start">
{% include "movies/moviesList.html" %}
</div>
{% else %}
<h1>No results.</h1>
{% endif %}
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}
{% block footer_content %}
<div class="container">
<img src="/static/svg/tmdb.svg" alt="" style="height: 40px;">
<p>This product uses the TMDb API but is not endorsed or certified by TMDb.</p>
</div>
{% endblock footer_content %}

View File

@ -1,7 +1,10 @@
from flask import Flask
from flask import g
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from io import BytesIO
from wand.image import Image
import sqlite3
import os, time
@ -338,6 +341,52 @@ def db_search_comics(query):
return {"publisher": publishers, "series": series, "comics": comics}
def db_search_movies(query):
results = db_search_table_columns_by_query(query, "movies", ["title", "year", "description"], order="title")
movies = []
for movie in results["title"]:
if movie not in movies:
movies.append(movie)
for movie in results["description"]:
if movie not in movies:
movies.append(movie)
for movie in results["year"]:
if movie not in movies:
movies.append(movie)
return movies
def resize_image(image, new_width=256, new_height=256):
new_image = image
orig_height = new_image.height
orig_width = new_image.width
if orig_height >= orig_width:
width = int((orig_width / orig_height) * new_height)
height = new_height
else:
height = int((orig_height / orig_width) * new_width)
width = new_width
new_image.thumbnail(width, height)
return new_image
def fix_thumbnails():
new_height = 256
new_width = 256
print("Start fix thumbnail size")
rows = get_db().execute("SELECT * FROM comic_thumbnails")
print("got list of all thumbnails\n")
for row in rows:
image = Image(file=BytesIO(row["image"]))
if image.width > new_width or image.height > new_height:
print("id:", row["id"], "pageNumber:", row["pageNumber"])
get_db().execute("UPDATE comic_thumbnails SET image=? WHERE id=? AND pageNumber=?",
[resize_image(image, new_width, new_height).make_blob(), row["id"], row["pageNumber"]])
get_db().commit()
print("Finished fix thumbnail size")
def get_user(username):
user_data = get_db().execute("SELECT * FROM users WHERE username=?", [username]).fetchone()
if user_data:

View File

@ -0,0 +1,46 @@
from io import BytesIO
from wand.image import Image
import sqlite3, os
RPI_DATABASE = "/var/lib/rpiWebApp/database.db"
MC_DATABASE = "***REMOVED***"
DATABASE = RPI_DATABASE if os.path.exists(RPI_DATABASE) else MC_DATABASE
db = sqlite3.connect(DATABASE)
db.row_factory = sqlite3.Row
def resize_image(image, new_width=256, new_height=256):
new_image = image
orig_height = new_image.height
orig_width = new_image.width
if orig_height >= orig_width:
width = int((orig_width/orig_height) * new_height)
height = new_height
else:
height = int((orig_height/orig_width) * new_width)
width = new_width
new_image.thumbnail(width, height)
return new_image
def fix_thumbnails():
new_height = 256
new_width = 256
print("Start fix thumbnail size")
rows = db.execute("SELECT * FROM comic_thumbnails")
print("got list of all thumbnails\n")
for row in rows:
image = Image(file=BytesIO(row["image"]))
if image.width > new_width or image.height > new_height:
print("id:", row["id"], "pageNumber:", row["pageNumber"])
db.execute("UPDATE comic_thumbnails SET image=? WHERE id=? AND pageNumber=?", [resize_image(image, new_width, new_height).make_blob(), row["id"], row["pageNumber"]])
db.commit()
fix_thumbnails()

View File

@ -39,6 +39,8 @@ def get_comics():
i = 0
for root, dirs, files in os.walk(COMICS_DIRECTORY):
for f in files:
if "temp" in root:
continue
if f.endswith(".cbr"):
total_comics += 1
path = os.path.join(root, f)
@ -98,7 +100,7 @@ def get_comic_thumbnails(comic):
image = Image(file=image_bytes)
orig_height = image.height
orig_width = image.width
if (orig_width/orig_height)*new_height <= new_width:
if orig_height >= orig_width:
width = int((orig_width/orig_height) * new_height)
height = new_height
else:
@ -116,7 +118,7 @@ def open_comic(path):
def get_movies():
print("start load movies")
pattern = r"(.+)( \(....\))(\(extended\))?(\(Director's Cut\))?(\.mkv)"
pattern = r"(.+)( \(....\))(\(extended\))?( Director's Cut)?(\.mkv)"
movies = []
total_movies = 0
movies_in_db = 0
@ -124,11 +126,13 @@ def get_movies():
for root, dirs, files in os.walk(MOVIES_DIRECTORY):
for f in files:
if f.endswith(".mkv"):
total_movies += 1
path = os.path.join(root, f)
if not database.movie_path_in_db(path):
try:
match = re.fullmatch(pattern, f)
if not match:
print(f, "did not match regex.")
continue
print("movie path:", path)
title = f[:-4].replace(match.group(2), "")
@ -158,6 +162,7 @@ def get_movies():
description = tmdb_data[1]
poster_path = tmdb_data[2]
backdrop_path = tmdb_data[3]
movies_added += 1
movies.append((path, imdb_id, tmdb_id, title, year, length, description, extended, directors_cut, poster_path, backdrop_path))
if len(movies) >= 20:
@ -165,6 +170,7 @@ def get_movies():
movies.clear()
except Exception as e:
print(e)
movies_in_db += 1
movie_loaded.send("anonymous", movies=movies)
print("finish load movies")
print("total movies:", total_movies)

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -57,9 +57,11 @@
{% endblock %}
</div>
<footer class="bg-secondary" style="flex-shrink: 0; padding: 20px;">
{% block footer %}
{% endblock %}
</footer>
<footer class="bg-secondary" style="flex-shrink: 0; padding: 20px;">
{% block footer_content %}
{% endblock footer_content %}
</footer>
{% endblock footer %}
</body>
</html>

18
templates/pagination.html Normal file
View File

@ -0,0 +1,18 @@
{% with page_count=(item_count/max_items)|round(method="ceil")|int %}
{% if page_count > 1 %}
<nav aria-label="Page navigation example" style="display: inline-block; margin: 5px">
<form method="get" action="">
{% for key in request.args.keys() %}
{% if key != "page" %}<input type="hidden" name="{{ key }}" value="{{ request.args.get(key) }}">{% endif %}
{% endfor %}
<ul class="pagination">
{% for i in range(1, page_count+1) %}
<li class="page-item{% if page == i %} active{% endif %}">
<button name="page" value="{{ i }}" class="page-link">{{ i }}</button>
</li>
{% endfor %}
</ul>
</form>
</nav>
{% endif %}
{% endwith %}

View File

@ -10,10 +10,9 @@ from PIL import Image
import datetime, pytz
from werkzeug.security import generate_password_hash
os.environ["UNRAR_LIB_PATH"] = "C:\\Program Files (x86)\\UnrarDLL\\UnRAR.dll"
from scripts import database
DATABASE = "***REMOVED***"
db = sqlite3.connect(DATABASE)
db = sqlite3.connect(database.DATABASE)
db.row_factory = sqlite3.Row
@ -74,7 +73,7 @@ def db_search_comics(query):
return {"publishers": publishers, "series": series, "comics": comics}
results = db_search_comics("ar")
results = db_search_comics("lord")
for key in results.keys():