From 0c646c5cf414c52f44b1f3441a5611b2340fde59 Mon Sep 17 00:00:00 2001 From: rimu <3310831+rimu@users.noreply.github.com> Date: Sat, 5 Oct 2024 18:58:07 +1300 Subject: [PATCH] cross-posting of bot-generated posts #206 --- app/community/routes.py | 13 +++++ app/post/forms.py | 5 ++ app/post/routes.py | 49 ++++++++++++++++++- app/static/scss/_typography.scss | 4 ++ app/static/styles.css | 6 ++- app/static/styles.scss | 2 +- app/templates/post/post_cross_post.html | 25 ++++++++++ app/templates/post/post_options.html | 4 ++ .../post/post_teaser/_utilities_bar.html | 3 ++ 9 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 app/templates/post/post_cross_post.html diff --git a/app/community/routes.py b/app/community/routes.py index 5cc64d20..7c298a87 100644 --- a/app/community/routes.py +++ b/app/community/routes.py @@ -672,6 +672,19 @@ def add_post(actor, type): form.finish_in.data = '3d' if community.posting_warning: flash(community.posting_warning) + + # The source query parameter is used when cross-posting - load the source post's content into the form + if post_type == POST_TYPE_LINK and request.args.get('source'): + source_post = Post.query.get(request.args.get('source')) + if source_post.deleted: + abort(404) + form.title.data = source_post.title + form.body.data = source_post.body + form.nsfw.data = source_post.nsfw + form.nsfl.data = source_post.nsfl + form.language_id.data = source_post.language_id + form.link_url.data = source_post.url + # 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 diff --git a/app/post/forms.py b/app/post/forms.py index bdc24272..eac11655 100644 --- a/app/post/forms.py +++ b/app/post/forms.py @@ -42,3 +42,8 @@ class ReportPostForm(FlaskForm): class MeaCulpaForm(FlaskForm): submit = SubmitField(_l('I changed my mind')) + + +class CrossPostForm(FlaskForm): + which_community = SelectField(_l('Community to post this link to'), validators=[DataRequired()], coerce=int, render_kw={'class': 'form-select'}) + submit = SubmitField(_l('Next')) diff --git a/app/post/routes.py b/app/post/routes.py index 6ba329d5..717f376c 100644 --- a/app/post/routes.py +++ b/app/post/routes.py @@ -13,7 +13,7 @@ from app.activitypub.signature import HttpSignature, post_request, default_conte from app.activitypub.util import notify_about_post_reply, inform_followers_of_post_update 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.post.forms import NewReplyForm, ReportPostForm, MeaCulpaForm, CrossPostForm from app.community.forms import CreateLinkForm, CreateImageForm, CreateDiscussionForm, CreateVideoForm, CreatePollForm, EditImageForm from app.post.util import post_replies, get_comment_branch, tags_to_string, url_needs_archive, \ generate_archive_link, body_has_no_archive_link @@ -1738,3 +1738,50 @@ def post_reply_view_voting_activity(comment_id: int): joined_communities=joined_communities(current_user.get_id()), menu_topics=menu_topics(), site=g.site ) + + +@bp.route('/post//cross-post', methods=['GET', 'POST']) +@login_required +def post_cross_post(post_id: int): + post = Post.query.get_or_404(post_id) + form = CrossPostForm() + which_community = {} + joined = joined_communities(current_user.get_id()) + moderating = moderating_communities(current_user.get_id()) + comms = [] + already_added = set() + for community in moderating: + if community.id not in already_added: + comms.append((community.id, community.display_name())) + already_added.add(community.id) + if len(comms) > 0: + which_community['Moderating'] = comms + comms = [] + for community in joined: + if community.id not in already_added: + comms.append((community.id, community.display_name())) + already_added.add(community.id) + if len(comms) > 0: + which_community['Joined communities'] = comms + + form.which_community.choices = which_community + if form.validate_on_submit(): + community = Community.query.get_or_404(form.which_community.data) + return redirect(url_for('community.add_post', actor=community.link(), type='link', source=str(post.id))) + else: + breadcrumbs = [] + breadcrumb = namedtuple("Breadcrumb", ['text', 'url']) + breadcrumb.text = _('Home') + breadcrumb.url = '/' + breadcrumbs.append(breadcrumb) + breadcrumb = namedtuple("Breadcrumb", ['text', 'url']) + breadcrumb.text = _('Communities') + breadcrumb.url = '/communities' + breadcrumbs.append(breadcrumb) + + return render_template('post/post_cross_post.html', title=_('Cross post'), form=form, post=post, + breadcrumbs=breadcrumbs, + moderating_communities=moderating, + joined_communities=joined, + menu_topics=menu_topics(), site=g.site + ) diff --git a/app/static/scss/_typography.scss b/app/static/scss/_typography.scss index 3a64cd7c..db02a763 100644 --- a/app/static/scss/_typography.scss +++ b/app/static/scss/_typography.scss @@ -286,6 +286,10 @@ h1 { content: "\e9be"; } +.fe-cross-post::before { + content: "\e9ba"; +} + .fe-image { position: relative; top: 2px; diff --git a/app/static/styles.css b/app/static/styles.css index b2131bb2..90765532 100644 --- a/app/static/styles.css +++ b/app/static/styles.css @@ -314,6 +314,10 @@ h1 .fe-bell, h1 .fe-no-bell { content: "\e9be"; } +.fe-cross-post::before { + content: "\e9ba"; +} + .fe-image { position: relative; top: 2px; @@ -1003,7 +1007,7 @@ time { justify-content: center; align-items: center; } -.post_utilities_bar .post_options_link, .post_utilities_bar .preview_image { +.post_utilities_bar .post_cross_post_link, .post_utilities_bar .post_options_link, .post_utilities_bar .preview_image { display: flex; width: 44px; height: 44px; diff --git a/app/static/styles.scss b/app/static/styles.scss index 5def3e26..875c57a6 100644 --- a/app/static/styles.scss +++ b/app/static/styles.scss @@ -600,7 +600,7 @@ time { align-items: center; } - .post_options_link, .preview_image { + .post_cross_post_link, .post_options_link, .preview_image { display: flex; width: $min-touch-target; height: $min-touch-target; diff --git a/app/templates/post/post_cross_post.html b/app/templates/post/post_cross_post.html new file mode 100644 index 00000000..839a23b6 --- /dev/null +++ b/app/templates/post/post_cross_post.html @@ -0,0 +1,25 @@ +{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') %} + {% extends 'themes/' + theme() + '/base.html' %} +{% else %} + {% extends "base.html" %} +{% endif %} %} +{% from 'bootstrap/form.html' import render_form %} + +{% block app_content %} +
+
+ +

{{ _('Cross-post %(post_name)s', post_name=post.title) }}

+ {{ render_form(form) }} +
+
+ +{% endblock %} diff --git a/app/templates/post/post_options.html b/app/templates/post/post_options.html index 3ca3dc3f..782e5f78 100644 --- a/app/templates/post/post_options.html +++ b/app/templates/post/post_options.html @@ -38,6 +38,10 @@ {{ _("I made a mistake with this post and have changed my mind about the topic") }} {% endif -%} {% if post.user_id != current_user.id -%} + {% if post.type == POST_TYPE_LINK and post.author.bot and (post.cross_posts is none or len(post.cross_posts) == 0) -%} +
  • + {{ _('Cross-post to another community') }}
  • + {% endif -%}
  • {{ _('Block post author @%(author_name)s', author_name=post.author.user_name) }}
  • diff --git a/app/templates/post/post_teaser/_utilities_bar.html b/app/templates/post/post_teaser/_utilities_bar.html index f641a9ae..0986b33d 100644 --- a/app/templates/post/post_teaser/_utilities_bar.html +++ b/app/templates/post/post_teaser/_utilities_bar.html @@ -11,6 +11,9 @@ {% endif -%} {% endif -%} + {% if current_user.is_authenticated and post.type == POST_TYPE_LINK and post.author.bot and (post.cross_posts is none or len(post.cross_posts) == 0) -%} + + {% endif -%} \ No newline at end of file