Even more work in the 'gruta' script.
[gruta.git] / Gruta / Data.pm
blobb136fe5ee070f1ff8df959ea9eb93ab1642c25a3
1 package Gruta::Data;
3 use strict;
4 use warnings;
6 package Gruta::Data::BASE;
8 use Carp;
10 sub fields { return (); }
11 sub vfields { return (); }
12 sub afields { return ($_[0]->fields(), $_[0]->vfields()); }
14 sub source {
15 my $self = shift;
17 if (@_) {
18 $self->{_source} = shift;
21 return $self->{_source};
25 sub _assert {
26 my $self = shift;
28 my $id = $self->get('id') || '';
29 $id =~ /^[\d\w_-]+$/ or croak "Bad id [$id]";
31 return $self;
34 sub new {
35 my $class = shift;
36 my %args = @_;
38 my $self = bless({ }, $class);
40 foreach my $k ($self->afields()) {
41 $self->{$k} = $args{$k};
44 return $self;
47 sub get {
48 my $self = shift;
49 my $field = shift;
51 croak 'get ' . ref($self) . " field '$field'?" unless exists $self->{$field};
53 return $self->{$field};
56 sub set {
57 my $self = shift;
58 my $field = shift;
60 croak 'set ' . ref($self) . " field '$field'?" unless exists $self->{$field};
62 $self->{$field} = shift;
64 return $self->{$field};
68 package Gruta::Data::Topic;
70 use base 'Gruta::Data::BASE';
72 sub fields { return qw(id name editors max_stories internal); }
74 sub is_editor {
75 my $self = shift;
76 my $user = shift; # Gruta::Data::User
78 return $user && ($user->get('is_admin') ||
79 $self->get('editors') =~ m{\b$user->get('id')\b}) ? 1 : 0;
82 package Gruta::Data::Story;
84 use base 'Gruta::Data::BASE';
86 use Carp;
88 sub fields { return qw(id topic_id title date date2 userid format hits ctime content); }
89 sub vfields { return qw(abstract body); }
91 sub _assert {
92 my $self = shift;
94 $self->SUPER::_assert();
96 my $topic_id = $self->get('topic_id') || '';
97 $topic_id =~ /^[\d\w_-]+$/ or croak "Bad topic_id";
99 return $self;
102 sub date { return Gruta::Data::format_date($_[0]->get('date'), $_[1]); }
103 sub date2 { return Gruta::Data::format_date($_[0]->get('date2'), $_[1]); }
105 sub touch { return $_[0]; }
107 sub tags {
108 my $self = shift;
109 my @ret = undef;
111 if (scalar(@_)) {
112 $self->set('tags', [ @_ ]);
114 else {
115 @ret = @{ $self->get('tags') };
118 return @ret;
121 sub new_id {
122 my $self = shift;
124 return sprintf ('%08x', int(rand(0xffffffff)));
127 sub is_visible {
128 my $self = shift;
129 my $user = shift; # Gruta::Data::User
131 return !$user && $self->get('date') > Gruta::Data::today() ? 0 : 1;
135 package Gruta::Data::User;
137 use base 'Gruta::Data::BASE';
139 sub fields { return qw(id username email password can_upload is_admin xdate); }
140 sub vfields { return qw(sid); }
142 sub xdate { return Gruta::Data::format_date($_[0]->get('xdate'), $_[1]); }
144 sub password {
145 my $self = shift;
146 my $passwd = shift;
148 my $salt = sprintf('%02d', rand(100));
149 my $pw = crypt($passwd, $salt);
151 $self->set('password', $pw);
153 return $self;
157 package Gruta::Data::Session;
159 use base 'Gruta::Data::BASE';
161 sub fields { return qw(id time user_id ip); }
163 package Gruta::Data;
165 sub format_date {
166 my $date = shift;
167 my $format = shift;
169 if ($format) {
170 my ($y, $m, $d, $H, $M, $S) = ($date =~
171 /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/);
173 $format =~ s/%Y/$y/g;
174 $format =~ s/%y/$y/g;
175 $format =~ s/%m/$m/g;
176 $format =~ s/%d/$d/g;
177 $format =~ s/%H/$H/g;
178 $format =~ s/%M/$M/g;
179 $format =~ s/%S/$S/g;
181 else {
182 $format = $date;
185 return $format;
189 sub today {
190 my $format = shift;
192 my ($S,$M,$H,$d,$m,$y) = (localtime)[0..5];
194 my $date = sprintf('%04d%02d%02d%02d%02d%02d',
195 1900 + $y, $m + 1, $d, $H, $M, $S);
197 return Gruta::Data::format_date($date, $format);