3 #=======================================================================
5 # File ID: 18245170-f924-11dd-93fc-0001805bf4b1
6 # Extract EXIF data from pictures for use with COPY in Postgres
9 # ©opyleft 2008– Øyvind A. Holm <sunny@sunbase.org>
10 # License: GNU General Public License version 3 or later, see end of
11 # file for legal stuff.
12 #=======================================================================
18 push(@INC, "$ENV{'HOME'}/bin/src/gpstools");
31 'output-format' => 'pgtab',
41 'output-format' => $Std{'output-format'},
42 'strip-whitespace' => 0,
43 'timezone' => $Std{'timezone'},
50 $progname =~ s/^.*\/(.*?)$/$1/;
51 our $VERSION = "0.00";
53 Getopt
::Long
::Configure
("bundling");
56 "author|a=s" => \
$Opt{'author'},
57 "debug" => \
$Opt{'debug'},
58 "description|d=s" => \
$Opt{'description'},
59 "help|h" => \
$Opt{'help'},
60 "output-format|o=s" => \
$Opt{'output-format'},
61 "strip-whitespace|w" => \
$Opt{'strip-whitespace'},
62 "timezone|T=s" => \
$Opt{'timezone'},
63 "verbose|v+" => \
$Opt{'verbose'},
64 "version" => \
$Opt{'version'},
66 ) || die("$progname: Option error. Use -h for help.\n");
68 $Opt{'debug'} && ($Debug = 1);
69 $Opt{'help'} && usage
(0);
70 if ($Opt{'version'}) {
75 $GPST::Spc
= $Opt{'strip-whitespace'} ?
"" : " ";
76 my $Spc = $GPST::Spc
; # FIXME
78 if (length($Opt{'timezone'})) {
79 if ($Opt{'timezone'} =~ /^[\+\-][0-2][0-9]{3}$/) {
80 $tz_str = $Opt{'timezone'};
81 } elsif ($Opt{'timezone'} =~ /^z$/i) {
82 $tz_str = $Opt{'timezone'};
83 } elsif ($Opt{'timezone'} =~ /^[a-z]+$/i) {
84 $tz_str = " $Opt{'timezone'}";
86 die("$progname: $Opt{'timezone'}: Invalid time zone\n");
88 $tz_str = uc($tz_str);
91 if ($Opt{'output-format'} eq "xml") {
92 print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gpstpic>\n");
101 for my $fname (@ARGV) {
106 if ($Opt{'output-format'} eq "xml") {
107 print("</gpstpic>\n");
112 my $filename = shift;
118 D
("filename = '$filename'");
119 if (open(PicFP
, "exifprobe -L \"$filename\" |")) { # FIXME: Quick & Dirty™
124 $date =~ s/^(\d\d\d\d)(.)(\d\d)(.)(\d\d)(.)(\d\d:\d\d:\d\d)(.*)/$1-$3-${5}T$7$8/;
130 @Dates = reverse sort @Dates;
132 defined($date) || ($date = '');
133 D
("final date = '$date'");
134 if ($date =~ /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d$/) {
135 $filename =~ s/^.*\/(.*?)$/$1/;
137 if ($Opt{'output-format'} eq "xml") {
138 if (length("$filename$date")) {
142 ?
sprintf("$Spc$Spc$Spc$Spc<filename>%s</filename>\n",
143 txt_to_xml
($filename))
146 ?
sprintf("$Spc$Spc$Spc$Spc<date>%s</date>\n",
147 txt_to_xml
("$date$tz_str"))
149 length($Opt{'description'})
150 ?
sprintf("$Spc$Spc$Spc$Spc<desc>%s</desc>\n",
151 txt_to_xml
($Opt{'description'}))
153 length($Opt{'author'})
154 ?
sprintf("$Spc$Spc$Spc$Spc<author>%s</author>\n",
155 txt_to_xml
($Opt{'author'}))
160 } elsif ($Opt{'output-format'} eq "pgtab") {
161 # Version information {{{
162 # Without version field (same as version 1):
164 # "(lat,lon)"-coordinates \t
171 # "(lat,lon)"-coordinates \t
176 $Output = pgtab_entry
(
185 die("$progname: $Opt{'output-format'}: Unknown output format\n");
188 $Opt{'verbose'} && print(STDERR
$Output);
191 warn("$filename: $date: Invalid date format");
196 warn("$filename: Cannot open exifprobe(1) pipe: $!");
205 my ($Version, $Date, $Coor, $Descr, $Filename, $Author) = @_;
206 defined($Date) || ($Date = $NA);
207 defined($Coor) || ($Coor = $NA);
208 defined($Descr) || ($Descr = $NA);
209 defined($Filename) || ($Filename = $NA);
210 defined($Author) || ($Author = $NA);
215 postgresql_copy_safe
($Date) . $tz_str,
217 ? postgresql_copy_safe
($Coor)
219 length($Opt{'description'})
220 ? postgresql_copy_safe
($Opt{'description'})
223 ? postgresql_copy_safe
($Filename)
225 length($Opt{'author'})
226 ? postgresql_copy_safe
($Opt{'author'})
235 # Print program version {{{
236 print("$progname v$VERSION\n");
241 # Send the help message to stdout {{{
244 if ($Opt{'verbose'}) {
250 Usage: $progname [options] [file [files [...]]]
252 Extract EXIF info from pictures for use with PostgreSQL's COPY command.
253 If no filenames are specified on the command line, file names are read
259 Specify author of picture.
261 Specify description for picture.
265 Increase level of verbosity. Can be repeated.
266 -o x, --output-format x
267 Create output of type x:
270 Default: "$Std{'output-format'}".
272 Prepend X as timezone to the date. Valid formats:
274 A '+' or '-' followed by a four-digit number (HHMM) which
275 indicates the offset relative to UTC. Examples:
279 Time zone abbreviation. Examples:
283 -w, --strip-whitespace
284 Strip all unnecessary whitespace.
286 Print version information.
288 Print debugging messages.
296 # Print a status message to stderr based on verbosity level {{{
297 my ($verbose_level, $Txt) = @_;
299 if ($Opt{'verbose'} >= $verbose_level) {
300 print(STDERR
"$progname: $Txt\n");
306 # Print a debugging message {{{
308 my @call_info = caller;
309 chomp(my $Txt = shift);
310 my $File = $call_info[1];
312 $File =~ s
#^.*/(.*?)$#$1#;
313 print(STDERR
"$File:$call_info[2] $$ $Txt\n");
320 # Plain Old Documentation (POD) {{{
330 [options] [file [files [...]]]
340 =item B<-h>, B<--help>
342 Print a brief help summary.
344 =item B<-v>, B<--verbose>
346 Increase level of verbosity. Can be repeated.
350 Print version information.
354 Print debugging messages.
364 Made by Øyvind A. Holm S<E<lt>sunny@sunbase.orgE<gt>>.
368 Copyleft © Øyvind A. Holm E<lt>sunny@sunbase.orgE<gt>
369 This is free software; see the file F<COPYING> for legalese stuff.
373 This program is free software: you can redistribute it and/or modify it
374 under the terms of the GNU General Public License as published by the
375 Free Software Foundation, either version 3 of the License, or (at your
376 option) any later version.
378 This program is distributed in the hope that it will be useful, but
379 WITHOUT ANY WARRANTY; without even the implied warranty of
380 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
381 See the GNU General Public License for more details.
383 You should have received a copy of the GNU General Public License along
385 If not, see L<http://www.gnu.org/licenses/>.
393 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :