10 $Gruta::VERSION
= '2.0.0-rc3';
12 sub sources
{ return @
{$_[0]->{sources
}}; }
13 sub template
{ return $_[0]->{template
}; }
14 sub cgi
{ return $_[0]->{cgi
}; }
16 sub version
{ return $Gruta::VERSION
; }
22 print STDERR
$self->{id
}, ' ', scalar(localtime), ': ', $msg, "\n";
33 foreach my $s ($self->sources()) {
34 if (my $m = $s->can($method)) {
35 my @pr = $m->($s, @_);
45 return wantarray ?
@r : $r[0];
48 sub topic
{ my $self = shift; return $self->_call('topic', 1, @_); }
49 sub topics
{ my $self = shift; return $self->_call('topics', 0); }
51 sub user
{ my $self = shift; return $self->_call('user', 1, @_); }
52 sub users
{ my $self = shift; return $self->_call('users', 0); }
59 if (! $topic_id || ! $id) {
64 my $ck = $topic_id . '/' . $id;
66 if ($story = $self->{story_cache
}->{$ck}) {
70 if (not $story = $self->_call('story', 1, $topic_id, $id)) {
74 my $format = $story->get('format') || 'grutatxt';
76 if (my $rndr = $self->{renderers_h
}->{$format}) {
80 return $self->{story_cache
}->{$ck} = $story;
84 sub stories
{ my $self = shift; return $self->_call('stories', 0, @_); }
91 my @r = sort { $b->[2] cmp $a->[2] } $self->_call('stories_by_date', 0, $topics, %opts);
93 if ($opts{num
} && scalar(@r) > $opts{num
}) {
94 @r = @r[0 .. $opts{num
} - 1];
102 my $topic_id = shift;
104 my @l = $self->_call('search_stories', 1, $topic_id, @_);
106 return sort { $self->story($topic_id, $a)->get('title') cmp
107 $self->story($topic_id, $b)->get('title') } @l;
110 sub stories_top_ten
{
113 my @l = $self->_call('stories_top_ten', 0, @_);
115 return sort { $b->[0] <=> $a->[0] } @l;
118 sub search_stories_by_tag
{
121 my @l = $self->_call('search_stories_by_tag', 0, @_);
123 return sort { $self->story($a->[0], $a->[1])->get('title') cmp
124 $self->story($b->[0], $b->[1])->get('title') } @l;
130 my @l = $self->_call('tags', 0, @_);
132 return sort { $a->[0] cmp $b->[0] } @l;
135 sub insert_topic
{ my $self = shift; return $self->_call('insert_topic', 1, @_); }
136 sub insert_user
{ my $self = shift; return $self->_call('insert_user', 1, @_); }
137 sub insert_story
{ my $self = shift; return $self->_call('insert_story', 1, @_); }
143 if (@_) { $self->{auth
} = shift; } # Gruta::Data::User
145 return $self->{auth
};
156 $self->_call('purge_old_sessions', 0);
158 if (my $session = $self->_call('session', 1, $sid)) {
159 $u = $session->source->user( $session->get('user_id') );
160 $u->set('sid', $sid);
176 if (my $u = $self->user( $user_id )) {
178 # account expired? go!
179 if (my $xdate = $u->get('xdate')) {
180 if (Gruta
::Data
::today
() > $xdate) {
185 my $p = $u->get('password');
187 if (crypt($passwd, $p) eq $p) {
191 my $session = Gruta
::Data
::Session
->new(
197 $u->source->insert_session( $session );
199 $u->set('sid', $sid);
211 if (my $auth = $self->auth()) {
212 if( my $sid = $auth->get('sid')) {
213 if (my $session = $auth->source->session( $sid )) {
214 $session->delete() if $session->can('delete');
219 $self->auth( undef );
224 sub base_url
{ $_[0]->{base_url
} || '' };
226 sub _topic_special_uri
{
228 my $topic_id = shift;
232 if (my $t = $self->topic($topic_id)) {
233 $ret = sprintf('<a href="%s?t=TOPIC;topic=%s">%s</a>',
234 $self->base_url(), $topic_id, $t->get('name')
238 $ret = "Bad topic $topic_id";
245 sub _story_special_uri
{
247 my $topic_id = shift;
248 my $story_id = shift;
252 if (my $s = $self->story($topic_id, $story_id)) {
253 $ret = sprintf('<a href="%s?t=STORY;topic=%s;id=%s">%s</a>',
254 $self->base_url(), $topic_id, $story_id, $s->get('title')
258 $ret = "Bad story '$topic_id/$story_id'";
265 sub _img_special_uri
{
270 my $r = sprintf('<img src = "%simg/%s" />',
271 $self->base_url(), $src
275 $r = "<span class = '$class'>" . $r . '</span>';
285 $string =~ s!topic://([\w\d_]+)!$self->_topic_special_uri($1)!ge;
286 $string =~ s!story://([\w\d_]+)/([\w\d_]+)!$self->_story_special_uri($1,$2)!ge;
287 $string =~ s!img://([\w\d_\.-]+)/?([\w\d_]*)!$self->_img_special_uri($1,$2)!ge;
293 sub transfer_to_source
{
297 foreach my $id ($self->users()) {
298 my $u = $self->user($id);
299 $dst->insert_user($u);
302 foreach my $topic_id (sort $self->topics()) {
303 my $t = $self->topic($topic_id);
308 if ($nti =~ /-arch$/) {
309 # don't insert topic, just rename
313 $dst->insert_topic($t);
316 foreach my $id ($self->stories($topic_id)) {
318 # get story and its tags
319 my $s = $self->story($topic_id, $id);
320 my @tags = $s->tags();
323 $s->set('topic_id', $nti);
325 my $ns = $dst->insert_story($s);
337 sub flush_story_cache
{
340 $self->{story_cache
} = {};
347 my $g = bless( { @_ } , $class);
349 $g->{id
} ||= 'Gruta';
350 $g->{story_cache
} = {};
351 $g->{renderers_h
} = {};
353 if (ref($g->{sources
}) ne 'ARRAY') {
354 $g->{sources
} = [ $g->{sources
} ];
357 if ($g->{renderers
}) {
358 if (ref($g->{renderers
}) ne 'ARRAY') {
359 $g->{renderers
} = [ $g->{renderers
} ];
362 foreach my $r (@
{$g->{renderers
}}) {
363 $g->{renderers_h
}->{$r->{renderer_id
}} = $r;
367 if ($g->{template
}) {
368 $g->template->data($g);
377 if (not @u = $g->users()) {
378 my $u = Gruta
::Data
::User
->new(
383 email
=> 'webmaster@localhost'
386 $u->password('admin');