mourningdove/cgi-bin/LJ/NotificationArchive.pm

215 lines
5.2 KiB
Perl
Raw Permalink Normal View History

2026-05-24 01:03:05 +00:00
# This code was forked from the LiveJournal project owned and operated
# by Live Journal, Inc. The code has been modified and expanded by
# Dreamwidth Studios, LLC. These files were originally licensed under
# the terms of the license supplied by Live Journal, Inc, which can
# currently be found at:
#
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
#
# In accordance with the original license, this code and all its
# modifications are provided under the GNU General Public License.
# A copy of that license can be found in the LICENSE file included as
# part of this distribution.
# This package is for managing a queue of archived notifications
# for a user.
# Henry Lyne 20070604
package LJ::NotificationArchive;
use strict;
use Carp qw(croak);
use LJ::NotificationItem;
use LJ::Event;
*new = \&instance;
my %singletons = ();
# constructor takes a $u
sub instance {
my ( $class, $u ) = @_;
croak "Invalid args to construct LJ::NotificationArchive" unless $class && $u;
croak "Invalid user" unless LJ::isu($u);
return $singletons{ $u->{userid} } if $singletons{ $u->{userid} };
my $self = {
uid => $u->userid,
count => undef, # defined once ->count is loaded/cached
items => undef,
};
$singletons{ $u->{userid} } = $self;
return bless $self, $class;
}
# returns the user object associated with this queue
sub u {
my $self = shift;
return LJ::load_userid( $self->{uid} );
}
# returns all non-deleted Event objects for this user
# in a hashref of {queueid => event}
# optional arg: daysold = how many days back to retrieve notifications for
sub notifications {
my $self = shift;
my $daysold = shift;
croak "notifications is an object method"
unless ( ref $self ) eq __PACKAGE__;
return $self->_load($daysold);
}
# Returns a list of LJ::NotificationItems in this queue.
sub items {
my $self = shift;
croak "items is an object method"
unless ( ref $self ) eq __PACKAGE__;
return @{ $self->{items} } if defined $self->{items};
my @qids = $self->_load;
my @items = ();
foreach my $qid (@qids) {
push @items, LJ::NotificationItem->new( $self->u, $qid );
}
$self->{items} = \@items;
return @items;
}
# load the events in this queue
sub _load {
my $self = shift;
return $self->{events} if $self->{loaded};
my $u = $self->u
or die "No user object";
# is it memcached?
my $qids;
$qids = LJ::MemCache::get( $self->_memkey ) and return @$qids;
# State of 'D' means Deleted
my $sth = $u->prepare( "SELECT userid, qid, journalid, etypeid, arg1, arg2, state, createtime "
. "FROM notifyarchive WHERE userid=? AND state!='D'" );
$sth->execute( $u->{userid} );
die $sth->errstr if $sth->err;
my @items = ();
while ( my $row = $sth->fetchrow_hashref ) {
my $qid = $row->{qid};
# load this item into process cache so it's ready to go
my $qitem = LJ::NotificationItem->new( $u, $qid );
$qitem->absorb_row($row);
push @items, $qitem;
}
# sort based on create time
@items = sort { $a->when_unixtime <=> $b->when_unixtime } @items;
# get sorted list of ids
my @item_ids = map { $_->qid } @items;
LJ::MemCache::set( $self->_memkey, \@item_ids );
return @item_ids;
}
sub _memkey {
my $self = shift;
my $userid = $self->{uid};
return [ $userid, "inbox:archive:$userid" ];
}
# deletes an Event that is queued for this user
# args: Queue ID to remove from queue
sub delete_from_queue {
my ( $self, $qid ) = @_;
croak "delete_from_queue is an object method"
unless ( ref $self ) eq __PACKAGE__;
croak "no queueid passed to delete_from_queue" unless int($qid);
my $u = $self->u
or die "No user object";
$self->_load;
# if this event was returned from our queue we should have
# its qid stored in our events hashref
delete $self->{events}->{$qid};
$u->do( "UPDATE notifyqueue SET state='D' WHERE qid=?", undef, $qid );
die $u->errstr if $u->err;
# invalidate caches
$self->expire_cache;
return 1;
}
sub expire_cache {
my $self = shift;
$self->{count} = undef;
$self->{items} = undef;
LJ::MemCache::delete( $self->_memkey );
}
# This will enqueue an event object
# Returns the queue id
sub enqueue {
my ( $self, %opts ) = @_;
my $evt = delete $opts{event};
croak "No event" unless $evt;
croak "Extra args passed to enqueue" if %opts;
my $u = $self->u or die "No user";
# get a qid
my $qid = LJ::alloc_user_counter( $u, 'Q' )
or die "Could not alloc new queue ID";
my %item = (
qid => $qid,
userid => $u->{userid},
journalid => $evt->u->{userid},
etypeid => $evt->etypeid,
arg1 => $evt->arg1,
arg2 => $evt->arg2,
state => ' ',
createtime => time()
);
# write to archive table
$u->do(
"INSERT INTO notifyarchive ("
. join( ",", keys %item )
. ") VALUES ("
. join( ",", map { '?' } values %item ) . ")",
undef,
values %item
) or die $u->errstr;
$self->{events}->{$qid} = $evt;
return $qid;
}
1;