Comics can be read

Comics can be opened and read. Thumbnails for each comics are now stored in the database. Some files have been renamed for clarification.
This commit is contained in:
Matthew Welch 2019-07-11 17:35:30 -07:00
parent d3eadee951
commit 2f855db067
12 changed files with 166 additions and 173 deletions

68
app.py
View File

@ -1,9 +1,9 @@
from flask import Flask
from flask import render_template
from flask import request
from flask import g
import threading
from flask import render_template, request, g, redirect, url_for
from urllib import parse
import threading
import base64
import scripts.func as func
from scripts import database
@ -39,7 +39,7 @@ def close_connection(exception):
def update_comic_db(sender, **kw):
try:
database.add_comics(kw["meta"])
database.add_comics(kw["meta"], kw["thumbnails"])
except Exception as e:
print(e)
@ -76,11 +76,17 @@ def comics():
return render_template("publisherList.html", comics=database.get_publishers())
except Exception as e:
print(e)
return "Sucks to be you"
return e
try:
return render_template("publisherView.html", title="Comics", comics=database.get_publishers())
except Exception as e:
print(e)
return e
@app.route("/comics/")
def comic_reroute():
return redirect(url_for("comics"))
@app.route("/comics/<publisher>")
@ -88,10 +94,54 @@ def comics_publisher(publisher):
publisher = parse.unquote(publisher)
series = request.args.get("series")
series_year = request.args.get("seriesYear")
comic = request.args.get("comic")
comic_path = request.args.get("path")
if series:
return render_template("comicView.html", title="Comics", comics=database.db_get_comics_in_series(series, publisher, series_year))
return render_template("seriesView.html", title="Comics", comics=database.db_get_series_by_publisher(publisher))
if comic_path:
comic_path = parse.unquote(comic_path)
return comic_viewer(comic_path, publisher, series, series_year)
return render_template("seriesView.html", title="Comics", publisher=publisher, seriesYear=series_year, comics=database.db_get_comics_in_series(series, publisher, series_year))
return render_template("publisherSeriesView.html", title="Comics", comics=database.db_get_series_by_publisher(publisher))
def comic_viewer(comic_path, publisher, series, series_year):
try:
comic_path_parsed = parse.quote(comic_path)
publisher_parsed = parse.quote(publisher)
series_parsed = parse.quote(series)
page_number = int(request.args.get("pageNumber"))
comic = func.open_comic(comic_path)
page_count = comic.getNumberOfPages()
prev_page = page_number - 1
next_page = page_number + 1
if next_page >= page_count:
next_page = 0
if prev_page < 0:
prev_page = page_count - 1
page = comic.getPage(page_number)
page = str(base64.b64encode(page))[2:-1]
prev_url = "/comics/{}?series={}&seriesYear={}&path={}&pageNumber={}".format(publisher_parsed, series_parsed, series_year, comic_path_parsed, prev_page)
next_url = "/comics/{}?series={}&seriesYear={}&path={}&pageNumber={}".format(publisher_parsed, series_parsed, series_year, comic_path_parsed, next_page)
return render_template("comicView.html", title="Comics", page=page, page_count=page_count, prev_url=prev_url, next_url=next_url)
except Exception as e:
print(e)
return e
@app.route("/comics/getPage")
def get_comic_page():
path = parse.unquote(request.args.get("path"))
page_number = int(request.args.get("pageNumber"))
comic = func.open_comic(path)
if page_number > comic.getNumberOfPages()-1:
page_number = 1
if page_number <= 0:
page_number = comic.getNumberOfPages()-1
page = comic.getPage(page_number)
page = base64.b64encode(page)
return page
if __name__ == '__main__':

View File

@ -60,6 +60,11 @@ def initialize_db():
"role" TEXT,
"name" TEXT,
"primary" INTEGER NOT NULL
)""")
get_db().execute("""CREATE TABLE IF NOT EXISTS "comic_thumbnails" (
"id" INTEGER,
"pageNumber" INTEGER,
"image" BLOB
)""")
get_db().execute("CREATE INDEX IF NOT EXISTS path_index ON comics(path);")
get_db().commit()
@ -73,7 +78,7 @@ def table_exists(table_name):
return True
def add_comics(meta):
def add_comics(meta, thumbnails):
data = []
for info in meta:
issue = IssueString(info[1].issue).asFloat()
@ -84,14 +89,32 @@ def add_comics(meta):
info[1].notes, info[1].webLink, info[1].format, info[1].manga, info[1].blackAndWhite,
info[1].pageCount, info[1].maturityRating, info[1].storyArc, info[1].seriesGroup, info[1].scanInfo,
info[1].characters, info[1].teams, info[1].locations))
get_db().executemany(
"""INSERT into comics(path, tagOrigin, series, issue, issueText, title, publisher,
for comic, images in zip(data, thumbnails):
get_db().execute("""INSERT INTO comics(path, tagOrigin, series, issue, issueText, title, publisher,
month, year, day, seriesYear, issueCount, volume, genre, language, comments, volumeCount,
criticalRating, country, alternateSeries, alternateNumber, alternateCount, imprint,
notes, webLink, format, manga, blackAndWhite, pageCount, maturityRating, storyArc,
seriesGroup, scanInfo, characters, teams, locations)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
data)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", comic)
get_db().commit()
comic_id = get_db().execute("SELECT id from comics ORDER BY id DESC LIMIT 1").fetchone()[0]
for index in range(len(images)):
get_db().execute("INSERT INTO comic_thumbnails(id, pageNumber, image) VALUES (?,?,?)", (comic_id, index, images[index]))
get_db().commit()
def add_comic_thumbnails(thumbnails):
comic_id = 1
row = get_db().execute("SELECT id from comic_thumbnails ORDER BY id DESC LIMIT 1").fetchone()
if row:
comic_id = row[0]+1
print("start comics added:", len(thumbnails))
for images in thumbnails:
print("pages in comic:", len(images))
for index in range(len(images)):
print("comic page added:", index)
get_db().execute("INSERT INTO comic_thumbnails(id, pageNumber, image) VALUES (?,?,?)", (comic_id, index, images[index]))
comic_id += 1
get_db().commit()
@ -120,7 +143,7 @@ def db_get_series_by_publisher(publisher):
def db_get_comics_in_series(series, publisher, series_year):
comics = []
rows = get_db().execute("SELECT series, issue, title FROM comics WHERE series LIKE ? AND publisher LIKE ? AND seriesYear LIKE ? ORDER BY series, issue", [series, publisher, series_year]).fetchall()
rows = get_db().execute("SELECT series, issue, title, path FROM comics WHERE series LIKE ? AND publisher LIKE ? AND seriesYear LIKE ? ORDER BY series, issue", [series, publisher, series_year]).fetchall()
get_db().commit()
for row in rows:
comics.append(row)

View File

@ -1,5 +1,8 @@
from comicapi import comicarchive
from blinker import Namespace
from io import BytesIO
from PIL import Image
import os, sys
from scripts import database
@ -20,21 +23,58 @@ MUSIC_DIRECTORY = "/usb/storage/media/Music/"
def get_comics():
total_comics = 0
comics_in_db = 0
comics_added = 0
meta = []
thumbnails = []
i = 0
for root, dirs, files in os.walk(COMICS_DIRECTORY):
for f in files:
if f.endswith(".cbr"):
total_comics += 1
path = os.path.join(root, f)
if not database.comic_path_in_db(path):
archive = comicarchive.ComicArchive(path, default_image_path="/usb/www/matthew/rpiWebApp/static/icon.png")
try:
test_path = path.encode("utf8")
except Exception as e:
print("encoding failed on:", path)
print(e)
continue
print(path)
archive = open_comic(path)
thumbnails.append(get_comic_thumbnails(archive))
meta.append((path, archive.readCIX()))
comics_added += 1
comics_in_db += 1
i += 1
if i > 20:
comic_loaded.send("anonymous", meta=meta.copy())
if i >= 20:
comic_loaded.send("anonymous", meta=meta.copy(), thumbnails=thumbnails.copy())
meta.clear()
thumbnails.clear()
i = 0
comic_loaded.send("anonymous", meta=meta)
else:
comics_in_db += 1
print("total number of comics:", total_comics)
print("comics in database:", comics_in_db)
print("number of comics added:", comics_added)
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
def get_comic_thumbnails(comic):
thumbnails = []
size = 128, 128
for page in range(comic.getNumberOfPages()):
image_bytes = BytesIO(comic.getPage(page))
image = Image.open(image_bytes)
image.thumbnail(size)
thumbnails.append(image.tobytes())
return thumbnails
def open_comic(path):
archive = comicarchive.ComicArchive(path, default_image_path="/usb/www/matthew/rpiWebApp/static/icon.png")
return archive
def bytestring_path(path):

View File

@ -0,0 +1,3 @@
{% for comic in comics %}
<li><a href="/comics/{{ comic[2]|urlencode }}?series={{ comic[0]|urlencode }}&seriesYear={{ comic[1] }}">{{ comic[0] }} {{ comic[1] }}</a></li>
{% endfor %}

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
<link rel="icon" type="image/png" href="static/icon.png" sizes="32x32">
<link rel="icon" type="image/png" href="../static/icon.png" sizes="32x32">
{% block head %}
{% endblock %}
</head>

View File

@ -1,5 +0,0 @@
{% for comic in comics %}
<li>
{{ comic[0] }} {% if comic[1] > 0 %}{{ "#{0:g}".format(comic[1]) }}{% endif %} {% if comic[2] != None %}{{ comic[2] }} {% endif %}
</li>
{% endfor %}

View File

@ -1,7 +1,9 @@
{% extends "base.html" %}
{% block content %}
<ul id="comics">
{% include "comicList.html" %}
</ul>
<a id="prev-button" href="{{ prev_url }}" style="position: fixed; height: 100%; width: 50%; text-align: center"></a>
<a id="next-button" href="{{ next_url }}" style="position: fixed; right: 0; height: 100%; width: 50%; text-align: center"></a>
<img id="comic-page" src="data:image/jpeg;base64,{{ page }}" alt="" style="height: 100vh; display: block; margin: auto">
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block content %}
<ul id="series">
{% include "PublisherSeriesList.html" %}
</ul>
{% endblock %}

View File

@ -1,26 +1,6 @@
{% extends "base.html" %}
{% block content %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
window.setInterval(function () {
$.ajax({
url: "comics",
type: "get",
data: {polling: true},
success: function(response) {
$("#publishers").html(response);
},
error: function(xhr) {
//Do Something to handle error
}
});
}, 5000);
</script>
<ul id="publishers">
{% include "publisherList.html" %}
</ul>

View File

@ -1,3 +1,7 @@
{% for comic in comics %}
<li><a href="/comics/{{ comic[2]|urlencode }}?series={{ comic[0]|urlencode }}&seriesYear={{ comic[1] }}">{{ comic[0] }} {{ comic[1] }}</a></li>
<li>
<a href="/comics/{{ publisher|urlencode }}?series={{ comic[0]|urlencode }}&seriesYear={{ seriesYear }}&path={{ comic[3]|urlencode }}&pageNumber=0">
{{ comic[0] }} {% if comic[1] > 0 %}{{ "#{0:g}".format(comic[1]) }}{% endif %} {% if comic[2] != None %}{{ comic[2] }} {% endif %}
</a>
</li>
{% endfor %}

View File

@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block content %}
<ul id="series">
<ul id="comics">
{% include "seriesList.html" %}
</ul>
{% endblock %}

135
test.py
View File

@ -5,138 +5,27 @@ import sqlite3
from comicapi import comicarchive
from comicapi.issuestring import IssueString
from urllib import parse
from io import BytesIO
from PIL import Image
os.environ["UNRAR_LIB_PATH"] = 'C:\\Program Files (x86)\\UnrarDLL\\UnRAR.dll'
COMICS_DIRECTORY = "F:\\comics"
print(b'\xE2\x80\x93'.decode("utf-8", "replace"))
#os._exit(0)
def get_comics():
meta = []
i = 0
for root, dirs, files in os.walk(COMICS_DIRECTORY):
for f in files:
if f.endswith(".cbr"):
path = os.path.join(root, f)
print(path)
if not og_comic_path_in_db(path):
archive = comicarchive.ComicArchive(path, default_image_path="C:\\Users\\Matthew\\Documents\\MyPrograms\\Websites\\rpi web interface\\rpiWebApp\\static\\icon.png")
meta.append((path, archive.readCIX()))
return meta
'''
thread = threading.Thread(target=get_comics, args=())
thread.daemon = True
print('start')
thread.start()
time.sleep(3)'''
DATABASE = "C:\\Users\\Matthew\\Documents\\MyPrograms\\Websites\\rpi web interface\\database.db"
db = sqlite3.connect(DATABASE)
def get_db():
global db
return db
def initialize_db():
get_db().execute("""CREATE TABLE IF NOT EXISTS "comics" (
"path" TEXT UNIQUE,
"tagOrigin" TEXT,
"series" TEXT,
"issue" REAL,
"issueText" TEXT,
"title" TEXT,
"publisher" TEXT,
"month" INTEGER,
"year" INTEGER,
"day" INTEGER,
"issueCount" INTEGER,
"volume" TEXT,
"genre" TEXT,
"language" TEXT,
"comments" TEXT,
"volumeCount" INTEGER,
"criticalRating" TEXT,
"country" TEXT,
"alternateSeries" TEXT,
"alternateNumber" TEXT,
"alternateCount" INTEGER,
"imprint" TEXT,
"notes" TEXT,
"webLink" TEXT,
"format" TEXT,
"manga" TEXT,
"blackAndWhite" TEXT,
"pageCount" TEXT,
"maturityRating" TEXT,
"storyArc" TEXT,
"seriesGroup" TEXT,
"scanInfo" TEXT,
"characters" TEXT,
"teams" TEXT,
"locations" TEXT,
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE
)""")
get_db().execute("""CREATE TABLE IF NOT EXISTS "credits" (
"id" INTEGER NOT NULL,
"role" TEXT,
"name" TEXT,
"primary" INTEGER NOT NULL
)""")
get_db().execute("CREATE INDEX IF NOT EXISTS path_index ON comics(path);")
get_db().commit()
row_id = 1
comic_id = 0
for row in get_db().execute("SELECT pageNumber, ROWID FROM comic_thumbnails ORDER BY ROWID").fetchall():
print("ROWID:", row[1])
if row[0] == 0:
comic_id += 1
print("comic id:", comic_id)
def add_comics(meta):
data = []
for info in meta:
issue = IssueString(info[1].issue).asFloat()
data.append((info[0], info[1].tagOrigin, info[1].series, (issue or -1), info[1].issue, info[1].title, info[1].publisher,
info[1].month, info[1].year, info[1].day, info[1].issueCount, info[1].volume, info[1].genre,
info[1].language, info[1].comments, info[1].volumeCount, info[1].criticalRating, info[1].country,
info[1].alternateSeries, info[1].alternateNumber, info[1].alternateCount, info[1].imprint,
info[1].notes, info[1].webLink, info[1].format, info[1].manga, info[1].blackAndWhite,
info[1].pageCount, info[1].maturityRating, info[1].storyArc, info[1].seriesGroup, info[1].scanInfo,
info[1].characters, info[1].teams, info[1].locations))
get_db().executemany(
"""INSERT into comics(path, tagOrigin, series, issue, issueText, title, publisher,
month, year, day, issueCount, volume, genre, language, comments, volumeCount,
criticalRating, country, alternateSeries, alternateNumber, alternateCount, imprint,
notes, webLink, format, manga, blackAndWhite, pageCount, maturityRating, storyArc,
seriesGroup, scanInfo, characters, teams, locations)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
data)
get_db().commit()
def og_comic_path_in_db(path):
result = get_db().execute("SELECT EXISTS(SELECT * FROM comics WHERE path=?) LIMIT 1;", (path,))
if result.fetchone()[0] == 1:
return True
return False
def comic_path_in_db(path):
result = get_db().execute("SELECT path FROM comics WHERE path LIKE ?", [path.encode("utf8")])
if result.fetchone():
return True
return False
#initialize_db()
#add_comics(get_comics())
#for row in get_db().execute('SELECT * FROM comics ORDER BY series'):
# print(row)
#test_path = "/usb/storage/media/Comics/Marvel/Marvel Super Hero Adventures - Spider-Man Web Designers 2019/Marvel Super Hero Adventures - Spider-Man Web Designers #001 (2019).cbr"
#print(comic_path_in_db(test_path))
get_db().execute("UPDATE comic_thumbnails SET id=? WHERE ROWID=?", (comic_id, row[1]))
row_id += 1
get_db().commit()