comics captcha and view fix
This commit is contained in:
parent
3fac6070ca
commit
db675ccf36
24
app.py
24
app.py
@ -160,14 +160,11 @@ def view(content_type, id):
|
||||
content = Comic.query.get_or_404(id)
|
||||
comments = Comments.query.filter_by(comic_id=id).order_by(Comments.comment_date.desc()).all()
|
||||
|
||||
comic_pages_dir = os.path.join(app.config['UPLOAD_FOLDER']['comics'], content.comic_folder)
|
||||
comic_pages = ComicPage.query.filter_by(comic_id=id).order_by(ComicPage.page_number).all()
|
||||
|
||||
if not os.path.exists(comic_pages_dir):
|
||||
if not comic_pages:
|
||||
return render_template('error.html', message="Comic pages not found")
|
||||
|
||||
comic_pages = os.listdir(comic_pages_dir)
|
||||
comic_pages = sorted(comic_pages)
|
||||
|
||||
all_comics = Comic.query.order_by(Comic.id).all()
|
||||
comic_ids = [comic.id for comic in all_comics]
|
||||
current_index = comic_ids.index(id)
|
||||
@ -530,28 +527,32 @@ async def comic_edit(comic_id):
|
||||
if action == 'delete' and (page_id := request.form.get('page')):
|
||||
page = ComicPage.query.get(page_id)
|
||||
if page:
|
||||
os.remove(page.file_path)
|
||||
os.remove(page.file_path.replace('\\', '/'))
|
||||
db.session.delete(page)
|
||||
db.session.commit()
|
||||
pages = ComicPage.query.filter_by(comic_id=comic.id).order_by(ComicPage.page_number).all()
|
||||
for i, page in enumerate(pages, start=1):
|
||||
page.page_number = i
|
||||
db.session.commit()
|
||||
|
||||
elif action == 'update' and (page_id := request.form.get('page')) and 'new_page' in request.files:
|
||||
new_page = request.files['new_page']
|
||||
filename = f"{uuid.uuid4().hex}.webp"
|
||||
file_path = os.path.join(cfp, filename)
|
||||
file_path = os.path.join(cfp, filename).replace('\\', '/')
|
||||
webp_image = await convert_to_webp(new_page)
|
||||
async with aiofiles.open(file_path, 'wb') as f:
|
||||
await f.write(webp_image.read())
|
||||
|
||||
page = ComicPage.query.get(page_id)
|
||||
if page:
|
||||
os.remove(page.file_path)
|
||||
os.remove(page.file_path.replace('\\', '/'))
|
||||
page.file_path = file_path
|
||||
db.session.commit()
|
||||
|
||||
elif action == 'add' and 'new_page' in request.files:
|
||||
new_page = request.files['new_page']
|
||||
filename = f"{uuid.uuid4().hex}.webp"
|
||||
file_path = os.path.join(cfp, filename)
|
||||
file_path = os.path.join(cfp, filename).replace('\\', '/')
|
||||
webp_image = await convert_to_webp(new_page)
|
||||
async with aiofiles.open(file_path, 'wb') as f:
|
||||
await f.write(webp_image.read())
|
||||
@ -562,7 +563,8 @@ async def comic_edit(comic_id):
|
||||
|
||||
return redirect(url_for('comic_edit', comic_id=comic.id))
|
||||
|
||||
return render_template('comic_edit.html', comic=comic, comic_pages=comic.pages, form=form)
|
||||
comic_pages = ComicPage.query.filter_by(comic_id=comic.id).order_by(ComicPage.page_number).all()
|
||||
return render_template('comic_edit.html', comic=comic, comic_pages=comic_pages, form=form)
|
||||
|
||||
def update_related_tables(old_username, new_username):
|
||||
|
||||
@ -862,4 +864,4 @@ def buy_item(item_id):
|
||||
if __name__ == '__main__':
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
app.run(debug=True)
|
||||
app.run(debug=False)
|
@ -29,7 +29,6 @@ from config import Config
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, PasswordField, SubmitField, FileField, BooleanField
|
||||
from wtforms.validators import DataRequired
|
||||
from flask_wtf import RecaptchaField
|
||||
from flask_wtf.file import FileAllowed
|
||||
|
||||
db = SQLAlchemy()
|
||||
@ -220,6 +219,14 @@ class UploadVideoForm(FlaskForm):
|
||||
submit = SubmitField('Upload')
|
||||
agree_with_rules = BooleanField('I agree with the publication rules', validators=[DataRequired()])
|
||||
|
||||
class UploadComicForm(FlaskForm):
|
||||
title = StringField('Comic Name', validators=[DataRequired()])
|
||||
thumbnail = FileField('Thumbnail', validators=[DataRequired()])
|
||||
tags = StringField('Tags (comma-separated)')
|
||||
recaptcha = RecaptchaField()
|
||||
agree_with_rules = BooleanField('I agree with the publication rules', validators=[DataRequired(message="You must agree with the publication rules.")])
|
||||
submit = SubmitField('Upload')
|
||||
|
||||
class EditTagsForm(FlaskForm):
|
||||
tags = StringField('Tags', validators=[DataRequired(), Length(max=100)], render_kw={"placeholder": "Enter tags"})
|
||||
submit = SubmitField('Save')
|
||||
|
15
static/js/comic_upload.js
Normal file
15
static/js/comic_upload.js
Normal file
@ -0,0 +1,15 @@
|
||||
let pageCount = 1;
|
||||
const maxPages = 64;
|
||||
|
||||
function addPage() {
|
||||
if (pageCount >= maxPages) {
|
||||
alert(`You can't add more than ${maxPages} pages!`);
|
||||
return;
|
||||
}
|
||||
|
||||
pageCount++;
|
||||
const newPage = document.createElement("div");
|
||||
newPage.classList.add("form-group");
|
||||
newPage.innerHTML = `<label>Page ${pageCount}:</label><input type="file" name="pages[]" class="file-input" accept="image/*" required>`;
|
||||
document.getElementById("pages").appendChild(newPage);
|
||||
}
|
@ -26,8 +26,8 @@
|
||||
<ul>
|
||||
{% for page in comic_pages %}
|
||||
<li>
|
||||
<img src="{{ url_for('static', filename=page.file_path) }}" alt="Comic Page {{ loop.index }}">
|
||||
<h3>Page {{ loop.index }}</h3>
|
||||
<img src="{{ url_for('static', filename=page.file_path) }}" alt="Comic Page {{ page.page_number }}">
|
||||
<h3>Page {{ page.page_number }}</h3>
|
||||
<div class="form-group">
|
||||
<form method="POST" action="{{ url_for('comic_edit', comic_id=comic.id) }}" class="form-group">
|
||||
{{ form.hidden_tag() }}
|
||||
|
@ -5,30 +5,26 @@
|
||||
<meta charset="UTF-8">
|
||||
<title>🫐comic upload - artberry🫐</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/comic_upload.css') }}">
|
||||
<link rel="icon" href="{{ url_for('static', filename='artberry.ico') }}" type="image/x-icon">
|
||||
|
||||
<link rel="icon" href="{{ url_for('static', filename='artberry.ico') }}" type="image/x-icon">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@400&display=swap" rel="stylesheet">
|
||||
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Upload Comic</h1>
|
||||
<form class="upload-comic-form" method="POST" action="{{ url_for('upload.comic_upload') }}" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="form-group">
|
||||
<label for="title">Comic Name:</label>
|
||||
<input type="text" name="title" class="input-field" required>
|
||||
{{ form.title.label }}
|
||||
{{ form.title(class="input-field") }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="thumbnail">Thumbnail:</label>
|
||||
<input type="file" name="thumbnail" class="file-input" accept="image/*" required>
|
||||
{{ form.thumbnail.label }}
|
||||
{{ form.thumbnail(class="file-input", accept="image/*") }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="tags">Tags:</label>
|
||||
<input type="text" name="tags" class="input-field" placeholder="Enter tags, separated by commas">
|
||||
{{ form.tags.label }}
|
||||
{{ form.tags(class="input-field", placeholder="Enter tags, separated by commas") }}
|
||||
</div>
|
||||
|
||||
<div id="pages">
|
||||
<div class="form-group">
|
||||
<label>Page 1:</label>
|
||||
@ -36,24 +32,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<button class="button" type="button" onclick="addPage()">Add Page:</button>
|
||||
<button type="submit" class="button">Upload Comic:</button>
|
||||
<div class="form-group">
|
||||
{{ form.recaptcha }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ form.agree_with_rules.label }}
|
||||
{{ form.agree_with_rules }}
|
||||
</div>
|
||||
{{ form.submit(class="button") }}
|
||||
</form>
|
||||
<script>
|
||||
let pageCount = 1;
|
||||
const maxPages = 64;
|
||||
|
||||
function addPage() {
|
||||
if (pageCount >= maxPages) {
|
||||
alert(`You cant add more than ${maxPages} pages!`);
|
||||
return;
|
||||
}
|
||||
|
||||
pageCount++;
|
||||
const newPage = document.createElement("div");
|
||||
newPage.classList.add("form-group");
|
||||
newPage.innerHTML = `<label>Page ${pageCount}:</label><input type="file" name="pages[]" class="file-input" accept="image/*" required>`;
|
||||
document.getElementById("pages").appendChild(newPage);
|
||||
}
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/comic_upload.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
@ -43,13 +43,13 @@
|
||||
<div class="comic-pages">
|
||||
{% if comic_pages %}
|
||||
{% for page in comic_pages %}
|
||||
<img src="{{ url_for('static', filename='comics/' + content.comic_folder + '/' + page) }}" alt="Page {{ loop.index }}">
|
||||
<img src="{{ url_for('static', filename=page.file_path.replace('static/', '').replace('\\', '/')) }}" alt="Page {{ page.page_number }}">
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>No pages available for this comic.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated and current_user.username == content.username %}
|
||||
<form method="POST" action="{{ url_for('delete', content_type=content_type, content_id=content.id) }}">
|
||||
|
119
upload.py
119
upload.py
@ -4,7 +4,7 @@ import aiofiles
|
||||
from flask import Blueprint, render_template, redirect, url_for, request, current_app
|
||||
from flask_login import login_required, current_user
|
||||
from werkzeug.utils import secure_filename
|
||||
from models import db, Image, Video, Comic, ComicPage, Post, Cookies, UploadForm, UploadVideoForm
|
||||
from models import db, Image, Video, Comic, ComicPage, Post, Cookies, UploadForm, UploadVideoForm, UploadComicForm
|
||||
from utils import allowed_file, check_file_content, check_file_size, convert_to_webp, generate_unique_filename
|
||||
|
||||
upload_bp = Blueprint('upload', __name__)
|
||||
@ -102,62 +102,69 @@ async def upload_video():
|
||||
@upload_bp.route('/comic_upload', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
async def comic_upload():
|
||||
if request.method == 'POST':
|
||||
ct = request.files['thumbnail']
|
||||
n = request.form['title']
|
||||
tags = request.form.get('tags', '')
|
||||
|
||||
allowed_image_mime_types = {'image/png', 'image/jpeg', 'image/gif', 'image/webp'}
|
||||
|
||||
if db.session.execute(db.select(Comic).filter_by(name=n)).scalar():
|
||||
return render_template('comic_upload.html')
|
||||
|
||||
if ct:
|
||||
if not (allowed_file(ct.filename, current_app.config['ALLOWED_IMAGE_EXTENSIONS']) and
|
||||
check_file_content(ct, allowed_image_mime_types)):
|
||||
return redirect(url_for('upload.comic_upload'))
|
||||
|
||||
tf = f"{uuid.uuid4().hex}.webp"
|
||||
tp = os.path.join(current_app.config['UPLOAD_FOLDER']['comicthumbs'], tf)
|
||||
webp_thumbnail = await convert_to_webp(ct)
|
||||
async with aiofiles.open(tp, 'wb') as f:
|
||||
await f.write(webp_thumbnail.read())
|
||||
|
||||
cf = os.path.join(current_app.config['UPLOAD_FOLDER']['comics'], n)
|
||||
os.makedirs(cf, exist_ok=True)
|
||||
|
||||
new_comic = Comic(
|
||||
comic_folder=n,
|
||||
comic_thumbnail_file=tf,
|
||||
username=current_user.username,
|
||||
name=n,
|
||||
tags=tags
|
||||
)
|
||||
db.session.add(new_comic)
|
||||
db.session.flush()
|
||||
|
||||
async def save_pages():
|
||||
pages = request.files.getlist('pages[]')
|
||||
for i, p in enumerate(sorted(pages, key=lambda x: x.filename), start=1):
|
||||
if p:
|
||||
if not (allowed_file(p.filename, current_app.config['ALLOWED_IMAGE_EXTENSIONS']) and
|
||||
check_file_content(p, allowed_image_mime_types)):
|
||||
return redirect(url_for('upload.comic_upload'))
|
||||
|
||||
filename = f"{uuid.uuid4().hex}.webp"
|
||||
file_path = os.path.join(cf, filename)
|
||||
webp_page = await convert_to_webp(p)
|
||||
async with aiofiles.open(file_path, 'wb') as f:
|
||||
await f.write(webp_page.read())
|
||||
|
||||
new_page = ComicPage(comic_id=new_comic.id, page_number=i, file_path=file_path)
|
||||
db.session.add(new_page)
|
||||
db.session.commit()
|
||||
|
||||
await save_pages()
|
||||
return redirect(url_for('comics'))
|
||||
form = UploadComicForm()
|
||||
|
||||
return render_template('comic_upload.html')
|
||||
if request.method == 'POST':
|
||||
if form.validate_on_submit():
|
||||
ct = form.thumbnail.data
|
||||
n = form.title.data
|
||||
tags = form.tags.data
|
||||
|
||||
allowed_image_mime_types = {'image/png', 'image/jpeg', 'image/gif', 'image/webp'}
|
||||
|
||||
if db.session.execute(db.select(Comic).filter_by(name=n)).scalar():
|
||||
return render_template('comic_upload.html', form=form)
|
||||
|
||||
if ct:
|
||||
if not (allowed_file(ct.filename, current_app.config['ALLOWED_IMAGE_EXTENSIONS']) and
|
||||
check_file_content(ct, allowed_image_mime_types)):
|
||||
return redirect(url_for('upload.comic_upload'))
|
||||
|
||||
tf = f"{uuid.uuid4().hex}.webp"
|
||||
tp = os.path.join(current_app.config['UPLOAD_FOLDER']['comicthumbs'], tf)
|
||||
webp_thumbnail = await convert_to_webp(ct)
|
||||
async with aiofiles.open(tp, 'wb') as f:
|
||||
await f.write(webp_thumbnail.read())
|
||||
|
||||
cf = os.path.join(current_app.config['UPLOAD_FOLDER']['comics'], n)
|
||||
os.makedirs(cf, exist_ok=True)
|
||||
|
||||
new_comic = Comic(
|
||||
comic_folder=n,
|
||||
comic_thumbnail_file=tf,
|
||||
username=current_user.username,
|
||||
name=n,
|
||||
tags=tags
|
||||
)
|
||||
db.session.add(new_comic)
|
||||
db.session.flush()
|
||||
|
||||
async def save_pages():
|
||||
pages = request.files.getlist('pages[]')
|
||||
for i, p in enumerate(sorted(pages, key=lambda x: x.filename), start=1):
|
||||
if p:
|
||||
if not (allowed_file(p.filename, current_app.config['ALLOWED_IMAGE_EXTENSIONS']) and
|
||||
check_file_content(p, allowed_image_mime_types)):
|
||||
return redirect(url_for('upload.comic_upload'))
|
||||
|
||||
filename = f"{uuid.uuid4().hex}.webp"
|
||||
file_path = os.path.join(cf, filename)
|
||||
webp_page = await convert_to_webp(p)
|
||||
async with aiofiles.open(file_path, 'wb') as f:
|
||||
await f.write(webp_page.read())
|
||||
|
||||
new_page = ComicPage(comic_id=new_comic.id, page_number=i, file_path=file_path)
|
||||
db.session.add(new_page)
|
||||
db.session.commit()
|
||||
|
||||
await save_pages()
|
||||
return redirect(url_for('comics'))
|
||||
else:
|
||||
for field, errors in form.errors.items():
|
||||
for error in errors:
|
||||
pass
|
||||
|
||||
return render_template('comic_upload.html', form=form)
|
||||
|
||||
@upload_bp.route('/upload_post', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
|
Loading…
x
Reference in New Issue
Block a user