Compare commits

...

5 Commits

Author SHA1 Message Date
janko 1d1efdec1b popravki bugov 2023-09-02 20:22:57 +02:00
janko e91b2a8893 templates za linke 2023-08-27 18:56:03 +02:00
janko e5739afbe7 templates za delo z linki 2023-08-27 18:55:24 +02:00
janko ce78dc767b delo na raindrop.io 2023-08-27 18:54:12 +02:00
janko 53e7b17e1c nov db idiom. funkcije za prikazovanje in importanje linkov 2023-08-27 18:52:59 +02:00
20 changed files with 536 additions and 348 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 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

108
auth.py
View File

@ -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')

View File

@ -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:
<vsebina klica>
get_engine().dispose()
"""

10
deck.py
View File

@ -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

View File

@ -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().dispose()
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)
commit_link(link.strip(" ").strip("\n"), user_id)

View File

@ -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",

View File

@ -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 = {}

19
menu.py
View File

@ -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":

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
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()
Session = get_session()
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 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?

24
raindrop.py 100644
View File

@ -0,0 +1,24 @@
from raindropio import API, Collection, Raindrop, CollectionRef
#from flask_oauthlib.client
raidrop_access_token = "f25eafb7-2d6f-4c50-9239-5b9703e29a9e"
api = API(raidrop_access_token)
l = []
collections = Collection.get_roots(api)
page = 0
while (items:=Raindrop.search(api, collection=CollectionRef.Unsorted, page=page)):
for item in items:
l.append(item.link)
page += 1
for col in collections:
page = 0
while (items:=Raindrop.search(api, collection=col, page=page)):
for item in items:
l.append(item.link)
page += 1
for link in l:
print(link)

View File

@ -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()

View File

@ -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)

View File

@ -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()
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 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,17 +279,21 @@ 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
print("card type: ", card_type)
if card_type == 'PDF':
if card_type == 'PDF' or card_type== None:
#these factors should be better packaged
return render_template("deck.html", username=username, card=show_card, maybe_in=round(interval*maybe_factor), no_in=round(no_factor*interval))
elif card_type == 'URL':

View File

@ -0,0 +1,5 @@
{% extends 'link.html' %}
{% block link %}
<p>Bad link</p>
{% endblock %}

View File

@ -6,10 +6,10 @@
<main>
<form method="post" enctype="multipart/form-data" action="/import_link/import">
<ol>
<li> <input placeholder="insert link" type="link" name="import_type"/></li>
<li> <button name="import_type" type="submit" value="import_txt">.txt file list of links</button></li>
<li> <button name="import_type" type="submit" value="import_twitter_bookmarks">import twitter bookmarks</button></li>
<li> <button name="import_type" type="submit" value="import_raindrop_links">import links from raindrop.io</button></li>
<li> <input placeholder="insert link" type="link" name="import_link"/></li>
<li> <button name="import_txt" type="submit" value="import_txt">.txt file list of links</button></li>
<li> <button name="import_twitter" type="submit" value="import_twitter_bookmarks">import twitter bookmarks</button></li>
<li> <button name="import_raindrop" type="submit" value="import_raindrop_links">import links from raindrop.io</button></li>
</ol>
</form>
</main>

View File

@ -4,8 +4,10 @@
{% block content %}
<main>
<form class="dropzone dropzone-form" method="post" enctype="multipart/form-data" action="/upload/uploader">
<span id="dropzone-txt" class="dropzone-txt">Drop file here or click to upload.</span>
<form class="dropzone dropzone-form" method="post" enctype="multipart/form-data" action="/import_link/import_txt">
<span id="dropzone-txt" class="dropzone-txt">
Drop .txt file here or click to upload
(1 link per line pls). </span>
<input class="dropzone-input" type="file" name="file" runat="server" accept=".txt" multiple >
</form>
</main>

View File

@ -6,6 +6,9 @@
{% block content %}
<main>
<article>
<header>
<span>Link: <a href="{{ card['item_location'] }}">{{ card['title'] }}</a></span>
</header>
{% block link %}{% endblock %}
<footer>
<form method="post">

View File

@ -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)