1
1
Fork 0

Great reorganization, rip flask-admin

dev
Jan Kužílek 5 years ago
parent 9464b2f3c0
commit 8255913c58

@ -6,15 +6,16 @@ from flask_migrate import Migrate
from flask_login import LoginManager
from flask_assets import Environment as AssetsEnvironment, Bundle as AssetsBundle
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
# from flask_admin import Admin
# from flask_admin.contrib.sqla import ModelView
db = SQLAlchemy()
migrate = Migrate()
login = LoginManager()
assets = AssetsEnvironment()
admin = Admin()
# THIS FUCKER DARES TO MESS WITH MY BLUEPRINTS (that blueprint collision shitxception)
# admin = Admin()
def create_app():
@ -27,7 +28,7 @@ def create_app():
POST_LIST_THUMB_HEIGHT=200,
POST_UPLOADS=os.path.join(app.instance_path, 'post'),
INSTANCE_NAME='YADC',
POSTS_PER_PAGE=8,
POSTS_PER_PAGE=4,
SQLALCHEMY_ECHO=True,
)
@ -44,17 +45,19 @@ def create_app():
from yadc import models
admin.init_app(app)
admin.add_view(ModelView(models.User, db.session))
admin.add_view(ModelView(models.Post, db.session))
admin.add_view(ModelView(models.Tag, db.session))
admin.add_view(ModelView(models.Comment, db.session))
# admin.init_app(app)
# admin.add_view(ModelView(models.User, db.session))
# admin.add_view(ModelView(models.Post, db.session))
# admin.add_view(ModelView(models.Tag, db.session))
# admin.add_view(ModelView(models.Comment, db.session))
from yadc.bp import main, auth
from yadc.bp import main, post, auth
app.register_blueprint(main.bp)
app.register_blueprint(post.bp, url_prefix='/post')
app.register_blueprint(auth.bp, url_prefix='/user')
login.login_view = 'auth.login'
#assets.url = app.static_url_path
scss = AssetsBundle('default.scss', filters='libsass', output='all.css')
assets.register('scss_all', scss)

@ -8,124 +8,15 @@ from PIL import Image
from sqlalchemy import func
from sqlalchemy.orm import aliased
from werkzeug.urls import Href
from yadc import db
from yadc.forms import UploadPostForm
from yadc.models import FILETYPE, RATING, Post, Tag, post_tags
def query_replace(dic, base=''):
args = request.args.to_dict()
return Href(base)(args.update(dic) or args)
from yadc.models import FILETYPE, RATING, Post, Tag
bp = Blueprint('main', __name__)
@bp.route('/')
def index():
return redirect(url_for('main.posts'))
# @bp.route('/')
@bp.route('/post', defaults={'page': 1})
@bp.route('/post/<int:page>')
def posts(page):
def tags_prepare(posts):
# tags = db.session.query(Tag, func.array_agg(posts.c.id)).join(posts, Tag.posts).group_by(Tag.id).all()
tags = db.session.query(Tag, func.array_agg(Post.id)).join(Tag.posts).filter(Post.id.in_([p.id for p in posts])).group_by(Tag.id).all()
# tagset = set()
# taglist = list()
# for post in posts:
# for tag in post.tags:
# tagset.add(tag)
# taglist.append(tag)
# for tag in tagset:
# tag.count = taglist.count(tag)
for tag,p_ids in tags:
tag.count = len(p_ids)
tag.post_ids = p_ids
tag.endpoint = query_replace({'tags': tag.content.replace(' ','_')}, url_for('main.posts'))
# tags = list(tagset)
tags = [t[0] for t in tags]
tags.sort(key=lambda x: (x.category.value, x.content) )
return tags
def parse_args():
args = request.args
tags = (args.get('tags') or '').split(' ')
tags = [t.replace('_',' ') for t in tags] if tags[0] != '' else []
rating = {r.name : r for r in RATING}.get(args.get('rating')) or RATING.safe
matched_ratings = [r for r in RATING if r.value<=rating.value]
# page = int(args.get('page') or 1)
return (tags, matched_ratings)
f_tags, f_rating = parse_args()
posts_query = Post.query
if len(f_tags)>0:
posts_query = posts_query.join(Post.tags).group_by(Post.id).filter(Tag.content.in_(f_tags)).having(func.count(Post.id)==len(f_tags))
posts_query = posts_query.filter(Post.rating.in_(f_rating)).order_by(Post.created) #.offset((page-1)*posts_on_page).limit(posts_on_page)
posts = posts_query.paginate(page, app.config.get('POSTS_PER_PAGE'))
tags = tags_prepare(posts.items)
flash(parse_args())
# flash(posts.items)
# flash(tags)
return render_template('index.html', posts=posts.items, tags=tags, pagination=posts, query_replace=query_replace)
@bp.route('/post/show/<id>')
def post_show(id):
post = Post.query.filter_by(id=id).first()
# flash(post)
tags_count = db.session.query(Tag, func.count(Post.id)).join(Tag.posts).filter(Post.id==id).join(aliased(Post), Tag.posts).group_by(Tag).all()
for tag_count in tags_count:
tag, count = tag_count
tag.count = count
tag.endpoint = query_replace({'tags': tag.content.replace(' ','_')}, url_for('main.posts'))
return render_template('post.html', post=post, tags=post.tags)
@bp.route('/post/upload', methods=['GET', 'POST'])
@login_required
def post_upload():
form = UploadPostForm(request.form)
if request.method == 'POST' and form.validate():
file = request.files.get(form.post_img.name)
file.data = io.BytesIO(file.read())
# tagy
post = Post(file, source=form.sauce.data, rating=RATING[form.rating.data], author=current_user)
with open(post.image_path, "wb") as f:
f.write(file.data.getbuffer())
# file.seek(0)
# file.save(post.image_path)
with Image.open(file.data) as im:
im = im.convert('RGB')
if post.jpeg_path is not None:
im.save(post.jpeg_path, 'JPEG', quality=80)
im.thumbnail([512,512])
im.save(post.thumb_path, 'JPEG', quality=80)
db.session.add(post)
db.session.commit()
flash('Successfully submitted {}'.format(str(post)))
return redirect(url_for('main.post_upload'))
return render_template('upload.html', form=form)
return redirect(url_for('post.posts'))
@bp.route('/i/<path:path>')
def uploaded_img(path, store='img', exten=None):
@ -147,15 +38,15 @@ def uploaded_thumb(*args, **kwargs):
return uploaded_img(*args, **kwargs, store='thumb', exten='jpg')
@bp.route('/threads')
def threads():
return render_template('index.html')
# @bp.route('/threads')
# def threads():
# return render_template('index.html')
@bp.route('/user/show/<username>')
def user_profile(username):
pass
# @bp.route('/user/show/<username>')
# def user_profile(username):
# pass
@bp.route('/user/settings')
@login_required
def user_settings():
pass
# @bp.route('/user/settings')
# @login_required
# def user_settings():
# pass

@ -0,0 +1,117 @@
import io
import os
from flask import (Blueprint, abort, current_app, flash, redirect,
render_template, request, send_from_directory, url_for)
from flask_login import current_user, login_required
from PIL import Image
from sqlalchemy import func
from sqlalchemy.orm import aliased
from yadc import db
from yadc.forms import UploadPostForm
from yadc.models import FILETYPE, RATING, Post, Tag
from yadc.utils import query_replace
bp = Blueprint('post', __name__)
# @bp.route('/')
@bp.route('', defaults={'page': 1})
@bp.route('/<int:page>')
def posts(page):
def tags_prepare(posts):
# tags = db.session.query(Tag, func.array_agg(posts.c.id)).join(posts, Tag.posts).group_by(Tag.id).all()
tags = db.session.query(Tag, func.array_agg(Post.id)).join(Tag.posts).filter(Post.id.in_([p.id for p in posts])).group_by(Tag.id).all()
# tagset = set()
# taglist = list()
# for post in posts:
# for tag in post.tags:
# tagset.add(tag)
# taglist.append(tag)
# for tag in tagset:
# tag.count = taglist.count(tag)
for tag,p_ids in tags:
tag.count = len(p_ids)
tag.post_ids = p_ids
tag.endpoint = query_replace({'tags': tag.content.replace(' ','_')}, url_for('.posts'))
# tags = list(tagset)
tags = [t[0] for t in tags]
tags.sort(key=lambda x: (x.category.value, x.content) )
return tags
def parse_args():
args = request.args
tags = (args.get('tags') or '').split(' ')
tags = [t.replace('_',' ') for t in tags] if tags[0] != '' else []
rating = {r.name : r for r in RATING}.get(args.get('rating')) or RATING.safe
matched_ratings = [r for r in RATING if r.value<=rating.value]
# page = int(args.get('page') or 1)
return (tags, matched_ratings)
f_tags, f_rating = parse_args()
posts_query = Post.query
if len(f_tags)>0:
posts_query = posts_query.join(Post.tags).group_by(Post.id).filter(Tag.content.in_(f_tags)).having(func.count(Post.id)==len(f_tags))
posts_query = posts_query.filter(Post.rating.in_(f_rating)).order_by(Post.created) #.offset((page-1)*posts_on_page).limit(posts_on_page)
posts = posts_query.paginate(page, current_app.config.get('POSTS_PER_PAGE'))
tags = tags_prepare(posts.items)
flash(parse_args())
# flash(posts.items)
# flash(tags)
return render_template('index.html', posts=posts.items, tags=tags, pagination=posts, query_replace=query_replace)
@bp.route('/show/<id>')
def post_show(id):
post = Post.query.filter_by(id=id).first()
# flash(post)
tags_count = db.session.query(Tag, func.count(Post.id)).join(Tag.posts).filter(Post.id==id).join(aliased(Post), Tag.posts).group_by(Tag).all()
for tag_count in tags_count:
tag, count = tag_count
tag.count = count
tag.endpoint = query_replace({'tags': tag.content.replace(' ','_')}, url_for('.posts'))
return render_template('post.html', post=post, tags=post.tags)
@bp.route('/upload', methods=['GET', 'POST'])
@login_required
def post_upload():
form = UploadPostForm(request.form)
if request.method == 'POST' and form.validate():
file = request.files.get(form.post_img.name)
file.data = io.BytesIO(file.read())
# tagy
post = Post(file, source=form.sauce.data, rating=RATING[form.rating.data], author=current_user)
with open(post.image_path, "wb") as f:
f.write(file.data.getbuffer())
# file.seek(0)
# file.save(post.image_path)
with Image.open(file.data) as im:
im = im.convert('RGB')
if post.jpeg_path is not None:
im.save(post.jpeg_path, 'JPEG', quality=80)
im.thumbnail([512,512])
im.save(post.thumb_path, 'JPEG', quality=80)
db.session.add(post)
db.session.commit()
flash('Successfully submitted {}'.format(str(post)))
return redirect(url_for('.post_upload'))
return render_template('upload.html', form=form)

@ -79,3 +79,6 @@ class UploadPostForm(CSRFForm):
# real_mimetype = Magic(mime=True).from_buffer(file.stream.read())
if client_mimetype not in ['image/png','image/jpeg']:
raise ValidationError('Please select an image file of PNG or JPEG format')
# class CommentForm(CSRFForm):

@ -152,7 +152,7 @@ class Post(TimestampMixin, db.Model):
@property
def image_path(self):
filename = "{}.{}".format(self.md5, 'jpg' if self.filetype is FILETYPE.jpeg else 'png')
return os.path.join(current_app.instance_path, 'post', 'img', filename)
return os.path.join(current_app.config.get('POST_UPLOADS'), 'img', filename)
@property
def jpeg_path(self):
@ -160,12 +160,12 @@ class Post(TimestampMixin, db.Model):
return None
jpeg_filename = "{}.{}".format(self.md5, 'jpg')
return os.path.join(current_app.instance_path, 'post', 'jpeg', jpeg_filename)
return os.path.join(current_app.config.get('POST_UPLOADS'), 'jpeg', jpeg_filename)
@property
def thumb_path(self):
jpeg_filename = "{}.{}".format(self.md5, 'jpg')
return os.path.join(current_app.instance_path, 'post', 'thumb', jpeg_filename)
return os.path.join(current_app.config.get('POST_UPLOADS'), 'thumb', jpeg_filename)
@cached_property
def image_resolution(self):

@ -17,9 +17,8 @@
<span>YaDc</span>
</a>
<nav id="main-nav">
<a href="{{ url_for('main.posts') }}">Posts</a>
<!-- <a href="{{ url_for('main.threads') }}">Threads</a> -->
<a href="{{ url_for('main.post_upload') }}">Upload</a>
<a href="{{ url_for('post.posts') }}">Posts</a>
<a href="{{ url_for('post.post_upload') }}">Upload</a>
<div class="user">
{% if current_user.is_anonymous %}

@ -10,7 +10,7 @@
<div class="posts">
{% for post in posts %}
<figure style="{{ post.flex }}">
<a href="{{ url_for('main.post_show', id=post.id) }}">
<a href="{{ url_for('post.post_show', id=post.id) }}">
<img src="{{ post.url(path=post.image_url, endpoint='thumb') }}" alt="">
</a>
</figure>
@ -27,7 +27,7 @@
</div>
</figure> -->
</div>
{{ render_pagination('main.posts') }}
{{ render_pagination('post.posts') }}
</section>
</div>
{% endblock content %}

@ -1,5 +1,5 @@
{% extends 'base.html' %}
{% from '_includes.html' import tags as tags_block %}
{% from '_includes.html' import render_tags with context %}
{% block content %}
<div class="important_subwrap">
@ -25,11 +25,10 @@
{% endif %}
</article>
{{ tags_block(tags) }}
{{ render_tags() }}
</section>
<section class="post_single">
<div class="image">
<!-- <img src="/static/pixiv/illust_72206228_20191026_131238.jpg" alt=""> -->
<img src="{{ post.url(path=post.image_url, endpoint='jpeg') }}" alt="">
</div>
</section>

@ -6,3 +6,10 @@ def sizeof_fmt(num, suffix='B'):
return "%3.1f%s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f%s%s" % (num, 'Yi', suffix)
from flask import request
from werkzeug.urls import Href
def query_replace(dic, base=''):
args = request.args.to_dict()
return Href(base)(args.update(dic) or args)
Loading…
Cancel
Save