source: extensions/piwigo_import_tree/piwigo_import_tree.pl @ 16353

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

add encoding instruction to make the script send the correct directory/file names with accents on Windows

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