source: server/trunk/web/lib/Sophie/Scan/RpmsPath.pm @ 335

Last change on this file since 335 was 335, checked in by nanardon, 13 years ago
  • don't use Sophie::Base::Header anymore
File size: 5.8 KB
Line 
1package Sophie::Scan::RpmsPath;
2
3use strict;
4use warnings;
5use RPM4;
6use File::Temp;
7use File::Copy;
8use Archive::Cpio;
9use Encode::Guess;
10use Encode;
11use Time::HiRes;
12use DBD::Pg qw(:pg_types);
13
14sub new {
15    my ($class, $pathkey, $db) = @_;
16
17    bless({ key => $pathkey, db => $db }, $class);
18}
19
20sub key { $_[0]->{key} } 
21sub db { 
22    $_[0]->{db}
23} 
24
25sub path {
26    my ($self) = @_;
27   
28    $self->db->base->resultset('Paths')->find(
29        { d_path_key => $self->key }
30    )->path;
31}
32
33sub ls_rpms {
34    my ($self) = @_;
35
36    my %list;
37    foreach ($self->db->base->resultset('RpmFile')->search(
38        { d_path => $self->key }
39    )->get_column('filename')->all) {
40        $list{$_} = 1;
41    }
42    return \%list;
43}
44
45sub local_ls_rpms {
46    my ($self) = @_;
47
48    if (opendir(my $dh, $self->path)) {
49        my %list;
50        while (my $entry = readdir($dh)) {
51            $entry eq '.' and next;
52            $entry eq '..' and next;
53            $list{$entry} = 1;
54        }
55        closedir($dh);
56        return \%list;
57    } else {
58        return;
59    }
60}
61
62sub find_delta {
63    my ($self) = @_;
64
65    warn "$$ " . $self->path;
66
67    my @delta;
68    my $localrpms = $self->local_ls_rpms;
69    my $baserpms  = $self->ls_rpms;
70
71    if ($localrpms) {
72        push(@delta, { delta => 'DE' });
73    } else {
74        push(@delta, { delta => 'DM' });
75    }
76
77
78    my %list;
79    foreach (keys %{ $localrpms || {} }, keys %{ $baserpms }) {
80        $list{$_} = 1;
81    }
82
83    foreach my $rpm (sort { $b cmp $a } keys %list) {
84        if ($localrpms->{$rpm} && $baserpms->{$rpm}) {
85            # nothing to do
86        } elsif ($localrpms->{$rpm}) {
87            push(@delta, { rpm => $rpm, delta => 'A' });
88        } elsif ($baserpms->{$rpm}) {
89            push(@delta, { rpm => $rpm, delta => 'R' });
90        }
91    }
92    @delta;
93}
94
95sub update_content {
96    my ($self, @delta) = @_;
97    foreach (@delta) {
98        if (!$_->{delta}) {
99        }
100        elsif ($_->{delta} eq 'A') {
101            $self->add_rpm($_->{rpm});
102            #sleep(1);
103            #Time::HiRes::usleep(750);
104        }
105        elsif ($_->{delta} eq 'R') {
106            $self->remove_rpm($_->{rpm});
107        } elsif ($_->{delta} eq 'DM') {
108            $self->set_exists(0);
109        } elsif ($_->{delta} eq 'DE') {
110            $self->set_exists(1);
111        }
112    }
113}
114
115sub set_exists {
116    my ($self, $exists) = @_;
117    $self->db->base->resultset('Paths')->find(
118        { d_path_key => $self->key }
119    )->update({ 'exists' => ($exists ? 1 : 0) });
120    $self->db->commit;
121}
122
123sub set_updated {
124    my ($self) = @_;
125    warn "$$ UPD";
126    $self->db->base->resultset('Paths')->find(
127        { d_path_key => $self->key }
128    )->update({ 'updated' => \'now()' });
129    $self->db->commit;
130}
131
132sub remove_rpm {
133    my ($self, $rpm) = @_;
134    warn "$$ deleting $rpm";
135    $self->db->base->storage->txn_do(
136        sub {
137
138            $self->db->base->resultset('RpmFile')->search(
139                { d_path => $self->key, filename => $rpm }
140            )->delete;
141        }
142    );
143}
144
145sub add_rpm {
146    my ($self, $rpm) = @_;
147
148    warn "$$ adding $rpm";
149    eval {
150    my ($pkgid, $new) = $self->db->base->storage->txn_do(
151        sub {
152            my ($pkgid, $new) = $self->_add_header($rpm);
153            if (defined($pkgid)) {
154                $pkgid or return;
155                $self->db->base->resultset('RpmFile')->create(
156                    {
157                        d_path => $self->key,
158                        filename => $rpm,
159                        pkgid => $pkgid,
160                    }
161                ); 
162                return $pkgid, $new;
163            }
164        },
165    );
166    foreach my $plugins (qw'sources') {
167        my $mod = ucfirst(lc($plugins));
168        eval "require Sophie::Scan::RpmParser::$mod;";
169        warn $@ if($@);
170        eval {
171            my $parser = "Sophie::Scan::RpmParser::$mod"->new($self->db);
172            $parser->run($self->path . '/' . $rpm, $pkgid, $new);
173        }
174    }
175    }
176}
177
178sub _add_header {
179    my ($self, $rpm) = @_;
180
181    my $header;
182    eval {
183        $header = RPM4::Header->new($self->path . '/' . $rpm, $self->{db}) 
184    };
185    $header or do {
186        warn "$$ Cannot read " . $self->path . '/' . $rpm;
187        return "";
188    };
189
190    {
191        my $find = $self->db->base->resultset('Rpms')->search(
192            { pkgid => $header->queryformat('%{PKGID}') }
193        )->get_column('pkgid')->all;
194        if ($find) {
195            warn "$$ Find";
196            return($header->queryformat('%{PKGID}'), 0);
197        }
198    }
199    my $tmp = File::Temp->new( UNLINK => 1, SUFFIX => '.hdr' );
200    unlink($tmp->filename);
201    $header->write($tmp, 0);
202    seek($tmp, 0, 0);
203    my $string = '';
204    while (read($tmp, my $str, 1024)) { $string .= $str }
205    $tmp = undef;
206    my $description = $header->queryformat('%{DESCRIPTION}');
207    {
208        my $enc = guess_encoding($description, qw/latin1/);
209        $description = $enc->decode($description) if ($enc && ref $enc);
210    }
211    my $summary = $header->queryformat('%{SUMMARY}');
212    {
213        my $enc = guess_encoding($summary, qw/latin1/);
214        $summary = $enc->decode($summary) if ($enc && ref $enc);
215    }
216
217    $self->db->base->resultset('Rpms')->create({
218        pkgid  => $header->queryformat('%{PKGID}'),
219        name   => $header->queryformat('%{name}'),
220        header => \sprintf(qq{rpmheader_in(decode('%s', 'hex')::bytea)}, unpack('H*', $string)),
221        evr    => $header->queryformat('%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}'),
222        arch   => $header->queryformat('%{ARCH}'),
223        issrc  => $header->hastag('SOURCERPM') ? 'f' : 't',
224        description => $description,
225        summary => $summary,
226    });
227    my $index_tag = $self->db->base->storage->dbh->prepare_cached(
228        q{
229        select index_rpms(?);
230        }
231    );
232    $index_tag->execute($header->queryformat('%{PKGID}')) or return;
233    $index_tag->finish;
234
235    return($header->queryformat('%{PKGID}'), 1);
236}
237
2381;
Note: See TracBrowser for help on using the repository browser.