mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 11:26:56 -08:00
federate votes
This commit is contained in:
parent
bfc4b243bf
commit
08a771daf0
4 changed files with 139 additions and 4 deletions
|
@ -7,10 +7,11 @@ from flask import request, Response, render_template, current_app, abort, jsonif
|
|||
|
||||
from app.activitypub.signature import HttpSignature
|
||||
from app.community.routes import show_community
|
||||
from app.models import User, Community, CommunityJoinRequest, CommunityMember, CommunityBan, ActivityPubLog
|
||||
from app.models import User, Community, CommunityJoinRequest, CommunityMember, CommunityBan, ActivityPubLog, Post, \
|
||||
PostReply, Instance, PostVote, PostReplyVote
|
||||
from app.activitypub.util import public_key, users_total, active_half_year, active_month, local_posts, local_comments, \
|
||||
post_to_activity, find_actor_or_create
|
||||
from app.utils import gibberish
|
||||
from app.utils import gibberish, get_setting
|
||||
|
||||
INBOX = []
|
||||
|
||||
|
@ -222,7 +223,48 @@ def shared_inbox():
|
|||
if 'type' in request_json:
|
||||
activity_log.activity_type = request_json['type']
|
||||
if request_json['type'] == 'Announce':
|
||||
...
|
||||
if request_json['object']['type'] == 'Like' or request_json['object']['type'] == 'Dislike':
|
||||
activity_log.activity_type = request_json['object']['type']
|
||||
vote_effect = 1.0 if request_json['object']['type'] == 'Like' else -1.0
|
||||
if vote_effect < 0 and get_setting('allow_dislike', True) is False:
|
||||
activity_log.exception_message = 'Dislike ignored because of allow_dislike setting'
|
||||
else:
|
||||
user_ap_id = request_json['object']['actor']
|
||||
liked_ap_id = request_json['object']['object']
|
||||
user = find_actor_or_create(user_ap_id)
|
||||
vote_weight = 1.0
|
||||
if user.ap_domain:
|
||||
instance = Instance.query.filter_by(domain=user.ap_domain).fetch()
|
||||
if instance:
|
||||
vote_weight = instance.vote_weight
|
||||
liked = find_liked_object(liked_ap_id)
|
||||
# insert into voted table
|
||||
if isinstance(liked, Post):
|
||||
existing_vote = PostVote.query.filter_by(user_id=user.id, post_id=liked.id).first()
|
||||
if existing_vote:
|
||||
existing_vote.effect = vote_effect * vote_weight
|
||||
else:
|
||||
vote = PostVote(user_id=user.id, author_id=liked.user_id, post_id=liked.id,
|
||||
effect=vote_effect * vote_weight)
|
||||
db.session.add(vote)
|
||||
db.session.commit()
|
||||
activity_log.result = 'success'
|
||||
elif isinstance(liked, PostReply):
|
||||
existing_vote = PostVote.query.filter_by(user_id=user.id, post_id=liked.id).first()
|
||||
if existing_vote:
|
||||
existing_vote.effect = vote_effect * vote_weight
|
||||
else:
|
||||
vote = PostReplyVote(user_id=user.id, author_id=liked.user_id, post_reply_id=liked.id,
|
||||
effect=vote_effect * vote_weight)
|
||||
db.session.add(vote)
|
||||
db.session.commit()
|
||||
activity_log.result = 'success'
|
||||
else:
|
||||
activity_log.result='failure'
|
||||
activity_log.exception_message = 'Could not detect type of like'
|
||||
if activity_log.result == 'success':
|
||||
... # todo: recalculate 'hotness' of liked post/reply
|
||||
|
||||
# remote user wants to follow one of our communities
|
||||
elif request_json['type'] == 'Follow':
|
||||
user_ap_id = request_json['actor']
|
||||
|
|
|
@ -49,6 +49,7 @@ def register(app):
|
|||
db.configure_mappers()
|
||||
db.create_all()
|
||||
db.session.append(Settings(name='allow_nsfw', value=json.dumps(False)))
|
||||
db.session.append(Settings(name='allow_dislike', value=json.dumps(True)))
|
||||
db.session.append(BannedInstances(domain='lemmygrad.ml'))
|
||||
db.session.append(BannedInstances(domain='gab.com'))
|
||||
db.session.append(BannedInstances(domain='exploding-heads.com'))
|
||||
|
|
|
@ -117,6 +117,7 @@ class User(UserMixin, db.Model):
|
|||
newsletter = db.Column(db.Boolean, default=True)
|
||||
bounces = db.Column(db.SmallInteger, default=0)
|
||||
timezone = db.Column(db.String(20))
|
||||
reputation = db.Column(db.Float, default=0.0)
|
||||
stripe_customer_id = db.Column(db.String(50))
|
||||
stripe_subscription_id = db.Column(db.String(50))
|
||||
searchable = db.Column(db.Boolean, default=True)
|
||||
|
@ -349,6 +350,7 @@ class Instance(db.Model):
|
|||
inbox = db.Column(db.String(256))
|
||||
shared_inbox = db.Column(db.String(256))
|
||||
outbox = db.Column(db.String(256))
|
||||
vote_weight = db.Column(db.Float, default=1.0)
|
||||
|
||||
|
||||
class Settings(db.Model):
|
||||
|
@ -374,11 +376,29 @@ class UserFollowRequest(db.Model):
|
|||
follow_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
|
||||
|
||||
class PostVote(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
|
||||
effect = db.Column(db.Float)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
|
||||
class PostReplyVote(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
post_reply_id = db.Column(db.Integer, db.ForeignKey('post_reply.id'))
|
||||
effect = db.Column(db.Float)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
|
||||
# save every activity to a log, to aid debugging
|
||||
class ActivityPubLog(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
direction = db.Column(db.String(3)) # 'in' or 'out'
|
||||
activity_id = db.Column(db.String(100), indexed=True)
|
||||
activity_id = db.Column(db.String(100), index=True)
|
||||
activity_type = db.Column(db.String(50)) # e.g. 'Follow', 'Accept', 'Like', etc
|
||||
activity_json = db.Column(db.Text) # the full json of the activity
|
||||
result = db.Column(db.String(10)) # 'success' or 'failure'
|
||||
|
|
72
migrations/versions/6b84580a94cd_voting.py
Normal file
72
migrations/versions/6b84580a94cd_voting.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
"""voting
|
||||
|
||||
Revision ID: 6b84580a94cd
|
||||
Revises: f032dbdfbd1d
|
||||
Create Date: 2023-09-10 19:59:15.735823
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '6b84580a94cd'
|
||||
down_revision = 'f032dbdfbd1d'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('post_vote',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=True),
|
||||
sa.Column('author_id', sa.Integer(), nullable=True),
|
||||
sa.Column('post_id', sa.Integer(), nullable=True),
|
||||
sa.Column('effect', sa.Float(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['author_id'], ['user.id'], ),
|
||||
sa.ForeignKeyConstraint(['post_id'], ['post.id'], ),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_table('post_reply_vote',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=True),
|
||||
sa.Column('author_id', sa.Integer(), nullable=True),
|
||||
sa.Column('post_reply_id', sa.Integer(), nullable=True),
|
||||
sa.Column('effect', sa.Float(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['author_id'], ['user.id'], ),
|
||||
sa.ForeignKeyConstraint(['post_reply_id'], ['post_reply.id'], ),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
with op.batch_alter_table('activity_pub_log', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('activity_id', sa.String(length=100), nullable=True))
|
||||
batch_op.create_index(batch_op.f('ix_activity_pub_log_activity_id'), ['activity_id'], unique=False)
|
||||
|
||||
with op.batch_alter_table('instance', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('vote_weight', sa.Float(), nullable=True))
|
||||
|
||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('reputation', sa.Float(), nullable=True))
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||
batch_op.drop_column('reputation')
|
||||
|
||||
with op.batch_alter_table('instance', schema=None) as batch_op:
|
||||
batch_op.drop_column('vote_weight')
|
||||
|
||||
with op.batch_alter_table('activity_pub_log', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_activity_pub_log_activity_id'))
|
||||
batch_op.drop_column('activity_id')
|
||||
|
||||
op.drop_table('post_reply_vote')
|
||||
op.drop_table('post_vote')
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in a new issue