# THE LIBRARY #
from itertools import groupby # to handle complex iterations
import os
import sqlite3
from webbrowser import get
from flask import Flask , render_template , url_for , request , redirect , flash
# ----- functions ----- #
def get_db_connection ( ) :
conn = sqlite3 . connect ( ' library.db ' )
conn . row_factory = sqlite3 . Row
return conn
# Added row_factory attribute to the sqlite connection, in this way you can have name-based access to columns; this means that the database connection will return rows that behave like regular Python dictionaries.
# ----- FLASK ----- #
class PrefixMiddleware ( object ) :
def __init__ ( self , app , prefix = " " ) :
self . app = app
self . prefix = prefix
def __call__ ( self , environ , start_response ) :
if environ [ " PATH_INFO " ] . startswith ( self . prefix ) :
environ [ " PATH_INFO " ] = environ [ " PATH_INFO " ] [ len ( self . prefix ) : ]
environ [ " SCRIPT_NAME " ] = self . prefix
return self . app ( environ , start_response )
else :
start_response ( " 404 " , [ ( " Content-Type " , " text/plain " ) ] )
return [ " This url does not belong to the app. " . encode ( ) ]
app = Flask ( __name__ )
app . config [ ' SECRET KEY ' ] = ' this should be a secret random string '
# register the middleware to prefix all the requests with our base_url
app . wsgi_app = PrefixMiddleware ( app . wsgi_app , prefix = ' /soupboat/library ' )
@ app . route ( " / " )
def home ( ) :
conn = get_db_connection ( )
todos = conn . execute ( ' SELECT c.id, c.content, cat.title \
FROM cards c JOIN categories cat \
ON c . category_id = cat . id ORDER BY cat . title ' ).fetchall()
categories = { }
# for each category and group of cards for each cat in groupby() grouper object
for k , g in groupby ( todos , key = lambda t : t [ ' title ' ] ) :
cards = [ ]
for card in g :
card = dict ( card )
print ( ' card is: ' , card )
cards . append ( card )
# print(categories[k])
categories [ k ] = list ( cards )
for cat , cards in categories . items ( ) : # ♥ .items is a build in attribute of the dictionary(?)
print ( cat )
for card in cards :
print ( ' ' , card [ ' content ' ] )
conn . close ( )
return render_template ( ' home.html ' , categories = categories )
@ app . route ( " /add/ " , methods = [ ' GET ' , ' POST ' ] )
def create ( ) :
conn = get_db_connection ( )
if request . method == ' POST ' :
content = request . form [ ' content ' ]
cat_title = request . form [ ' cat ' ]
if not content :
flash ( ' plz write a content! ' )
return redirect ( url_for ( ' home ' ) )
cat_id = conn . execute ( ' SELECT id FROM categories WHERE title = (?); ' ,
( cat_title , ) ) . fetchone ( ) [ ' id ' ]
conn . execute ( ' INSERT INTO cards (content, category_id) VALUES (?,?) ' ,
( content , cat_id ) )
conn . commit ( )
conn . close ( )
return redirect ( url_for ( ' home ' ) )
categories = conn . execute ( ' SELECT title FROM categories; ' ) . fetchall ( )
conn . close ( )
return render_template ( ' create.html ' , categories = categories )
@ app . route ( ' /<int:id>/edit/ ' , methods = ( ' GET ' , ' POST ' ) )
def edit ( id ) :
conn = get_db_connection ( )
todo = conn . execute ( ' SELECT c.id, c.category_id, c.content, cat.title \
FROM cards c JOIN categories cat \
ON c . category_id = cat . id WHERE c . id = ? ' , (id,)).fetchone()
categories = conn . execute ( ' SELECT title FROM categories; ' ) . fetchall ( )
if request . method == ' POST ' :
content = request . form [ ' content ' ]
cat_title = request . form [ ' cat ' ]
if not content :
flash ( ' plz insert any content! ' )
return redirect ( url_for ( ' home ' ) )
cat_id = conn . execute ( ' SELECT id FROM categories WHERE title = (?); ' ,
( cat_title , ) ) . fetchone ( ) [ ' id ' ]
conn . execute ( ' UPDATE cards SET content = ?, category_id = ? \
WHERE id = ? ' ,
( content , cat_id , id ) )
conn . commit ( )
conn . close ( )
return redirect ( url_for ( ' home ' ) )
return render_template ( ' edit.html ' , todo = todo , categories = categories )
@ app . route ( ' /<int:id>/delete/ ' , methods = ( ' POST ' , ) )
def delete ( id ) :
conn = get_db_connection ( )
conn . execute ( ' DELETE FROM cards WHERE id = ? ' , ( id , ) )
conn . commit ( )
conn . close ( )
return redirect ( url_for ( ' home ' ) )
# app.run(port=3148)
# TODO:
# - list the cards
# - put its category inside