fancy search
This commit is contained in:
parent
676b111e59
commit
7b0b325ba3
@ -11,13 +11,18 @@ class AuthorForm(NoCsrfForm):
|
||||
# this forms is never exposed so we can user the non CSRF version
|
||||
author_name = StringField('Author Name', validators=[DataRequired()])
|
||||
|
||||
class UserForm(FlaskForm):
|
||||
class UploadForm(FlaskForm):
|
||||
title = StringField('title', validators=[InputRequired()])
|
||||
author = FieldList(FormField(AuthorForm, default=lambda: Author()), min_entries=1)
|
||||
category = StringField('category', validators=[InputRequired()])
|
||||
file = FileField()
|
||||
upload = SubmitField(label='Upload')
|
||||
wish = SubmitField(label='''I don't have the file, but wish I did.''')
|
||||
|
||||
class UserForm_Edit(FlaskForm):
|
||||
class EditForm(FlaskForm):
|
||||
title = StringField('title', validators=[InputRequired()])
|
||||
author = FieldList(FormField(AuthorForm, default=lambda: Author()), min_entries=1)
|
||||
category = StringField('category', validators=[InputRequired()])
|
||||
|
||||
class SearchForm(FlaskForm):
|
||||
search = StringField('', validators=[InputRequired()])
|
||||
|
@ -27,13 +27,12 @@ class Book(db.Model):
|
||||
scapeX = db.Column(db.Numeric(10,2))
|
||||
scapeY = db.Column(db.Numeric(10,2))
|
||||
|
||||
def __init__(self, title, file, cover, fileformat, category, stack):
|
||||
def __init__(self, title, file, cover, fileformat, category):
|
||||
self.title = title
|
||||
self.file = file
|
||||
self.cover = cover
|
||||
self.fileformat = fileformat
|
||||
self.category = category
|
||||
self.stack = stack
|
||||
self.scapeX = 0
|
||||
self.scapeY = 0
|
||||
|
||||
|
@ -71,6 +71,34 @@ width: 500px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.search input{
|
||||
margin: 0;
|
||||
float: left;
|
||||
width: 400px;
|
||||
height: 36px;
|
||||
font-size: 20px;
|
||||
font-weight: regular;
|
||||
padding: 2px;
|
||||
background:rgba(50, 50, 50, 0.2);
|
||||
border:0px;
|
||||
}
|
||||
|
||||
.button {
|
||||
height:40px;
|
||||
font-size: 18px;
|
||||
padding:6px 15px;
|
||||
left:0px;
|
||||
border:0px solid #dbdbdb;
|
||||
background-color: grey;
|
||||
color:#fafafa;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color:red;
|
||||
color: #fafafa;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.footer{
|
||||
width: 100%;
|
||||
|
12
app/templates/_formhelpers.html
Normal file
12
app/templates/_formhelpers.html
Normal file
@ -0,0 +1,12 @@
|
||||
{% macro render_field(field) %}
|
||||
<dt>{{ field.label }}
|
||||
<dd>{{ field(**kwargs)|safe }}
|
||||
{% if field.errors %}
|
||||
<ul class=errors>
|
||||
{% for error in field.errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</dd>
|
||||
{% endmacro %}
|
@ -37,7 +37,8 @@
|
||||
<br>
|
||||
<div class="form-group">{{ form.category.label }} {{ form.category(size=20, class="form-control") }}</div>
|
||||
{{ form.file }}
|
||||
<button type="submit" class="btn btn-primary">Upload</button>
|
||||
{{ form.upload }}
|
||||
{{ form.wish }}
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
@ -24,7 +24,48 @@
|
||||
{% block header %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<h1>ID: {{ id }}</h1>
|
||||
<p>red link page</p>
|
||||
<h1>We don't have any results for: {{ title }}</h1>
|
||||
<p><a href="{{ url_for('add_book') }}">upload</a>?</p>
|
||||
<p><a href="{{ url_for('home') }}">go back home</a>?</p>
|
||||
|
||||
|
||||
<div class="container">
|
||||
<h1 class="page-header">Add Book</h1>
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
{% for message in messages %}
|
||||
<li>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<form method="POST" action="{{ url_for('add_book') }}" enctype=multipart/form-data>
|
||||
{{ form.csrf_token }}
|
||||
<div class="form-group">{{ form.title.label }} {{ form.title(size=20, class="form-control") }}</div>
|
||||
<br>
|
||||
<div data-toggle="fieldset" id="phone-fieldset">
|
||||
{{ form.author.label }} <button type="button" data-toggle="fieldset-add-row"
|
||||
data-target="#phone-fieldset">+</button>
|
||||
<table>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
{% for author in form.author %}
|
||||
<tr data-toggle="fieldset-entry">
|
||||
<td>{{ author.author_name }}</td>
|
||||
<td><button type="button" data-toggle="fieldset-remove-row" id="phone-{{loop.index0}}-remove">-</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
<br>
|
||||
<div class="form-group">{{ form.tag.label }} {{ form.tag(size=20, class="form-control") }}</div>
|
||||
{{ form.file }}
|
||||
<button type="submit" class="btn btn-primary">Upload</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
91
app/templates/results.html
Normal file
91
app/templates/results.html
Normal file
@ -0,0 +1,91 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block main %}
|
||||
|
||||
<div class="container">
|
||||
{% from "_formhelpers.html" import render_field %}
|
||||
<form method="POST">
|
||||
<div class="search">
|
||||
{{ render_field(form.search) }} </div>
|
||||
<button type="submit" class="button">Search</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h1 class="page-header">Search Results for: {{ query }}</h1>
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
<div class="alert alert-success">
|
||||
<ul>
|
||||
{% for message in messages %}
|
||||
<li>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<th>Cover</th>
|
||||
<th>Title</th>
|
||||
<th>Author</th>
|
||||
<th>Filetype</th>
|
||||
<th>Tag</th>
|
||||
</tr>
|
||||
{% for book in books %}
|
||||
<tr>
|
||||
<td><img src="/uploads/cover/{{ book.cover }}" width="80"></td>
|
||||
<td><a href="{{url_for('show_book_by_id', id=book.id)}}">{{ book.title }}</a></td>
|
||||
|
||||
<td> {% for author in book.authors %}
|
||||
|
||||
<li><a href="{{url_for('show_author_by_id', id=author.id)}}">{{ author.author_name }}</a> </li>
|
||||
|
||||
{% endfor %}</td>
|
||||
<td>{{ book.fileformat }}</td>
|
||||
<td>{{ book.tag}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container" >
|
||||
<hr>
|
||||
<h2> Other books </h2>
|
||||
|
||||
<table style="width:100%; ">
|
||||
<tr>
|
||||
<th>Cover</th>
|
||||
<th>Title</th>
|
||||
<th>Author</th>
|
||||
<th>Filetype</th>
|
||||
<th>Tag</th>
|
||||
</tr>
|
||||
{% for book in books_all %}
|
||||
<tr>
|
||||
<td><img src="/uploads/cover/{{ book.cover }}" width="80"></td>
|
||||
<td><a href="{{url_for('show_book_by_id', id=book.id)}}">{{ book.title }}</a></td>
|
||||
|
||||
<td> {% for author in book.authors %}
|
||||
|
||||
<li><a href="{{url_for('show_author_by_id', id=author.id)}}">{{ author.author_name }}</a> </li>
|
||||
|
||||
|
||||
{% endfor %}</td>
|
||||
<td>{{ book.fileformat }}</td>
|
||||
<td>{{ book.tag}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<p>
|
||||
<a href="/books"> See all books </a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
@ -2,6 +2,14 @@
|
||||
|
||||
{% block main %}
|
||||
<div class="container">
|
||||
|
||||
{% from "_formhelpers.html" import render_field %}
|
||||
<form method="POST">
|
||||
<div class="search">
|
||||
{{ render_field(form.search) }} </div>
|
||||
<button type="submit" class="button">Search</button>
|
||||
</form>
|
||||
|
||||
<h1 class="page-header">All Books</h1>
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
|
78
app/views.py
78
app/views.py
@ -8,7 +8,8 @@ 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 app.forms import UserForm, UserForm_Edit
|
||||
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
|
||||
|
||||
@ -54,10 +55,13 @@ def uploaded_file_cover(filename):
|
||||
return send_from_directory(app.config['UPLOAD_FOLDER_COVER'],
|
||||
filename)
|
||||
|
||||
@app.route('/books')
|
||||
@app.route('/books', methods= ['POST','GET'])
|
||||
def show_books():
|
||||
books = db.session.query(Book).all() # or you could have used User.query.all()
|
||||
return render_template('show_books.html', books=books)
|
||||
books = db.session.query(Book).all()
|
||||
search = SearchForm(request.form)
|
||||
if request.method == 'POST':
|
||||
return redirect((url_for('search_results', query=search.search.data)))
|
||||
return render_template('show_books.html', books=books, form=search)
|
||||
|
||||
@app.route('/scape', methods=['POST', 'GET'])
|
||||
def scape():
|
||||
@ -100,7 +104,7 @@ def remove_book_by_id(id):
|
||||
@app.route('/books/<int:id>/edit', methods=['POST', 'GET'])
|
||||
def edit_book_by_id(id):
|
||||
book_to_edit = Book.query.filter_by(id=id).first()
|
||||
user_form = UserForm_Edit(title = book_to_edit.title, author =book_to_edit.authors, category = book_to_edit.category )
|
||||
user_form = EditForm(title = book_to_edit.title, author =book_to_edit.authors, category = book_to_edit.category )
|
||||
|
||||
if request.method == 'POST':
|
||||
if user_form.validate_on_submit():
|
||||
@ -148,11 +152,12 @@ def edit_book_by_id(id):
|
||||
|
||||
@app.route('/add-book', methods=['POST', 'GET'])
|
||||
def add_book():
|
||||
user_form = UserForm()
|
||||
upload_form = UploadForm()
|
||||
|
||||
if request.method == 'POST':
|
||||
|
||||
if user_form.validate_on_submit():
|
||||
if upload_form.validate_on_submit():
|
||||
if upload_form.upload.data:
|
||||
# check if the post request has the file part
|
||||
if 'file' not in request.files:
|
||||
flash('No file part')
|
||||
@ -169,9 +174,9 @@ def add_book():
|
||||
name, file_extension = os.path.splitext(filename)
|
||||
file.save(fullpath)
|
||||
cover = get_cover(fullpath, name)
|
||||
title = user_form.title.data # You could also have used request.form['name']
|
||||
authors = user_form.author.data # You could also have used
|
||||
category = user_form.category.data
|
||||
title = upload_form.title.data # You could also have used request.form['name']
|
||||
authors = upload_form.author.data # You could also have used
|
||||
category = upload_form.category.data
|
||||
#print(author)
|
||||
#print(len(author))
|
||||
book = Book(title, filename, cover, file_extension, category)
|
||||
@ -193,8 +198,36 @@ def add_book():
|
||||
else:
|
||||
flash('allowed file formats: %s' % ALLOWED_EXTENSIONS)
|
||||
|
||||
flash_errors(user_form)
|
||||
return render_template('add_book.html', form=user_form)
|
||||
if upload_form.wish.data:
|
||||
file = open('app/uploads/potential.pdf')
|
||||
filename = 'potential.pdf'
|
||||
file_extension = '.pdf'
|
||||
cover = get_cover('app/uploads/potential.pdf', 'default')
|
||||
|
||||
title = upload_form.title.data # You could also have used request.form['name']
|
||||
authors = upload_form.author.data # You could also have used
|
||||
category = upload_form.category.data
|
||||
#print(author)
|
||||
#print(len(author))
|
||||
book = Book(title, filename, cover, file_extension, category)
|
||||
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):
|
||||
@ -235,6 +268,27 @@ def show_stack_by_id(id):
|
||||
else:
|
||||
return render_template('show_stack_detail.html', stack=stack)
|
||||
|
||||
## search
|
||||
|
||||
@app.route('/search/<query>/', methods=['POST', 'GET'])
|
||||
def search_results(query):
|
||||
search = SearchForm(request.form)
|
||||
books_all=Book.query.all()
|
||||
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 = []
|
||||
results=Book.query.filter(Book.title.contains(query)).all()
|
||||
return redirect((url_for('search_results', query=search.search.data)))
|
||||
|
||||
return render_template('results.html', form=search, books=results, books_all=random_order, query=query)
|
||||
|
||||
|
||||
###
|
||||
# The API
|
||||
|
Loading…
Reference in New Issue
Block a user