diff --git a/app/admin/forms.py b/app/admin/forms.py index 62cf3105..3bb7c528 100644 --- a/app/admin/forms.py +++ b/app/admin/forms.py @@ -10,14 +10,15 @@ from app.models import Community, User class SiteProfileForm(FlaskForm): - name = StringField(_l('Name')) + name = StringField(_l('Site Name')) description = StringField(_l('Tagline')) icon = FileField(_('Icon'), validators=[ FileAllowed(['jpg', 'jpeg', 'png', 'webp'], 'Images only!') ]) sidebar = TextAreaField(_l('Sidebar')) + about = TextAreaField(_l('About')) legal_information = TextAreaField(_l('Legal information')) - contact_email = EmailField(_l('General instance contact email address'), validators=[Email(), DataRequired(), Length(min=5, max=255)]) + contact_email = EmailField(_l('General instance contact email address'), validators=[DataRequired(), Length(min=5, max=255)]) submit = SubmitField(_l('Save')) diff --git a/app/admin/routes.py b/app/admin/routes.py index b6fc6966..f19621ad 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -44,7 +44,8 @@ def admin_site(): site = Site() if form.validate_on_submit(): site.name = form.name.data - site.description = form.description.data + site.description = form.description.data #tagline + site.about = form.about.data site.sidebar = form.sidebar.data site.legal_information = form.legal_information.data site.updated = utcnow() @@ -56,8 +57,10 @@ def admin_site(): elif request.method == 'GET': form.name.data = site.name form.description.data = site.description + form.about.data = site.about form.sidebar.data = site.sidebar form.legal_information.data = site.legal_information + form.contact_email.data = site.contact_email return render_template('admin/site.html', title=_('Site profile'), form=form, moderating_communities=moderating_communities(current_user.get_id()), joined_communities=joined_communities(current_user.get_id()), diff --git a/app/community/routes.py b/app/community/routes.py index 0dadabe7..6c7051a3 100644 --- a/app/community/routes.py +++ b/app/community/routes.py @@ -33,7 +33,7 @@ from app.utils import get_setting, render_template, allowlist_html, markdown_to_ request_etag_matches, return_304, instance_banned, can_create_post, can_upvote, can_downvote, user_filters_posts, \ joined_communities, moderating_communities, blocked_domains, mimetype_from_url, blocked_instances, \ community_moderators, communities_banned_from, show_ban_message, recently_upvoted_posts, recently_downvoted_posts, \ - blocked_users + blocked_users, post_ranking from feedgen.feed import FeedGenerator from datetime import timezone, timedelta @@ -496,6 +496,7 @@ def add_discussion_post(actor): post.ap_id = f"https://{current_app.config['SERVER_NAME']}/post/{post.id}" db.session.commit() + upvote_own_post(post) notify_about_post(post) if not community.local_only: @@ -571,6 +572,7 @@ def add_image_post(actor): post.cross_posts.append(op.id) db.session.commit() + upvote_own_post(post) notify_about_post(post) if not community.local_only: @@ -644,6 +646,7 @@ def add_link_post(actor): post.cross_posts.append(op.id) db.session.commit() + upvote_own_post(post) notify_about_post(post) if not community.local_only: @@ -717,6 +720,7 @@ def add_video_post(actor): post.cross_posts.append(op.id) db.session.commit() + upvote_own_post(post) notify_about_post(post) if not community.local_only: @@ -1407,3 +1411,11 @@ def lookup(community, domain): return redirect('/') +def upvote_own_post(post): + post.score = 1 + post.up_votes = 1 + post.ranking = post_ranking(post.score, utcnow()) + vote = PostVote(user_id=current_user.id, post_id=post.id, author_id=current_user.id, effect=1) + db.session.add(vote) + db.session.commit() + cache.delete_memoized(recently_upvoted_posts, current_user.id) diff --git a/app/models.py b/app/models.py index 376a8740..f3f0db7f 100644 --- a/app/models.py +++ b/app/models.py @@ -1332,6 +1332,7 @@ class Site(db.Model): log_activitypub_json = db.Column(db.Boolean, default=False) default_theme = db.Column(db.String(20), default='') contact_email = db.Column(db.String(255), default='') + about = db.Column(db.Text, default='') @staticmethod def admins() -> List[User]: diff --git a/app/post/routes.py b/app/post/routes.py index a1387743..204825be 100644 --- a/app/post/routes.py +++ b/app/post/routes.py @@ -84,6 +84,16 @@ def show_post(post_id: int): flash(_('This type of comment is not accepted, sorry.'), 'error') return redirect(url_for('activitypub.post_ap', post_id=post_id)) + # respond to comments that are just variants of 'this' + if reply_is_stupid(form.body.data): + existing_vote = PostVote.query.filter_by(user_id=current_user.id, post_id=post.id).first() + if existing_vote is None: + flash(_('We have upvoted the post for you.'), 'warning') + post_vote(post.id, 'upvote') + else: + flash(_('You have already upvoted the post, you do not need to say "this" also.'), 'error') + return redirect(url_for('activitypub.post_ap', post_id=post_id)) + reply = PostReply(user_id=current_user.id, post_id=post.id, community_id=community.id, body=form.body.data, body_html=markdown_to_html(form.body.data), body_html_safe=True, from_bot=current_user.bot, nsfw=post.nsfw, nsfl=post.nsfl, @@ -102,6 +112,15 @@ def show_post(post_id: int): db.session.add(reply) db.session.commit() + + # upvote own reply + reply.score = 1 + reply.up_votes = 1 + reply.ranking = confidence(1, 0) + vote = PostReplyVote(user_id=current_user.id, post_reply_id=reply.id, author_id=current_user.id, effect=1) + db.session.add(vote) + cache.delete_memoized(recently_upvoted_post_replies, current_user.id) + reply.ap_id = reply.profile_id() if current_user.reputation > 100: reply.up_votes += 1 @@ -612,8 +631,16 @@ def add_reply(post_id: int, comment_id: int): db.session.add(notification) in_reply_to.author.unread_notifications += 1 db.session.commit() + + # upvote own reply + reply.score = 1 + reply.up_votes = 1 + reply.ranking = confidence(1, 0) + vote = PostReplyVote(user_id=current_user.id, post_reply_id=reply.id, author_id=current_user.id, effect=1) + db.session.add(vote) + cache.delete_memoized(recently_upvoted_post_replies, current_user.id) + reply.ap_id = reply.profile_id() - db.session.commit() if current_user.reputation > 100: reply.up_votes += 1 reply.score += 1 @@ -726,6 +753,7 @@ def add_reply(post_id: int, comment_id: int): return redirect(url_for('post.continue_discussion', post_id=post_id, comment_id=reply.parent_id)) else: form.notify_author.data = True + return render_template('post/add_reply.html', title=_('Discussing %(title)s', title=post.title), post=post, is_moderator=is_moderator, form=form, comment=in_reply_to, markdown_editor=current_user.is_authenticated and current_user.markdown_editor, moderating_communities=moderating_communities(current_user.get_id()), mods=mod_list, diff --git a/app/templates/about.html b/app/templates/about.html index a7a7c018..a2acbdfb 100644 --- a/app/templates/about.html +++ b/app/templates/about.html @@ -11,12 +11,18 @@

{{g.site.name}} is a pyfedi instance created on {{instance.created_at.strftime('%d-%m-%Y')}}. It is home to {{user_amount}} users (of which {{mau}} active in the last month). In the {{community_amount}} communities we discussed {{domains_amount}} domains and made {{posts_amount}} posts.

Team

This instance is administerred by {% for admin in admins %}{{ admin.user_name }}{{ ", " if not loop.last }}{% endfor %}.

+ {% if staff %}

It is moderated by {% for s in staff %}{{ s.user_name }}{{ ", " if not loop.last }}{% endfor %}.

+ {% endif %}

Contact

{{g.site.contact_email | safe }}

About Us

{{g.site.description | safe }}

+ {% if g.site.about %} +

{{g.site.about | safe }}

+ {% elif g.site.sidebar %}

{{g.site.sidebar | safe }}

+ {% endif %} {% if g.site.legal_information %}

Legal Information

{{g.site.legal_information | safe }}

diff --git a/app/templates/admin/site.html b/app/templates/admin/site.html index 57496d52..c8a62dac 100644 --- a/app/templates/admin/site.html +++ b/app/templates/admin/site.html @@ -13,11 +13,17 @@

{{ _('Site profile') }}

{{ form.csrf_token() }} +

{{ _('Configure the flair the instance, by giving it a name, ashort slogan, basic info for the sidebar and a logo. This information appears in link previews in social media.') }}

{{ render_field(form.name) }} {{ render_field(form.description) }} - {{ render_field(form.icon) }} {{ render_field(form.sidebar) }}

HTML is allowed in this field.

+ {{ render_field(form.icon) }} + +

{{ _('About this instance') }}

+

{{ _('Provide a more extensive description of the instance, set a contact address and provide legal information. This information appears on the about page.') }}

+ {{ render_field(form.about) }} +

HTML is allowed in this field.

{{ render_field(form.legal_information) }}

HTML is allowed in this field.

{{ render_field(form.contact_email) }} diff --git a/migrations/versions/46c170499e71_long_instance_about_field.py b/migrations/versions/46c170499e71_long_instance_about_field.py new file mode 100644 index 00000000..06f50951 --- /dev/null +++ b/migrations/versions/46c170499e71_long_instance_about_field.py @@ -0,0 +1,32 @@ +"""long instance about field + +Revision ID: 46c170499e71 +Revises: 7aee4cb7db24 +Create Date: 2024-04-22 18:28:51.826149 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '46c170499e71' +down_revision = '7aee4cb7db24' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('site', schema=None) as batch_op: + batch_op.add_column(sa.Column('about', sa.Text(), nullable=True)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('site', schema=None) as batch_op: + batch_op.drop_column('about') + + # ### end Alembic commands ###