nov db idiom. funkcije za prikazovanje in importanje linkov

master
janko 2023-08-27 18:52:59 +02:00
parent be6a3242f9
commit 53e7b17e1c
15 changed files with 495 additions and 341 deletions

2
app.py
View File

@ -3,11 +3,11 @@ from flask import Flask, redirect, render_template, session, url_for
from auth import login_required, bp as auth_bp from auth import login_required, bp as auth_bp
from deck import bp as deck_bp from deck import bp as deck_bp
from menu import bp as menu_bp from menu import bp as menu_bp
from sr_session import sr_session
from upload import bp as upload_bp from upload import bp as upload_bp
from import_link import bp as import_link_bp from import_link import bp as import_link_bp
from matches import bp as matches_bp from matches import bp as matches_bp
from settings import bp as settings_bp from settings import bp as settings_bp
from sr_session import sr_session
from config import CONFIG from config import CONFIG

100
auth.py
View File

@ -4,54 +4,56 @@ from flask import (
Blueprint, flash, g, redirect, render_template, request, session, url_for Blueprint, flash, g, redirect, render_template, request, session, url_for
) )
from hashlib import md5 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 from share import get_all_shared
bp = Blueprint('auth', __name__, url_prefix='/auth') bp = Blueprint('auth', __name__, url_prefix='/auth')
@bp.route('/register', methods=('GET', 'POST')) @bp.route('/register', methods=('GET', 'POST'))
def register(): def register():
dbsession = get_session()
if request.method == 'POST': Session = get_session()
username = request.form['username'] with Session() as dbsession:
password = request.form['password'] if request.method == 'POST':
mail = request.form['email'] username = request.form['username']
error = None password = request.form['password']
mail = request.form['email']
error = None
#@TODO check if this really is an email. #@TODO check if this really is an email.
if not username: if not username:
error = 'Username is required.' error = 'Username is required.'
elif not password: elif not password:
error = 'Password is required.' error = 'Password is required.'
elif not mail: elif not mail:
error = 'Please enter your email adress.' error = 'Please enter your email adress.'
elif dbsession.query(User).filter(User.username == username).first() != None: elif dbsession.query(User).filter(User.username == username).first() != None:
error = "Username already exists, please choose another one." error = "Username already exists, please choose another one."
elif dbsession.query(User).filter(User.email == mail).first() != None: elif dbsession.query(User).filter(User.email == mail).first() != None:
error = "This email adress is already in use, please choose another one." error = "This email adress is already in use, please choose another one."
if error is None: if error is None:
try: try:
user = User(username=username, password=md5(password.encode("utf-8")).hexdigest(), email=mail, settings = "") user = User(username=username, password=md5(password.encode("utf-8")).hexdigest(), email=mail, settings = "")
dbsession.add(user) dbsession.add(user)
dbsession.commit() dbsession.commit()
#Preden zapremo naj user dobi vse shared karte od prej. #Preden zapremo naj user dobi vse shared karte od prej.
new_user = dbsession.query(User).filter(User.username == username).first() new_user = dbsession.query(User).filter(User.username == username).first()
new_user_id = new_user.id new_user_id = new_user.id
get_all_shared(new_user_id) get_all_shared(new_user_id)
dbsession.close() dbsession.close()
except Exception as e: except Exception as e:
error = f"napaka pri registraciji {username} je {e}" error = f"napaka pri registraciji {username} je {e}"
else: else:
return redirect(url_for("auth.login")) return redirect(url_for("auth.login"))
flash(error) flash(error)
get_engine().dispose()
return render_template('register.html') return render_template('register.html')
@ -59,26 +61,28 @@ def register():
@bp.route('/login', methods=('GET', 'POST')) @bp.route('/login', methods=('GET', 'POST'))
def login(): def login():
if request.method == 'POST': if request.method == 'POST':
dbsession = get_session()
username = request.form['username'] Session = get_session()
password = request.form['password'] with Session() as dbsession:
error = None username = request.form['username']
user = dbsession.query(User).filter(User.username == username).first() password = request.form['password']
error = None
user = dbsession.query(User).filter(User.username == username).first()
if user is None: if user is None:
error = 'Incorrect username.' error = 'Incorrect username.'
elif not user.password == md5(password.encode("utf-8")).hexdigest(): #compare input pw has and bd pw hash elif not user.password == md5(password.encode("utf-8")).hexdigest(): #compare input pw has and bd pw hash
error = 'Incorrect password.' error = 'Incorrect password.'
if error is None: if error is None:
session.clear() session.clear()
session['user_id'] = user.id session['user_id'] = user.id
session['username'] = user.username session['username'] = user.username
return redirect(url_for("menu.index")) #TODO ne dela return redirect(url_for("menu.index")) #TODO ne dela
flash(error) flash(error)
get_engine().dispose()
return render_template('login.html') return render_template('login.html')

View File

@ -47,10 +47,44 @@ class Rating(Base):
engine = create_engine(CONFIG['DB_CONNECTION']) 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(): def get_session():
# Engine je samo enkrat treba inicializirat, se mi zdi. return Session
# engine = create_engine(CONFIG['DB_CONNECTION'])
dbsessionmaker = sessionmaker(bind=engine) def get_engine():
return dbsessionmaker() 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:
<vsebina klica>
get_engine().dispose()
"""

10
deck.py
View File

@ -3,7 +3,7 @@ from flask import (
Blueprint, g, session Blueprint, g, session
) )
from auth import login_required 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 from numpy.random import choice
@ -11,8 +11,12 @@ bp = Blueprint('deck', __name__)
@bp.route('/deck', methods=['GET']) @bp.route('/deck', methods=['GET'])
def get_collection(user_id): def get_collection(user_id):
dbsession = get_session() Session = get_session()
c = dbsession.query(Card).filter(Card.owner_id == user_id).all() with Session() as dbsession:
c = dbsession.query(Card).filter(Card.owner_id == user_id).all()
dbsession.close()
get_engine().dispose()
return c return c

View File

@ -1,8 +1,11 @@
from flask import ( from flask import (
Blueprint, render_template, request, session, flash Blueprint, render_template, request, session, flash
) )
from create_db import Card, get_session from create_db import Card, get_session, get_engine
from link_handler import check_response 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') bp = Blueprint('import_link', __name__, url_prefix='/import_link')
@ -19,45 +22,76 @@ def import_link():
username = session['username'] username = session['username']
user_id = session['user_id'] user_id = session['user_id']
if request.method == 'POST': if request.method == 'POST':
import_type = request.form.get("import_type", False) import_type = request.form.get("import_txt")
print(import_type) print("###########################", import_type)
if import_type == "import_txt": if import_type == "import_txt":
print("!2313232321") return render_template("import_txt.html", user_id=user_id, username=username)
else: else:
link = request.form.get("link", False) link = request.form.get("import_link", False)
if check_response(link) == 1: commit_link(link=link, user_id=user_id)
print(link, 'is ok')
commit_link(link=link, user_id=user_id)
else:
print(link, 'is not ok')
return render_template("import_link.html", user_id=user_id, username=username) return render_template("import_link.html", user_id=user_id, username=username)
def commit_link(link, user_id): def commit_link(link, user_id):
dbsession = get_session()
existing_link = dbsession.query(Card).filter_by(owner_id=user_id, item_location=link).first() Session = get_session()
if existing_link: with Session() as dbsession:
flash(f"{link} has already been imported.") existing_link = dbsession.query(Card).filter_by(owner_id=user_id, item_location=link).first()
else: if existing_link:
#add card print(f"{link} has already been imported.")
#TODO ni razlike med title in vsebino urlja ?? flash(f"{link} has already been imported.","error")
card = Card(title=link, return -1
interest_rate=-1.0,
owner_id=user_id, link_check = check_link(link)
item_location=link, if link_check != 1:
last_review=None, print(link, 'is not ok')
card_type="URL", flash(f"{link}, 'is not ok', {link_check}", "rror")
share_id=0) return -1
dbsession.add(card) else:
dbsession.commit() print(link, 'is ok')
flash(f"{link} imported successfully") #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()
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)
dbsession.close()
def import_list_of_links(list_of_links, user_id): def import_list_of_links(list_of_links, user_id):
#TODO nekak bi bilo dobro, da pokaže kateri so failali.... #TODO nekak bi bilo dobro, da pokaže kateri so failali....
for link in list_of_links: for link in list_of_links:
commit_link(link, user_id) commit_link(link.strip(" ").strip("\n"), user_id)

View File

@ -3,6 +3,14 @@ import re
from flask import render_template from flask import render_template
from urllib.parse import urlparse 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): def check_response(link):
""" """
@ -10,26 +18,32 @@ def check_response(link):
2 if there's conncetion error 2 if there's conncetion error
3 if link is invalid (no "http" for example) 3 if link is invalid (no "http" for example)
""" """
parsed_url = urlparse(link) try:
if parsed_url.scheme and parsed_url.netloc: response = requests.head(link)
try: if response.status_code == 200:
response = requests.head(link) return 1
if response.status_code == 200: else:
return 1 #TODO drugi statusi code?
else: #return "WEIRD", response
#TODO drugi statusi code? #TODO samo za testiranje
return "WEIRD" return f"Error: {response.status_code}"
except requests.exceptions.RequestException: except Exception as e:
print("conncetion error") print(e)
return 2 return f"Link error: {e}"
else:
print("link not valid (https:// missing??)")
return 3
# kako vse možne linke embeddat? # kako vse možne linke embeddat?
def render_embed_link(cm_username, card, maybe_in, no_in): def render_embed_link(cm_username, card, maybe_in, no_in):
url = card.item_location 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): if re.match(r'^https?://(www\.)?twitter\.com/.*/status/\d+$', url):
tweet_id = url.split("/")[-1] tweet_id = url.split("/")[-1]
return render_template("embed_link/twitter_embed.html", return render_template("embed_link/twitter_embed.html",

View File

@ -3,29 +3,37 @@ from flask import (
) )
from requests import get from requests import get
from config import CONFIG 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') bp = Blueprint('matches', __name__, url_prefix='/matches')
def get_matches(user_id): def get_matches(user_id):
#@TODO this is buggy #@TODO this is buggy
dbsession = get_session()
list_of_matches = [] list_of_matches = []
#in all shared cards for the ones you voted yes #in all shared cards for the ones you voted yes
all_cards = dbsession.query(Card) Session = get_session()
all_shared_of_user_of_ir_1 = all_cards.filter(Card.share_id != "0", Card.owner_id == user_id, Card.interest_rate == "1").all() 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 == []: if all_shared_of_user_of_ir_1 == []:
return list_of_matches return list_of_matches
# see who else voted yes # see who else voted yes
for c in all_shared_of_user_of_ir_1: Session = get_session()
others_yes = all_cards.filter(Card.share_id == c.share_id, Card.interest_rate == "1", Card.owner_id != user_id).all() with Session() as dbsession:
if others_yes == []: for c in all_shared_of_user_of_ir_1:
pass others_yes = all_cards.filter(Card.share_id == c.share_id, Card.interest_rate == "1", Card.owner_id != user_id).all()
else: if others_yes == []:
list_of_matches.append(others_yes) pass
else:
list_of_matches.append(others_yes)
dbsession.close()
get_engine().dispose()
return list_of_matches return list_of_matches
@ -35,7 +43,6 @@ def index():
if not 'user_id' in session: if not 'user_id' in session:
redirect(url_for('index')) redirect(url_for('index'))
dbsession = get_session()
user_id = session["user_id"] user_id = session["user_id"]
username = session["username"] username = session["username"]
@ -48,7 +55,12 @@ def index():
for card in match: for card in match:
user_ids.append(card.owner_id) 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 = {} names_by_ids = {}
emails_by_ids = {} emails_by_ids = {}

17
menu.py
View File

@ -1,7 +1,7 @@
from flask import ( from flask import (
Blueprint, redirect, render_template, request, session, url_for 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 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 settings import get_settings
from auth import login from auth import login
@ -10,7 +10,7 @@ bp = Blueprint('menu', __name__, url_prefix='/menu')
@bp.route("/", methods=("GET", "POST")) @bp.route("/", methods=("GET", "POST"))
def index(): def index():
dbsession = get_session()
if 'user_id' not in session: if 'user_id' not in session:
return login() 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 action = request.form.get("menu", False) #internetna rešitev, nevem kako, ampak dela, tj. dobi info iz meni buttonov
if action == "new_session": if action == "new_session":
#preverimo če so sploh karte v collectionu #preverimo če so sploh karte v collectionu
c = dbsession.query(Card).filter(Card.owner_id == user_id).all() Session = get_session()
if c == []: with Session() as dbsession:
return render_template("error/no_cards_in_collection.html", username=username) 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")) return redirect(url_for("deck"))
elif action == "matches": elif action == "matches":
return redirect(url_for("matches.index")) return redirect(url_for("matches.index"))
elif action == "upload": elif action == "upload":

View File

@ -1,4 +1,4 @@
from create_db import Card, get_session from create_db import Card, get_session, get_engine
from config import CONFIG from config import CONFIG
import nextcloud_client import nextcloud_client
@ -17,6 +17,10 @@ for item in l:
public_share = nc.share_file_with_link("/GIA CLOUD/"+name) public_share = nc.share_file_with_link("/GIA CLOUD/"+name)
public_link = public_share.get_link()+"/download/"+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") 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() Session = get_session()
dbsession.close() with Session() as dbsession:
dbsession.add(card)
dbsession.commit()
dbsession.close()
get_engine().dispose()

View File

@ -1,5 +1,5 @@
from flask import session, redirect, url_for,request, flash, render_template 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 from share import share
""" """
@ -9,80 +9,81 @@ rabi še deck funkcionalnosti, ki so bile prej v menu.py itd...
""" """
def prob_session(): def prob_session():
dbsession = get_session()
if not 'user_id' in session: if not 'user_id' in session:
redirect(url_for('login')) redirect(url_for('login'))
user_id = session['user_id'] user_id = session['user_id']
username = session['username'] username = session['username']
#pokliče na bazo, da dobi str card idjev, ga spremeni v list in srevira karte po idjih #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) Session = get_session()
deck_object = deck_query.filter(Deck.completed == False).first() with Session() as dbsession:
# @TODO: ce deck, ne obstaja, kaj naj zaj jas? deck_query = dbsession.query(Deck).filter(Deck.owner_id == user_id)
if len(deck_object.cards_by_id.split(",")) == 0: deck_object = deck_query.filter(Deck.completed == False).first()
deck_query.filter(Deck) # @TODO: ce deck, ne obstaja, kaj naj zaj jas?
redirect(url_for('login')) if len(deck_object.cards_by_id.split(",")) == 0:
deck_query.filter(Deck)
redirect(url_for('login'))
# Smo oddali obrazec? # Smo oddali obrazec?
if request.method == 'POST': if request.method == 'POST':
card_id = request.form.get('card_id', None) card_id = request.form.get('card_id', None)
if not card_id: if not card_id:
raise Exception("card_id je nujen!") 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) # Ali damo share? Potem nastavi na share in ponovi obrazec
# @TODO preveri, ali je card del trenutnega decka! 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 # Če ne, gre za rate!
share_request = request.form.get("share", None) else:
if share_request: rate = request.form.get('rate', None) #je to nevarno??
# @TODO logika za share! print(rate)
share(submit_card, user_id)
# Če ne, gre za rate! if not rate:
else: raise Exception("manjka rate info!")
rate = request.form.get('rate', None) #je to nevarno??
print(rate)
if not rate: if rate == "Yes":
raise Exception("manjka rate info!") submit_card.interest_rate = 1
if rate == "Yes": elif rate == "Maybe":
submit_card.interest_rate = 1 k = 0.5
print(submit_card)
submit_card.interest_rate= abs(submit_card.interest_rate*k)
elif rate == "Maybe": elif rate == "No":
k = 0.5 k = 0.1
print(submit_card) submit_card.interest_rate = abs(submit_card.interest_rate*k)
submit_card.interest_rate= abs(submit_card.interest_rate*k)
elif rate == "No": elif rate == "Delete":
k = 0.1 submit_card.interest_rate = 0
submit_card.interest_rate = abs(submit_card.interest_rate*k) #@TODO to bi lahko zbrisalo tudi file v določenih primerih
elif rate == "Delete": # zaporedno število trenutnega carda v decku
submit_card.interest_rate = 0 next_card = deck_object.current_card + 1
#@TODO to bi lahko zbrisalo tudi file v določenih primerih
# zaporedno število trenutnega carda v decku # Ali je deck končan?
next_card = deck_object.current_card + 1 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"))
# Ali je deck končan? deck_object.current_card = next_card
if next_card >= deck_object.number_of_cards:
deck_object.completed = True
dbsession.commit() dbsession.commit()
dbsession.close()
flash("Deck rating finished!")
return redirect(url_for("menu.index"))
deck_object.current_card = next_card # Loudamo naslednjo karto v decku
dbsession.commit() show_card_index = deck_object.current_card
show_card_id = deck_object.cards_by_id.split(",")[show_card_index]
# Loudamo naslednjo karto v decku print("GET CARD PLS", show_card_id)
show_card_index = deck_object.current_card show_card = dbsession.query(Card).get(show_card_id)
show_card_id = deck_object.cards_by_id.split(",")[show_card_index] dbsession.close()
print("GET CARD PLS", show_card_id) get_engine().dispose()
show_card = dbsession.query(Card).get(show_card_id)
dbsession.close()
if not show_card: if not show_card:
# @TODO how to handle missing card? # @TODO how to handle missing card?

View File

@ -4,27 +4,27 @@ from requests import session
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from config import CONFIG 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 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() l = get_file_list()
id = 0 #TODO id = 0 #TODO
for title in l: for title in l:
if title[-4:] == ".pdf": if title[-4:] != ".pdf":
card = Card( continue
id=id,
title=title[:-4], card = Card(
interest_rate=-1, id=id,
owner_id = 1 title=title[:-4],
) interest_rate=-1,
owner_id = 1
)
id = id+1
Session = get_session()
with Session() as dbsession:
session.add(card) session.add(card)
session.commit() session.commit()
session.close() session.close()
get_engine().dispose()
id = id+1

View File

@ -1,41 +1,42 @@
from flask import flash, render_template, Blueprint, request, session 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 import json
bp = Blueprint('settings', __name__, url_prefix='/settings') bp = Blueprint('settings', __name__, url_prefix='/settings')
def get_settings(user_id): def get_settings(user_id):
dbsession = get_session()
"""get settings from db, turns it into a dict and returns it""" """get settings from db, turns it into a dict and returns it"""
Session = get_session()
user = dbsession.query(User).get(user_id) with Session() as dbsession:
#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) 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 settings_db = user.settings
if settings_db == "": if settings_db == "":
#userji se zaenkrat generirajo brez settingsov aka empty string, zato dodamo te defaulte #userji se zaenkrat generirajo brez settingsov aka empty string, zato dodamo te defaulte
settings_dict = { settings_dict = {
"max_new" : 5, "max_new" : 5,
"max_due" : 5, "max_due" : 5,
"max_shared" : 5, "max_shared" : 5,
} }
else: else:
settings_dict = json.loads(settings_db) settings_dict = json.loads(settings_db)
dbsession.close() dbsession.close()
get_engine().dispose()
return settings_dict return settings_dict
@bp.route("/save_settings", methods=["GET", "POST"]) @bp.route("/save_settings", methods=["GET", "POST"])
def save_settings(): def save_settings():
dbsession = get_session()
"""takes a dict of settings turns it into json and updates the database with it""" """takes a dict of settings turns it into json and updates the database with it"""
user_id = session['user_id'] user_id = session['user_id']
username = session['username'] username = session['username']
@ -50,13 +51,15 @@ def save_settings():
"max_due" : request.form.get('max_due', False), "max_due" : request.form.get('max_due', False),
"max_shared" : request.form.get('max_shared', False), "max_shared" : request.form.get('max_shared', False),
} }
Session = get_session()
with Session() as dbsession:
settings_json = json.dumps(settings_dict)
user = dbsession.query(User).get(user_id)
settings_json = json.dumps(settings_dict) user.settings = settings_json
user = dbsession.query(User).get(user_id) dbsession.commit()
dbsession.close()
user.settings = settings_json flash("settings updated")
dbsession.commit() get_engine().dispose()
dbsession.close()
flash("settings updated")
return render_template("settings.html", username=username, settings=settings_dict) return render_template("settings.html", username=username, settings=settings_dict)

View File

@ -1,42 +1,48 @@
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from config import CONFIG 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 from hashlib import md5
#@TODO najbrž je treba narediti tako da org card tudi dobi share id in se ostalo, kar to obsega #@TODO najbrž je treba narediti tako da org card tudi dobi share id in se ostalo, kar to obsega
def share(card, user_id): 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 #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() h = md5(str(card.id).encode("utf-8")).hexdigest()
card.share_id = h card.share_id = h
owner_card = dbsession.query(Card).filter(Card.id == card.id).first() Session = get_session()
owner_card.share_id = h with Session() as dbsession:
dbsession.commit() owner_card = dbsession.query(Card).filter(Card.id == card.id).first()
owner_card.share_id = h
dbsession.commit()
# all users # all users
users = dbsession.query(User).filter(User.id != user_id).all() users = dbsession.query(User).filter(User.id != user_id).all()
for user in users: for user in users:
#skip če že ima ta card v db. #skip če že ima ta card v db.
existing = dbsession.query(Card).filter(Card.title == card.title, Card.owner_id==user.id).all() existing = dbsession.query(Card).filter(Card.title == card.title, Card.owner_id==user.id).all()
if existing == []: 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) 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.add(new_card)
dbsession.commit() dbsession.commit()
dbsession.close()
get_engine().dispose()
def get_all_shared(user_id): def get_all_shared(user_id):
"""adds all existing shared cards to this users collection""" """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 #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? #@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)
for c in all_shared_cards: Session = get_session()
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) with Session() as dbsession:
dbsession.add(new_card) all_shared_cards = dbsession.query(Card).filter(Card.share_id != "0").distinct(Card.share_id).group_by(Card.share_id)
dbsession.commit()
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()

View File

@ -3,7 +3,7 @@ from datetime import date, timedelta
from flask import flash, session, redirect, url_for, request, render_template from flask import flash, session, redirect, url_for, request, render_template
from sqlalchemy import desc from sqlalchemy import desc
from share import share 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 settings import get_settings
from link_handler import render_embed_link from link_handler import render_embed_link
@ -12,12 +12,15 @@ from link_handler import render_embed_link
testing testing
""" """
def autofill_ratings(): def autofill_ratings():
dbsession = get_session()
for i in range(100): Session = get_session()
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)]))) with Session() as dbsession:
dbsession.add(card) for i in range(100):
dbsession.commit() 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.close() dbsession.add(card)
dbsession.commit()
dbsession.close()
get_engine().dispose()
return None 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 takes card_id looks at the history of rates and gives the current interval
""" """
dbsession = get_session() Session = get_session()
sorted_rates_by_card = dbsession.query(Rating).filter(Rating.card_id == card_id).order_by(desc(Rating.rating_time)).all() with Session() as dbsession:
dbsession.close() 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: if sorted_rates_by_card == None:
print("ni kart... kaj zdaj") #@TODO print("ni kart... kaj zdaj") #@TODO
return None return None
@ -60,53 +66,59 @@ def get_interval(card_id):
#to vključuje tudi new... #to vključuje tudi new...
def is_due(card_id): def is_due(card_id):
dbsession = get_session() Session = get_session()
interval = get_interval(card_id) 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: if interval < 0:
return False 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: if last_rating_date == None:
dbsession.close()
return True return True
due_date = last_rating_date.rating_time + timedelta(interval)
dbsession.close()
return date.today() >= due_date 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): def list_of_due_cards_by_ids(user_id):
"this should not include new cards" "this should not include new cards"
dbsession = get_session() Session = get_session()
cards = dbsession.query(Card).filter(Card.owner_id == user_id).all() with Session() as dbsession:
l = [] cards = dbsession.query(Card).filter(Card.owner_id == user_id).all()
for card in cards: l = []
if is_new(card.id): for card in cards:
pass if is_new(card.id):
elif is_due(card.id): pass
l.append(card.id) elif is_due(card.id):
dbsession.close() l.append(card.id)
dbsession.close()
get_engine().dispose()
return l return l
def list_of_new_cards_by_ids(user_id): def list_of_new_cards_by_ids(user_id):
dbsession = get_session() Session = get_session()
cards = dbsession.query(Card).filter(Card.owner_id == user_id).all() with Session() as dbsession:
l = [] cards = dbsession.query(Card).filter(Card.owner_id == user_id).all()
for card in cards: l = []
rating = dbsession.query(Rating).filter(Rating.card_id == card.id).first() for card in cards:
if rating == None: rating = dbsession.query(Rating).filter(Rating.card_id == card.id).first()
l.append(card.id) if rating == None:
dbsession.close() l.append(card.id)
dbsession.close()
return l 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) 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 n = 0
d = 0 d = 0
for rating in ratings_today: today = date.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: Session = get_session()
n+=1 with Session() as dbsession:
elif count_all_rates_of_card > 1: ratings_today = dbsession.query(Rating).filter(
d+=1 Rating.rating_time == today,
else: Rating.user_id == user_id
print("wtf") )
raise Exception("Count be wrong! There should be at least one rating") 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": if card_status == "new":
return n return n
elif card_status == "due": elif card_status == "due":
@ -199,7 +214,6 @@ def remaining_by_status(user_id, status):
Engine Engine
""" """
def sr_session(): def sr_session():
dbsession = get_session()
#check if user in session #check if user in session
if not 'user_id' in session: if not 'user_id' in session:
@ -216,23 +230,26 @@ def sr_session():
raise Exception("card_id necesarry!") raise Exception("card_id necesarry!")
#@TODO check if this card is part of the user's deck to prevent possibile hack? #@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 # Share
#@@TODO, this should not change the card #@@TODO, this should not change the card
share_request = request.form.get("share", None) share_request = request.form.get("share", None)
if share_request: if share_request:
share(submit_card, user_id) share(submit_card, user_id)
#Rate #Rate
else: else:
rate = request.form.get('rate', None) rate = request.form.get('rate', None)
if not rate: if not rate:
raise Exception("Need rate info!") raise Exception("Need rate info!")
r = Rating(user_id=user_id, card_id=submit_card.id, rating_value=rate, rating_time=date.today()) r = Rating(user_id=user_id, card_id=submit_card.id, rating_value=rate, rating_time=date.today())
dbsession.add(r) dbsession.add(r)
dbsession.commit() dbsession.commit()
dbsession.close() dbsession.close()
get_engine().dispose()
user_settings = get_settings(user_id) user_settings = get_settings(user_id)
max_new = int(user_settings["max_new"]) max_new = int(user_settings["max_new"])
@ -262,11 +279,15 @@ def sr_session():
print("getting due") print("getting due")
next_card_id=get_a_card_by_status(user_id, "due") next_card_id=get_a_card_by_status(user_id, "due")
else: else:
dbsession.close()
flash("no more cards today") flash("no more cards today")
return redirect("/menu") 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) interval = get_interval(next_card_id)
card_type = show_card.card_type card_type = show_card.card_type

View File

@ -7,7 +7,7 @@ from werkzeug.utils import secure_filename
from auth import login_required from auth import login_required
from config import CONFIG 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 nextcloud_client
import magic import magic
@ -27,7 +27,6 @@ def index():
@bp.route('/uploader', methods = ('GET', 'POST')) @bp.route('/uploader', methods = ('GET', 'POST'))
def upload_file(): def upload_file():
dbsession = get_session()
user_id = session["user_id"] user_id = session["user_id"]
username = session["username"] username = session["username"]
@ -42,7 +41,13 @@ def upload_file():
return render_template("upload.html", username=username) return render_template("upload.html", username=username)
#prevent duplicate filenames #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') flash("Filename already in database, please rename if you want to upload: " + filename, 'error')
continue continue
@ -62,9 +67,14 @@ def upload_file():
#add card #add card
card = Card(title=filename, interest_rate=-1.0, owner_id=user_id, item_location=public_link, last_review=None, share_id=0) 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") flash(f"{filename} uploaded successfully")
dbsession.add(card)
dbsession.commit() Session = get_session()
dbsession.close() with Session() as dbsession:
dbsession.add(card)
dbsession.commit()
dbsession.close()
get_engine().dispose()
else: else:
flash("Please insert a PDF file, support for other formats comming soon...") flash("Please insert a PDF file, support for other formats comming soon...")
#return render_template("upload.html", user_id=user_id, username=username) #return render_template("upload.html", user_id=user_id, username=username)