File Coverage

blib/lib/Brackup/Target/Gmail.pm
Criterion Covered Total %
statement 12 49 24.4
branch 0 14 0.0
condition 0 6 0.0
subroutine 4 9 44.4
pod 0 4 0.0
total 16 82 19.5


line stmt bran cond sub pod time code
1             package Brackup::Target::Gmail;
2              
3 1     1   1002 use strict;
  1         3  
  1         151  
4 1     1   1029 use Net::FS::Gmail;
  1         122269  
  1         39  
5 1     1   1337 use File::Temp qw/tempfile/;
  1         27826  
  1         69  
6 1     1   8 use base 'Brackup::Target';
  1         3  
  1         1075  
7              
8             our $VERSION = "0.1";
9             our $CACHE_TABLE = "gmail_key_exists";
10              
11             =head1 NAME
12              
13             Brackup::Target::Gmail - a GMail target to Brackup
14              
15             =head1 SYNOPSIS
16              
17             See Brackup for a details
18              
19             =head1 EXTREMELY SERIOUS WARNING AND GENERAL ASS COVERING
20              
21             This is completely alpha software. It hasn't even been tested properly.
22              
23             It will almost certainly destroy all your data then come round your house,
24             empty any the bags of flour all over the kitchen, kick in your TV,
25             scratch the screen of your iPod Nano, get jam fingerprints on your favourite
26             limited edition "Me First and the Gimmie Gimmies" CDs and then urinate in
27             your laundry basket.
28              
29             In fact, to paraphrase Neal Stephenson: Unless you are as smart as Johann Karl
30             Friedrich Gauss, savvy as a half-blind Calcutta bootblack, tough as General
31             William Tecumseh Sherman, rich as the Queen of England, emotionally resilient as
32             a Red Sox fan, and as generally able to take care of yourself as the average
33             nuclear submarine commander, you should never have been allowed near this module.
34             Please dispose of it as you would any piece of high-level radioactive waste and
35             then arrange with a qualified surgeon to amputate your arms at the elbows and gouge
36             your eyes from their sockets.
37              
38             If you ignore this warning, read on at your peril -- you are dead certain to lose
39             everything you've got and live out your final decades beating back waves of termites
40             in a Mississippi Delta leper colony.
41              
42             =head1 AUTHOR
43              
44             Simon Wistow
45              
46             =head1 COPYRIGHT
47              
48             Copyright 2006, Simon Wistow
49              
50             Distributed under the same terms as Perl itself.
51              
52             =cut
53              
54             # NOTE
55             # the cache stuff is ripped off Brackup::Target::Amazon
56             # and could probably be merged to give a generic hash implementation
57              
58              
59             sub new {
60 0     0 0   my ($class, $confsec) = @_;
61 0           my $self = bless {}, $class;
62 0           my $user = $confsec->value("gmail_username");
63 0           my $pass = $confsec->value("gmail_password");
64 0           $self->{_gmail} = Net::FS::Gmail->new( username => "$user", password => "$pass" );
65              
66 0 0         if (my $cache_file = $confsec->value("exist_cache")) {
67 0 0         $self->{dbh} = DBI->connect("dbi:SQLite:dbname=$cache_file","","", { RaiseError => 1, PrintError => 0 }) or
68             die "Failed to connect to SQLite filesystem digest cache database at $cache_file: " . DBI->errstr;
69              
70 0           eval {
71 0           $self->{dbh}->do("CREATE TABLE ${CACHE_TABLE} (key TEXT PRIMARY KEY, value TEXT)");
72             };
73 0 0 0       die "Error: $@" if $@ && $@ !~ /table ${CACHE_TABLE} already exists/;
74             }
75              
76              
77              
78 0           return $self;
79             }
80              
81              
82             # returns bool
83             sub has_chunk {
84 0     0 0   my ($self, $chunk) = @_;
85 0           my $dig = $chunk->backup_digest; # "sha1:sdfsdf" format scalar
86              
87 0 0         if (my $dbh = $self->{dbh}) {
88 0           my $ans = $dbh->selectrow_array("SELECT COUNT(*) FROM ${CACHE_TABLE} WHERE key=?", undef, $dig);
89 0           warn "gmail database for $dig is = $ans\n";
90 0 0         return 1 if $ans;
91             }
92              
93 0           my %files = eval { map { $_ => 1 } $self->{_gmail}->files() };
  0            
  0            
94 0   0       my $ret = !$@ && exists $files{$dig};
95 0 0         $self->_cache_existence_of($dig) if ($ret);
96 0           return $ret;
97              
98             }
99              
100              
101             sub _cache_existence_of {
102 0     0     my ($self, $dig) = @_;
103 0 0         if (my $dbh = $self->{dbh}) {
104 0           $dbh->do("INSERT INTO ${CACHE_TABLE} VALUES (?,1)", undef, $dig);
105             }
106             }
107              
108             # returns true on success, or returns false or dies otherwise.
109             sub store_chunk {
110 0     0 0   my ($self, $chunk) = @_;
111 0           my ($fh, $filename) = tempfile( UNLINK => 1 );
112 0           print $fh ${ $chunk->chunkref };
  0            
113 0           close($fh);
114 0           $self->{_gmail}->store($filename, $chunk->backup_digest);
115             }
116              
117             sub store_backup_meta {
118 0     0 0   my ($self, $name, $file) = @_;
119 0           my ($fh, $filename) = tempfile( UNLINK => 1 );
120 0           print $fh $file;
121 0           close($fh);
122 0           $self->{_gmail}->store($filename, $name);
123              
124             }
125              
126             1;