source: server/trunk/web/lib/Sophie/Base/Header.pm @ 24

Last change on this file since 24 was 18, checked in by nanardon, 14 years ago
  • improve database error management
  • add options to command line
File size: 2.9 KB
Line 
1package Sophie::Base::Header;
2
3use strict;
4use warnings;
5use base qw(Sophie::Base);
6use File::Temp;
7use File::Copy;
8use Archive::Cpio;
9use Encode::Guess;
10use Encode;
11
12sub new {
13    my ($class, $pkgid) = @_;
14
15    bless(\$pkgid, $class);
16}
17
18sub rpm_path {
19    my ($self) = @_;
20
21    my $listrpm = $self->db->prepare_cached(
22        q{
23        select * from rpmfile join rpmspath
24        on rpmfile.path = rpmspath.path
25        where pkgid = ?
26        }
27    );
28    $listrpm->execute($$self);
29
30    return $listrpm->fetchall_hashref({});
31}
32
33sub addfiles_content {
34    my ($self, $rpm) = @_;
35
36    my $tmp = File::Temp->new( UNLINK => 1, SUFFIX => '.cpio' );
37    unlink($tmp->filename);
38    my $ok = 0;
39    foreach ($rpm ? ($rpm) : (@{ $self->rpm_path })) {
40        if (open(my $cpioh, "rpm2cpio " . quotemeta($_->{path} . '/' .
41                    $_->{filename}) . " |")) {
42        File::Copy::copy($cpioh, $tmp);
43        close($cpioh);
44        $ok = 1;
45        last;
46        }
47    }
48    $ok or return;
49
50    my $list_file = $self->db->prepare_cached(q{
51        select (rpmqueryfiles(header)).* from rpms where pkgid = ?
52    });
53    $list_file->execute($$self);
54
55    my $files = $list_file->fetchall_hashref([ 'dirname', 'basename' ]);
56
57    my $add_content = $self->db->prepare_cached(
58        q{
59        UPDATE allfiles set contents = ? where pkgid = ? and count = ?
60        }
61    );
62    seek($tmp, 0, 0);
63    my $cpio = Archive::Cpio->new();
64    eval {
65        $cpio->read_with_handler(
66            $tmp,
67            sub {
68                my ($file) = @_;
69                my ($dirname, $basename) = $file->name =~ /^(?:\.(.*\/))?([^\/]+)$/;
70                $dirname ||= '';
71                my $entry = $files->{$dirname}{$basename};
72                for (1) {
73                    $entry->{size} > 1024 * 1024 and return 1;
74                    # Spec files and patch
75                    $entry->{flags} == 32 and last;
76                    $dirname eq '' and last;
77                    # Doc files
78                    $entry->{flags} & (1 << 1) || $entry->{flags} & (1 << 8)
79                        and last;
80                    # Config file
81                    $entry->{flags}  & (1 << 0) and last;
82                    $basename =~ /\.h$/ and last;
83
84                    return 1;
85                }
86                my $content = $file->get_content;
87                my $enc = guess_encoding($content, qw/latin1/);
88                if ($enc && ref $enc) {
89                    $content = $enc->decode($content);
90
91                    $self->db->pg_savepoint('FILECONTENT');
92                    $add_content->execute(
93                        $enc && ref $enc ? encode('utf8', $enc->decode($content)) : $content,
94                        $$self,
95                        $entry->{count}) or do {
96                        $self->db->pg_rollback_to('FILECONTENT');
97                    };
98                } else {
99                }
100                1;
101            }
102        );
103    };
104
105    $tmp = undef;
106    return 1;
107}
108
1091;
Note: See TracBrowser for help on using the repository browser.