Comenzando a utilizar SQLAlchemy
Tuve que reescribir bastante para lograrlo, pero ya funciona :3
This commit is contained in:
23
.idea/dataSources.xml
generated
Normal file
23
.idea/dataSources.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="files" uuid="630cc1a9-f960-489a-9dd4-5eb988f04598">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/instance/files.sqlite</jdbc-url>
|
||||
<driver-properties>
|
||||
<property name="enable_load_extension" value="true" />
|
||||
</driver-properties>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="files-test" uuid="8b911962-ca9f-4f64-973c-88617733acd2">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/instance/files-test.sqlite</jdbc-url>
|
||||
<driver-properties>
|
||||
<property name="enable_load_extension" value="true" />
|
||||
</driver-properties>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
4
.idea/encodings.xml
generated
Normal file
4
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
|
||||
</project>
|
||||
19
.idea/files.danielcortes.xyz.iml
generated
Normal file
19
.idea/files.danielcortes.xyz.iml
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="TemplatesService">
|
||||
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
|
||||
<option name="TEMPLATE_FOLDERS">
|
||||
<list>
|
||||
<option value="$MODULE_DIR$/files/templates" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="TestRunnerService">
|
||||
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
|
||||
</component>
|
||||
</module>
|
||||
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (files.danielcortes.xyz)" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/files.danielcortes.xyz.iml" filepath="$PROJECT_DIR$/.idea/files.danielcortes.xyz.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -3,42 +3,45 @@ import os
|
||||
from flask import Flask, render_template
|
||||
from werkzeug import SharedDataMiddleware
|
||||
|
||||
|
||||
def create_app():
|
||||
app = Flask(__name__, instance_relative_config=True)
|
||||
|
||||
app.config.from_mapping(
|
||||
DATABASE = os.path.join(app.instance_path, 'files.sqlite'),
|
||||
USERNAME = 'dev',
|
||||
PASSWORD = 'secret',
|
||||
SECRET_KEY = '1337',
|
||||
UPLOAD_FOLDER = 'uploads',
|
||||
ALLOWED_EXTENSIONS = set(['png', 'jpg'])
|
||||
SQLALCHEMY_DATABASE_URI="sqlite:///{}".format(os.path.join(app.instance_path, 'files.sqlite')),
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS=False,
|
||||
USERNAME='dev',
|
||||
PASSWORD='secret',
|
||||
SECRET_KEY='1337',
|
||||
UPLOAD_FOLDER='uploads'
|
||||
)
|
||||
|
||||
app.config.from_pyfile('config.py')
|
||||
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { '/uploads': app.config['UPLOAD_FOLDER'] })
|
||||
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {'/uploads': app.config['UPLOAD_FOLDER']})
|
||||
|
||||
try:
|
||||
os.makedirs(app.instance_path)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
from . import db
|
||||
from files.models import db
|
||||
db.init_app(app)
|
||||
|
||||
from . import auth
|
||||
from files import commands
|
||||
commands.init_app(app)
|
||||
|
||||
from files import auth
|
||||
app.register_blueprint(auth.bp)
|
||||
|
||||
from . import categories
|
||||
from files import categories
|
||||
app.register_blueprint(categories.bp)
|
||||
|
||||
from . import about
|
||||
from files import about
|
||||
app.register_blueprint(about.bp)
|
||||
app.add_url_rule('/about', endpoint='about')
|
||||
|
||||
from . import files
|
||||
from files import files
|
||||
app.register_blueprint(files.bp)
|
||||
app.add_url_rule('/', endpoint='index')
|
||||
|
||||
|
||||
return app
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from files.db import get_db
|
||||
|
||||
from flask import Blueprint, request, render_template, redirect, url_for, flash
|
||||
from files.models import db, Message
|
||||
|
||||
bp = Blueprint('about', __name__, url_prefix='/about')
|
||||
|
||||
|
||||
@bp.route('/', methods=('GET', 'POST'))
|
||||
def about():
|
||||
if request.method == 'POST':
|
||||
@@ -11,7 +11,6 @@ def about():
|
||||
email = request.form['email']
|
||||
message = request.form['message']
|
||||
|
||||
db = get_db()
|
||||
error = None
|
||||
|
||||
if not name:
|
||||
@@ -20,21 +19,18 @@ def about():
|
||||
error = 'Missing email'
|
||||
elif not message:
|
||||
error = 'Empty message'
|
||||
|
||||
|
||||
if error is not None:
|
||||
flash(error)
|
||||
else:
|
||||
db.execute(
|
||||
'INSERT INTO messages'
|
||||
' (name, email, message)'
|
||||
' VALUES (?, ?, ?)',
|
||||
(name, email, message)
|
||||
)
|
||||
db.commit()
|
||||
return redirect(url_for('about.thanks'))
|
||||
m = Message(name, email, message)
|
||||
db.session.add(m)
|
||||
db.session.commit()
|
||||
return redirect(url_for('about.thanks'))
|
||||
|
||||
return render_template('about/about.html')
|
||||
|
||||
|
||||
@bp.route('/thanks')
|
||||
def thanks():
|
||||
return render_template('about/thanks.html')
|
||||
|
||||
@@ -1,47 +1,46 @@
|
||||
import functools
|
||||
|
||||
from files.db import get_db
|
||||
from files.models import db, User
|
||||
|
||||
from werkzeug.exceptions import abort
|
||||
from werkzeug.security import check_password_hash
|
||||
|
||||
from flask import Blueprint, request, flash, render_template, session, g, redirect, url_for
|
||||
|
||||
|
||||
bp = Blueprint('auth', __name__, url_prefix='/auth')
|
||||
|
||||
|
||||
@bp.route('/login', methods=('GET', 'POST'))
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
|
||||
db = get_db()
|
||||
error = None
|
||||
|
||||
user = db.execute(
|
||||
'SELECT * FROM users WHERE username = ?', (username,)
|
||||
).fetchone()
|
||||
user = User.query.filter_by(username=username).first()
|
||||
|
||||
if user is None:
|
||||
error = 'Incorrect username.'
|
||||
elif not check_password_hash(user['password'], password):
|
||||
elif not check_password_hash(user.password, password):
|
||||
error = 'Incorrect password.'
|
||||
|
||||
if error is None:
|
||||
session.clear()
|
||||
session['user_id'] = user['id']
|
||||
session['user_id'] = user.id
|
||||
return redirect(url_for('index'))
|
||||
|
||||
flash(error)
|
||||
|
||||
return render_template('auth/login.html')
|
||||
|
||||
|
||||
@bp.route('/logout')
|
||||
def logout():
|
||||
session.clear()
|
||||
return redirect(url_for('index'))
|
||||
|
||||
|
||||
@bp.before_app_request
|
||||
def load_logged_in_user():
|
||||
user_id = session.get('user_id')
|
||||
@@ -49,9 +48,7 @@ def load_logged_in_user():
|
||||
if user_id is None:
|
||||
g.user = None
|
||||
else:
|
||||
g.user = get_db().execute(
|
||||
'SELECT * FROM users WHERE id = ?', (user_id,)
|
||||
).fetchone()
|
||||
g.user = User.query.get(user_id)
|
||||
|
||||
|
||||
def admin_required(view):
|
||||
@@ -63,4 +60,3 @@ def admin_required(view):
|
||||
return view(**kwargs)
|
||||
|
||||
return wrapped_view
|
||||
|
||||
|
||||
@@ -1,48 +1,15 @@
|
||||
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 flask import Flask, Blueprint, flash, request, redirect, url_for, current_app, render_template, jsonify
|
||||
from files.auth import admin_required
|
||||
from files.files import get_files_by_category
|
||||
from files.models import Category, db
|
||||
|
||||
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)
|
||||
categories = Category.query.all()
|
||||
return render_template('categories/index.html', categories=categories)
|
||||
|
||||
|
||||
@bp.route('/create', methods=['GET', 'POST'])
|
||||
@admin_required
|
||||
@@ -57,21 +24,18 @@ def create():
|
||||
if error is not None:
|
||||
flash(error)
|
||||
else:
|
||||
db = get_db()
|
||||
db.execute(
|
||||
'INSERT INTO categories (name)'
|
||||
' VALUES (?)',
|
||||
(name,)
|
||||
)
|
||||
db.commit()
|
||||
c = Category(name)
|
||||
db.session.add(c)
|
||||
db.session.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)
|
||||
category = Category.query.get(id)
|
||||
files = category.files
|
||||
return render_template('categories/view.html', category=category, files=files)
|
||||
|
||||
|
||||
@@ -80,9 +44,8 @@ def view(id):
|
||||
def update():
|
||||
pass
|
||||
|
||||
|
||||
@bp.route('/<int:id>/delete')
|
||||
@admin_required
|
||||
def delete():
|
||||
pass
|
||||
|
||||
|
||||
|
||||
90
files/commands.py
Normal file
90
files/commands.py
Normal file
@@ -0,0 +1,90 @@
|
||||
import click
|
||||
import os
|
||||
|
||||
from flask import current_app
|
||||
from flask.cli import with_appcontext
|
||||
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
from files.models import db, User, Category, File
|
||||
|
||||
|
||||
def init_db():
|
||||
db.drop_all()
|
||||
db.create_all()
|
||||
|
||||
|
||||
def generate_admin():
|
||||
username = current_app.config['USERNAME']
|
||||
password = current_app.config['PASSWORD']
|
||||
|
||||
u = User(username, generate_password_hash(password))
|
||||
db.session.add(u)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def add_defaults():
|
||||
default_category = Category('Default')
|
||||
db.session.add(default_category)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def add_files():
|
||||
existing_files = os.listdir(current_app.config['UPLOAD_FOLDER'])
|
||||
default_category = Category.query.filter_by(name='Default').first()
|
||||
added = 0
|
||||
|
||||
for f in existing_files:
|
||||
search = File.query.filter_by(filename=f).first()
|
||||
if search is None:
|
||||
file = File(f, 0, default_category.id)
|
||||
db.session.add(file)
|
||||
added += 1
|
||||
db.session.commit()
|
||||
|
||||
return added
|
||||
|
||||
|
||||
@click.command('init-db')
|
||||
@with_appcontext
|
||||
def init_db_command():
|
||||
"""
|
||||
Creates the db file
|
||||
"""
|
||||
init_db()
|
||||
|
||||
|
||||
@click.command("add-defaults")
|
||||
@with_appcontext
|
||||
def add_defaults_command():
|
||||
"""
|
||||
Initializes the database with default data
|
||||
"""
|
||||
add_defaults()
|
||||
click.echo("Defaults added")
|
||||
|
||||
|
||||
@click.command('generate-admin')
|
||||
@with_appcontext
|
||||
def generate_admin_command():
|
||||
"""Creates the admin of the system"""
|
||||
generate_admin()
|
||||
click.echo('The admin was created')
|
||||
|
||||
|
||||
@click.command('add-files')
|
||||
@with_appcontext
|
||||
def add_files_command():
|
||||
"""
|
||||
Generates the rows in the database for the files currently uploaded
|
||||
They all will have default privacy, so, public
|
||||
"""
|
||||
added_size= add_files()
|
||||
click.echo(f'added {added_size} files')
|
||||
|
||||
|
||||
def init_app(app):
|
||||
app.cli.add_command(init_db_command)
|
||||
app.cli.add_command(add_defaults_command)
|
||||
app.cli.add_command(generate_admin_command)
|
||||
app.cli.add_command(add_files_command)
|
||||
77
files/db.py
77
files/db.py
@@ -1,77 +0,0 @@
|
||||
import sqlite3
|
||||
import click
|
||||
|
||||
from flask import current_app, g
|
||||
from flask.cli import with_appcontext
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
def get_db():
|
||||
if 'db' not in g:
|
||||
g.db = sqlite3.connect(
|
||||
current_app.config['DATABASE'],
|
||||
detect_types = sqlite3.PARSE_DECLTYPES
|
||||
)
|
||||
g.db.row_factory = sqlite3.Row
|
||||
return g.db
|
||||
|
||||
def close_db(e=None):
|
||||
db = g.pop('db', None)
|
||||
|
||||
if db is not None:
|
||||
db.close()
|
||||
|
||||
def init_db():
|
||||
db = get_db()
|
||||
|
||||
with current_app.open_resource('schema.sql') as f:
|
||||
db.executescript(f.read().decode('utf8'))
|
||||
|
||||
def generate_admin():
|
||||
db = get_db()
|
||||
username = current_app.config['USERNAME']
|
||||
password = current_app.config['PASSWORD']
|
||||
|
||||
db.execute(
|
||||
'INSERT INTO users (username, password) VALUES (?, ?)',
|
||||
(username, generate_password_hash(password),)
|
||||
)
|
||||
db.commit()
|
||||
|
||||
def generate_files():
|
||||
pass
|
||||
|
||||
|
||||
@click.command('init-db')
|
||||
@with_appcontext
|
||||
def init_db_command():
|
||||
"""Inits the database with it's schema"""
|
||||
init_db()
|
||||
click.echo('The database was initialized')
|
||||
|
||||
@click.command('generate-admin')
|
||||
@with_appcontext
|
||||
def generate_admin_command():
|
||||
"""Creates the admin of the system"""
|
||||
generate_admin()
|
||||
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):
|
||||
app.teardown_appcontext(close_db)
|
||||
app.cli.add_command(init_db_command)
|
||||
app.cli.add_command(generate_admin_command)
|
||||
|
||||
|
||||
|
||||
|
||||
170
files/files.py
170
files/files.py
@@ -1,155 +1,74 @@
|
||||
import os
|
||||
import random
|
||||
|
||||
from flask import Flask, Blueprint, flash, request, redirect, url_for, current_app, render_template, send_from_directory, g
|
||||
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.exceptions import abort
|
||||
from files.models import db, File, Category, User
|
||||
|
||||
from files.auth import admin_required
|
||||
from files.db import get_db
|
||||
|
||||
|
||||
bp = Blueprint('files', __name__)
|
||||
bp.add_url_rule('/uploads/<path:filename>', 'uploaded_file', build_only=True)
|
||||
|
||||
def get_extension(filename):
|
||||
return filename.rsplit('.', 1)[1].lower()
|
||||
|
||||
def get_path_in_upload(filename):
|
||||
def _get_extension(filename):
|
||||
return filename.rsplit('.', 1)[1].lower()
|
||||
|
||||
|
||||
def _get_path_in_upload(filename):
|
||||
return os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
|
||||
|
||||
def save_file(file, private, category):
|
||||
|
||||
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))
|
||||
file.save(_get_path_in_upload(filename))
|
||||
f = File(filename, is_private, category.id)
|
||||
|
||||
db.commit()
|
||||
db.session.add(f)
|
||||
db.session.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))
|
||||
os.rename(_get_path_in_upload(file.filename), _get_path_in_upload(new_name))
|
||||
file.filename = new_name
|
||||
|
||||
db.commit()
|
||||
|
||||
return new_name
|
||||
db.session.commit()
|
||||
|
||||
|
||||
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()
|
||||
os.remove(_get_path_in_upload(file.filename))
|
||||
db.session.delete(file)
|
||||
db.session.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():
|
||||
if g.user is None:
|
||||
files = get_public_files()
|
||||
else:
|
||||
files = get_files()
|
||||
files = File.query.filter_by(private=0).all()
|
||||
else:
|
||||
files = File.query.all()
|
||||
|
||||
return render_template('files/index.html', files=files)
|
||||
|
||||
|
||||
@bp.route('/upload', methods=['GET', 'POST'])
|
||||
@admin_required
|
||||
def upload_file():
|
||||
db = get_db()
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'file' not in request.files:
|
||||
flash('No file part')
|
||||
return redirect(request.url)
|
||||
else:
|
||||
else:
|
||||
file = request.files['file']
|
||||
|
||||
if 'private' not in request.form:
|
||||
@@ -160,23 +79,27 @@ def upload_file():
|
||||
if 'category' not in request.form:
|
||||
flash('No category selected')
|
||||
return redirect(request.url)
|
||||
else:
|
||||
category = get_category(request.form['category'])
|
||||
|
||||
category = Category.query.get(request.form['category'])
|
||||
if category is None:
|
||||
flash('The category selected won\'t exists')
|
||||
return redirect(request.url)
|
||||
|
||||
if file.filename == '':
|
||||
flash('No seleted file')
|
||||
return redirect(request.url)
|
||||
|
||||
if file:
|
||||
filename = save_file(file, private, category)
|
||||
_save_file(file, private, category)
|
||||
return redirect(url_for('files.index'))
|
||||
|
||||
return render_template('files/upload.html', categories=get_categories())
|
||||
|
||||
return render_template('files/upload.html', categories=Category.query.all())
|
||||
|
||||
|
||||
@bp.route('/preview/<int:id>')
|
||||
def preview_file(id):
|
||||
file = get_file(id)
|
||||
if (file['private'] == 1 and g.user is not None) or (file['private'] == 0):
|
||||
file = File.query.get(id)
|
||||
if (file.private == 1 and g.user is not None) or (file.private == 0):
|
||||
return render_template('files/preview.html', file=file)
|
||||
else:
|
||||
return abort(404)
|
||||
@@ -186,28 +109,27 @@ def preview_file(id):
|
||||
@admin_required
|
||||
def rename_file(id):
|
||||
if request.method == 'POST':
|
||||
file = get_file(id)
|
||||
file = File.query.get(id)
|
||||
|
||||
new_name = request.form['new_name'].lower()
|
||||
extension = file['filename'].rsplit('.', 1)[1].lower()
|
||||
extension = file.filename.rsplit('.', 1)[1].lower()
|
||||
|
||||
if "." in new_name and get_extension(new_name):
|
||||
new_name = new_name.rsplit('.',1)[0] + '.' + extension
|
||||
if "." in new_name and _get_extension(new_name):
|
||||
new_name = new_name.rsplit('.', 1)[0] + '.' + extension
|
||||
else:
|
||||
new_name = new_name + '.' + extension
|
||||
|
||||
|
||||
_rename_file(file, new_name)
|
||||
|
||||
return redirect(url_for('files.preview_file', id=file['id']))
|
||||
|
||||
return redirect(url_for('files.preview_file', id=file.id))
|
||||
|
||||
|
||||
@bp.route('/delete/<int:id>', methods=['POST'])
|
||||
@admin_required
|
||||
def delete_file(id):
|
||||
if request.method == 'POST':
|
||||
file = get_file(id)
|
||||
print(file)
|
||||
file = File.query.get(id)
|
||||
_delete_file(file)
|
||||
return redirect(url_for('index'))
|
||||
else:
|
||||
abort(404)
|
||||
|
||||
|
||||
64
files/models.py
Normal file
64
files/models.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from datetime import datetime
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
|
||||
class User(db.Model):
|
||||
__tablename__ = 'users'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String, unique=True, nullable=False)
|
||||
password = db.Column(db.String, nullable=False)
|
||||
|
||||
def __init__(self, username=None, password=None):
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
def __repr__(self):
|
||||
return f'<User {self.username}>'
|
||||
|
||||
|
||||
class Message(db.Model):
|
||||
__tablename__ = 'messages'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String, nullable=False)
|
||||
email = db.Column(db.String, nullable=False)
|
||||
message = db.Column(db.Text, nullable=False)
|
||||
sended = db.Column(db.DateTime, default=datetime.utcnow())
|
||||
|
||||
def __init__(self, name=None, email=None, message=None):
|
||||
self.name = name
|
||||
self.email = email
|
||||
self.message = message
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Message from:{self.name} message:{self.message}>'
|
||||
|
||||
|
||||
class File(db.Model):
|
||||
__tablename__ = 'files'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
filename = db.Column(db.String, nullable=False)
|
||||
private = db.Column(db.Integer, nullable=False)
|
||||
category_id = db.Column(db.Integer, db.ForeignKey('categories.id'), nullable=False)
|
||||
|
||||
def __init__(self, filename=None, private=None, category_id=None):
|
||||
self.filename = filename
|
||||
self.private = private
|
||||
self.category_id = category_id
|
||||
|
||||
def __repr__(self):
|
||||
return f'<File name:{self.filename}>'
|
||||
|
||||
|
||||
class Category(db.Model):
|
||||
__tablename__ = 'categories'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String, nullable=False)
|
||||
files = db.relationship('File', backref='category', lazy=True)
|
||||
|
||||
def __init__(self, name=None):
|
||||
self.name = name
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Category name:{self.name}>'
|
||||
@@ -1,33 +0,0 @@
|
||||
DROP TABLE IF EXISTS users;
|
||||
DROP TABLE IF EXISTS messages;
|
||||
DROP TABLE IF EXISTS files;
|
||||
DROP TABLE IF EXISTS categories;
|
||||
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE messages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
sended TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE files (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
filename TEXT NOT NULL,
|
||||
private INTEGER NOT NULL DEFAULT 0,
|
||||
category INTEGER NOT NULL,
|
||||
FOREIGN KEY(category) REFERENCES categories(id)
|
||||
);
|
||||
|
||||
CREATE TABLE categories (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user