#!/wwwhome/home/tjlahton/public_html/cgi-bin/tiea2080/venv/bin/python
# -*- coding: utf-8 -*-
# videovuokrausesimerkki toteutettuna sqlalchemyn ORM-rajapinnalla
# kts. https://docs.sqlalchemy.org/en/latest/orm/tutorial.html
from flask import Flask, session, redirect, url_for, escape, request, Response, render_template
import hashlib
import sys
from functools import wraps
import logging
import os
# sqlalchemy pitää asentaa omaan virtuaaliympäristöön
# pip install SQLAlchemy
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine
from datetime import datetime, date, time
# dateutil pitää asentaa omaan virtuaaliympäristöön
# pip install python-dateutil
import dateutil.parser
logging.basicConfig(filename='flask.log',level=logging.DEBUG)
app = Flask(__name__)
app.debug = True
tietokanta = os.path.abspath('../../../hidden/video')
# alustetaan sqlalchemy
# Käytetään automap-luokkaa, joka alustaa tietokannan rakenteen perusteella
# https://docs.sqlalchemy.org/en/latest/orm/extensions/automap.html
Base = automap_base()
engine = create_engine("sqlite:///" + tietokanta)
Base.prepare(engine, reflect=True)
session = Session(engine)
# Tehdään tauluja vastaavat luokat helpommin käsiteltäviksi
Elokuva = Base.classes.Elokuva
Lajityyppi = Base.classes.Lajityyppi
Vuokraus = Base.classes.Vuokraus
Jasen = Base.classes.Jasen
@app.route('/', methods=['POST','GET'])
def index():
# tavallinen kysely
# https://docs.sqlalchemy.org/en/latest/orm/tutorial.html#querying
jasenet = session.query(Jasen).all()
# tehdään liitos eli kysely kahteen tai useampaan tauluun
# kts. https://docs.sqlalchemy.org/en/latest/orm/tutorial.html#querying-with-joins
elokuvat = session.query(Elokuva).join(Lajityyppi).all()
flash = ""
if request.form.get("vuokraa", None): # jos on valittu vuokraa-painike
lisattavat = request.form.getlist("elokuva") # Palauttaa kaikki arvot listana
jasen = request.form.get("jasen", -1)
# Lisäys kaatuu jos yritetään vuokrata sama elokuva samalle henkilölle useammin kuin kerran
# täytyy tehdä silmukassa koska voidaan valita useampi elokuva
for e in lisattavat:
# Tämä laitettava varalta try..exceptin sisään
# päivämäärien on oltava python Date-objekteja
try:
uusi = Vuokraus(JasenID=jasen, ElokuvaID=e, PalautusPVM=date(2019,03,10), VuokrausPVM=date.today())
session.add(uusi)
session.commit()
except:
flash = u"Vuokraus epäonnistui"
session.rollback()
if request.form.get("palauta", None): # valittu palauta-painike
# tehdään poisto (delete)
# kts. https://docs.sqlalchemy.org/en/latest/orm/tutorial.html#deleting
palautettavat = request.form.getlist("vuokrattu")
for p in palautettavat:
tiedot = p.split("|") # palauttaa tuplen jossa kaksi alkiota
# cur.execute(delete_sql, {"jasen":tiedot[1], "elokuva":tiedot[0]})
session.query(Vuokraus).filter_by(JasenID=tiedot[1], ElokuvaID=tiedot[0]).delete()
session.commit()
# tehdään liitos eli kysely kahteen tai useampaan tauluun
# kts. https://docs.sqlalchemy.org/en/latest/orm/tutorial.html#querying-with-joins
vuokratut = session.query(Vuokraus).join(Elokuva).join(Jasen).all()
return render_template('video.html', elokuvat=elokuvat, vuokratut=vuokratut, jasenet=jasenet, flash=flash)
@app.route('/vuokraus//', methods=['POST','GET'])
def vuokraus(jasen, elokuva):
pvm = request.form.get("pvm", None)
if pvm:
# tehdään päivitys
# Kts. https://docs.sqlalchemy.org/en/latest/orm/tutorial.html#adding-and-updating-objects
# kaatuu, jos syötetään vääränlainen pvm. Lisättävä try..except
session.query(Vuokraus).filter_by(JasenID=jasen, ElokuvaID=elokuva).update( {"PalautusPVM":dateutil.parser.parse(pvm)} )
session.commit()
return redirect(url_for('index'))
vuokraus = session.query(Vuokraus).filter_by(JasenID=jasen, ElokuvaID=elokuva).join(Elokuva).join(Jasen).first()
return render_template('vuokraus.html', vuokraus=vuokraus)
if __name__ == '__main__':
app.debug = True
app.run(debug=True)