source: extensions/piwigo_import_tree/piwigo_import_tree.pl @ 15734

Last change on this file since 15734 was 15734, checked in by plg, 12 years ago

make sure we fetch all (1 million max = all) photos of the album

File size: 6.2 KB
Line 
1#!/usr/bin/perl
2
3# usage:
4# perl piwigo_import_tree.pl --directory=/Users/pierrick/piwigo/album1
5
6use strict;
7use warnings;
8
9use File::Find;
10use Data::Dumper;
11use File::Basename;
12use LWP::UserAgent;
13use JSON;
14use Getopt::Long;
15use Encode qw/is_utf8 decode/;
16
17my %opt = ();
18GetOptions(
19    \%opt,
20    qw/
21          base_url=s
22          username=s
23          password=s
24          directory=s
25          parent_album_id=s
26          define=s%
27          quiet
28      /
29);
30
31my $album_dir = $opt{directory};
32$album_dir =~ s{^\./*}{};
33
34our $ua = LWP::UserAgent->new;
35$ua->agent('Mozilla/piwigo_remote.pl 1.25');
36$ua->cookie_jar({});
37
38my %conf;
39my %conf_default = (
40    base_url => 'http://localhost/plg/piwigo/salon',
41    username => 'plg',
42    password => 'plg',
43);
44
45foreach my $conf_key (keys %conf_default) {
46    $conf{$conf_key} = defined $opt{$conf_key} ? $opt{$conf_key} : $conf_default{$conf_key}
47}
48
49$ua->default_headers->authorization_basic(
50    $conf{username},
51    $conf{password}
52);
53
54my $result = undef;
55my $query = undef;
56
57binmode STDOUT, ":encoding(utf-8)";
58
59# Login to Piwigo
60piwigo_login();
61
62# Fill an "album path to album id" cache
63my %piwigo_albums = ();
64
65my $response = $ua->post(
66    $conf{base_url}.'/ws.php?format=json',
67    {
68        method => 'pwg.categories.getList',
69        recursive => 1,
70        fullname => 1,
71    }
72);
73
74my $albums_aref = from_json($response->content)->{result}->{categories};
75foreach my $album_href (@{$albums_aref}) {
76    $piwigo_albums{ $album_href->{name} } = $album_href->{id};
77}
78# print Dumper(\%piwigo_albums)."\n\n";
79
80if (defined $opt{parent_album_id}) {
81    foreach my $album_path (keys %piwigo_albums) {
82        if ($piwigo_albums{$album_path} == $opt{parent_album_id}) {
83            $conf{parent_album_id} = $opt{parent_album_id};
84            $conf{parent_album_path} = $album_path;
85        }
86    }
87
88    if (not defined $conf{parent_album_path}) {
89        print "Parent album ".$opt{parent_album_id}." does not exist\n";
90        exit();
91    }
92}
93
94# Initialize a cache with file names of existing photos, for related albums
95my %photos_of_album = ();
96
97# Synchronize local folder with remote Piwigo gallery
98find({wanted => \&add_to_piwigo, no_chdir => 1}, $album_dir);
99
100#---------------------------------------------------------------------
101# Functions
102#---------------------------------------------------------------------
103
104sub piwigo_login {
105    $ua->post(
106        $conf{base_url}.'/ws.php?format=json',
107        {
108            method => 'pwg.session.login',
109            username => $conf{username},
110            password => $conf{password},
111        }
112    );
113}
114
115sub fill_photos_of_album {
116    my %params = @_;
117
118    if (defined $photos_of_album{ $params{album_id} }) {
119        return 1;
120    }
121
122    piwigo_login();
123    my $response = $ua->post(
124        $conf{base_url}.'/ws.php?format=json',
125        {
126            method => 'pwg.categories.getImages',
127            cat_id => $params{album_id},
128            per_page => 1000000,
129        }
130    );
131
132    foreach my $image_href (@{from_json($response->content)->{result}{images}{_content}}) {
133        $photos_of_album{ $params{album_id} }{ $image_href->{file} } = 1;
134    }
135}
136
137sub photo_exists {
138    my %params = @_;
139
140    fill_photos_of_album(album_id => $params{album_id});
141
142    if (defined $photos_of_album{ $params{album_id} }{ $params{file} }) {
143        return 1;
144    }
145    else {
146        return 0;
147    }
148}
149
150sub add_album {
151    my %params = @_;
152
153    my $form = {
154        method => 'pwg.categories.add',
155        name => $params{name},
156    };
157
158    if (defined $params{parent}) {
159        $form->{parent} = $params{parent};
160    }
161
162    piwigo_login();
163    my $response = $ua->post(
164        $conf{base_url}.'/ws.php?format=json',
165        $form
166    );
167
168    return from_json($response->content)->{result}{id};
169}
170
171sub add_photo {
172    my %params = @_;
173
174    my $form = {
175        method => 'pwg.images.addSimple',
176        image => [$params{path}],
177        category => $params{album_id},
178    };
179
180    # is there any title defined in a descript.ion file?
181    my $property = undef;
182    my $desc_filepath = dirname($params{path}).'/descript.ion';
183    if (-f $desc_filepath) {
184        my $photo_filename = basename($params{path});
185        open(IN, '<', $desc_filepath);
186        while (my $desc_line = <IN>) {
187            if ($desc_line =~ /^$photo_filename/) {
188                chomp($desc_line);
189                $property = (split /\t/, $desc_line, 2)[1];
190            }
191        }
192        close(IN);
193    }
194
195    if (defined $property and $property ne '') {
196        $form->{name} = $property;
197    }
198
199    piwigo_login();
200    my $response = $ua->post(
201        $conf{base_url}.'/ws.php?format=json',
202        $form,
203        'Content_Type' => 'form-data',
204    );
205}
206
207sub add_to_piwigo {
208    # print $File::Find::name."\n";
209    my $path = $File::Find::name;
210    my $parent_dir = dirname($album_dir);
211    if ($parent_dir ne '.') {
212        # print '$parent_dir = '.$parent_dir."\n";
213        $path =~ s{^$parent_dir/}{};
214    }
215    # print $path."\n";
216
217    if (-d) {
218        my $up_dir = '';
219        my $parent_id = undef;
220
221        if (defined $conf{parent_album_path}) {
222            $up_dir = $conf{parent_album_path}.' / ';
223            $parent_id = $conf{parent_album_id};
224        }
225
226        foreach my $dir (split '/', $path) {
227            if (not defined $piwigo_albums{$up_dir.$dir}) {
228                print 'album "'.$up_dir.$dir.'" must be created'."\n";
229                my $id = add_album(name => $dir, parent => $parent_id);
230                $piwigo_albums{$up_dir.$dir} = $id;
231            }
232            $parent_id = $piwigo_albums{$up_dir.$dir};
233            $up_dir.= $dir.' / ';
234        }
235    }
236
237    if (-f and $path =~ /\.(jpe?g|gif|png)$/i) {
238        my $album_key = join(' / ', split('/', dirname($path)));
239
240        if (defined $conf{parent_album_path}) {
241            $album_key = $conf{parent_album_path}.' / '.$album_key;
242        }
243
244        my $album_id = $piwigo_albums{$album_key};
245
246        if (photo_exists(album_id => $album_id, file => basename($File::Find::name))) {
247            if (not $opt{quiet}) {
248                print $File::Find::name.' already exists in Piwigo, skipped'."\n";
249            }
250            return 1;
251        }
252
253        print $File::Find::name.' must be uploaded in "'.$album_key.'" (id='.$album_id.')'."\n";
254        add_photo(path => $File::Find::name, album_id => $album_id);
255        # print 'dirname = '.dirname($path)."\n\n";
256    }
257}
Note: See TracBrowser for help on using the repository browser.