1 # This file is part of Email-Reminder.
3 # Email-Reminder is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License as
5 # published by the Free Software Foundation; either version 3 of the
6 # License, or (at your option) any later version.
8 # Email-Reminder is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with Email-Reminder; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 package EmailReminder
::EventList
;
20 # Holds all user information and events.
22 # Events are stored in the proper EventStore and they can be accessed
23 # using this class. The main XML parsing and generation happen here.
31 use EmailReminder
::AnniversaryEvent
;
32 use EmailReminder
::AnniversaryStore
;
33 use EmailReminder
::BirthdayEvent
;
34 use EmailReminder
::BirthdayStore
;
35 use EmailReminder
::MonthlyEvent
;
36 use EmailReminder
::MonthlyStore
;
37 use EmailReminder
::Utils
;
38 use EmailReminder
::WeeklyEvent
;
39 use EmailReminder
::WeeklyStore
;
40 use EmailReminder
::YearlyEvent
;
41 use EmailReminder
::YearlyStore
;
43 # XML tags, attributes and values
45 my $EMAIL_TAG = 'email';
46 my $EVENT_TAG = 'event';
47 my $EVENTS_TAG = 'events';
48 my $FIRST_NAME_TAG = 'first_name';
49 my $LAST_NAME_TAG = 'last_name';
50 my $USER_TAG = 'email-reminder_user';
52 my $TYPE_ATTR = 'type';
56 my ($class, $filename, $create) = @_;
58 my $self = { "NEXT_EVENT_ID" => 0,
59 "LOADED_FILENAME" => $filename,
61 "EVENTS_NODE" => undef,
67 $self->process_file($create);
74 my ($self, $create, $readonly) = @_;
76 # Make sure the config file exists and is readable
77 my $filename = $self->{LOADED_FILENAME
};
78 unless (-e
$filename) {
79 if ($create and open my $config_fh, '>:utf8', "$filename") {
80 print $config_fh '<?xml version="1.0"?><email-reminder_user/>';
84 die "File '$filename' does not exist and it is impossible to create it.\n";
87 unless (-r
$filename) {
88 die "File '$filename' exists but is not readable.\n";
90 if (!$readonly && !(-w
$filename)) {
91 warn "WARNING: File '$filename' is not writable, your changes will be lost!\n";
94 # Start parsing the XML file
95 my $parser = XML
::DOM
::Parser
->new();
98 $doc = $parser->parsefile($filename);
100 unless (defined($doc)) {
101 die "File '$filename' is an invalid XML file. Fix it or delete it.\n";
103 $self->{XML_DOC
} = $doc;
106 my $user = $doc->getElementsByTagName($USER_TAG)->item(0);
107 unless (defined($user)) {
108 die "File '$filename' is an invalid XML file. Fix it or delete it.\n";
110 $self->{USER_NODE
} = $user;
113 my $events = $doc->getElementsByTagName($EVENTS_TAG)->item(0);
114 return unless defined($events);
115 $self->{EVENTS_NODE
} = $events;
117 foreach my $event_node ($events->getElementsByTagName($EVENT_TAG)) {
118 my $type = $event_node->getAttribute($TYPE_ATTR);
119 my $event = $self->create_event($type, $event_node);
120 next unless defined($event);
122 # Add to proper EventStore
123 my $store = $self->get_model($type);
124 $store->add_event($event);
131 my ($self, $type, $event_node) = @_;
133 if (!defined($event_node))
135 $event_node = $self->{XML_DOC
}->createElement($EVENT_TAG);
136 $event_node->setAttribute($TYPE_ATTR, $type);
138 my $events = $self->{EVENTS_NODE
};
139 unless (defined($events))
141 $events = $self->{XML_DOC
}->createElement($EVENTS_TAG);
142 $self->{USER_NODE
}->appendChild($events);
143 $self->{EVENTS_NODE
} = $events;
145 $events->appendChild($event_node);
149 my $id = $self->{NEXT_EVENT_ID
}++;
151 if ($type eq EmailReminder
::BirthdayEvent
->get_type()) {
152 $event = EmailReminder
::BirthdayEvent
->new($event_node, $id);
154 elsif ($type eq EmailReminder
::AnniversaryEvent
->get_type()) {
155 $event = EmailReminder
::AnniversaryEvent
->new($event_node, $id);
157 elsif ($type eq EmailReminder
::MonthlyEvent
->get_type()) {
158 $event = EmailReminder
::MonthlyEvent
->new($event_node, $id);
160 elsif ($type eq EmailReminder
::WeeklyEvent
->get_type()) {
161 $event = EmailReminder
::WeeklyEvent
->new($event_node, $id);
163 elsif ($type eq EmailReminder
::YearlyEvent
->get_type()) {
164 $event = EmailReminder
::YearlyEvent
->new($event_node, $id);
174 my $filename = shift || $self->{LOADED_FILENAME
};
176 my $xml_document = $self->{XML_DOC
}->toString();
177 print $xml_document if $verbose;
180 if (open my $out_fh, '>:utf8', "$filename") {
181 print $out_fh $xml_document;
182 print "Sucessfully wrote reminders to '$filename'\n" if $verbose;
186 print STDERR
"Cannot write to file '$filename', your changes have been lost.\n";
194 my ($self, $type) = @_;
196 my $store = $self->{STORES
}->{$type};
197 unless (defined($store)) {
198 if ($type eq EmailReminder
::AnniversaryEvent
->get_type()) {
199 $store = EmailReminder
::AnniversaryStore
->new();
201 elsif ($type eq EmailReminder
::BirthdayEvent
->get_type()) {
202 $store = EmailReminder
::BirthdayStore
->new();
204 elsif ($type eq EmailReminder
::MonthlyEvent
->get_type()) {
205 $store = EmailReminder
::MonthlyStore
->new();
207 elsif ($type eq EmailReminder
::WeeklyEvent
->get_type()) {
208 $store = EmailReminder
::WeeklyStore
->new();
210 elsif ($type eq EmailReminder
::YearlyEvent
->get_type()) {
211 $store = EmailReminder
::YearlyStore
->new();
215 $self->{STORES
}->{$type} = $store;
226 foreach my $store (values(%{$self->{STORES
}})) {
227 push(@events, @
{$store->get_events()});
235 my ($self, $event_type) = @_;
236 my $event = $self->create_event($event_type);
237 return 0 unless defined($event);
239 $event->set_name("<New Event>");
240 $event->set_reminders([0]); # default reminder: same day
242 return $self->{STORES
}->{$event_type}->add_event($event);
245 # View/edit user properties
247 sub _get_user_fname
{
249 return EmailReminder
::Utils
::get_node_value
($self->{USER_NODE
}, $FIRST_NAME_TAG) || '';
252 sub _get_user_lname
{
254 return EmailReminder
::Utils
::get_node_value
($self->{USER_NODE
}, $LAST_NAME_TAG) || '';
261 my $fname = $self->_get_user_fname;
262 my $lname = $self->_get_user_lname;
264 if (!$fname && !$lname) {
265 # Get name from UNIX password file
266 my @pwinfo = getpwuid($>);
267 my $fullname = $pwinfo[6];
268 $fullname =~ s/[^0-9A-Za-z_\- ]//g;
269 my @name_parts = split(/ /, $fullname);
271 $fname = $name_parts[0];
272 $lname = $name_parts[-1] if @name_parts > 1;
278 return ($fname, $lname);
284 return EmailReminder
::Utils
::get_node_value
($self->{USER_NODE
}, $EMAIL_TAG) || "";
289 my ($self, $new_fname) = @_;
290 return EmailReminder
::Utils
::set_node_value
($self->{USER_NODE
}, $FIRST_NAME_TAG, $new_fname);
295 my ($self, $new_lname) = @_;
296 return EmailReminder
::Utils
::set_node_value
($self->{USER_NODE
}, $LAST_NAME_TAG, $new_lname);
299 # Return 0 if the email was ignored (invalid)
302 my ($self, $new_email) = @_;
303 if (!$new_email || Email
::Valid
->address($new_email)) {
304 return EmailReminder
::Utils
::set_node_value
($self->{USER_NODE
}, $EMAIL_TAG, $new_email);