summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDerf Null <derf@finalrewind.org>2023-05-31 22:16:27 +0200
committerDerf Null <derf@finalrewind.org>2023-05-31 22:16:27 +0200
commit9332f60a4370cc5ec9a000ef505e613f84b17d2f (patch)
tree77dde0d66b10d19373ed618a32682ba467520fad /lib
parentf3ae26374b10ce73224b64ad5588adb6e16e7663 (diff)
prepare for follow relations and follow-only checkins
Diffstat (limited to 'lib')
-rw-r--r--lib/Travelynx/Command/database.pm48
-rw-r--r--lib/Travelynx/Model/Users.pm194
2 files changed, 242 insertions, 0 deletions
diff --git a/lib/Travelynx/Command/database.pm b/lib/Travelynx/Command/database.pm
index 39404c4..f906cb5 100644
--- a/lib/Travelynx/Command/database.pm
+++ b/lib/Travelynx/Command/database.pm
@@ -1470,6 +1470,54 @@ my @migrations = (
}
);
},
+
+ # v34 -> v35
+ sub {
+ my ($db) = @_;
+
+ # 1 : follows
+ # 2 : follow requested
+ # 3 : is blocked by
+ $db->query(
+ qq{
+ create table relations (
+ subject_id integer not null references users (id),
+ predicate smallint not null,
+ object_id integer not null references users (id),
+ primary key (subject_id, object_id)
+ );
+ create view followers as select
+ relations.object_id as self_id,
+ users.id as id,
+ users.name as name
+ from relations
+ join users on relations.subject_id = users.id
+ where predicate = 1;
+ create view followees as select
+ relations.subject_id as self_id,
+ users.id as id,
+ users.name as name
+ from relations
+ join users on relations.object_id = users.id
+ where predicate = 1;
+ create view follow_requests as select
+ relations.object_id as self_id,
+ users.id as id,
+ users.name as name
+ from relations
+ join users on relations.subject_id = users.id
+ where predicate = 2;
+ create view blocked_users as select
+ relations.object_id as self_id,
+ users.id as id,
+ users.name as name
+ from relations
+ join users on relations.subject_id = users.id
+ where predicate = 3;
+ update schema_version set version = 35;
+ }
+ );
+ },
);
sub sync_stations {
diff --git a/lib/Travelynx/Model/Users.pm b/lib/Travelynx/Model/Users.pm
index 67296ca..9b0a115 100644
--- a/lib/Travelynx/Model/Users.pm
+++ b/lib/Travelynx/Model/Users.pm
@@ -27,6 +27,18 @@ my %visibility_atoi = (
private => 10,
);
+my %predicate_itoa = (
+ 1 => 'follows',
+ 2 => 'requests_follow',
+ 3 => 'is_blocked_by',
+);
+
+my %predicate_atoi = (
+ follows => 1,
+ requests_follow => 2,
+ is_blocked_by => 3,
+);
+
my @sb_templates = (
undef,
[ 'DBF', 'https://dbf.finalrewind.org/{name}?rt=1#{tt}{tn}' ],
@@ -710,4 +722,186 @@ sub update_webhook_status {
);
}
+# TODO irgendwo muss auch noch ne einstellung rein, um follows / follow requests global zu deaktivieren
+
+sub get_relation {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+ my $target = $opt{target};
+
+ my $res_h = $db->select(
+ 'relations',
+ ['predicate'],
+ {
+ subject_id => $uid,
+ object_id => $target
+ }
+ )->hash;
+
+ if ($res_h) {
+ return $predicate_itoa{ $res_h->{predicate} };
+ }
+ return;
+
+ #my $res_h = $db->select( 'relations', ['subject_id', 'predicate'],
+ # { subject_id => [$uid, $target], object_id => [$target, $target] } )->hash;
+}
+
+sub request_follow {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+ my $target = $opt{target};
+
+ $db->insert(
+ 'relations',
+ {
+ subject_id => $uid,
+ predicate => $predicate_atoi{requests_follow},
+ object_id => $target,
+ }
+ );
+}
+
+sub accept_follow_request {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+ my $applicant = $opt{applicant};
+
+ $db->update(
+ 'relations',
+ {
+ predicate => $predicate_atoi{follows},
+ },
+ {
+ subject_id => $applicant,
+ predicate => $predicate_atoi{requests_follow},
+ object_id => $uid
+ }
+ );
+}
+
+sub reject_follow_request {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+ my $applicant = $opt{applicant};
+
+ $db->delete(
+ 'relations',
+ {
+ subject_id => $applicant,
+ predicate => $predicate_atoi{requests_follow},
+ object_id => $uid
+ }
+ );
+}
+
+sub remove_follower {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+ my $follower = $opt{follower};
+
+ $db->delete(
+ 'relations',
+ {
+ subject_id => $follower,
+ predicate => $predicate_atoi{follows},
+ object_id => $uid
+ }
+ );
+}
+
+sub block {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+ my $target = $opt{target};
+
+ $db->insert(
+ 'relations',
+ {
+ subject_id => $target,
+ predicate => $predicate_atoi{is_blocked_by},
+ object_id => $uid
+ },
+ {
+ on_conflict => \
+'(subject_id, object_id) do update set predicate = EXCLUDED.predicate'
+ },
+ );
+}
+
+sub unblock {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+ my $target = $opt{target};
+
+ $db->delete(
+ 'relations',
+ {
+ subject_id => $target,
+ predicate => $predicate_atoi{is_blocked_by},
+ object_id => $uid
+ },
+ );
+}
+
+sub get_followers {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+
+ my $res = $db->select( 'followers', [ 'id', 'name' ], { self_id => $uid } );
+
+ return $res->hashes->each;
+}
+
+sub get_follow_requests {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+
+ my $res
+ = $db->select( 'follow_requests', [ 'id', 'name' ], { self_id => $uid } );
+
+ return $res->hashes->each;
+}
+
+sub get_followees {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+
+ my $res = $db->select( 'followees', [ 'id', 'name' ], { self_id => $uid } );
+
+ return $res->hashes->each;
+}
+
+sub get_blocked_users {
+ my ( $self, %opt ) = @_;
+
+ my $db = $opt{db} // $self->{pg}->db;
+ my $uid = $opt{uid};
+
+ my $res
+ = $db->select( 'blocked_users', [ 'id', 'name' ], { self_id => $uid } );
+
+ return $res->hashes->each;
+}
+
1;