Browse Source

updated with covers and authors

ansible-setup-and-deploy
Alex 6 years ago
parent
commit
7e1c504e09
  1. 1
      app/__init__.py
  2. BIN
      app/__pycache__/__init__.cpython-36.pyc
  3. BIN
      app/__pycache__/forms.cpython-36.pyc
  4. BIN
      app/__pycache__/models.cpython-36.pyc
  5. BIN
      app/__pycache__/views.cpython-36.pyc
  6. 17
      app/forms.py
  7. 26
      app/models.py
  8. 36
      app/static/css/style.css
  9. 33
      app/static/js/app.js
  10. 19
      app/templates/add_book.html
  11. 7
      app/templates/base.html
  12. 7
      app/templates/footer.html
  13. 1
      app/templates/header.html
  14. 2
      app/templates/home.html
  15. 14
      app/templates/show_book_detail.html
  16. 10
      app/templates/show_books.html
  17. 72
      app/views.py

1
app/__init__.py

@ -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__)

BIN
app/__pycache__/__init__.cpython-36.pyc

Binary file not shown.

BIN
app/__pycache__/forms.cpython-36.pyc

Binary file not shown.

BIN
app/__pycache__/models.cpython-36.pyc

Binary file not shown.

BIN
app/__pycache__/views.cpython-36.pyc

Binary file not shown.

17
app/forms.py

@ -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)

26
app/models.py

@ -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:

36
app/static/css/style.css

@ -31,8 +31,42 @@ font-style: italic;
display: table;
}
.container{
padding: 0px 8px;
.header{
}
.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';
}

33
app/static/js/app.js

@ -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
});
});

19
app/templates/add_book.html

@ -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>

7
app/templates/base.html

@ -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>

7
app/templates/footer.html

@ -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>

1
app/templates/header.html

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

2
app/templates/home.html

@ -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:

14
app/templates/show_book_detail.html

@ -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 %}

10
app/templates/show_books.html

@ -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>

72
app/views.py

@ -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:

Loading…
Cancel
Save