1 package Gruta
::Template
::Artemus
;
7 use base
'Gruta::Template::BASE';
16 my $a = bless( {}, $class );
18 $a->{_artemus
} = undef;
19 $a->{path
} = $args{path
};
28 if (not $self->{_artemus
}) {
29 my $data = $self->data();
37 return '?t=' . $t . ';' . join(';', @_);
40 $f{'add'} = sub { $_[0] + $_[1]; };
41 $f{'sub'} = sub { $_[0] - $_[1]; };
42 $f{'gt'} = sub { $_[0] > $_[1]; };
43 $f{'lt'} = sub { $_[0] < $_[1]; };
44 $f{'eq'} = sub { $_[0] eq $_[1] ?
1 : 0; };
46 $f{date
} = sub { Gruta
::Data
::today
(); };
47 $f{random
} = sub { $_[rand(scalar(@_))]; };
49 foreach my $p (Gruta
::Data
::Topic
->new->afields()) {
50 $f{'topic_' . $p} = sub {
55 $ret = $data->topic($topic)->get($p) || '';
62 foreach my $p (Gruta
::Data
::Story
->new->afields()) {
63 $f{'story_' . $p} = sub {
69 $ret = $data->story($topic_id, $id)->get($p);
76 $f{story_tags
} = sub {
82 my $story = $data->story($topic_id, $id);
84 $ret = join(', ', $story->tags());
90 $f{story_body
} = sub {
91 my $story = $data->story($_[0], $_[1]);
92 my $ret = $story->get('body');
94 if (not $data->auth()) {
101 $f{story_date
} = sub {
103 my $topic_id = shift;
108 $ret = $data->story($topic_id, $id)->date($format);
114 foreach my $p (Gruta
::Data
::User
->new->afields()) {
115 $f{'user_' . $p} = sub {
120 $ret = $data->user($id)->get($p);
127 $f{user_xdate
} = sub {
133 $ret = $data->user($id)->xdate($format);
144 $t = $data->template->template($t);
145 $ret = $self->{_artemus
}->armor($t);
151 $f{save_template
} = sub {
152 my $template = shift;
156 $content = $self->{_artemus
}->unarmor($content);
157 $data->template->save_template($template, $content);
159 return $msg || "Template saved.";
162 $f{loop_topics
} = sub {
163 my $template = shift;
166 return join($sep, map {
167 my $t = $data->topic($_);
168 sprintf('{-%s|%s|%s}',
169 $template, $t->get('name'),
175 $f{loop_users
} = sub {
176 return join($_[1], map { "{-$_[0]|$_}" } $data->users());
179 $f{loop_renderers
} = sub {
180 return join($_[1], map { "{-$_[0]|$_}" }
181 sort(keys(%{$data->{renderers_h
}})));
184 $f{loop_templates
} = sub {
185 return join($_[1], map { "{-$_[0]|$_}" }
186 $data->template->templates());
189 $f{loop_upload_dirs
} = sub {
190 return join($_[1], map { "{-$_[0]|$_}" }
191 $data->cgi->upload_dirs());
194 $f{loop_story_tags
} = sub {
195 my $topic_id = shift;
198 return join($_[1], map { "{-$_[0]|$_}" }
199 $data->story($topic_id, $id)->tags());
202 $f{story_loop_by_date
} = sub {
206 my $template = shift;
212 return join($sep, map { "{-$template|$topic|$_}" }
213 $data->stories_by_date(
224 $f{is_logged_in
} = sub {
225 return $data->auth() ?
1 : 0;
229 if ($data->auth() and $data->auth->get('is_admin')) {
235 $f{is_topic_editor
} = sub {
238 if (not $auth = $data->auth()) {
242 if ($auth->get('is_admin')) {
248 if (not $topic = $data->topic($_[0])) {
252 if (my $editors = $topic->get('editors') and
253 my $user_id = $auth->get('id')) {
254 return 1 if $editors =~/\b$user_id\b/;
262 my $password = shift;
263 my $error_msg = shift;
265 if ($user_id eq '' || $user_id eq 'cgi-userid') {
266 $error_msg = '{-login_box}';
268 elsif (my $sid = $data->login($user_id, $password)) {
269 $data->cgi->cookie("sid=$sid");
270 $data->cgi->redirect('?t=INDEX');
274 return $error_msg || 'Login incorrect.';
279 $data->cgi->redirect('?t=INDEX');
285 my $redir = shift || 'ADMIN';
288 $data->cgi->redirect('?t=' . $redir);
299 $ret = $data->auth->get('username');
305 $f{search_stories
} = sub {
306 my $topic_id = shift;
309 return "search_stories: FIXME";
312 $f{story_loop_top_ten
} = sub {
314 my $internal = shift; # ignored
315 my $template = shift;
318 return join($sep, map { "{-$template|$_->[1]|$_->[2]}" }
319 $data->stories_top_ten($num)
323 $f{is_visible_story
} = sub {
324 my $story = $data->story($_[0], $_[1]);
326 if (!$data->auth() && $story->get('date') > Gruta
::Data
::today
()) {
333 $f{redir_if_archived
} = sub {
334 my $template = shift;
335 my $topic_id = shift;
338 if ($topic_id =~ /-arch$/) {
342 my $story = $data->story($topic_id, $id);
344 if ($story->get('topic_id') =~ /-arch$/) {
345 $data->cgi->redirect(
346 sprintf('?t=%s;topic=%s;id=%s',
348 $story->get('topic_id'),
357 $f{topic_has_archive
} = sub {
358 return $data->topic($_[0] . '-arch') ?
1 : 0;
361 $f{save_topic
} = sub {
362 my $topic_id = shift || return 'Error 1';
366 if (not $topic = $data->topic($topic_id)) {
367 $topic = Gruta
::Data
::Topic
->new (
371 $topic->set('name', shift);
372 $topic->set('editors', shift);
373 $topic->set('internal', shift eq 'on' ?
1 : 0);
374 $topic->set('max_stories', shift);
377 if ($topic->source()) {
378 $topic = $topic->save();
381 $topic = $data->insert_topic($topic);
384 return $topic ?
'OK' : 'Error 2';
387 $f{save_story
} = sub {
388 my $topic_id = shift || return 'Error 1';
393 if (not $story = $data->story($topic_id, $id)) {
394 $story = Gruta
::Data
::Story
->new (
395 topic_id
=> $topic_id,
401 $content = $self->{_artemus
}->unarmor($content);
403 $story->set('content', $content);
405 # pick date and drop time
410 my $date = Gruta
::Data
::today
();
412 if ($y && $m && $d) {
413 $date = sprintf("%04d%02d%02d000000", $y, $m, $d);
416 $story->set('date', $date);
417 $story->set('format', shift || 'grutatxt');
419 # drop all cached stories
420 $data->flush_story_cache();
422 if ($story->source()) {
423 $story = $story->save();
426 $story = $data->insert_story($story);
432 if ($tags ne 'cgi-tags') {
433 $story->tags(split(/\s*,\s*/, $tags));
436 return $story ?
$story->get('id') : 'Error 2';
439 $f{save_user
} = sub {
440 shift; # new (ignored)
441 my $id = shift || return 'Error 1';
445 if (not $user = $data->user($id)) {
446 $user = Gruta
::Data
::User
->new (
453 $user->set('username', shift);
454 $user->set('email', shift);
456 # these params can only be set by an admin
457 if ($data->auth() && $data->auth->get('is_admin')) {
458 my $is_admin = shift;
459 my $can_upload = shift;
461 $user->set('is_admin', $is_admin eq 'on' ?
1 : 0);
462 $user->set('can_upload', $can_upload eq 'on' ?
1 : 0);
472 if ($pass1 and $pass2) {
473 if ($pass1 ne $pass2) {
474 croak
"Passwords are different";
477 my $salt = sprintf('%02d', rand(100));
478 my $pw = crypt($pass1, $salt);
480 $user->set('password', $pw);
483 # pick expiration date
488 if ($xy and $xm and $xd) {
490 sprintf('%04d%02d%02d000000',
494 $user->set('xdate', '');
497 if ($user->source()) {
498 $user = $user->save();
501 $user = $data->insert_user($user);
504 return $user ?
'OK' : 'Error 2';
509 $data->cgi->upload($_[0], $_[1]);
513 $f{delete_story
} = sub {
514 my $topic_id = shift || return 'Error 1';
517 $data->story($topic_id, $id)->delete();
519 # drop all cached stories
520 $data->flush_story_cache();
525 $f{search_stories_by_tag
} = sub {
527 my $template = shift;
530 return join($sep, map { "{-$template|$_->[0]|$_->[1]}" }
531 $data->search_stories_by_tag($tag)
536 $self->{unresolved
} = [];
538 $self->{_artemus
} = Artemus
->new(
539 'include-path' => $self->{path
},
542 'unresolved' => $self->{unresolved
},
543 'abort' => \
$self->{abort
},
546 if ($self->{cgi_vars
}) {
547 foreach my $k (keys(%{ $self->{cgi_vars
} })) {
548 my $c = $self->{_artemus
}->
549 armor
($self->{cgi_vars
}->{$k});
557 return $self->{_artemus
};
565 if (defined($data)) {
566 $self->{data
} = $data;
567 $self->{_artemus
} = undef;
570 return $self->{data
};
578 $self->{cgi_vars
} = shift;
579 $self->{_artemus
} = undef;
582 return $self->{cgi_vars
};
586 sub process
{ $_[0]->_artemus->process('{-' . $_[1] . '}'); }