Committer: slobin
LJSUP-10501: Push-notifications (WP7, Android, iOS)M LJ/Event.pm
M LJ/Event/Befriended.pm
M LJ/Event/Birthday.pm
M LJ/Event/CommunityJoinRequest.pm
M LJ/Event/Defriended.pm
M LJ/Event/InvitedFriendJoins.pm
M LJ/Event/JournalNewComment.pm
M LJ/Event/JournalNewEntry.pm
M LJ/Event/NewUserpic.pm
M LJ/Event/OfficialPost.pm
M LJ/Event/PollVote.pm
M LJ/Event/UserExpunged.pm
M LJ/Event/UserMessageRecvd.pm
M LJ/Subscription.pm
M LJ/User.pm
M ljprotocol.pl
U trunk/cgi-bin/LJ/Event/Befriended.pm U trunk/cgi-bin/LJ/Event/Birthday.pm U trunk/cgi-bin/LJ/Event/CommunityJoinRequest.pm U trunk/cgi-bin/LJ/Event/Defriended.pm U trunk/cgi-bin/LJ/Event/InvitedFriendJoins.pm U trunk/cgi-bin/LJ/Event/JournalNewComment.pm U trunk/cgi-bin/LJ/Event/JournalNewEntry.pm U trunk/cgi-bin/LJ/Event/NewUserpic.pm U trunk/cgi-bin/LJ/Event/OfficialPost.pm U trunk/cgi-bin/LJ/Event/PollVote.pm U trunk/cgi-bin/LJ/Event/UserExpunged.pm U trunk/cgi-bin/LJ/Event/UserMessageRecvd.pm U trunk/cgi-bin/LJ/Event.pm U trunk/cgi-bin/LJ/Subscription.pm U trunk/cgi-bin/LJ/User.pm U trunk/cgi-bin/ljprotocol.pl
Modified: trunk/cgi-bin/LJ/Event/Befriended.pm =================================================================== --- trunk/cgi-bin/LJ/Event/Befriended.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/Befriended.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -184,4 +184,18 @@ sub is_tracking { 0 } +sub as_push { + my $self = shift; + my $u = shift; + + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.befriended", 1, { + user => $self->friend->user, + }) +} + +sub as_push_payload { + my $self = shift; + return '"t":7,"j":"'.$self->friend->user.'"'; +} + 1; Modified: trunk/cgi-bin/LJ/Event/Birthday.pm =================================================================== --- trunk/cgi-bin/LJ/Event/Birthday.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/Birthday.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -30,6 +30,19 @@ return "$months[$mon-1] $day"; } +sub next_bday { + my $self = shift; + + my ($year, $mon, $day) = split(/-/, $self->bdayuser->{bdate}); + + $year = (localtime())[5] + 1900; + + $year++ + if $mon == 1 && $day < 3; + + return join '-',($year, $mon, $day) +} + sub matches_filter { my ($self, $subscr) = @_; @@ -194,4 +207,19 @@ return $self->userid ? 1 : 0; } +sub as_push { + my $self = shift; + my $u = shift; + + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.birthday", 1, { + user => $self->bdayuser->user(), + date => $self->email_bday($u->prop('browselang')) + }) +} + +sub as_push_payload { + my $self = shift; + return '"t":17,"j":"'.$self->bdayuser->user().'","b":"'. $self->next_bday().'"'; +} + 1; Modified: trunk/cgi-bin/LJ/Event/CommunityJoinRequest.pm =================================================================== --- trunk/cgi-bin/LJ/Event/CommunityJoinRequest.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/CommunityJoinRequest.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -165,6 +165,22 @@ sub is_subscription_visible_to { 1 } sub is_tracking { 0 } +sub as_push { + my $self = shift; + my $u = shift; + + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.communityjoinrequest", 1, { + user => $self->requestor->user(), + community => $self->comm->user(), + }) +} + +sub as_push_payload { + my $self = shift; + return '"t":15,"j":"'.$self->comm->user().'","u":"'.$self->requestor->user().'"'; +} + + package LJ::Error::Event::CommunityJoinRequest; sub fields { 'u' } sub as_string { Modified: trunk/cgi-bin/LJ/Event/Defriended.pm =================================================================== --- trunk/cgi-bin/LJ/Event/Defriended.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/Defriended.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -166,4 +166,19 @@ sub is_tracking { 0 } +sub as_push { + my $self = shift; + my $u = shift; + + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.defriended", 1, { + user => $self->friend->user, + }) +} + +sub as_push_payload { + my $self = shift; + return '"t":8,"j":"'.$self->friend->user.'"'; +} + + 1; Modified: trunk/cgi-bin/LJ/Event/InvitedFriendJoins.pm =================================================================== --- trunk/cgi-bin/LJ/Event/InvitedFriendJoins.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/InvitedFriendJoins.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -153,4 +153,18 @@ sub is_subscription_visible_to { 1 } sub is_tracking { 0 } +sub as_push { + my $self = shift; + my $u = shift; + + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.invitedfriendjoins", 1, { + journal => $self->friend->user, + }) +} + +sub as_push_payload { + my $self = shift; + return '"t":13,"j":"'.$self->friend->user.'"'; +} + 1; Modified: trunk/cgi-bin/LJ/Event/JournalNewComment.pm =================================================================== --- trunk/cgi-bin/LJ/Event/JournalNewComment.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/JournalNewComment.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -833,6 +833,7 @@ !$entry->prop('opt_noemail') ) { + if (!LJ::u_equals($entry_author, $entry_journal)) { # community journal my @subs2 = LJ::Subscription->find($entry_author, @@ -875,4 +876,122 @@ return 0; } + +sub as_push { + my $self = shift; + my $u = shift; + my %opts = @_; + + my $parent = $self->comment->parent; + my $entry = $self->comment->entry; + + my $subject; + if($subject = $entry->subject_text) { + + $subject = (substr $subject, 0, $opts{cut})."..." + if $opts{cut} && length($subject) > $opts{cut}; + + } else { + $subject = LJ::Lang::get_text($u->prop('browselang'), "widget.officialjournals.nosubject") + } + + # tracking event + unless($u->equals($self->event_journal)) { + + if($self->event_journal->journaltype eq 'C') { + + if($self->comment->parent) { +warn 01; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.eventtrackcommetstreadinentrytitle", 1, { + user => $self->comment->poster->user, + subject => $subject, + poster => $self->comment->parent->poster->user, + journal => $self->event_journal->user, + }); + + } else { +warn 11; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.eventtrackcommetsonentrytitle", 1, { + user => $self->comment->poster->user, + subject => $subject, + journal => $self->event_journal->user, + }); + } + } else { +warn 2; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.eventtrackcommetsonentrytitle", 1, { + user => $self->comment->poster->user, + subject => $subject, + journal => $self->event_journal->user, + }); + } + + } else { + + if($parent && LJ::u_equals($parent->poster, $u)) { +warn 3; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.commentreply", 1, { + user => $self->comment->poster->user, + journal => $self->event_journal->user, + }); + + } elsif($self->event_journal->journaltype eq 'C') { +warn 4; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.communityentryreply", 1, { + user => $self->comment->poster->user, + community => $self->event_journal->user, + }) + + } else { +warn 5; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.journalnewcomment", 1, { + user => $self->comment->poster->user, + }) + } + } +} + +sub as_push_payload { + my $self = shift; + my $u = shift; + + my $entry = $self->comment->entry; + my $parent = $self->comment->parent; + + + unless($u->equals($self->event_journal)) { + + if($self->event_journal->journaltype eq 'C') { + + if($parent) { + return '"t":26, "j":"'.$self->event_journal->user.'",'. + '"p":'.$entry->ditemid.', "r":'.$self->comment->parent->dtalkid.', "c":'.$self->comment->dtalkid + } else { + return '"t":25,"j":"'.$self->event_journal->user.'","p":'.$entry->ditemid.',"c":'.$self->comment->dtalkid; + } + + } else { + return '"t": "eventEntryCommunityReply","j":"'.$self->event_journal->user .'","p":'.$entry->ditemid.'","c":'.$self->comment->dtalkid + } + } else { + if($parent && LJ::u_equals($parent->poster, $u)) { + return '"t":5,"j":"'.$self->event_journal->user.'","p":'.$entry->ditemid .',"c":'.$self->comment->dtalkid; + } elsif($self->event_journal->journaltype eq 'C') { +warn 2; + return '"type": "eventEntryCommunityReply", ' + . '"journalName": "'.$self->event_journal->user .'", ' + . '"postid": "'.$entry->ditemid.'", ' + . '"commentid": '.$self->comment->dtalkid; + + } else { +warn 3; + return "\"type\": \"eventEntryReply\", " + . "\"journalName\": \"".$self->event_journal->user."\" " + . "\"postid\": ".$entry->ditemid.", " + . "\"commentid\": ".$self->comment->dtalkid; + } + + } +} + 1; Modified: trunk/cgi-bin/LJ/Event/JournalNewEntry.pm =================================================================== --- trunk/cgi-bin/LJ/Event/JournalNewEntry.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/JournalNewEntry.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -49,9 +49,10 @@ # all posts by friends return 1 if ! $subscr->journalid && LJ::is_friend($subscr->owner, $self->event_journal); + # a post on a specific journal + my $journal = LJ::load_userid($subscr->journal); - # a post on a specific journal - return LJ::u_equals($subscr->journal, $evtju); + return LJ::u_equals($journal, $evtju); } sub content { @@ -428,4 +429,18 @@ sub zero_journalid_subs_means { undef } +sub as_push { + my ($self,$u) = @_; + + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.eventtrackjournalpostsentry", { user => $u->user }) . + ($self->entry->tags + ? LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.eventtrackjournalpostsentry.tagged", { tag => join(', ', $self->entry->tags )}) + : '' ); +} + +sub as_push_payload { + my ($self,$u) = @_; + return '"t":19,"j":"'.$u->user.'","p":'.$self->entry->ditemid; +} + 1; Modified: trunk/cgi-bin/LJ/Event/NewUserpic.pm =================================================================== --- trunk/cgi-bin/LJ/Event/NewUserpic.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/NewUserpic.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -157,4 +157,19 @@ return $self->userid ? 1 : 0; } +sub as_push { + my $self = shift; + my $u = shift; + + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.newuserpic", 1, { + user => $self->event_journal->user(), + }) +} + +sub as_push_payload { + my $self = shift; + return '"t":16,"j":"'.$self->event_journal->user().'"'; +} + + 1; Modified: trunk/cgi-bin/LJ/Event/OfficialPost.pm =================================================================== --- trunk/cgi-bin/LJ/Event/OfficialPost.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/OfficialPost.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -182,4 +182,17 @@ sub is_subscription_visible_to { 1 } +sub as_push { + my $self = shift; + my $u = shift; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.offcialpost", 1, { + community => $self->event_journal->user, + }) +} + +sub as_push_payload { + my $self = shift; + return '"t":1,"p":'.$self->arg1; +} + 1; Modified: trunk/cgi-bin/LJ/Event/PollVote.pm =================================================================== --- trunk/cgi-bin/LJ/Event/PollVote.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/PollVote.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -188,4 +188,19 @@ sub is_tracking { 0 } +sub as_push { + my $self = shift; + my $u = shift; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.pollvote", 1, { + user => $self->voter->user, + journal => $u->user, + }) +} + +sub as_push_payload { + my $self = shift; + + return '"t":6,"j":"'.$self->entry->poster->user.'","p":'.$self->entry->ditemid.',"pl":'.$self->arg2; +} + 1; Modified: trunk/cgi-bin/LJ/Event/UserExpunged.pm =================================================================== --- trunk/cgi-bin/LJ/Event/UserExpunged.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/UserExpunged.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -104,4 +104,17 @@ sub is_subscription_visible_to { 1 } sub is_tracking { 1 } +sub as_push { + my ($self, $u) = @_; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.eventtrackusernamepurged", 1, { + user => $self->event_journal->user + }) +} + +sub as_push_payload { + my $self = shift; + return '"t": 24, "j": "'.$self->event_journal->user.'"'; +} + + 1; Modified: trunk/cgi-bin/LJ/Event/UserMessageRecvd.pm =================================================================== --- trunk/cgi-bin/LJ/Event/UserMessageRecvd.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event/UserMessageRecvd.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -201,30 +201,14 @@ sub as_push { my $self = shift; my $u = shift; - my %args = @_; - my $message ; - if($args{from}) { - $message = LJ::Lang::get_text($u->prop('browselang'), 'esn.push.notification.usermessagerecvd.from', 1, { user => $u->{user}}); - } else { - $message = LJ::Lang::get_text($u->prop('browselang'), 'esn.push.notification.usermessagerecvd'); - } - - return $message; + return LJ::Lang::get_text($u->prop('browselang'), "esn.push.notification.usermessagerecvd", 1, { + user => $self->load_message->other_u->{user}, + }) } -sub as_push_title { - my $self = shift; - my $u = shift; - my %args = @_; +sub as_push_payload { '"t":9,"m":'.shift->arg1 } - my $message = LJ::Lang::get_text($u->prop('browselang'), 'esn.push.notification.usermessagerecvd.title'); - - return $message; -} - - - sub subscription_as_html { my ($class, $subscr) = @_; my $journal = $subscr->journal or croak "No user"; Modified: trunk/cgi-bin/LJ/Event.pm =================================================================== --- trunk/cgi-bin/LJ/Event.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Event.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -219,7 +219,12 @@ # my $etypeid = LJ::Event->event_to_etypeid('LJ::Event::ExampleEvent'); sub event_to_etypeid { my ($class, $evt_name) = @_; + $evt_name = "LJ::Event::$evt_name" unless $evt_name =~ /^LJ::Event::/; + + return undef + unless $class->typemap->class_to_typeid($evt_name); + my $tm = $class->typemap or return undef; return $tm->class_to_typeid($evt_name); @@ -488,6 +493,12 @@ ); } +sub as_push { warn "method 'as_push' has to be overriden in ".ref(shift)."!"; return '' } + +sub as_push_payload { warn "method 'as_push_payload' has to be overriden in ".ref(shift)."!"; return ''} + + + # Returns a string representing a Schwartz role [queue] used to handle this event # By default returns undef, which is ok for most cases. sub schwartz_role { Modified: trunk/cgi-bin/LJ/Subscription.pm =================================================================== --- trunk/cgi-bin/LJ/Subscription.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/Subscription.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -181,7 +181,7 @@ my $journalid = delete $params{journalid}; $journalid ||= LJ::want_userid(delete $params{journal}) if defined $params{journal}; - + $arg1 = delete $params{arg1}; $arg2 = delete $params{arg2}; @@ -349,7 +349,8 @@ # easier way to specify journal if (my $ju = delete $args{'journal'}) { - $args{journalid} = $ju->{userid} if $ju; + $args{journalid} = $ju->{userid} + if !$args{journalid} && $ju; } $args{arg1} ||= 0; Modified: trunk/cgi-bin/LJ/User.pm =================================================================== --- trunk/cgi-bin/LJ/User.pm 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/LJ/User.pm 2012-01-26 14:24:36 UTC (rev 21014) @@ -3505,6 +3505,7 @@ sub subscribe { my ($u, %opts) = @_; croak "No subscription options" unless %opts; + return LJ::Subscription->create($u, %opts); } @@ -3515,11 +3516,16 @@ # find all matching subscriptions my @subs = LJ::Subscription->find($u, %opts); + + return 0 + unless @subs; foreach (@subs) { # run delete method on each subscription $_->delete(); } + + return 1; } @@ -6319,6 +6325,23 @@ return $self->{'__social_influence_info'}; } +sub push_subscriptions { + my $u = shift; + my %opts = @_; + + $u->{push_subscriptions} = LJ::PushNotification::Storage->get_all($u) + if !$u->{push_subscriptions} || $opts{flush}; + + return keys %{$u->{push_subscriptions}}; +} + +sub push_subscription { + my $u = shift; + my $key = shift; + return $u->{push_subscriptions}{$key} || {}; +} + + package LJ; use Carp; @@ -8693,7 +8716,6 @@ } my $sclient = LJ::theschwartz(); - # part of the criteria for whether to fire defriended event my $notify = !$LJ::DISABLED{esn} && !$opts->{nonotify} && $u->is_visible && $u->is_person; @@ -10331,5 +10353,3 @@ } 1; - - Modified: trunk/cgi-bin/ljprotocol.pl =================================================================== --- trunk/cgi-bin/ljprotocol.pl 2012-01-26 13:54:43 UTC (rev 21013) +++ trunk/cgi-bin/ljprotocol.pl 2012-01-26 14:24:36 UTC (rev 21014) @@ -184,6 +184,9 @@ votepoll => \&votepoll, registerpush => \®isterpush, unregisterpush => \&unregisterpush, + pushsubscriptions => \&pushsubscriptions, + resetpushcounter => \&resetpushcounter, + getpushlist => \&getpushlist, ); sub translate @@ -5014,8 +5017,109 @@ return { status => 'OK' }; } +sub pushsubscriptions { + my ($req, $err, $flags) = @_; + return undef + unless authenticate($req, $err, $flags); + my $u = $flags->{u}; + my @errors; + foreach my $event (@{$req->{events}}) { + if($event->{action} =~ /^(un)?subscribe$/) { + my $res = eval{ + LJ::PushNotification->manage( + $u, + platform => $req->{platform}, + deviceid => $req->{deviceid}, + registrationid => $req->{registrationid}, + %$event, + ) + }; + + push @errors, $@ + if $@; + + } else { + push @errors, "wrong action '$event->{action}'"; + } + } + + return { status => 'Has errors', errors => join "; ", @errors } + if @errors; + + return { status => 'OK' }; + +} + +sub resetpushcounter { + my ($req, $err, $flags) = @_; + return undef + unless authenticate($req, $err, $flags); + + my $u = $flags->{u}; + + return fail($err,200) + unless $req->{platform} && $req->{deviceid}; + + return fail($err,200) + if $req->{platform} eq 'android'; + + + if(LJ::PushNotification::Storage->reset_counter($u, $req->{platform}, $req->{deviceid})) { + return { status => 'OK' } + } + + return { status => 'Error', error => "Can't reset counter"} + +} + +sub getpushlist { + my ($req, $err, $flags) = @_; + return undef + unless authenticate($req, $err, $flags); + + my $u = $flags->{u}; + + return fail($err,200) + unless $req->{platform} && $req->{deviceid}; + + my @subs = grep { $_->{ntypeid} == LJ::NotificationMethod::Push->ntypeid } ($u->subscriptions); + + my @events; + foreach my $s (@subs) { + + my ($event) = $s->event_class =~ /LJ::Event::(.*)/; + + my $journal = LJ::load_userid($s->{journalid}); + + my %event = ( + event => $event, + ); + + $event{journal} = LJ::load_userid($s->{journalid})->user + if $s->{journalid} != $s->{userid}; + + if($event eq 'JournalNewComment' && $s->arg1) { + $event{ditemid} = $s->arg1; + } + + if($event eq 'JournalNewComment' && $s->arg2) { + my $comment = LJ::Comment->instance($s->{journalid}, jtalkid => $s->arg2); + $event{dtalkid} = $comment->dtalkid; + } + + push @events, \%event; + } + + return { + status => 'OK', + events => \@events, + } + +} + + #### Old interface (flat key/values) -- wrapper aruond LJ::Protocol package LJ;