2009-02-11 17:18:38 +01:00
|
|
|
## @file
|
|
|
|
# File storage methods for notifications
|
|
|
|
|
|
|
|
## @class
|
|
|
|
# File storage methods for notifications
|
2016-06-02 23:20:36 +02:00
|
|
|
package Lemonldap::NG::Common::Notifications::File;
|
2009-02-11 17:18:38 +01:00
|
|
|
|
|
|
|
use strict;
|
2016-05-30 22:20:53 +02:00
|
|
|
use Mouse;
|
2009-02-11 17:18:38 +01:00
|
|
|
use MIME::Base64;
|
|
|
|
|
2016-03-17 23:19:44 +01:00
|
|
|
our $VERSION = '2.0.0';
|
2009-06-08 18:29:13 +02:00
|
|
|
|
2016-06-02 23:20:36 +02:00
|
|
|
extends 'Lemonldap::NG::Common::Notifications';
|
2017-01-31 23:10:26 +01:00
|
|
|
|
2017-02-01 06:30:44 +01:00
|
|
|
our $ext = 'json';
|
|
|
|
|
2017-01-31 20:11:59 +01:00
|
|
|
sub import {
|
|
|
|
shift;
|
2017-02-01 06:30:44 +01:00
|
|
|
$ext = 'xml' if ( $_[0] eq 'XML' );
|
2017-01-31 23:10:26 +01:00
|
|
|
return Lemonldap::NG::Common::Notifications->import(@_);
|
2017-01-31 20:11:59 +01:00
|
|
|
}
|
|
|
|
|
2016-06-02 23:20:36 +02:00
|
|
|
has dirName => ( is => 'ro', required => 1 );
|
2011-07-29 10:23:18 +02:00
|
|
|
|
2016-05-30 22:20:53 +02:00
|
|
|
has table => (
|
|
|
|
is => 'rw',
|
|
|
|
trigger => sub {
|
|
|
|
$_[0]->{dirName} =~ s/\/conf\/?$//;
|
|
|
|
$_[0]->{dirName} .= "/$_[0]->{table}";
|
|
|
|
}
|
|
|
|
);
|
2011-07-29 10:23:18 +02:00
|
|
|
|
2016-05-30 22:20:53 +02:00
|
|
|
has fileNameSeparator => ( is => 'rw', default => '_' );
|
2009-02-11 17:18:38 +01:00
|
|
|
|
2009-03-04 09:37:08 +01:00
|
|
|
# Returns notifications corresponding to the user $uid.
|
2009-02-11 17:18:38 +01:00
|
|
|
# If $ref is set, returns only notification corresponding to this reference.
|
|
|
|
sub get {
|
|
|
|
my ( $self, $uid, $ref ) = @_;
|
|
|
|
return () unless ($uid);
|
2011-07-29 10:23:18 +02:00
|
|
|
my $fns = $self->{fileNameSeparator};
|
2016-02-24 18:26:52 +01:00
|
|
|
my $identifier = &getIdentifier( $self, $uid, $ref );
|
|
|
|
|
|
|
|
opendir D, $self->{dirName};
|
2017-02-01 06:30:44 +01:00
|
|
|
my @notif = grep /^\d{8}${fns}${identifier}\S*\.$ext$/, readdir(D);
|
2012-07-12 14:10:44 +02:00
|
|
|
closedir D;
|
2016-02-24 18:26:52 +01:00
|
|
|
|
2009-02-11 17:18:38 +01:00
|
|
|
my $files;
|
|
|
|
foreach my $file (@notif) {
|
|
|
|
unless ( open F, $self->{dirName} . "/$file" ) {
|
2011-07-29 10:23:18 +02:00
|
|
|
$self->lmLog( "Unable to read notification $self->{dirName}/$file",
|
2009-02-12 20:48:53 +01:00
|
|
|
'error' );
|
2009-02-11 17:18:38 +01:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
$files->{$file} = join( '', <F> );
|
|
|
|
}
|
|
|
|
return $files;
|
|
|
|
}
|
|
|
|
|
2009-03-04 09:37:08 +01:00
|
|
|
## @method hashref getAll()
|
|
|
|
# Return all messages not notified.
|
|
|
|
# @return hashref where keys are internal reference and values are hashref with
|
|
|
|
# keys date, uid and ref.
|
|
|
|
sub getAll {
|
|
|
|
my $self = shift;
|
|
|
|
opendir D, $self->{dirName};
|
|
|
|
my @notif;
|
2011-07-29 10:23:18 +02:00
|
|
|
my $fns = $self->{fileNameSeparator};
|
2017-02-01 06:30:44 +01:00
|
|
|
@notif = grep /^\S*\.$ext$/, readdir(D);
|
2009-03-04 09:37:08 +01:00
|
|
|
my %h = map {
|
2017-02-01 06:30:44 +01:00
|
|
|
/^(\d{8})${fns}([^\s${fns}]+)${fns}([^\s${fns}]+)(?:${fns}([^\s${fns}]+))?\.$ext$/
|
2011-06-29 17:06:04 +02:00
|
|
|
? (
|
|
|
|
$_ => {
|
|
|
|
date => $1,
|
|
|
|
uid => $2,
|
|
|
|
ref => decode_base64($3),
|
2015-05-14 08:45:03 +02:00
|
|
|
condition => decode_base64( $4 // '' )
|
2011-06-29 17:06:04 +02:00
|
|
|
}
|
|
|
|
)
|
2009-03-04 09:37:08 +01:00
|
|
|
: ()
|
|
|
|
} @notif;
|
|
|
|
return \%h;
|
|
|
|
}
|
|
|
|
|
2009-02-11 17:18:38 +01:00
|
|
|
## @method boolean delete(string myref)
|
|
|
|
# Mark a notification as done.
|
2009-03-04 09:37:08 +01:00
|
|
|
# @param $myref identifier returned by get() or getAll()
|
2009-02-11 17:18:38 +01:00
|
|
|
sub delete {
|
2009-02-17 16:22:42 +01:00
|
|
|
my ( $self, $myref ) = @_;
|
2017-02-01 06:30:44 +01:00
|
|
|
my $new = ( $myref =~ /(.*?)(?:\.$ext)$/ )[0] . '.done';
|
2009-02-17 16:22:42 +01:00
|
|
|
return rename( $self->{dirName} . "/$myref", $self->{dirName} . "/$new" );
|
2009-02-11 17:18:38 +01:00
|
|
|
}
|
|
|
|
|
2009-03-04 09:37:08 +01:00
|
|
|
## @method boolean purge(string myref)
|
|
|
|
# Purge notification (really delete record)
|
|
|
|
# @param $myref identifier returned by get() or getAll()
|
|
|
|
# @return true if something was deleted
|
|
|
|
sub purge {
|
|
|
|
my ( $self, $myref ) = @_;
|
|
|
|
return unlink( $self->{dirName} . "/$myref" );
|
|
|
|
}
|
|
|
|
|
2009-02-11 17:18:38 +01:00
|
|
|
# Insert a new notification
|
|
|
|
sub newNotif {
|
2017-02-01 06:30:44 +01:00
|
|
|
my ( $self, $date, $uid, $ref, $condition, $content ) = @_;
|
2011-07-29 10:23:18 +02:00
|
|
|
my $fns = $self->{fileNameSeparator};
|
2009-02-11 17:18:38 +01:00
|
|
|
$date =~ s/-//g;
|
|
|
|
return ( 0, "Bad date" ) unless ( $date =~ /^\d{8}/ );
|
|
|
|
my $filename =
|
2011-07-29 10:23:18 +02:00
|
|
|
$self->{dirName}
|
|
|
|
. "/${date}${fns}${uid}${fns}"
|
|
|
|
. encode_base64( $ref, '' );
|
|
|
|
$filename .= "${fns}" . encode_base64( $condition, '' ) if $condition;
|
2017-02-01 06:30:44 +01:00
|
|
|
$filename .= ".$ext";
|
2011-06-29 17:06:04 +02:00
|
|
|
|
2009-02-11 17:18:38 +01:00
|
|
|
return ( 0, 'This notification still exists' ) if ( -e $filename );
|
2017-02-01 06:30:44 +01:00
|
|
|
my $old = ( $filename =~ /(.*?)(?:\.$ext)$/ )[0] . '.done';
|
2009-02-11 17:18:38 +01:00
|
|
|
return ( 0, 'This notification has been done' ) if ( -e $old );
|
|
|
|
open my $F, ">$filename" or return ( 0, "Unable to create $filename ($!)" );
|
|
|
|
binmode($F);
|
2017-02-01 06:30:44 +01:00
|
|
|
print $F $content;
|
2009-02-11 17:18:38 +01:00
|
|
|
return ( 0, "Unable to close $filename ($!)" ) unless ( close $F );
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-03-04 09:37:08 +01:00
|
|
|
## @method hashref getDone()
|
|
|
|
# Returns a list of notification that have been done
|
|
|
|
# @return hashref where keys are internal reference and values are hashref with
|
|
|
|
# keys notified, uid and ref.
|
|
|
|
sub getDone {
|
|
|
|
my ($self) = @_;
|
|
|
|
opendir D, $self->{dirName};
|
|
|
|
my @notif;
|
2011-07-29 10:23:18 +02:00
|
|
|
my $fns = $self->{fileNameSeparator};
|
|
|
|
@notif = grep /^\d{8}${fns}\S*\.done$/, readdir(D);
|
2009-03-04 09:37:08 +01:00
|
|
|
my $res;
|
|
|
|
foreach my $file (@notif) {
|
2011-07-29 10:23:18 +02:00
|
|
|
my ( $u, $r ) =
|
|
|
|
( $file =~
|
|
|
|
/^\d+${fns}([^${fns}]+)${fns}([^${fns}]+)${fns}?([^${fns}]+)\.done$/
|
|
|
|
);
|
2009-03-04 09:37:08 +01:00
|
|
|
die unless ( -f "$self->{dirName}/$file" );
|
|
|
|
my $time = ( stat("$self->{dirName}/$file") )[10];
|
|
|
|
$res->{$file} = {
|
|
|
|
'uid' => $u,
|
|
|
|
'ref' => decode_base64($r),
|
|
|
|
'notified' => $time,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
2016-02-24 18:26:52 +01:00
|
|
|
## @method string getIdentifier(string uid, string ref, string date)
|
|
|
|
# Get notification identifier
|
|
|
|
# @param $uid uid
|
|
|
|
# @param $ref ref
|
|
|
|
# @param $date date
|
|
|
|
# @return the notification identifier
|
|
|
|
sub getIdentifier {
|
|
|
|
my ( $self, $uid, $ref, $date ) = @_;
|
|
|
|
my $result;
|
|
|
|
|
|
|
|
# Special fix to manage purge from notification explorer
|
|
|
|
return $date if $date;
|
|
|
|
|
|
|
|
my $fns = $self->{fileNameSeparator};
|
|
|
|
if ($date) {
|
|
|
|
$result .= $date . $fns;
|
|
|
|
}
|
|
|
|
$result .= $uid;
|
|
|
|
if ($ref) {
|
|
|
|
my $tmp = encode_base64( $ref, '' );
|
|
|
|
$result .= $fns . $tmp;
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2009-02-11 17:18:38 +01:00
|
|
|
1;
|
|
|
|
|