Merge pull request 'Adjusting the post editing for images to display the existing image' (#297) from JollyDevelopment/pyfedi:jollydev/edit-image-posts-uses-existing-image into main

Reviewed-on: https://codeberg.org/rimu/pyfedi/pulls/297
This commit is contained in:
rimu 2024-08-18 01:55:52 +00:00
commit 0f4863afcf
5 changed files with 86 additions and 50 deletions

View file

@ -176,6 +176,16 @@ class CreateImageForm(CreatePostForm):
return True
class EditImageForm(CreatePostForm):
image_alt_text = StringField(_l('Alt text'), validators=[Optional(), Length(min=3, max=1500)])
def validate(self, extra_validators=None) -> bool:
if self.communities:
community = Community.query.get(self.communities.data)
if community.is_local() and g.site.allow_local_image_posts is False:
self.communities.errors.append(_l('Images cannot be posted to local communities.'))
return True
class CreatePollForm(CreatePostForm):
mode = SelectField(_('Mode'), validators=[DataRequired()], choices=[('single', _l('Voters choose one option')), ('multiple', _l('Voters choose many options'))], render_kw={'class': 'form-select'})

View file

@ -613,9 +613,13 @@ def add_post(actor, type):
form.finish_in.data = '3d'
if community.posting_warning:
flash(community.posting_warning)
# empty post to pass since add_post.html extends edit_post.html
# and that one checks for a post.image_id for editing image posts
post = None
return render_template('community/add_post.html', title=_('Add post to community'), form=form,
post_type=post_type, community=community,
post_type=post_type, community=community, post=post,
markdown_editor=current_user.markdown_editor, low_bandwidth=False, actor=actor,
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.id),

View file

@ -301,60 +301,64 @@ def save_post(form, post: Post, type: int):
elif type == POST_TYPE_IMAGE:
post.type = POST_TYPE_IMAGE
alt_text = form.image_alt_text.data if form.image_alt_text.data else form.title.data
uploaded_file = request.files['image_file']
if uploaded_file and uploaded_file.filename != '':
if post.image_id:
remove_old_file(post.image_id)
post.image_id = None
if post.image_id is not None:
# editing an existing image post, dont try an upload
pass
else:
uploaded_file = request.files['image_file']
if uploaded_file and uploaded_file.filename != '':
if post.image_id:
remove_old_file(post.image_id)
post.image_id = None
# check if this is an allowed type of file
file_ext = os.path.splitext(uploaded_file.filename)[1]
if file_ext.lower() not in allowed_extensions:
abort(400)
new_filename = gibberish(15)
# check if this is an allowed type of file
file_ext = os.path.splitext(uploaded_file.filename)[1]
if file_ext.lower() not in allowed_extensions:
abort(400)
new_filename = gibberish(15)
# set up the storage directory
directory = 'app/static/media/posts/' + new_filename[0:2] + '/' + new_filename[2:4]
ensure_directory_exists(directory)
# set up the storage directory
directory = 'app/static/media/posts/' + new_filename[0:2] + '/' + new_filename[2:4]
ensure_directory_exists(directory)
# save the file
final_place = os.path.join(directory, new_filename + file_ext)
final_place_medium = os.path.join(directory, new_filename + '_medium.webp')
final_place_thumbnail = os.path.join(directory, new_filename + '_thumbnail.webp')
uploaded_file.seek(0)
uploaded_file.save(final_place)
# save the file
final_place = os.path.join(directory, new_filename + file_ext)
final_place_medium = os.path.join(directory, new_filename + '_medium.webp')
final_place_thumbnail = os.path.join(directory, new_filename + '_thumbnail.webp')
uploaded_file.seek(0)
uploaded_file.save(final_place)
if file_ext.lower() == '.heic':
register_heif_opener()
if file_ext.lower() == '.heic':
register_heif_opener()
Image.MAX_IMAGE_PIXELS = 89478485
Image.MAX_IMAGE_PIXELS = 89478485
# resize if necessary
img = Image.open(final_place)
if '.' + img.format.lower() in allowed_extensions:
img = ImageOps.exif_transpose(img)
img_width = img.width
img_height = img.height
img.thumbnail((2000, 2000))
img.save(final_place)
if img.width > 512 or img.height > 512:
img.thumbnail((512, 512))
img.save(final_place_medium, format="WebP", quality=93)
# resize if necessary
img = Image.open(final_place)
if '.' + img.format.lower() in allowed_extensions:
img = ImageOps.exif_transpose(img)
img_width = img.width
img_height = img.height
# save a second, smaller, version as a thumbnail
img.thumbnail((170, 170))
img.save(final_place_thumbnail, format="WebP", quality=93)
thumbnail_width = img.width
thumbnail_height = img.height
img.thumbnail((2000, 2000))
img.save(final_place)
if img.width > 512 or img.height > 512:
img.thumbnail((512, 512))
img.save(final_place_medium, format="WebP", quality=93)
img_width = img.width
img_height = img.height
# save a second, smaller, version as a thumbnail
img.thumbnail((170, 170))
img.save(final_place_thumbnail, format="WebP", quality=93)
thumbnail_width = img.width
thumbnail_height = img.height
file = File(file_path=final_place_medium, file_name=new_filename + file_ext, alt_text=alt_text,
width=img_width, height=img_height, thumbnail_width=thumbnail_width,
thumbnail_height=thumbnail_height, thumbnail_path=final_place_thumbnail,
source_url=final_place.replace('app/static/', f"https://{current_app.config['SERVER_NAME']}/static/"))
db.session.add(file)
db.session.commit()
post.image_id = file.id
file = File(file_path=final_place_medium, file_name=new_filename + file_ext, alt_text=alt_text,
width=img_width, height=img_height, thumbnail_width=thumbnail_width,
thumbnail_height=thumbnail_height, thumbnail_path=final_place_thumbnail,
source_url=final_place.replace('app/static/', f"https://{current_app.config['SERVER_NAME']}/static/"))
db.session.add(file)
db.session.commit()
post.image_id = file.id
elif type == POST_TYPE_VIDEO:
form.video_url.data = form.video_url.data.strip()
url_changed = post.id is None or form.video_url.data != post.url

View file

@ -14,7 +14,7 @@ from app.activitypub.util import notify_about_post_reply, inform_followers_of_po
from app.community.util import save_post, send_to_remote_instance
from app.inoculation import inoculation
from app.post.forms import NewReplyForm, ReportPostForm, MeaCulpaForm
from app.community.forms import CreateLinkForm, CreateImageForm, CreateDiscussionForm, CreateVideoForm, CreatePollForm
from app.community.forms import CreateLinkForm, CreateImageForm, CreateDiscussionForm, CreateVideoForm, CreatePollForm, EditImageForm
from app.post.util import post_replies, get_comment_branch, post_reply_count, tags_to_string, url_needs_archive, \
generate_archive_link, body_has_no_archive_link
from app.constants import SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER, SUBSCRIPTION_MODERATOR, POST_TYPE_LINK, \
@ -898,7 +898,7 @@ def post_edit(post_id: int):
elif post.type == POST_TYPE_LINK:
form = CreateLinkForm()
elif post.type == POST_TYPE_IMAGE:
form = CreateImageForm()
form = EditImageForm()
elif post.type == POST_TYPE_VIDEO:
form = CreateVideoForm()
elif post.type == POST_TYPE_POLL:
@ -978,6 +978,7 @@ def post_edit(post_id: int):
if post.type == POST_TYPE_LINK:
form.link_url.data = post.url
elif post.type == POST_TYPE_IMAGE:
# existing_image = True
form.image_alt_text.data = post.image.alt_text
elif post.type == POST_TYPE_VIDEO:
form.video_url.data = post.url
@ -994,7 +995,7 @@ def post_edit(post_id: int):
if not (post.community.is_moderator() or post.community.is_owner() or current_user.is_admin()):
form.sticky.render_kw = {'disabled': True}
return render_template('post/post_edit.html', title=_('Edit post'), form=form,
post_type=post.type, community=post.community,
post_type=post.type, community=post.community, post=post,
markdown_editor=current_user.markdown_editor, mods=mod_list,
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),

View file

@ -17,7 +17,24 @@
{{ render_field(form.link_url) }}
<div id="urlUsed"></div>
{% elif post_type == POST_TYPE_IMAGE %}
{{ render_field(form.image_file) }}
{% if post.image_id -%}
<div class="post_image">
{% if low_bandwidth -%}
<a href="{{ post.image.view_url(resize=True) }}" rel="nofollow ugc"><img src="{{ post.image.medium_url() }}"
alt="{{ post.image.alt_text if post.image.alt_text else post.title }}" fetchpriority="high" referrerpolicy="same-origin"
width="{{ post.image.width }}" height="{{ post.image.height }}" /></a>
{% else -%}
<a href="{{ post.image.view_url() }}" rel="nofollow ugc">
<img src="{{ post.image.view_url(resize=True) }}" lowsrc="{{ post.image.medium_url() }}"
sizes="(max-width: 512px) 100vw, 854px" srcset="{{ post.image.medium_url() }} 512w, {{ post.image.view_url(resize=True) }} 1024w"
alt="{{ post.image.alt_text if post.image.alt_text else post.title }}"
fetchpriority="high" referrerpolicy="same-origin" >
</a>
{% endif -%}
</div>
{% else %}
{{ render_field(form.image_file) }}
{% endif %}
{{ render_field(form.image_alt_text) }}
<small class="field_hint">{{ _('Describe the image, to help visually impaired people.') }}</small>
{% elif post_type == POST_TYPE_VIDEO %}