Merge remote-tracking branch 'upstream/main'

This commit is contained in:
Martynas Sklizmantas 2024-03-20 17:36:56 +01:00
commit b07cee8051
14 changed files with 123 additions and 4 deletions

View file

@ -666,6 +666,24 @@ def process_inbox_request(request_json, activitypublog_id, ip_address):
target_ap_id = request_json['object']['object']['object'] # object object object!
post = undo_vote(activity_log, comment, post, target_ap_id, user)
activity_log.result = 'success'
elif request_json['object']['type'] == 'Add':
activity_log.activity_type = request_json['object']['type']
featured_url = Community.query.filter(Community.ap_public_url == request_json['actor']).first().ap_featured_url
if featured_url:
if 'target' in request_json['object'] and featured_url == request_json['object']['target']:
post = Post.query.filter(Post.ap_id == request_json['object']['object']).first()
if post:
post.sticky = True
activity_log.result = 'success'
elif request_json['object']['type'] == 'Remove':
activity_log.activity_type = request_json['object']['type']
featured_url = Community.query.filter(Community.ap_public_url == request_json['actor']).first().ap_featured_url
if featured_url:
if 'target' in request_json['object'] and featured_url == request_json['object']['target']:
post = Post.query.filter(Post.ap_id == request_json['object']['object']).first()
if post:
post.sticky = False
activity_log.result = 'success'
else:
activity_log.exception_message = 'Invalid type for Announce'

View file

@ -562,6 +562,7 @@ def actor_json_to_model(activity_json, address, server):
ap_followers_url=activity_json['followers'],
ap_inbox_url=activity_json['endpoints']['sharedInbox'],
ap_outbox_url=activity_json['outbox'],
ap_featured_url=activity_json['featured'],
ap_moderators_url=mods_url,
ap_fetched_at=utcnow(),
ap_domain=server,

View file

@ -89,6 +89,7 @@ class CreatePostForm(FlaskForm):
render_kw={'placeholder': 'Text (optional)'})
image_file = FileField(_('Image'))
# flair = SelectField(_l('Flair'), coerce=int)
sticky = BooleanField(_l('Sticky'))
nsfw = BooleanField(_l('NSFW'))
nsfl = BooleanField(_l('Gore/gross'))
notify_author = BooleanField(_l('Notify about replies'))

View file

@ -120,6 +120,8 @@ def show_community(community: Community):
page = request.args.get('page', 1, type=int)
sort = request.args.get('sort', '' if current_user.is_anonymous else current_user.default_sort)
if sort is None:
sort = ''
low_bandwidth = request.cookies.get('low_bandwidth', '0') == '1'
if low_bandwidth:
post_layout = None
@ -171,13 +173,13 @@ def show_community(community: Community):
posts = posts.filter(or_(Post.instance_id.not_in(instance_ids), Post.instance_id == None))
if sort == '' or sort == 'hot':
posts = posts.order_by(desc(Post.ranking)).order_by(desc(Post.posted_at))
posts = posts.order_by(desc(Post.sticky)).order_by(desc(Post.ranking)).order_by(desc(Post.posted_at))
elif sort == 'top':
posts = posts.filter(Post.posted_at > utcnow() - timedelta(days=7)).order_by(desc(Post.score))
posts = posts.filter(Post.posted_at > utcnow() - timedelta(days=7)).order_by(desc(Post.sticky)).order_by(desc(Post.score))
elif sort == 'new':
posts = posts.order_by(desc(Post.posted_at))
elif sort == 'active':
posts = posts.order_by(desc(Post.last_active))
posts = posts.order_by(desc(Post.sticky)).order_by(desc(Post.last_active))
per_page = 100
if post_layout == 'masonry':
per_page = 200
@ -444,6 +446,8 @@ def add_post(actor):
if community.nsfl:
form.nsfl.data = True
form.nsfw.render_kw = {'disabled': True}
if not(community.is_moderator() or community.is_owner() or current_user.is_admin()):
form.sticky.render_kw = {'disabled': True}
form.communities.choices = [(c.id, c.display_name()) for c in current_user.communities()]
@ -485,6 +489,7 @@ def add_post(actor):
'commentsEnabled': post.comments_enabled,
'sensitive': post.nsfw,
'nsfl': post.nsfl,
'stickied': post.sticky,
'published': ap_datetime(utcnow()),
'audience': community.ap_profile_id
}

View file

@ -121,6 +121,18 @@ def retrieve_mods_and_backfill(community_id: int):
if c.post_count > 0:
c.last_active = Post.query.filter(Post.community_id == community_id).order_by(desc(Post.posted_at)).first().posted_at
db.session.commit()
if community.ap_featured_url:
featured_request = get_request(community.ap_featured_url, headers={'Accept': 'application/activityjson'})
if featured_request.status_code == 200:
featured_data = featured_request.json()
featured_request.close()
if featured_data['type'] == 'OrderedCollection' and 'orderedItems' in featured_data:
for item in featured_data['orderedItems']:
featured_id = item['id']
p = Post.query.filter(Post.ap_id == featured_id).first()
if p:
p.sticky = True
db.session.commit()
def community_url_exists(url) -> bool:
@ -173,6 +185,7 @@ def url_to_thumbnail_file(filename) -> File:
def save_post(form, post: Post):
post.indexable = current_user.indexable
post.sticky = form.sticky.data
post.nsfw = form.nsfw.data
post.nsfl = form.nsfl.data
post.notify_author = form.notify_author.data

View file

@ -266,6 +266,7 @@ class Community(db.Model):
ap_deleted_at = db.Column(db.DateTime)
ap_inbox_url = db.Column(db.String(255))
ap_outbox_url = db.Column(db.String(255))
ap_featured_url = db.Column(db.String(255))
ap_moderators_url = db.Column(db.String(255))
ap_domain = db.Column(db.String(255))

View file

@ -649,6 +649,7 @@ def post_edit(post_id: int):
'commentsEnabled': post.comments_enabled,
'sensitive': post.nsfw,
'nsfl': post.nsfl,
'stickied': post.sticky,
'published': ap_datetime(post.posted_at),
'updated': ap_datetime(post.edited_at),
'audience': post.community.ap_profile_id
@ -722,6 +723,9 @@ def post_edit(post_id: int):
form.notify_author.data = post.notify_author
form.nsfw.data = post.nsfw
form.nsfl.data = post.nsfl
form.sticky.data = post.sticky
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=post,
markdown_editor=current_user.markdown_editor,
moderating_communities=moderating_communities(current_user.get_id()),

View file

@ -309,6 +309,19 @@ h1 {
}
}
.fe-sticky-left::before {
position: relative;
top: 2px;
content: "\e934";
}
.fe-sticky-right::before {
position: relative;
top: 2px;
content: "\e933";
}
a.no-underline {
text-decoration: none;
&:hover {

View file

@ -333,6 +333,18 @@ h1 .fe-bell, h1 .fe-no-bell {
/* possibly e985 */
}
.fe-sticky-left::before {
position: relative;
top: 2px;
content: "\e934";
}
.fe-sticky-right::before {
position: relative;
top: 2px;
content: "\e933";
}
a.no-underline {
text-decoration: none;
}

View file

@ -332,6 +332,18 @@ h1 .fe-bell, h1 .fe-no-bell {
/* possibly e985 */
}
.fe-sticky-left::before {
position: relative;
top: 2px;
content: "\e934";
}
.fe-sticky-right::before {
position: relative;
top: 2px;
content: "\e933";
}
a.no-underline {
text-decoration: none;
}

View file

@ -98,6 +98,9 @@
<div class="col-md-3">
{{ render_field(form.notify_author) }}
</div>
<div class="col-md-1">
{{ render_field(form.sticky) }}
</div>
<div class="col-md-1">
{{ render_field(form.nsfw) }}
</div>

View file

@ -43,7 +43,7 @@
</div>
{% endif %}
{% endif %}
<h3><a href="{{ url_for('activitypub.post_ap', post_id=post.id, sort='new' if sort == 'active' else None) }}" class="post_teaser_title_a">{{ post.title }}</a>
<h3>{% if post.sticky %}<span class="fe fe-sticky-left"></span>{% endif %}<a href="{{ url_for('activitypub.post_ap', post_id=post.id, sort='new' if sort == 'active' else None) }}" class="post_teaser_title_a">{{ post.title }}</a>
{% if post.type == POST_TYPE_IMAGE %}<span class="fe fe-image" aria-hidden="true"> </span>{% endif %}
{% if post.type == POST_TYPE_LINK and post.domain_id %}
{% if post.url and 'youtube.com' in post.url %}
@ -58,6 +58,7 @@
{% if post.reports and current_user.is_authenticated and post.community.is_moderator(current_user) %}
<span class="red fe fe-report" title="{{ _('Reported. Check post for issues.') }}"></span>
{% endif %}
{% if post.sticky %}<span class="fe fe-sticky-right"></span>{% endif %}
</h3>
<span class="small">{% if show_post_community %}<strong><a href="/c/{{ post.community.link() }}" aria-label="{{ _('Go to community %(name)s', name=post.community.name) }}">c/{{ post.community.name }}</a></strong>{% endif %}

View file

@ -120,6 +120,9 @@
<div class="col-md-3">
{{ render_field(form.notify_author) }}
</div>
<div class="col-md-1">
{{ render_field(form.sticky) }}
</div>
<div class="col-md-1">
{{ render_field(form.nsfw) }}
</div>

View file

@ -0,0 +1,32 @@
"""ap_featured_url
Revision ID: 12d60b9d5417
Revises: 81175e11c083
Create Date: 2024-03-19 07:05:04.588051
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '12d60b9d5417'
down_revision = '81175e11c083'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('community', schema=None) as batch_op:
batch_op.add_column(sa.Column('ap_featured_url', sa.String(length=255), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('community', schema=None) as batch_op:
batch_op.drop_column('ap_featured_url')
# ### end Alembic commands ###