csv-library-website/library/page.py

160 lines
4.7 KiB
Python

"""This is the main flask library page"""
import os
import flask
from requests import get
from icalendar import Calendar
import datetime
import bcrypt
from flask import (
render_template,
redirect,
request,
)
from flask_wtf.csrf import CSRFProtect
from werkzeug.utils import secure_filename
from PIL import Image
from rnrfeed.rnrfeeder import getevents, getlatestevent
from uploadform import PublicationForm
from borrowform import BorrowForm
from csvparser.csvparser import (
getlicenses,
getpublications,
gettypes,
getyears,
getfullpublication,
writepublication,
editborrowedby,
)
csrf = CSRFProtect()
APP = flask.Flask(__name__, static_folder="static")
APP.config["SECRET_KEY"] = "ty4425hk54a21eee5719b9s9df7sdfklx"
APP.config["UPLOAD_FOLDER"] = "tmpupload"
csrf.init_app(APP)
@APP.route("/")
def index():
"""Main route, shows all the books and you can filter them, a bit"""
pubtypes = gettypes()
pubyears = getyears()
publicenses = getlicenses()
publicatons = getpublications()
template = render_template(
"index.html",
publications=publicatons,
pubtypes=pubtypes,
pubyears=pubyears,
publicenses=publicenses,
)
return template
@APP.route("/upload", methods=["GET", "POST"])
def upload():
"""Upload route, a page to upload a book to the csv"""
uploadform = PublicationForm()
if request.method == "POST":
if uploadform.validate_on_submit() and checksecret(
uploadform.secret.data
):
id = writepublication(uploadform)
saveimage(uploadform.image.data, id)
return redirect(str(id), code=303)
else:
return render_template("upload.html", uploadform=uploadform)
print("test")
return render_template("upload.html", uploadform=uploadform)
@APP.route("/<publicationID>", methods=["GET", "POST"])
def show_book(publicationID):
"""route for a single publication, shows full info and allows borrowing"""
fullpublication = getfullpublication(publicationID)
borrowform = BorrowForm()
if request.method == "POST":
if borrowform.validate_on_submit() and checksecret(
borrowform.secret.data
):
editborrowedby(publicationID, borrowform.borrowed.data)
fullpublication["Borrowed"] = borrowform.borrowed.data
return render_template(
"publication.html",
fullpublication=fullpublication,
publicationID=publicationID,
borrowform=borrowform,
)
# return a full publication with or without form errors
return render_template(
"publication.html",
fullpublication=fullpublication,
publicationID=publicationID,
borrowform=borrowform,
)
@APP.route("/pastevents")
def pastevents():
"""show past R&R events and book recommendations"""
events = getevents()
return render_template("pastevents.html", events=events)
@APP.route("/upcoming")
def latestevent():
"""show upcoming or latest R&R events and book recommendations"""
event = getlatestevent()
return render_template("upcomingevent.html", event=event)
@APP.context_processor
def upcoming_or_latest():
"""determines wether the newest R&R event is upcoming or not"""
upcoming = True
ics = get("https://varia.zone/events.ics").text
gcal = Calendar.from_ical(ics)
eventtimes = [
c.get("dtstart").dt
for c in gcal.walk()
if c.name == "VEVENT" and "Read & Repair" in c.get("summary")
]
now = datetime.datetime.now()
eventtimes.sort()
eventtimes.reverse()
if now > eventtimes[0]:
upcoming = False
return dict(upcoming=upcoming)
def saveimage(image, id):
"""helper function that can save images"""
image.save(os.path.join(APP.config["UPLOAD_FOLDER"], image.filename))
orig_image = Image.open(
os.path.join(APP.config["UPLOAD_FOLDER"], image.filename)
)
new_width = 640
new_height = int(new_width * orig_image.height / orig_image.width)
resized_image = orig_image.resize((new_width, new_height), Image.ANTIALIAS)
filename = secure_filename("image-{0}.jpg".format(id))
resized_image.save(os.path.join("static/images/", filename), "JPEG")
os.remove(os.path.join(APP.config["UPLOAD_FOLDER"], image.filename))
def checksecret(secret):
"""small simple check to a secret, library group members can upload"""
with open("secret") as f:
secrethash = f.readline().rstrip()
if bcrypt.checkpw(secret.encode("utf-8"), secrethash.encode("utf-8")):
return True
else:
return False
if __name__ == "__main__":
APP.debug = True
APP.run(port=5000)