updated with covers and authors

This commit is contained in:
Alex 2018-05-23 14:12:24 +02:00
parent 9461301d21
commit 7e1c504e09
17 changed files with 221 additions and 26 deletions

View File

@ -7,6 +7,7 @@ from werkzeug.utils import secure_filename
basedir = os.path.abspath(os.path.dirname(__file__))
UPLOAD_FOLDER = os.path.join(basedir, 'uploads')
UPLOAD_FOLDER_COVER = os.path.join(basedir, 'uploads/cover')
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
app = Flask(__name__)

Binary file not shown.

Binary file not shown.

View File

@ -1,8 +1,21 @@
from flask_wtf import FlaskForm
from wtforms import StringField, FileField
from wtforms.validators import InputRequired
from wtforms.validators import InputRequired, DataRequired
from wtforms import FieldList
from wtforms import Form as NoCsrfForm
from wtforms.fields import StringField, FormField, SubmitField
from app.models import Book, BookSchema, Author
# - - - Forms - - -
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):
title = StringField('title', validators=[InputRequired()])
author = StringField('author', validators=[InputRequired()])
author = FieldList(FormField(AuthorForm, default=lambda: Author()), min_entries=1)
file = FileField()
class UserForm_Edit(FlaskForm):
title = StringField('title', validators=[InputRequired()])
author = FieldList(FormField(AuthorForm, default=lambda: Author()), min_entries=1)

View File

@ -2,26 +2,44 @@ from app import db
from marshmallow import Schema, fields, ValidationError, pre_load
class Book(db.Model):
__tablename__ = 'books'
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(255))
author = db.Column(db.String(255))
file = db.Column(db.String(255))
cover = db.Column(db.String(255))
fileformat = db.Column(db.String(255))
author = db.relationship('Author')
def __init__(self, title, author, file):
def __init__(self, title, file, cover, fileformat):
self.title = title
self.author = author
self.file = file
self.cover = cover
self.fileformat = fileformat
def __repr__(self):
return '<Title %r>' % self.title
def get_id(self):
return self.id
class Author(db.Model):
__tablename__ = 'authors'
id = db.Column(db.Integer(), primary_key=True)
user_id = db.Column(db.Integer(), db.ForeignKey('books.id'))
author_name = db.Column(db.String(50))
def __init__(self, author_name):
self.author_name = author_name
class BookSchema(Schema):
id = fields.Int(dump_only=True)
title = fields.Str()
author = fields.Str()
file = fields.Str()
cover = fields.Str()
fileformat = fields.Str()
def must_not_be_blank(data):
if not data:

View File

@ -31,8 +31,42 @@ font-style: italic;
display: table;
}
.header{
.container{
padding: 0px 8px;
}
.header input{
height:40px;
width: 500px;
font-size: 30px;
font-weight: bold;
}
.author input{
height:20px;
width: 500px;
font-size: 16px;
}
.footer{
width: 100%;
font-family:'Courier New';
font-weight:100;
font-size:12px;
}
.footer pre{
width: 60px;
margin:0 auto;
font-family:'Courier New';
}
.footer p{
width: 30%;
margin:0 auto;
text-align: center;
font-family:'Courier New';
}

View File

@ -1 +1,32 @@
/* Add your Application JavaScript */
/* Add your Application JavaScript */
$(function() {
$("div[data-toggle=fieldset]").each(function() {
var $this = $(this);
//Add new entry
$this.find("button[data-toggle=fieldset-add-row]").click(function() {
var target = $($(this).data("target"))
console.log(target);
var oldrow = target.find("[data-toggle=fieldset-entry]:last");
var row = oldrow.clone(true, true);
console.log(row.find(":input")[0]);
var elem_id = row.find(":input")[0].id;
var elem_num = parseInt(elem_id.replace(/.*-(\d{1,4})-.*/m, '$1')) + 1;
row.attr('data-id', elem_num);
row.find(":input").each(function() {
console.log(this);
var id = $(this).attr('id').replace('-' + (elem_num - 1) + '-', '-' + (elem_num) + '-');
$(this).attr('name', id).attr('id', id).val('').removeAttr("checked");
});
oldrow.after(row);
}); //End add new entry
//Remove row
$this.find("button[data-toggle=fieldset-remove-row]").click(function() {
if($this.find("[data-toggle=fieldset-entry]").length > 1) {
var thisRow = $(this).closest("[data-toggle=fieldset-entry]");
thisRow.remove();
}
}); //End remove row
});
});

View File

@ -17,7 +17,24 @@
<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>
<div class="form-group">{{ form.author.label }} {{ form.author(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>
{{ form.file }}
<button type="submit" class="btn btn-primary">Upload</button>
</form>

View File

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>XPUB LIB</title>
<title>XPPL</title>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
@ -14,12 +14,15 @@
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link rel="stylesheet" href="/static/css/style.css">
{% block css %} {% endblock%}
</head>
<body>
{% block header %}
<header>
{% include "header.html" %}
</header>
{% endblock %}
<main>
<div class="container">
{% block main %}{% endblock %}
@ -32,5 +35,7 @@
</footer>
{% block js %} {% endblock%}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="{{ url_for("static", filename="js/app.js") }}"></script>
</body>
</html>

View File

@ -1,7 +1,8 @@
<br>
<pre style="font-family:'Courier New'; font-weight:100; font-size:12px;">
<div class="footer">
<pre>
, ,
/////|
///// |
@ -9,7 +10,9 @@
|===| |
|x | |
| p | |
|u b| /
|p l| /
|===|/
'---'
</pre>
<p>XPPL. MADE POSSIBLE BY EXPERIMENTAL PUBLISHING, PZI.</p>
</div>

View File

@ -6,5 +6,4 @@
<li><a href="{{ url_for('about') }}">About</a></li>
</ul>
<div class="clearfix"></div>
</nav>

View File

@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block main %}
<h1 class="header">XPUB LIB</h1>
<h1 class="header">XPPL</h1>
<p class="lead">This is the awesome library of Experimental Publishing. <br>
This might only be one interface to this library:

View File

@ -4,9 +4,19 @@
<div class="container">
<h1 class="header">{{ book.title }}</h1>
<p>Author: {{ book.author }}</p>
<a href="../uploads/{{ book.file }}">download file</a>
<img src="../uploads/cover/{{ book.cover }}" width="200">
<p>Author(s): {% for author in book.author %}
<li> {{ author.author_name }}</li>
{% endfor %}</p>
<a href="../uploads/{{ book.file }}">download {{ book.fileformat }}</a>
<br>
<br>
<a href="{{ url_for('edit_book_by_id', id=book.id )}}">edit</a>
</div>
{% endblock %}

View File

@ -17,13 +17,21 @@
<table style="width:100%">
<tr>
<th>Cover</th>
<th>Title</th>
<th>Author</th>
<th>Filetype</th>
</tr>
{% for book in books %}
<tr>
<td><img src="../uploads/cover/{{ book.cover }}" width="80"></td>
<td><a href="books/{{ book.id }}">{{ book.title }}</a></td>
<td>{{ book.author }}</td>
<td> {% for author in book.author %}
<li> {{ author.author_name }}</li>
{% endfor %}</td>
<td>{{ book.fileformat }}</td>
</tr>
{% endfor %}
</table>

View File

@ -8,11 +8,13 @@ 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
from app.forms import UserForm
from app.models import Book, BookSchema
from app.forms import UserForm, UserForm_Edit
from app.models import Book, BookSchema, Author
from app.cover import get_cover
import os
from werkzeug.utils import secure_filename
# import sqlite3
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
@ -31,6 +33,9 @@ def home():
"""Render website's home page."""
return render_template('home.html')
@app.route('/hello/<name>')
def hello(name):
return "Hello " + name
@app.route('/about/')
def about():
@ -42,20 +47,61 @@ def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'],
filename)
@app.route('/uploads/cover/<filename>')
def uploaded_file_cover(filename):
return send_from_directory(app.config['UPLOAD_FOLDER_COVER'],
filename)
@app.route('/books')
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)
@app.route('/books/<int:id>')
def show_book_by_id(id):
book = Book.query.get(id)
if not book:
abort(404)
return render_template('red_link.html', id=id)
else:
return render_template('show_book_detail.html', book=book)
@app.route('/books/<int:id>/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(user_id=book_to_edit.id).delete()
db.session.commit()
flash("%s deleted from library" % (title))
return redirect(url_for('show_books'))
@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.author)
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']
author = user_form.author.data # You could also have used request.form['email']
# save user to database
#book = Book(title, author, filename, cover, file_extension)
book_to_edit.title = title
db.session.commit()
book = Book.query.filter_by(title=title).first()
author_table = Author.query.filter_by(user_id=book.id).delete()
for this_author in author:
this_author = Author(this_author.get('author_name'))
book.author.append(this_author)
db.session.commit()
flash("%s updated" % (title))
return redirect(url_for('show_books'))
return render_template('edit_book_detail.html', book=book_to_edit, form=user_form)
@app.route('/add-book', methods=['POST', 'GET'])
def add_book():
@ -77,15 +123,25 @@ def add_book():
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
fullpath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
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']
author = user_form.author.data # You could also have used request.form['email']
# save user to database
book = Book(title, author, filename)
print(author)
print(len(author))
book = Book(title, filename, cover, file_extension)
db.session.add(book)
db.session.commit()
book = Book.query.filter_by(title=title).first()
for this_author in author:
this_author = Author(this_author.get('author_name'))
book.author.append(this_author)
db.session.commit()
#author = "hallo"
# save user to database
flash("%s added to the library" % (title))
return redirect(url_for('show_books'))
else: