Deleted unused functions and templates (Closes: #1012, #1013, #1014, #1020, #1021).
[gruta.git] / Gruta / Template / Artemus.pm
blob26f6a8eb5cd1ee7dedfeee43db94fdfd4eb6c2ba
1 package Gruta::Template::Artemus;
3 use strict;
4 use warnings;
5 use Carp;
7 use base 'Gruta::Template::BASE';
9 use Artemus;
10 use Gruta::Data;
12 sub new {
13 my $class = shift;
14 my %args = @_;
16 my $a = bless( {}, $class );
18 $a->{_artemus} = undef;
19 $a->{path} = $args{path};
21 $a->create();
23 return $a;
27 sub _artemus {
28 my $self = shift;
30 if (not $self->{_artemus}) {
31 my $data = $self->data();
33 my %f = ();
34 my %v = ();
36 $f{l} = sub {
37 my $t = shift;
39 return '?t=' . $t . ';' . join(';', @_);
42 $f{'add'} = sub { $_[0] + $_[1]; };
43 $f{'sub'} = sub { $_[0] - $_[1]; };
44 $f{'gt'} = sub { $_[0] > $_[1]; };
45 $f{'lt'} = sub { $_[0] < $_[1]; };
46 $f{'eq'} = sub { $_[0] eq $_[1] ? 1 : 0; };
48 $f{date} = sub { Gruta::Data::today(); };
49 $f{random} = sub { $_[rand(scalar(@_))]; };
51 foreach my $p (Gruta::Data::Topic->new->afields()) {
52 $f{'topic_' . $p} = sub {
53 my $topic = shift;
54 my $ret = '';
56 if ($topic ne '[]') {
57 $ret = $data->topic($topic)->get($p) || '';
60 return $ret;
64 foreach my $p (Gruta::Data::Story->new->afields()) {
65 $f{'story_' . $p} = sub {
66 my $topic_id = shift;
67 my $id = shift;
68 my $ret = '';
70 if ($id ne '[]') {
71 $ret = $data->story($topic_id, $id)->get($p);
74 return $ret;
78 $f{story_abstract} = sub {
79 my $story = $data->story($_[0], $_[1]);
81 return $data->special_uris($story->get('abstract'));
84 $f{story_body} = sub {
85 my $topic_id = shift;
86 my $id = shift;
87 my $ret = '{-404}';
89 if (my $topic = $data->topic($topic_id)) {
90 if (my $story = $data->story($topic_id, $id)) {
91 my $date2 = $story->get('date2');
93 # if no user and story is not freed, bounce
94 if (!$data->auth() && $date2 && $date2 > Gruta::Data::today()) {
95 $ret = '{-restricted_access}';
97 else {
98 # touch the story if user is not
99 # (potentially) involved on it
100 if (! $topic->is_editor($data->auth())) {
101 $story->touch();
104 $ret = $data->special_uris($story->get('body'));
109 return $ret;
112 $f{story_date} = sub {
113 my $format = shift;
114 my $topic_id = shift;
115 my $id = shift;
116 my $ret = '';
118 if ($id ne '[]') {
119 $ret = $data->story($topic_id, $id)->date($format);
122 return $ret;
125 $f{story_date2} = sub {
126 my $format = shift;
127 my $topic_id = shift;
128 my $id = shift;
129 my $ret = '';
131 if ($id ne '[]') {
132 $ret = $data->story($topic_id, $id)->date2($format);
135 return $ret;
138 foreach my $p (Gruta::Data::User->new->afields()) {
139 $f{'user_' . $p} = sub {
140 my $id = shift;
141 my $ret = '';
143 if ($id ne '[]') {
144 $ret = $data->user($id)->get($p);
147 return $ret;
151 $f{user_xdate} = sub {
152 my $format = shift;
153 my $id = shift;
154 my $ret = '';
156 if ($id ne '[]') {
157 $ret = $data->user($id)->xdate($format);
160 return $ret;
163 $f{template} = sub {
164 my $t = shift;
165 my $ret = '';
167 if ($t ne '[]') {
168 $t = $data->template->template($t);
169 $ret = $self->{_artemus}->armor($t);
172 return $ret;
175 $f{save_template} = sub {
176 my $template = shift;
177 my $content = shift;
178 my $msg = shift;
180 $content = $self->{_artemus}->unarmor($content);
181 $data->template->save_template($template, $content);
183 return $msg || "Template saved.";
186 $f{loop_topics} = sub {
187 my $template = shift;
188 my $sep = shift;
190 return join($sep, map {
191 my $t = $data->topic($_);
192 sprintf('{-%s|%s|%s}',
193 $template, $t->get('name'),
194 $t->get('id')
196 } $data->topics());
199 $f{loop_users} = sub {
200 return join($_[1], map { "{-$_[0]|$_}" } $data->users());
203 $f{loop_renderers} = sub {
204 return join($_[1], map { "{-$_[0]|$_}" }
205 sort(keys(%{$data->{renderers_h}})));
208 $f{loop_templates} = sub {
209 return join($_[1], map { "{-$_[0]|$_}" }
210 $data->template->templates());
213 $f{loop_upload_dirs} = sub {
214 return join($_[1], map { "{-$_[0]|$_}" }
215 $data->cgi->upload_dirs());
218 $f{loop_story_tags} = sub {
219 my $topic_id = shift;
220 my $id = shift;
222 return join($_[1], map { "{-$_[0]|$_}" }
223 $data->story($topic_id, $id)->tags());
226 $f{story_loop_by_date} = sub {
227 my $topic = shift;
228 my $num = shift;
229 my $offset = shift;
230 my $template = shift;
231 my $sep = shift;
232 my $from = shift;
233 my $to = shift;
234 my $future = shift;
236 return join($sep, map { "{-$template|$topic|$_}" }
237 $data->stories_by_date(
238 $topic,
239 num => $num,
240 offset => $offset,
241 from => $from,
242 to => $to,
243 future => $future
248 $f{is_logged_in} = sub {
249 return $data->auth() ? 1 : 0;
252 $f{is_admin} = sub {
253 return $data->auth() && $data->auth->get('is_admin') ? 1 : 0;
256 $f{is_topic_editor} = sub {
257 if (my $topic = $data->topic($_[0])) {
258 return $topic->is_editor($data->auth()) ? 1 : 0;
261 return 0;
264 $f{login} = sub {
265 my $user_id = shift;
266 my $password = shift;
267 my $error_msg = shift;
269 if ($user_id eq '' || $user_id eq 'cgi-userid') {
270 $error_msg = '{-login_box}';
272 elsif (my $sid = $data->login($user_id, $password)) {
273 $data->cgi->cookie("sid=$sid");
274 $data->cgi->redirect('?t=INDEX');
275 $self->{abort} = 1;
278 return $error_msg || 'Login incorrect.';
281 $f{logout} = sub {
282 $data->logout();
283 $data->cgi->redirect('?t=INDEX');
284 $self->{abort} = 1;
287 $f{assert} = sub {
288 my $cond = shift;
289 my $redir = shift || 'ADMIN';
291 if (! $cond) {
292 $data->cgi->redirect('?t=' . $redir);
293 $self->{abort} = 1;
296 return '';
299 $f{username} = sub {
300 return $data->auth() && $data->auth->get('username') || '';
303 $f{userid} = sub {
304 return $data->auth() && $data->auth->get('id') || '';
307 $f{search_stories} = sub {
308 my $topic_id = shift;
309 my $query = shift;
310 my $future = shift;
311 my $template = shift || '_story_link_as_item_with_edit';
312 my $sep = shift || '';
314 my $ret = '';
315 my @l = $data->search_stories($topic_id, $query, $future);
317 if (@l) {
318 $ret = "<p><b>{-topic_name|$topic_id}</b><br>\n";
320 $ret .= join($sep, map { "{-$template|$topic_id|$_}" } @l);
322 $self->{search_count} += scalar(@l);
325 return $ret;
328 $f{is_visible_story} = sub {
329 if (my $story = $data->story($_[0], $_[1])) {
330 return $story->is_visible($data->auth()) ? 1 : 0;
333 return 0;
336 $f{redir_if_archived} = sub {
337 my $template = shift;
338 my $topic_id = shift;
339 my $id = shift;
341 if ($topic_id =~ /-arch$/) {
342 return '';
345 my $story = $data->story($topic_id, $id);
347 if ($story->get('topic_id') =~ /-arch$/) {
348 $data->cgi->redirect(
349 sprintf('?t=%s;topic=%s;id=%s',
350 $template,
351 $story->get('topic_id'),
352 $id)
354 $self->{abort} = 1;
357 return '';
360 $f{topic_has_archive} = sub {
361 return $data->topic($_[0] . '-arch') ? 1 : 0;
364 $f{save_topic} = sub {
365 my $topic_id = shift || return 'Error 1';
367 my $topic = undef;
369 if (not $topic = $data->topic($topic_id)) {
370 $topic = Gruta::Data::Topic->new (
371 id => $topic_id );
374 $topic->set('name', shift);
375 $topic->set('editors', shift);
376 $topic->set('internal', shift eq 'on' ? 1 : 0);
377 $topic->set('max_stories', shift);
379 # update or insert
380 if ($topic->source()) {
381 $topic = $topic->save();
383 else {
384 $topic = $data->insert_topic($topic);
387 return $topic ? 'OK' : 'Error 2';
390 $f{save_story} = sub {
391 my $topic_id = shift || return 'Error 1';
392 my $id = shift;
394 my $story = undef;
396 if (not $story = $data->story($topic_id, $id)) {
397 $story = Gruta::Data::Story->new (
398 topic_id => $topic_id,
399 id => $id
403 my $content = shift;
404 $content = $self->{_artemus}->unarmor($content);
406 $story->set('content', $content);
408 # pick date and drop time
409 my $y = shift;
410 my $m = shift;
411 my $d = shift;
412 shift; shift; shift;
413 my $date = Gruta::Data::today();
415 if ($y && $m && $d) {
416 $date = sprintf("%04d%02d%02d000000", $y, $m, $d);
419 $story->set('date', $date);
420 $story->set('format', shift || 'grutatxt');
422 # get the tags
423 my $tags = shift;
425 # get date2
426 $y = shift;
427 $m = shift;
428 $d = shift;
430 if ($y && $m && $d) {
431 $date = sprintf("%04d%02d%02d000000", $y, $m, $d);
433 else {
434 $date = '';
437 $story->set('date2', $date);
439 # drop all cached stories
440 $data->flush_story_cache();
442 if ($story->source()) {
443 $story = $story->save();
445 else {
446 $story = $data->insert_story($story);
449 if ($tags ne 'cgi-tags') {
450 $story->tags(split(/\s*,\s*/, $tags));
453 return $story ? $story->get('id') : 'Error 2';
456 $f{save_user} = sub {
457 shift; # new (ignored)
458 my $id = shift || return 'Error 1';
459 my $username = shift;
460 my $email = shift;
461 my $is_admin = shift;
462 my $can_upload = shift;
463 my $pass1 = shift;
464 my $pass2 = shift;
465 my $xy = shift;
466 my $xm = shift;
467 my $xd = shift;
469 if ($data->auth->get('username') ne $username &&
470 ! $data->auth->get('is_admin')) {
471 $data->cgi->redirect('?t=LOGIN');
472 $self->{abort} = 1;
473 return '';
476 my $user = undef;
478 if (not $user = $data->user($id)) {
479 $user = Gruta::Data::User->new (
480 id => $id,
481 is_admin => 0,
482 can_upload => 0,
483 xdate => ''
487 $user->set('username', $username);
488 $user->set('email', $email);
490 # these params can only be set by an admin
491 if ($data->auth->get('is_admin')) {
493 $user->set('is_admin', $is_admin eq 'on' ? 1 : 0);
494 $user->set('can_upload', $can_upload eq 'on' ? 1 : 0);
496 if ($xy and $xm and $xd) {
497 $user->set('xdate',
498 sprintf('%04d%02d%02d000000',
499 $xy, $xm, $xd));
501 else {
502 $user->set('xdate', '');
506 if ($pass1 and $pass2) {
507 if ($pass1 ne $pass2) {
508 croak "Passwords are different";
511 $user->password($pass1);
514 if ($user->source()) {
515 $user = $user->save();
517 else {
518 $user = $data->insert_user($user);
521 return $user ? 'OK' : 'Error 2';
524 $f{upload} = sub {
526 $data->cgi->upload($_[0], $_[1]);
527 return 'OK';
530 $f{delete_story} = sub {
531 my $topic_id = shift || return 'Error 1';
532 my $id = shift;
534 $data->story($topic_id, $id)->delete();
536 # drop all cached stories
537 $data->flush_story_cache();
539 return 'OK';
542 $f{search_count} = sub { $self->{search_count}; };
544 $f{content_type} = sub {
545 $data->cgi->http_headers('Content-Type' => $_[0]);
546 return '';
549 $f{topics} = sub { join(':', $data->topics()); };
550 $f{templates} = sub { join(':', $data->template->templates()); };
551 $f{users} = sub { join(':', $data->users()); };
553 $f{renderers} = sub { join(':', sort(keys(%{$data->{renderers_h}}))); };
554 $f{upload_dirs} = sub { join(':', $data->cgi->upload_dirs()); };
555 $f{tags} = sub { join(':', map { $_->[0] . ',' . $_->[1] } $data->tags()); };
557 $f{var} = sub {
558 my $ret = $self->{cgi_vars}->{$_[0]} || $_[1] || '';
560 return $self->{_artemus}->armor($ret);
563 $f{story_tags} = sub {
564 my $topic_id = shift;
565 my $id = shift;
566 my $ret = '';
568 if ($id ne '[]') {
569 my $story = $data->story($topic_id, $id);
571 $ret = join(':', $story->tags());
574 return $ret;
577 $f{stories_by_date} = sub {
578 my $topic = shift;
579 my $num = shift;
580 my $offset = shift;
581 my $from_date = shift;
582 my $to_date = shift;
583 my $future = shift;
585 return join(':',
586 $data->stories_by_date(
587 $topic,
588 num => $num,
589 offset => $offset,
590 from => $from_date,
591 to => $to_date,
592 future => $future
597 $f{stories_by_tag} = sub {
598 my $tag = shift;
599 my $future = shift;
601 my @ret = $data->search_stories_by_tag($tag, $future);
602 $self->{search_count} += scalar(@ret);
604 return join(':', map { $_->[0] . ',' . $_->[1] } @ret);
607 $f{stories_top_ten} = sub {
608 my $num = shift;
610 return join(':', map { join(',', @{$_}) }
611 $data->stories_top_ten($num)
615 $self->{abort} = 0;
616 $self->{unresolved} = [];
617 $self->{search_count} = 0;
619 $self->{_artemus} = Artemus->new(
620 'include-path' => $self->{path},
621 'funcs' => \%f,
622 'vars' => \%v,
623 'unresolved' => $self->{unresolved},
624 'abort' => \$self->{abort},
627 if ($self->{cgi_vars}) {
628 foreach my $k (keys(%{ $self->{cgi_vars} })) {
629 my $c = $self->{_artemus}->
630 armor($self->{cgi_vars}->{$k});
631 $c =~ s/\r//g;
633 $v{"cgi-${k}"} = $c;
638 return $self->{_artemus};
642 sub data {
643 my $self = shift;
644 my $data = shift;
646 if (defined($data)) {
647 $self->{data} = $data;
648 $self->{_artemus} = undef;
651 return $self->{data};
655 sub cgi_vars {
656 my $self = shift;
658 if (@_) {
659 $self->{cgi_vars} = shift;
660 $self->{_artemus} = undef;
663 return $self->{cgi_vars};
667 sub process { $_[0]->_artemus->process('{-' . $_[1] . '}'); }