# THE LIBRARY #
from itertools import groupby # to handle complex iterations
import os
from pydoc_data . topics import topics
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.category_name \
FROM cards c JOIN categories cat \
ON c . category_id = cat . id ORDER BY cat . category_name ' ).fetchall()
categories = { }
topics = { } # hint for later to fetch all the topics ehhe
# for each category and group of cards for each cat in groupby() grouper object
for k , g in groupby ( todos , key = lambda t : t [ ' category_name ' ] ) :
cards = [ ]
for card in g :
topics = conn . execute ( ' SELECT t.id, t.content FROM topics t \
JOIN topic_cards t_c \
ON t . id = t_c . topic_id \
WHERE t_c . card_id = ? ' ,
( card [ ' id ' ] , ) ) . fetchall ( )
card = dict ( card )
card [ ' topics ' ] = topics
print ( ' card is: ' , card )
cards . append ( card )
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 :
topicss = [ t [ ' content ' ] for t in card [ ' topics ' ] ]
print ( ' ' , card [ ' content ' ] )
print ( ' ' , list ( topicss ) )
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 ' ]
category_name = request . form [ ' cat ' ]
# can this be a category? o be general?
topic_tag = request . form [ ' topic_tag ' ]
# create a new category and topic:
new_category = request . form [ ' new_category ' ]
new_topic = request . form [ ' new_topic ' ]
# if a new category_category_name is created add it to the table of categories
if category_name == ' New category ' and new_category :
conn . execute ( ' INSERT INTO categories (category_name) VALUES (?) ' ,
( new_category , ) )
conn . commit ( )
# update category_name to refer to the newly added category
category_name = new_category
if topic_tag == ' New topic ' and new_topic :
conn . execute ( ' INSERT INTO topics (content) VALUES (?) ' ,
( new_topic , ) )
conn . commit ( )
topic_tag = new_topic
topic_id = conn . execute ( ' SELECT id FROM topics WHERE content = (?); ' ,
( topic_tag , ) ) . fetchone ( ) [ ' id ' ]
conn . execute ( ' INSERT INTO topic_cards (topic_id, card_id) VALUES (?,?) ' ,
( topic_id , cat_id ) )
if not content :
flash ( ' plz write a content! ' )
return redirect ( url_for ( ' home ' ) )
cat_id = conn . execute ( ' SELECT id FROM categories WHERE category_name = (?); ' ,
( category_name , ) ) . 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 category_name FROM categories; ' ) . fetchall ( )
topics = conn . execute ( ' SELECT content FROM topics; ' ) . fetchall ( )
conn . close ( )
return render_template ( ' create.html ' , categories = categories , topics = topics )
@ 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.category_name \
FROM cards c JOIN categories cat \
ON c . category_id = cat . id WHERE c . id = ? ' , (id,)).fetchone()
categories = conn . execute (
' SELECT category_name FROM categories; ' ) . fetchall ( )
if request . method == ' POST ' :
content = request . form [ ' content ' ]
category_name = 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 category_name = (?); ' ,
( category_name , ) ) . 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