From 53e7b17e1c852480f4efdae506bfe513649fcc45 Mon Sep 17 00:00:00 2001 From: janko Date: Sun, 27 Aug 2023 18:52:59 +0200 Subject: [PATCH] nov db idiom. funkcije za prikazovanje in importanje linkov --- app.py | 2 +- auth.py | 108 +++++++++++++------------- create_db.py | 44 +++++++++-- deck.py | 10 ++- import_link.py | 94 +++++++++++++++-------- link_handler.py | 44 +++++++---- matches.py | 36 ++++++--- menu.py | 19 +++-- populate_db_once.py | 12 ++- prob_session.py | 123 +++++++++++++++--------------- search_cloud.py | 30 ++++---- settings.py | 61 ++++++++------- share.py | 52 +++++++------ sr_session.py | 179 +++++++++++++++++++++++++------------------- upload.py | 22 ++++-- 15 files changed, 495 insertions(+), 341 deletions(-) diff --git a/app.py b/app.py index 9eff9b9..db5dc8f 100644 --- a/app.py +++ b/app.py @@ -3,11 +3,11 @@ from flask import Flask, redirect, render_template, session, url_for from auth import login_required, bp as auth_bp from deck import bp as deck_bp from menu import bp as menu_bp -from sr_session import sr_session from upload import bp as upload_bp from import_link import bp as import_link_bp from matches import bp as matches_bp from settings import bp as settings_bp +from sr_session import sr_session from config import CONFIG diff --git a/auth.py b/auth.py index c4c4fc0..42b88b8 100644 --- a/auth.py +++ b/auth.py @@ -4,54 +4,56 @@ from flask import ( Blueprint, flash, g, redirect, render_template, request, session, url_for ) from hashlib import md5 -from create_db import User, get_session +from create_db import User, get_session, get_engine from share import get_all_shared bp = Blueprint('auth', __name__, url_prefix='/auth') @bp.route('/register', methods=('GET', 'POST')) def register(): - dbsession = get_session() - if request.method == 'POST': - username = request.form['username'] - password = request.form['password'] - mail = request.form['email'] - error = None + Session = get_session() + with Session() as dbsession: + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + mail = request.form['email'] + error = None - #@TODO check if this really is an email. - if not username: - error = 'Username is required.' - elif not password: - error = 'Password is required.' - elif not mail: - error = 'Please enter your email adress.' - elif dbsession.query(User).filter(User.username == username).first() != None: - error = "Username already exists, please choose another one." - elif dbsession.query(User).filter(User.email == mail).first() != None: - error = "This email adress is already in use, please choose another one." + #@TODO check if this really is an email. + if not username: + error = 'Username is required.' + elif not password: + error = 'Password is required.' + elif not mail: + error = 'Please enter your email adress.' + elif dbsession.query(User).filter(User.username == username).first() != None: + error = "Username already exists, please choose another one." + elif dbsession.query(User).filter(User.email == mail).first() != None: + error = "This email adress is already in use, please choose another one." - if error is None: - try: - user = User(username=username, password=md5(password.encode("utf-8")).hexdigest(), email=mail, settings = "") - dbsession.add(user) - dbsession.commit() + if error is None: + try: + user = User(username=username, password=md5(password.encode("utf-8")).hexdigest(), email=mail, settings = "") + dbsession.add(user) + dbsession.commit() - #Preden zapremo naj user dobi vse shared karte od prej. - new_user = dbsession.query(User).filter(User.username == username).first() - new_user_id = new_user.id - - get_all_shared(new_user_id) + #Preden zapremo naj user dobi vse shared karte od prej. + new_user = dbsession.query(User).filter(User.username == username).first() + new_user_id = new_user.id + + get_all_shared(new_user_id) - dbsession.close() + dbsession.close() - except Exception as e: - error = f"napaka pri registraciji {username} je {e}" - else: - return redirect(url_for("auth.login")) + except Exception as e: + error = f"napaka pri registraciji {username} je {e}" + else: + return redirect(url_for("auth.login")) - flash(error) + flash(error) + get_engine().dispose() return render_template('register.html') @@ -59,26 +61,28 @@ def register(): @bp.route('/login', methods=('GET', 'POST')) def login(): if request.method == 'POST': - dbsession = get_session() - username = request.form['username'] - password = request.form['password'] - error = None - user = dbsession.query(User).filter(User.username == username).first() + Session = get_session() + with Session() as dbsession: + username = request.form['username'] + password = request.form['password'] + error = None + user = dbsession.query(User).filter(User.username == username).first() + + if user is None: + error = 'Incorrect username.' + elif not user.password == md5(password.encode("utf-8")).hexdigest(): #compare input pw has and bd pw hash + + error = 'Incorrect password.' + + if error is None: + session.clear() + session['user_id'] = user.id + session['username'] = user.username + return redirect(url_for("menu.index")) #TODO ne dela + flash(error) - if user is None: - error = 'Incorrect username.' - elif not user.password == md5(password.encode("utf-8")).hexdigest(): #compare input pw has and bd pw hash - - error = 'Incorrect password.' - - if error is None: - session.clear() - session['user_id'] = user.id - session['username'] = user.username - return redirect(url_for("menu.index")) #TODO ne dela - flash(error) - + get_engine().dispose() return render_template('login.html') diff --git a/create_db.py b/create_db.py index 8fe8747..3beb28c 100644 --- a/create_db.py +++ b/create_db.py @@ -47,10 +47,44 @@ class Rating(Base): engine = create_engine(CONFIG['DB_CONNECTION']) -Base.metadata.create_all(engine) + +def create_all(): + Base.metadata.create_all(Engine) + +Engine = create_engine(CONFIG['DB_CONNECTION']) +Session = sessionmaker(Engine) def get_session(): - # Engine je samo enkrat treba inicializirat, se mi zdi. - # engine = create_engine(CONFIG['DB_CONNECTION']) - dbsessionmaker = sessionmaker(bind=engine) - return dbsessionmaker() + return Session + +def get_engine(): + return Engine + + +""" +NAVODILA TODO + +Upravljanje klicev na bazo + Base = declarative_base() + class ImeTabele(Base): + __tablename__ = 'imetabele' + stolpec = Column(Tip, druge lastnosti stolpca) + + def create_all(): + Base.metadata.create_all(Engine) + +Ustvarimo engine in session objekt ter funkciji, ki ju vračata + Engine = create_engine(CONFIG['DB_CONNECTION']) + Session = sessionmaker(Engine) + + def get_session(): + return Session + def get_engine(): + return Engine + +V skripti, ki želi dostopati pa do baze pa klic postavimo v naslednji okvir: + Session = get_session() + with Session() as session: + + get_engine().dispose() +""" \ No newline at end of file diff --git a/deck.py b/deck.py index cde58b5..a718085 100644 --- a/deck.py +++ b/deck.py @@ -3,7 +3,7 @@ from flask import ( Blueprint, g, session ) from auth import login_required -from create_db import Card, User, get_session +from create_db import Card, User, get_session, get_engine from numpy.random import choice @@ -11,8 +11,12 @@ bp = Blueprint('deck', __name__) @bp.route('/deck', methods=['GET']) def get_collection(user_id): - dbsession = get_session() - c = dbsession.query(Card).filter(Card.owner_id == user_id).all() + Session = get_session() + with Session() as dbsession: + c = dbsession.query(Card).filter(Card.owner_id == user_id).all() + dbsession.close() + + get_engine().dispose() return c diff --git a/import_link.py b/import_link.py index bb35de4..6d2f839 100644 --- a/import_link.py +++ b/import_link.py @@ -1,8 +1,11 @@ from flask import ( Blueprint, render_template, request, session, flash ) -from create_db import Card, get_session -from link_handler import check_response +from create_db import Card, get_session, get_engine +from link_handler import check_link +from werkzeug.utils import secure_filename +import tempfile +import os bp = Blueprint('import_link', __name__, url_prefix='/import_link') @@ -19,45 +22,76 @@ def import_link(): username = session['username'] user_id = session['user_id'] if request.method == 'POST': - import_type = request.form.get("import_type", False) - print(import_type) + import_type = request.form.get("import_txt") + print("###########################", import_type) if import_type == "import_txt": - print("!2313232321") + return render_template("import_txt.html", user_id=user_id, username=username) else: - link = request.form.get("link", False) - if check_response(link) == 1: - print(link, 'is ok') - commit_link(link=link, user_id=user_id) - else: - print(link, 'is not ok') + link = request.form.get("import_link", False) + commit_link(link=link, user_id=user_id) return render_template("import_link.html", user_id=user_id, username=username) def commit_link(link, user_id): - dbsession = get_session() - existing_link = dbsession.query(Card).filter_by(owner_id=user_id, item_location=link).first() - if existing_link: - flash(f"{link} has already been imported.") - else: - #add card - #TODO ni razlike med title in vsebino urlja ?? - card = Card(title=link, - interest_rate=-1.0, - owner_id=user_id, - item_location=link, - last_review=None, - card_type="URL", - share_id=0) - dbsession.add(card) - dbsession.commit() - flash(f"{link} imported successfully") + Session = get_session() + with Session() as dbsession: + existing_link = dbsession.query(Card).filter_by(owner_id=user_id, item_location=link).first() + if existing_link: + print(f"{link} has already been imported.") + flash(f"{link} has already been imported.","error") + return -1 + + link_check = check_link(link) + if link_check != 1: + print(link, 'is not ok') + flash(f"{link}, 'is not ok', {link_check}", "rror") + return -1 + else: + print(link, 'is ok') + #add card + #TODO ni razlike med title in vsebino urlja ?? + card = Card(title=link, + interest_rate=-1.0, + owner_id=user_id, + item_location=link, + last_review=None, + card_type="URL", + share_id=0) + dbsession.add(card) + dbsession.commit() + + flash(f"{card.title} imported successfully") + dbsession.close() - dbsession.close() + get_engine().disolve() + return 1 + +@bp.route('/import_txt', methods = ('GET', 'POST')) +def import_link_from_txt(): + user_id = session["user_id"] + username = session["username"] + + #@TODO ta forloop bi lahko flashal postopoma + for txt_file in request.files.getlist("file"): + filename = secure_filename(txt_file.filename) + # Is there really a file? + if not filename: + flash('There is no file. Try again?') + return render_template("upload.html", username=username) + + lines = txt_file.readlines() + links = [line.decode("UTF-8") for line in lines] + import_list_of_links(links, user_id) + + + + return render_template("import_link.html", user_id=user_id, username=username) + def import_list_of_links(list_of_links, user_id): #TODO nekak bi bilo dobro, da pokaže kateri so failali.... for link in list_of_links: - commit_link(link, user_id) \ No newline at end of file + commit_link(link.strip(" ").strip("\n"), user_id) \ No newline at end of file diff --git a/link_handler.py b/link_handler.py index c680bdd..a80fd1f 100644 --- a/link_handler.py +++ b/link_handler.py @@ -3,6 +3,14 @@ import re from flask import render_template from urllib.parse import urlparse +def check_link(link): + parsed_url = urlparse(link) + if parsed_url.scheme and parsed_url.netloc: + return 1 + else: + print("link not valid (https:// missing??)") + return -1 + def check_response(link): """ @@ -10,26 +18,32 @@ def check_response(link): 2 if there's conncetion error 3 if link is invalid (no "http" for example) """ - parsed_url = urlparse(link) - if parsed_url.scheme and parsed_url.netloc: - try: - response = requests.head(link) - if response.status_code == 200: - return 1 - else: - #TODO drugi statusi code? - return "WEIRD" - except requests.exceptions.RequestException: - print("conncetion error") - return 2 - else: - print("link not valid (https:// missing??)") - return 3 + try: + response = requests.head(link) + if response.status_code == 200: + return 1 + else: + #TODO drugi statusi code? + #return "WEIRD", response + #TODO samo za testiranje + return f"Error: {response.status_code}" + except Exception as e: + print(e) + return f"Link error: {e}" # kako vse možne linke embeddat? def render_embed_link(cm_username, card, maybe_in, no_in): url = card.item_location + + response = check_response(url) + if response != 1: + render_template("embed_link/bad_link.html", + card=card, + username=cm_username, + maybe_in=maybe_in, + no_in=no_in) + if re.match(r'^https?://(www\.)?twitter\.com/.*/status/\d+$', url): tweet_id = url.split("/")[-1] return render_template("embed_link/twitter_embed.html", diff --git a/matches.py b/matches.py index a28a892..f07b0ef 100644 --- a/matches.py +++ b/matches.py @@ -3,29 +3,37 @@ from flask import ( ) from requests import get from config import CONFIG -from create_db import Card, User, get_session +from create_db import Card, User, get_session, get_engine bp = Blueprint('matches', __name__, url_prefix='/matches') def get_matches(user_id): #@TODO this is buggy - dbsession = get_session() list_of_matches = [] #in all shared cards for the ones you voted yes - all_cards = dbsession.query(Card) - all_shared_of_user_of_ir_1 = all_cards.filter(Card.share_id != "0", Card.owner_id == user_id, Card.interest_rate == "1").all() + Session = get_session() + with Session() as dbsession: + all_cards = dbsession.query(Card) + all_shared_of_user_of_ir_1 = all_cards.filter(Card.share_id != "0", Card.owner_id == user_id, Card.interest_rate == "1").all() + dbsession.close() + get_engine().dispose() + if all_shared_of_user_of_ir_1 == []: return list_of_matches # see who else voted yes - for c in all_shared_of_user_of_ir_1: - others_yes = all_cards.filter(Card.share_id == c.share_id, Card.interest_rate == "1", Card.owner_id != user_id).all() - if others_yes == []: - pass - else: - list_of_matches.append(others_yes) + Session = get_session() + with Session() as dbsession: + for c in all_shared_of_user_of_ir_1: + others_yes = all_cards.filter(Card.share_id == c.share_id, Card.interest_rate == "1", Card.owner_id != user_id).all() + if others_yes == []: + pass + else: + list_of_matches.append(others_yes) + dbsession.close() + get_engine().dispose() return list_of_matches @@ -35,7 +43,6 @@ def index(): if not 'user_id' in session: redirect(url_for('index')) - dbsession = get_session() user_id = session["user_id"] username = session["username"] @@ -48,7 +55,12 @@ def index(): for card in match: user_ids.append(card.owner_id) - users = dbsession.query(User) + Session = get_session() + with Session() as dbsession: + users = dbsession.query(User).all() + dbsession.close() + get_engine().dispose() + names_by_ids = {} emails_by_ids = {} diff --git a/menu.py b/menu.py index 5a0e9bb..039070a 100644 --- a/menu.py +++ b/menu.py @@ -1,7 +1,7 @@ from flask import ( Blueprint, redirect, render_template, request, session, url_for ) -from create_db import Card, get_session +from create_db import Card, get_session, get_engine from sr_session import schedule_status, remaining_items, list_of_due_cards_by_ids, list_of_new_cards_by_ids, rated_today_by_staus from settings import get_settings from auth import login @@ -10,7 +10,7 @@ bp = Blueprint('menu', __name__, url_prefix='/menu') @bp.route("/", methods=("GET", "POST")) def index(): - dbsession = get_session() + if 'user_id' not in session: return login() @@ -34,11 +34,18 @@ def index(): action = request.form.get("menu", False) #internetna rešitev, nevem kako, ampak dela, tj. dobi info iz meni buttonov if action == "new_session": #preverimo če so sploh karte v collectionu - c = dbsession.query(Card).filter(Card.owner_id == user_id).all() - if c == []: - return render_template("error/no_cards_in_collection.html", username=username) - + Session = get_session() + with Session() as dbsession: + c = dbsession.query(Card).filter(Card.owner_id == user_id).all() + if c == []: + dbsession.close() + return render_template("error/no_cards_in_collection.html", username=username) + dbsession.close() + + get_engine().dispose() return redirect(url_for("deck")) + + elif action == "matches": return redirect(url_for("matches.index")) elif action == "upload": diff --git a/populate_db_once.py b/populate_db_once.py index 304cce3..ab36215 100644 --- a/populate_db_once.py +++ b/populate_db_once.py @@ -1,4 +1,4 @@ -from create_db import Card, get_session +from create_db import Card, get_session, get_engine from config import CONFIG import nextcloud_client @@ -17,6 +17,10 @@ for item in l: public_share = nc.share_file_with_link("/GIA CLOUD/"+name) public_link = public_share.get_link()+"/download/"+name card = Card(title=name, interest_rate=-1.0, owner_id=1, item_location=public_link, last_review=None, share_id="0") - dbsession.add(card) - dbsession.commit() - dbsession.close() \ No newline at end of file + + Session = get_session() + with Session() as dbsession: + dbsession.add(card) + dbsession.commit() + dbsession.close() + get_engine().dispose() \ No newline at end of file diff --git a/prob_session.py b/prob_session.py index b899a5a..1e79213 100644 --- a/prob_session.py +++ b/prob_session.py @@ -1,5 +1,5 @@ from flask import session, redirect, url_for,request, flash, render_template -from create_db import get_session, Deck, Card +from create_db import get_session, Deck, Card, get_engine from share import share """ @@ -9,80 +9,81 @@ rabi še deck funkcionalnosti, ki so bile prej v menu.py itd... """ def prob_session(): - dbsession = get_session() if not 'user_id' in session: redirect(url_for('login')) user_id = session['user_id'] username = session['username'] #pokliče na bazo, da dobi str card idjev, ga spremeni v list in srevira karte po idjih - deck_query = dbsession.query(Deck).filter(Deck.owner_id == user_id) - deck_object = deck_query.filter(Deck.completed == False).first() - # @TODO: ce deck, ne obstaja, kaj naj zaj jas? - if len(deck_object.cards_by_id.split(",")) == 0: - deck_query.filter(Deck) - redirect(url_for('login')) + Session = get_session() + with Session() as dbsession: + deck_query = dbsession.query(Deck).filter(Deck.owner_id == user_id) + deck_object = deck_query.filter(Deck.completed == False).first() + # @TODO: ce deck, ne obstaja, kaj naj zaj jas? + if len(deck_object.cards_by_id.split(",")) == 0: + deck_query.filter(Deck) + redirect(url_for('login')) - # Smo oddali obrazec? - if request.method == 'POST': - card_id = request.form.get('card_id', None) - if not card_id: - raise Exception("card_id je nujen!") + # Smo oddali obrazec? + if request.method == 'POST': + card_id = request.form.get('card_id', None) + if not card_id: + raise Exception("card_id je nujen!") + submit_card = dbsession.query(Card).get(card_id) + # @TODO preveri, ali je card del trenutnega decka! - submit_card = dbsession.query(Card).get(card_id) - # @TODO preveri, ali je card del trenutnega decka! + # Ali damo share? Potem nastavi na share in ponovi obrazec + share_request = request.form.get("share", None) + if share_request: + # @TODO logika za share! + share(submit_card, user_id) - # Ali damo share? Potem nastavi na share in ponovi obrazec - share_request = request.form.get("share", None) - if share_request: - # @TODO logika za share! - share(submit_card, user_id) - - # Če ne, gre za rate! - else: - rate = request.form.get('rate', None) #je to nevarno?? - print(rate) - - if not rate: - raise Exception("manjka rate info!") - - if rate == "Yes": - submit_card.interest_rate = 1 - - elif rate == "Maybe": - k = 0.5 - print(submit_card) - submit_card.interest_rate= abs(submit_card.interest_rate*k) + # Če ne, gre za rate! + else: + rate = request.form.get('rate', None) #je to nevarno?? + print(rate) - elif rate == "No": - k = 0.1 - submit_card.interest_rate = abs(submit_card.interest_rate*k) - - elif rate == "Delete": - submit_card.interest_rate = 0 - #@TODO to bi lahko zbrisalo tudi file v določenih primerih + if not rate: + raise Exception("manjka rate info!") - # zaporedno število trenutnega carda v decku - next_card = deck_object.current_card + 1 + if rate == "Yes": + submit_card.interest_rate = 1 + + elif rate == "Maybe": + k = 0.5 + print(submit_card) + submit_card.interest_rate= abs(submit_card.interest_rate*k) + + elif rate == "No": + k = 0.1 + submit_card.interest_rate = abs(submit_card.interest_rate*k) + + elif rate == "Delete": + submit_card.interest_rate = 0 + #@TODO to bi lahko zbrisalo tudi file v določenih primerih - # Ali je deck končan? - if next_card >= deck_object.number_of_cards: - deck_object.completed = True + # zaporedno število trenutnega carda v decku + next_card = deck_object.current_card + 1 + + # Ali je deck končan? + if next_card >= deck_object.number_of_cards: + deck_object.completed = True + dbsession.commit() + dbsession.close() + flash("Deck rating finished!") + return redirect(url_for("menu.index")) + + deck_object.current_card = next_card dbsession.commit() - dbsession.close() - flash("Deck rating finished!") - return redirect(url_for("menu.index")) - - deck_object.current_card = next_card - dbsession.commit() - - # Loudamo naslednjo karto v decku - show_card_index = deck_object.current_card - show_card_id = deck_object.cards_by_id.split(",")[show_card_index] - print("GET CARD PLS", show_card_id) - show_card = dbsession.query(Card).get(show_card_id) - dbsession.close() + + # Loudamo naslednjo karto v decku + show_card_index = deck_object.current_card + show_card_id = deck_object.cards_by_id.split(",")[show_card_index] + print("GET CARD PLS", show_card_id) + show_card = dbsession.query(Card).get(show_card_id) + dbsession.close() + get_engine().dispose() if not show_card: # @TODO how to handle missing card? diff --git a/search_cloud.py b/search_cloud.py index e939853..2cf98bf 100644 --- a/search_cloud.py +++ b/search_cloud.py @@ -4,27 +4,27 @@ from requests import session from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from config import CONFIG -from create_db import Base, Card +from create_db import Base, Card, get_engine, get_session from get_files import get_file_list -engine = create_engine(CONFIG['DB_CONNECTION']) -Base.metadata.bind = engine -DBSsession = sessionmaker(bind=engine) -session = DBSsession() - l = get_file_list() id = 0 #TODO for title in l: - if title[-4:] == ".pdf": - card = Card( - id=id, - title=title[:-4], - interest_rate=-1, - owner_id = 1 - ) + if title[-4:] != ".pdf": + continue + + card = Card( + id=id, + title=title[:-4], + interest_rate=-1, + owner_id = 1 + ) + id = id+1 + + Session = get_session() + with Session() as dbsession: session.add(card) session.commit() session.close() - - id = id+1 + get_engine().dispose() diff --git a/settings.py b/settings.py index 7d45ca1..46fa8d3 100644 --- a/settings.py +++ b/settings.py @@ -1,41 +1,42 @@ from flask import flash, render_template, Blueprint, request, session -from create_db import User, get_session +from create_db import User, get_session, get_engine import json bp = Blueprint('settings', __name__, url_prefix='/settings') def get_settings(user_id): - dbsession = get_session() """get settings from db, turns it into a dict and returns it""" - - user = dbsession.query(User).get(user_id) - #tu rešujejo none user bug, ki se pojavi, ko na novo reg user, ni zazznan v querryju - # zdaj imamo problem clasha med globalno in lokalno spremenljivko "dbsession" - if user == None: + Session = get_session() + with Session() as dbsession: user = dbsession.query(User).get(user_id) + #tu rešujejo none user bug, ki se pojavi, ko na novo reg user, ni zazznan v querryju + # zdaj imamo problem clasha med globalno in lokalno spremenljivko "dbsession" + if user == None: + user = dbsession.query(User).get(user_id) + + settings_db = user.settings + if settings_db == "": + #userji se zaenkrat generirajo brez settingsov aka empty string, zato dodamo te defaulte + settings_dict = { + "max_new" : 5, + "max_due" : 5, + "max_shared" : 5, + } + else: + settings_dict = json.loads(settings_db) + + dbsession.close() - settings_db = user.settings - if settings_db == "": - #userji se zaenkrat generirajo brez settingsov aka empty string, zato dodamo te defaulte - settings_dict = { - "max_new" : 5, - "max_due" : 5, - "max_shared" : 5, - } - else: - settings_dict = json.loads(settings_db) - - dbsession.close() + get_engine().dispose() return settings_dict @bp.route("/save_settings", methods=["GET", "POST"]) def save_settings(): - dbsession = get_session() - """takes a dict of settings turns it into json and updates the database with it""" + user_id = session['user_id'] username = session['username'] @@ -50,13 +51,15 @@ def save_settings(): "max_due" : request.form.get('max_due', False), "max_shared" : request.form.get('max_shared', False), } - - settings_json = json.dumps(settings_dict) - user = dbsession.query(User).get(user_id) - - user.settings = settings_json - dbsession.commit() - dbsession.close() - flash("settings updated") + Session = get_session() + with Session() as dbsession: + settings_json = json.dumps(settings_dict) + user = dbsession.query(User).get(user_id) + + user.settings = settings_json + dbsession.commit() + dbsession.close() + flash("settings updated") + get_engine().dispose() return render_template("settings.html", username=username, settings=settings_dict) \ No newline at end of file diff --git a/share.py b/share.py index ab138e8..fd26435 100644 --- a/share.py +++ b/share.py @@ -1,42 +1,48 @@ from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from config import CONFIG -from create_db import User, Card, get_session +from create_db import User, Card, get_session, get_engine from hashlib import md5 #@TODO najbrž je treba narediti tako da org card tudi dobi share id in se ostalo, kar to obsega def share(card, user_id): - dbsession = get_session() #tu bi lahko naredili nek autoincrement ampak i guess da hash unique idja tudi daje unique share_id, tega potem uporabljamo, da preverimo matche h = md5(str(card.id).encode("utf-8")).hexdigest() card.share_id = h - owner_card = dbsession.query(Card).filter(Card.id == card.id).first() - owner_card.share_id = h - dbsession.commit() - - # all users - users = dbsession.query(User).filter(User.id != user_id).all() - for user in users: - #skip če že ima ta card v db. - existing = dbsession.query(Card).filter(Card.title == card.title, Card.owner_id==user.id).all() - if existing == []: - new_card = card = Card(title=card.title, interest_rate=-1.0, owner_id=user.id, item_location=card.item_location, last_review=None, share_id=h) - dbsession.add(new_card) - dbsession.commit() + Session = get_session() + with Session() as dbsession: + owner_card = dbsession.query(Card).filter(Card.id == card.id).first() + owner_card.share_id = h + dbsession.commit() + # all users + users = dbsession.query(User).filter(User.id != user_id).all() + for user in users: + #skip če že ima ta card v db. + existing = dbsession.query(Card).filter(Card.title == card.title, Card.owner_id==user.id).all() + if existing == []: + new_card = card = Card(title=card.title, interest_rate=-1.0, owner_id=user.id, item_location=card.item_location, last_review=None, share_id=h) + dbsession.add(new_card) + dbsession.commit() + dbsession.close() + get_engine().dispose() + def get_all_shared(user_id): """adds all existing shared cards to this users collection""" - dbsession = get_session() - #get all cards with a shared id but make suer they are unique. add them to collection of user - #@TODO A je to resres ok? - all_shared_cards = dbsession.query(Card).filter(Card.share_id != "0").distinct(Card.share_id).group_by(Card.share_id) + #@TODO A je to resres ok? + + Session = get_session() + with Session() as dbsession: + all_shared_cards = dbsession.query(Card).filter(Card.share_id != "0").distinct(Card.share_id).group_by(Card.share_id) - for c in all_shared_cards: - new_card = Card(title= c.title, interest_rate=-1.0, owner_id=user_id, item_location=c.item_location, last_review=None, share_id=c.share_id) - dbsession.add(new_card) - dbsession.commit() \ No newline at end of file + for c in all_shared_cards: + new_card = Card(title= c.title, interest_rate=-1.0, owner_id=user_id, item_location=c.item_location, last_review=None, share_id=c.share_id) + dbsession.add(new_card) + dbsession.commit() + dbsession.close() + get_engine().dispose() \ No newline at end of file diff --git a/sr_session.py b/sr_session.py index a829c9d..134b735 100644 --- a/sr_session.py +++ b/sr_session.py @@ -3,7 +3,7 @@ from datetime import date, timedelta from flask import flash, session, redirect, url_for, request, render_template from sqlalchemy import desc from share import share -from create_db import Card, Rating, get_session +from create_db import Card, Rating, get_session, get_engine from settings import get_settings from link_handler import render_embed_link @@ -12,12 +12,15 @@ from link_handler import render_embed_link testing """ def autofill_ratings(): - dbsession = get_session() - for i in range(100): - card = Rating(user_id="1", card_id=choice([10, 13, 14, 75]), rating_value=choice(["Maybe", "No"]), rating_time=date.today()-timedelta(choice([i for i in range(100)]))) - dbsession.add(card) - dbsession.commit() - dbsession.close() + + Session = get_session() + with Session() as dbsession: + for i in range(100): + card = Rating(user_id="1", card_id=choice([10, 13, 14, 75]), rating_value=choice(["Maybe", "No"]), rating_time=date.today()-timedelta(choice([i for i in range(100)]))) + dbsession.add(card) + dbsession.commit() + dbsession.close() + get_engine().dispose() return None """ @@ -48,9 +51,12 @@ def get_interval(card_id): """ takes card_id looks at the history of rates and gives the current interval """ - dbsession = get_session() - sorted_rates_by_card = dbsession.query(Rating).filter(Rating.card_id == card_id).order_by(desc(Rating.rating_time)).all() - dbsession.close() + Session = get_session() + with Session() as dbsession: + sorted_rates_by_card = dbsession.query(Rating).filter(Rating.card_id == card_id).order_by(desc(Rating.rating_time)).all() + dbsession.close() + get_engine().dispose() + if sorted_rates_by_card == None: print("ni kart... kaj zdaj") #@TODO return None @@ -60,53 +66,59 @@ def get_interval(card_id): #to vključuje tudi new... def is_due(card_id): - dbsession = get_session() - interval = get_interval(card_id) + Session = get_session() + with Session() as dbsession: + + interval = get_interval(card_id) + last_rating_date = dbsession.query(Rating).filter(Rating.card_id == card_id).order_by(desc(Rating.rating_time)).first() + due_date = last_rating_date.rating_time + timedelta(interval) + dbsession.close() + get_engine().dispose() + if interval < 0: return False - - last_rating_date = dbsession.query(Rating).filter(Rating.card_id == card_id).order_by(desc(Rating.rating_time)).first() if last_rating_date == None: - dbsession.close() return True - due_date = last_rating_date.rating_time + timedelta(interval) - dbsession.close() return date.today() >= due_date -def is_new(card_id): - dbsession = get_session() - rating = dbsession.query(Rating).filter(Rating.card_id == card_id).first() - dbsession.close() - if rating == None: - return True - else: - return False +def is_new(card_id): + Session = get_session() + with Session() as dbsession: + rating = dbsession.query(Rating).filter(Rating.card_id == card_id).first() + dbsession.close() + get_engine().dispose() + + return rating == None def list_of_due_cards_by_ids(user_id): "this should not include new cards" - dbsession = get_session() - cards = dbsession.query(Card).filter(Card.owner_id == user_id).all() - l = [] - for card in cards: - if is_new(card.id): - pass - elif is_due(card.id): - l.append(card.id) - dbsession.close() + Session = get_session() + with Session() as dbsession: + cards = dbsession.query(Card).filter(Card.owner_id == user_id).all() + l = [] + for card in cards: + if is_new(card.id): + pass + elif is_due(card.id): + l.append(card.id) + dbsession.close() + + get_engine().dispose() return l def list_of_new_cards_by_ids(user_id): - dbsession = get_session() - cards = dbsession.query(Card).filter(Card.owner_id == user_id).all() - l = [] - for card in cards: - rating = dbsession.query(Rating).filter(Rating.card_id == card.id).first() - if rating == None: - l.append(card.id) - dbsession.close() + Session = get_session() + with Session() as dbsession: + cards = dbsession.query(Card).filter(Card.owner_id == user_id).all() + l = [] + for card in cards: + rating = dbsession.query(Rating).filter(Rating.card_id == card.id).first() + if rating == None: + l.append(card.id) + dbsession.close() return l @@ -114,28 +126,31 @@ def rated_today_by_staus (card_status, user_id): """ Returns number of cards rated today by user by status (new or due) """ - dbsession = get_session() - today = date.today() - - ratings_today = dbsession.query(Rating).filter( - Rating.rating_time == today, - Rating.user_id == user_id - ) n = 0 d = 0 - for rating in ratings_today: - count_all_rates_of_card = dbsession.query(Rating).filter(rating.card_id == Rating.card_id).count() - print("count_all_rates_of_card: ", count_all_rates_of_card) + today = date.today() - if count_all_rates_of_card == 1: - n+=1 - elif count_all_rates_of_card > 1: - d+=1 - else: - print("wtf") - raise Exception("Count be wrong! There should be at least one rating") + Session = get_session() + with Session() as dbsession: + ratings_today = dbsession.query(Rating).filter( + Rating.rating_time == today, + Rating.user_id == user_id + ) + for rating in ratings_today: + count_all_rates_of_card = dbsession.query(Rating).filter(rating.card_id == Rating.card_id).count() + print("count_all_rates_of_card: ", count_all_rates_of_card) + + if count_all_rates_of_card == 1: + n+=1 + elif count_all_rates_of_card > 1: + d+=1 + else: + print("wtf") + raise Exception("Count be wrong! There should be at least one rating") + + dbsession.close() + get_engine().dispose() - dbsession.close() if card_status == "new": return n elif card_status == "due": @@ -199,7 +214,6 @@ def remaining_by_status(user_id, status): Engine """ def sr_session(): - dbsession = get_session() #check if user in session if not 'user_id' in session: @@ -216,23 +230,26 @@ def sr_session(): raise Exception("card_id necesarry!") #@TODO check if this card is part of the user's deck to prevent possibile hack? - submit_card = dbsession.query(Card).get(card_id) + Session = get_session() + with Session() as dbsession: + submit_card = dbsession.query(Card).get(card_id) - # Share - #@@TODO, this should not change the card - share_request = request.form.get("share", None) - if share_request: - share(submit_card, user_id) - #Rate - else: - rate = request.form.get('rate', None) - if not rate: - raise Exception("Need rate info!") + # Share + #@@TODO, this should not change the card + share_request = request.form.get("share", None) + if share_request: + share(submit_card, user_id) + #Rate + else: + rate = request.form.get('rate', None) + if not rate: + raise Exception("Need rate info!") - r = Rating(user_id=user_id, card_id=submit_card.id, rating_value=rate, rating_time=date.today()) - dbsession.add(r) - dbsession.commit() - dbsession.close() + r = Rating(user_id=user_id, card_id=submit_card.id, rating_value=rate, rating_time=date.today()) + dbsession.add(r) + dbsession.commit() + dbsession.close() + get_engine().dispose() user_settings = get_settings(user_id) max_new = int(user_settings["max_new"]) @@ -262,11 +279,15 @@ def sr_session(): print("getting due") next_card_id=get_a_card_by_status(user_id, "due") else: - dbsession.close() flash("no more cards today") return redirect("/menu") - - show_card = dbsession.query(Card).get(next_card_id) + + Session = get_session() + with Session() as dbsession: + show_card = dbsession.query(Card).get(next_card_id) + dbsession.close() + get_engine().dispose() + interval = get_interval(next_card_id) card_type = show_card.card_type diff --git a/upload.py b/upload.py index 418a8af..cca71c0 100644 --- a/upload.py +++ b/upload.py @@ -7,7 +7,7 @@ from werkzeug.utils import secure_filename from auth import login_required from config import CONFIG -from create_db import User, Card, get_session +from create_db import User, Card, get_session, get_engine import nextcloud_client import magic @@ -27,7 +27,6 @@ def index(): @bp.route('/uploader', methods = ('GET', 'POST')) def upload_file(): - dbsession = get_session() user_id = session["user_id"] username = session["username"] @@ -42,7 +41,13 @@ def upload_file(): return render_template("upload.html", username=username) #prevent duplicate filenames - if dbsession.query(Card).filter(Card.title == filename).first() != None: + Session = get_session() + with Session() as dbsession: + filename_exists = dbsession.query(Card).filter(Card.title == filename).first() != None + dbsession.close() + get_engine().dispose() + + if filename_exists: flash("Filename already in database, please rename if you want to upload: " + filename, 'error') continue @@ -62,9 +67,14 @@ def upload_file(): #add card card = Card(title=filename, interest_rate=-1.0, owner_id=user_id, item_location=public_link, last_review=None, share_id=0) flash(f"{filename} uploaded successfully") - dbsession.add(card) - dbsession.commit() - dbsession.close() + + Session = get_session() + with Session() as dbsession: + dbsession.add(card) + dbsession.commit() + dbsession.close() + get_engine().dispose() + else: flash("Please insert a PDF file, support for other formats comming soon...") #return render_template("upload.html", user_id=user_id, username=username)