""" Flask Documentation: http://flask.pocoo.org/docs/ Jinja2 Documentation: http://jinja.pocoo.org/2/documentation/ Werkzeug Documentation: http://werkzeug.pocoo.org/documentation/ This file creates your application. """ from app import app, db from flask import Flask, render_template, request, redirect, url_for, flash, send_from_directory, jsonify, abort import json from sqlalchemy.sql.expression import func, select from app.forms import UploadForm, EditForm, SearchForm from app.models import Book, BookSchema, Author, AuthorSchema, Stack, StackSchema from app.cover import get_cover import os from werkzeug.utils import secure_filename # import sqlite3 ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'epub', 'chm', 'mobi']) author_schema = AuthorSchema() authors_schema = AuthorSchema(many=True) book_schema = BookSchema() books_schema = BookSchema(many=True) stack_schema = StackSchema() stacks_schema = StackSchema(many=True) def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS ### # Routing for your application. ### @app.route('/') def home(): """Render website's home page.""" return render_template('home.html') @app.route('/hello/') def hello(name): return "Hello " + name @app.route('/about/') def about(): """Render the website's about page.""" return render_template('about.html', name="Mary Jane") @app.route('/uploads/') def uploaded_file(filename): return send_from_directory(app.config['UPLOAD_FOLDER'], filename) @app.route('/uploads/cover/') def uploaded_file_cover(filename): return send_from_directory(app.config['UPLOAD_FOLDER_COVER'], filename) @app.route('/books', methods= ['POST','GET']) def show_books(): books = db.session.query(Book).all() search = SearchForm(request.form) if request.method == 'POST': if search.select.data == 'Title': return redirect((url_for('search_results', query=search.search.data))) if search.select.data == 'Category': return redirect((url_for('search_cat', query=search.search.data))) return render_template('show_books.html', books=books, form=search) @app.route('/scape', methods=['POST', 'GET']) def scape(): if request.method == 'POST': data = request.form book = Book.query.get(data['id']) print(book.scapeX) book.scapeX = data['x'] book.scapeY = data['y'] db.session.commit() books = db.session.query(Book).all() # or you could have used User.query.all() return render_template('scape.html', books=books) @app.route('/books_grid') def show_books_grid(): books = db.session.query(Book).all() # or you could have used User.query.all() return render_template('show_books_grid.html', books=books) @app.route('/books/') def show_book_by_id(id): book = Book.query.get(id) if not book: return render_template('red_link.html', id=id) else: return render_template('show_book_detail.html', book=book) @app.route('/books//delete', methods=['POST', 'GET']) def remove_book_by_id(id): book_to_edit = Book.query.filter_by(id=id).first() title = book_to_edit.title Book.query.filter_by(id=id).delete() #author_table = Author.query.filter_by(book_id=book_to_edit.id).delete() db.session.commit() flash("%s deleted from library" % (title)) return redirect(url_for('show_books')) @app.route('/books//edit', methods=['POST', 'GET']) def edit_book_by_id(id): book_to_edit = Book.query.filter_by(id=id).first() user_form = EditForm(title = book_to_edit.title, author =book_to_edit.authors, category = book_to_edit.category, year_published= book_to_edit.year_published) if request.method == 'POST': if user_form.validate_on_submit(): # check if the post request has the file part title = user_form.title.data # You could also have used request.form['name'] input_authors = user_form.author.data # You could also have used request.form['email'] category = user_form.category.data year_published = user_form.year_published.data if year_published=="": year_published = None # save user to database #book = Book(title, author, filename, cover, file_extension) book = Book.query.filter_by(id=id).first() book.title = title book.category = category book.year_published = year_published #authors update book.authors.clear() for i, author in enumerate(input_authors): author_name = author.get("author_name") if author_name: a = db.session.query(Author).filter_by(author_name=author_name).first() if a == None: a = Author(author_name=author_name) db.session.add(a) book.authors.append(a) db.session.commit() flash("%s updated" % (title)) return redirect(url_for('show_book_by_id', id=id)) return render_template('edit_book_detail.html', book=book_to_edit, form=user_form) @app.route('/add-book', methods=['POST', 'GET']) def add_book(): upload_form = UploadForm() if request.method == 'POST': if upload_form.validate_on_submit(): #get data from form title = upload_form.title.data authors = upload_form.author.data category = upload_form.category.data year_published = upload_form.year_published.data if year_published=="": year_published = None #if upload with file if upload_form.upload.data: # check if the post request has the file part if 'file' not in request.files: flash('No file part') return redirect(request.url) file = request.files['file'] # if user does not select file, browser also # submit a empty part without filename if file.filename == '': flash('No selected file') return redirect(request.url) if file and allowed_file(file.filename): filename = secure_filename(file.filename) allbooks = db.session.query(Book).all() id = len(allbooks)+1 new_filename = str(id) +"_"+ filename fullpath = os.path.join(app.config['UPLOAD_FOLDER'], new_filename) name, file_extension = os.path.splitext(new_filename) file.save(fullpath) cover = get_cover(fullpath, name) else: flash('allowed file formats: %s' % ALLOWED_EXTENSIONS) #if upload without file -> wishform, with potential PDF if upload_form.wish.data: #TO DO: make pdf generator #file = open('app/uploads/potential.pdf') #filename = 'potential.pdf' #file_extension = '.pdf' filename = '' file_extension = '' cover = '' book = Book(title, filename, cover, file_extension, category,year_published) db.session.add(book) for author in authors: author_name = author.get("author_name") if author_name: a = db.session.query(Author).filter_by(author_name=author_name).first() if a == None: a = Author(author_name=author_name) db.session.add(a) book.authors.append(a) db.session.commit() flash("%s added to the library" % (title)) return redirect(url_for('show_books')) flash_errors(upload_form) return render_template('add_book.html', form=upload_form) # Flash errors from the form if validation fails def flash_errors(form): for field, errors in form.errors.items(): for error in errors: flash(u"Error in the %s field - %s" % ( getattr(form, field).label.text, error )) #Authors @app.route('/authors/') def show_author_by_id(id): author = Author.query.get(id) if not author: abort (404) else: return render_template('show_author_detail.html', author=author) @app.route('/authors//edit', methods=['POST', 'GET']) def edit_author_by_id(id): return "Ask the programmer." ##stacks @app.route('/stacks') def show_stacks(): stacks = db.session.query(Stack).all() return render_template('show_stacks.html', stacks=stacks) @app.route('/stacks/', methods=['POST', 'GET']) def show_stack_by_id(id): stack = Stack.query.get(id) if not stack: abort (404) else: return render_template('show_stack_detail.html', stack=stack) ## search @app.route('/search/titles//', methods=['POST', 'GET']) def search_results(query): search = SearchForm(request.form) random_order=Book.query.order_by(func.random()).limit(10) results=Book.query.filter(Book.title.contains(query)).all() if not results: upload_form = UploadForm(title= query, author='') return render_template('red_link.html', form=upload_form, title=query) if request.method == 'POST': query = search.search.data results = [] if search.select.data == 'Title': return redirect((url_for('search_results', query=search.search.data))) if search.select.data == 'Category': return redirect((url_for('search_cat', query=search.search.data))) return render_template('results.html', form=search, books=results, books_all=random_order, query=query) @app.route('/search/cat//', methods=['POST', 'GET']) def search_cat(query): search = SearchForm(request.form) random_order=Book.query.order_by(func.random()).limit(10) results=Book.query.filter(Book.category.contains(query)).all() if not results: upload_form = UploadForm(category=query) return render_template('red_link.html', form=upload_form, category=query) if request.method == 'POST': query = search.search.data results = [] if search.select.data == 'Title': return redirect((url_for('search_results', query=search.search.data))) if search.select.data == 'Category': return redirect((url_for('search_cat', query=search.search.data))) return render_template('results.html', form=search, books=results, books_all=random_order, query=query) ### # The API ### @app.route('/api/books', methods=['GET']) def get_books(): books = Book.query.all() data = books_schema.dump(books) #print(errors) return jsonify({'books': data}) @app.route('/api/books/', methods=['GET']) def get_book_by_id(id): book = Book.query.get(id) data = book_schema.dump(book) if not data: return jsonify({"message": "Book could not be found."}), 400 else: return jsonify({'book': data }) ### # The functions below should be applicable to all Flask apps. ### @app.route('/.txt') def send_text_file(file_name): """Send your static text file.""" file_dot_text = file_name + '.txt' return app.send_static_file(file_dot_text) @app.after_request def add_header(response): """ Add headers to both force latest IE rendering engine or Chrome Frame, and also to cache the rendered page for 10 minutes. """ response.headers['X-UA-Compatible'] = 'IE=Edge,chrome=1' response.headers['Cache-Control'] = 'public, max-age=600' return response @app.errorhandler(404) def page_not_found(error): """Custom 404 page.""" return render_template('404.html'), 404 if __name__ == '__main__': app.run(debug=True,host="0.0.0.0",port="8080")