Los archivos se guardan en la base de datos y se agregaron categorias

Si, creo que eso nada mas
This commit is contained in:
Daniel Cortes
2019-03-09 02:44:17 -03:00
parent fcf30823f7
commit cd2087c567
12 changed files with 340 additions and 41 deletions

View File

@@ -29,6 +29,9 @@ def create_app():
from . import auth from . import auth
app.register_blueprint(auth.bp) app.register_blueprint(auth.bp)
from . import categories
app.register_blueprint(categories.bp)
from . import about from . import about
app.register_blueprint(about.bp) app.register_blueprint(about.bp)
app.add_url_rule('/about', endpoint='about') app.add_url_rule('/about', endpoint='about')
@@ -37,4 +40,5 @@ def create_app():
app.register_blueprint(files.bp) app.register_blueprint(files.bp)
app.add_url_rule('/', endpoint='index') app.add_url_rule('/', endpoint='index')
return app return app

88
files/categories.py Normal file
View File

@@ -0,0 +1,88 @@
from flask import Flask, Blueprint, flash, request, redirect, url_for, current_app, render_template, jsonify
from werkzeug.exceptions import abort
from files.db import get_db
from files.auth import admin_required
from files.files import get_files_by_category
bp = Blueprint('categories', __name__, url_prefix='/categories')
def get_categories():
db = get_db()
categories = db.execute(
'SELECT id, name'
' FROM categories'
' ORDER BY name DESC'
).fetchall()
return categories
def get_category(id):
db = get_db()
category = db.execute(
'SELECT id, name'
' FROM categories'
' WHERE id = ?'
' LIMIT 1',
(id,)
).fetchone()
return category
def get_files_by_category(id):
db = get_db()
files = db.execute(
'SELECT id, filename, private'
' FROM files'
' WHERE category = ?'
' ORDER BY filename DESC',
(id,)
).fetchall()
return files
@bp.route('/')
def index():
categories = get_categories()
return render_template('categories/index.html', categories=categories)
@bp.route('/create', methods=['GET', 'POST'])
@admin_required
def create():
if request.method == 'POST':
name = request.form['name']
error = None
if not name:
error = "Name is required"
if error is not None:
flash(error)
else:
db = get_db()
db.execute(
'INSERT INTO categories (name)'
' VALUES (?)',
(name,)
)
db.commit()
return redirect(url_for('categories.index'))
return render_template('categories/create.html')
@bp.route('<int:id>')
def view(id):
category = get_category(id)
files = get_files_by_category(id)
return render_template('categories/view.html', category=category, files=files)
@bp.route('/<int:id>/update')
@admin_required
def update():
pass
@bp.route('/<int:id>/delete')
@admin_required
def delete():
pass

View File

@@ -37,6 +37,10 @@ def generate_admin():
) )
db.commit() db.commit()
def generate_files():
pass
@click.command('init-db') @click.command('init-db')
@with_appcontext @with_appcontext
def init_db_command(): def init_db_command():
@@ -51,6 +55,18 @@ def generate_admin_command():
generate_admin() generate_admin()
click.echo('The admin was created') click.echo('The admin was created')
@click.command('generate-files')
@with_appcontext
def generate_files_command():
"""
Generates the rows in the database for the files currently uploaded
They all will have default privacy, so, public
"""
generate_files()
click.echo('files generated')
def init_app(app): def init_app(app):
app.teardown_appcontext(close_db) app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command) app.cli.add_command(init_db_command)

View File

@@ -1,12 +1,13 @@
import os import os
import random import random
from flask import Flask, Blueprint, flash, request, redirect, url_for, current_app, render_template, send_from_directory from flask import Flask, Blueprint, flash, request, redirect, url_for, current_app, render_template, send_from_directory, g
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
from werkzeug.exceptions import abort from werkzeug.exceptions import abort
from files.auth import admin_required from files.auth import admin_required
from files.db import get_db
bp = Blueprint('files', __name__) bp = Blueprint('files', __name__)
@@ -18,62 +19,194 @@ def get_extension(filename):
def get_path_in_upload(filename): def get_path_in_upload(filename):
return os.path.join(current_app.config['UPLOAD_FOLDER'], filename) return os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
def save_file(file, private, category):
if private is None:
is_private = 0
else:
is_private = 1
db = get_db()
filename = secure_filename(file.filename)
db.execute(
'INSERT INTO files (filename, private, category)'
' VALUES (?,?,?)',
(filename, is_private, category['id'],)
)
file.save(get_path_in_upload(filename))
db.commit()
return filename
def _rename_file(file, new_name):
db = get_db()
new_name = secure_filename(new_name)
db.execute(
'UPDATE files'
' SET filename = ?'
' WHERE id = ?',
(new_name, file['id'],)
)
os.rename(get_path_in_upload(file['filename']), get_path_in_upload(new_name))
db.commit()
return new_name
def _delete_file(file):
db = get_db()
db.execute(
'DELETE from files'
' WHERE id = ?',
(file['id'],)
)
os.remove(get_path_in_upload(file['filename']))
db.commit()
def get_files():
db = get_db()
files = db.execute(
'SELECT id, filename, private, category'
' FROM files'
' ORDER BY filename'
).fetchall()
return files
def get_public_files():
db = get_db()
files = db.execute(
'SELECT id, filename, private, category'
' FROM files'
' WHERE private = false'
' ORDER BY filename'
).fetchall()
return files
def get_files_by_category(id):
db = get_db()
files = db.execute(
'SELECT id, filename, private'
' FROM files'
' WHERE category = ?'
' ORDER BY filename',
(id,)
).fetchall()
def get_file(id):
db = get_db()
file = db.execute(
'SELECT id, filename, private, category'
' FROM files'
' WHERE id = ?'
' LIMIT 1',
(id,)
).fetchone()
return file
def get_categories():
db = get_db()
categories = db.execute(
'SELECT id, name'
' FROM categories'
' ORDER BY name'
).fetchall()
return categories
def get_category(id):
db = get_db()
category = db.execute(
'SELECT id, name'
' FROM categories'
' WHERE id = ?'
' LIMIT 1',
(id,)
).fetchone()
return category
@bp.route('/', methods=['GET', 'POST']) @bp.route('/', methods=['GET', 'POST'])
def index(): def index():
filenames = os.listdir(current_app.config['UPLOAD_FOLDER']) if g.user is None:
return render_template('files/index.html', filenames=filenames) files = get_public_files()
else:
files = get_files()
return render_template('files/index.html', files=files)
@bp.route('/upload', methods=['GET', 'POST']) @bp.route('/upload', methods=['GET', 'POST'])
@admin_required @admin_required
def upload_file(): def upload_file():
db = get_db()
if request.method == 'POST': if request.method == 'POST':
if 'file' not in request.files: if 'file' not in request.files:
flash('No file part') flash('No file part')
return redirect(request.url) return redirect(request.url)
file = request.files['file'] else:
file = request.files['file']
if 'private' not in request.form:
private = None
else:
private = request.form['private']
if 'category' not in request.form:
flash('No category selected')
return redirect(request.url)
else:
category = get_category(request.form['category'])
if file.filename == '': if file.filename == '':
flash('No seleted file') flash('No seleted file')
return rediret(request.url) return redirect(request.url)
if file: if file:
filename = secure_filename(file.filename) filename = save_file(file, private, category)
file.save(get_path_in_upload(filename)) return redirect(url_for('files.index'))
return render_template('files/upload.html', categories=get_categories())
return redirect(url_for('files.preview_file', filename=filename)) @bp.route('/preview/<int:id>')
return render_template('files/upload.html') def preview_file(id):
file = get_file(id)
@bp.route('/preview/<path:filename>') if (file['private'] == 1 and g.user is not None) or (file['private'] == 0):
def preview_file(filename): return render_template('files/preview.html', file=file)
file = os.path.isfile(get_path_in_upload(filename))
if os.path.isfile(get_path_in_upload(filename)):
return render_template('files/preview.html', filename=filename)
else: else:
abort(404) return abort(404)
@bp.route('/rename/<path:filename>', methods=['POST']) @bp.route('/rename/<int:id>', methods=['POST'])
@admin_required @admin_required
def rename_file(filename): def rename_file(id):
if request.method == 'POST' and os.path.isfile(get_path_in_upload(filename)): if request.method == 'POST':
file = get_file(id)
new_name = request.form['new_name'].lower() new_name = request.form['new_name'].lower()
extension = filename.rsplit('.', 1)[1].lower() extension = file['filename'].rsplit('.', 1)[1].lower()
if "." in new_name and get_extension(new_name): if "." in new_name and get_extension(new_name):
new_name = new_name.rsplit('.',1)[0] + '.' + extension new_name = new_name.rsplit('.',1)[0] + '.' + extension
else: else:
new_name = new_name + '.' + extension new_name = new_name + '.' + extension
_rename_file(file, new_name)
return redirect(url_for('files.preview_file', id=file['id']))
new_name = secure_filename(new_name) @bp.route('/delete/<int:id>', methods=['POST'])
os.rename(get_path_in_upload(filename), get_path_in_upload(new_name))
return redirect(url_for('files.preview_file', filename=new_name))
@bp.route('/delete/<path:filename>', methods=['POST'])
@admin_required @admin_required
def delete_file(filename): def delete_file(id):
full_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename) if request.method == 'POST':
file = get_file(id)
if request.method == 'POST' and os.path.isfile(full_path): print(file)
os.remove(full_path) _delete_file(file)
return redirect(url_for('index')) return redirect(url_for('index'))
else: else:
abort(404) abort(404)

View File

@@ -63,7 +63,7 @@ input[type="button"].button-primary:focus {
border-color: var(--secondary-color); border-color: var(--secondary-color);
} }
.file-listing{ .grid{
display: grid; display: grid;
grid-template-columns: repeat(5, 1fr); grid-template-columns: repeat(5, 1fr);
grid-gap: 3rem 1rem; grid-gap: 3rem 1rem;

View File

@@ -12,7 +12,9 @@
<nav class="navbar"> <nav class="navbar">
<div class="container"> <div class="container">
<a href="{{ url_for('index') }}" class="nav-brand">/files</a> <a href="{{ url_for('index') }}" class="nav-brand">/files</a>
<a href="{{ url_for('categories.index') }}" class="nav-link">/categories</a>
<a href="{{ url_for('about') }}" class="nav-link">/about</a> <a href="{{ url_for('about') }}" class="nav-link">/about</a>
{% if g.user %} {% if g.user %}
<a href="{{ url_for('files.upload_file') }}" class="nav-link">/upload</a> <a href="{{ url_for('files.upload_file') }}" class="nav-link">/upload</a>
<a href="{{ url_for('auth.logout') }}" class="nav-link">/logout</a> <a href="{{ url_for('auth.logout') }}" class="nav-link">/logout</a>
@@ -21,6 +23,12 @@
</nav> </nav>
<section class="container"> <section class="container">
<ul>
{% for message in get_flashed_messages() %}
<li class="flash">{{ message }}</li>
{% endfor %}
</ul>
{% block content %}{% endblock %} {% block content %}{% endblock %}
</section> </section>
</body> </body>

View File

@@ -0,0 +1,12 @@
{% extends 'base.html' %}
{% block title %}Categories{% endblock %}
{% block content %}
<h3>Create a new Category</h3>
<form method="post">
<label for="name">~/name</label>
<input type="text" class="u-full-width" name="name" id="name">
<input type="submit" class="button-primary" value="create">
</form>
{% endblock %}

View File

@@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block title %}category{% endblock %}
{% block content %}
<div class="grid">
{% for category in categories %}
<a href="{{ url_for('categories.view', id=category.id) }}">{{ category.name }}</a>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block title %}categories/view/{{ category.name }}{% endblock %}
{% block content %}
<h3>{{ category.name }}</h3>
<div class="grid">
{% for file in files %}
<a href="{{ url_for('files.preview_file', id=file.id) }}">{{ file.filename }}</a>
{% endfor %}
</div>
{% endblock %}

View File

@@ -3,9 +3,9 @@
{% block title %}{% endblock %} {% block title %}{% endblock %}
{% block content %} {% block content %}
<div class="file-listing"> <div class="grid">
{% for filename in filenames %} {% for file in files %}
<a href="{{ url_for('files.preview_file', filename=filename) }}">{{ filename }}</a> <a href="{{ url_for('files.preview_file', id=file.id) }}">{{ file.filename}}</a>
{% endfor %} {% endfor %}
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -3,21 +3,21 @@
{% block content %} {% block content %}
{% if g.user %} {% if g.user %}
<form method="post" action={{ url_for('files.delete_file', filename=filename) }}> <form method="post" action={{ url_for('files.delete_file', id=file.id) }}>
<input type="submit" class="button-primary u-pull-right" value="delete"> <input type="submit" class="button-primary u-pull-right" value="delete">
</form> </form>
{% endif %} {% endif %}
<div class="row"> <div class="row">
<h3 class="u-pull-left"><a href="{{ url_for('files.uploaded_file', filename=filename) }}">{{ filename }}</a></h3> <h3 class="u-pull-left"><a href="{{ url_for('files.uploaded_file', filename=file.filename) }}">{{ file.filename }}</a></h3>
</div> </div>
<img src="{{ url_for('files.uploaded_file', filename=filename) }}"> <img src="{{ url_for('files.uploaded_file', filename=file.filename) }}">
{% if g.user %} {% if g.user %}
<form action="{{ url_for('files.rename_file', filename=filename) }}" method="post"> <form action="{{ url_for('files.rename_file', id=file.id) }}" method="post">
<label for="new_name">~/rename</label> <label for="new_name">~/rename</label>
<input type="text" class="u-full-width" id="new_name" name="new_name" value="{{ filename }}"> <input type="text" class="u-full-width" id="new_name" name="new_name" value="{{ file.filename }}">
<input type="submit" class="button-primary u-pull-right" value="rename"> <input type="submit" class="button-primary u-pull-right" value="rename">
</form> </form>
{% endif %} {% endif %}

View File

@@ -4,7 +4,19 @@
{% block content %} {% block content %}
<form method="post" enctype="multipart/form-data"> <form method="post" enctype="multipart/form-data">
<input type="file" class="u-full-width" name="file"> <label for="file">~/file</label>
<input type="file" class="u-full-width" name="file" id="file">
<label for="category">~/category</label>
<select class="u-full-width" name="category" id="category">
{% for category in categories %}
<option value="{{ category.id }}">{{ category.name }}</option>
{% endfor %}
</select>
<label for="private">~/private</label>
<label>
<input type="checkbox" name="private" id="private">
</label>
<input type="submit" class="button-primary" value="upload"> <input type="submit" class="button-primary" value="upload">
</form> </form>
{% endblock %} {% endblock %}