-
Notifications
You must be signed in to change notification settings - Fork 0
/
extractDigikamPres.pl
executable file
·123 lines (102 loc) · 2.82 KB
/
extractDigikamPres.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/perl
use Getopt::Long qw(GetOptions);
use XML::Simple;
use File::Fetch;
use File::Basename;
use Data::Dumper;
Getopt::Long::Configure qw(gnu_getopt);
############################ usage ############################
# usage(string)
sub usage {
my $msg = shift;
print $msg."\n" if $msg ne "";
print "Usage:\n";
print $my_name." [options] [src file name]\n";
print " -t, --target specify target dir\n";
print " -p generate pure code-names (i.e. dont use old filename)\n";
print " -v be verbose\n";
die;
}
############################ code gen ############################
# TODO: rewrite as class
$cg_len=-1;
$cg_inc=-1;
$cg_last=0;
$cg_pure=false;
# cg_init(int,int,bool)
sub cg_init {
my $count = shift;
$cg_inc = 1 + shift;
$cg_pure = shift;
my $max = ($cg_inc) * ($count+1);
$cg_len = log($max) / log(26); # log_26(max)=log(max)/log(26)
$cg_len = int($cg_len) + 1;
#print 'calculated code length of '.$cg_len." chars\n";
}
sub cg_code {
my $num = shift;
my @buf = ();
for( my $i=0; $i<$cg_len; $i++ ) {
use integer;
my $rest = $num;
if( $num > 25 ) {
$rest = $num % 26;
}
unshift @buf, chr( ord('a')+$rest );
$num = $num / 26;
}
return join( '', @buf );
}
# string cg_next(Fetch)
sub cg_next {
my $where = shift;
$cg_last += $cg_inc;
$fcode = cg_code($cg_last);
my ($fname,$fpath,$fext) = fileparse( $where, qr/\.[^.]+/ );
if($cg_pure) {
return $fpath.$fcode.$fext;
} else {
return $fpath.$fcode.'-'.$fname.$fext;
}
}
############################ main ############################
$my_name = $0;
# parse args
my $source_file = 'list.xml';
my $target_dir = '.';
my $verbose;
my $pure_name;
GetOptions(
'target|t=s' => \$target_dir,
'p' => \$pure_name,
'v' => \$verbose ) or die usage();
$source_file = shift @ARGV if scalar(@ARGV)>0;
die usage('too many arguments') if scalar(@ARGV)>0;
#print $source_file ."\n";
#print $target_dir ."\n";
$xml = new XML::Simple;
$pres = $xml->XMLin( $source_file );
@images = @{$pres->{Image}};
cg_init( scalar(@images), 3, $pure_name ); # count, gap
if($verbose) {
print 'digikam presentation contains '.scalar(@images)." pictures\n";
}
#print Dumper($pres);
foreach $i (@images) {
my $ff = File::Fetch->new( uri => $i->{url} );
my $where = $ff->fetch( to => $target_dir ) or print $ff->error;
if( $where ) {
my $newname = cg_next($where);
if($verbose) {
print $newname.' <- '.$where.' <- '.$i->{url}."\n";
}
rename $where, $newname;
}
}
############################ references ############################
# XML::Simple usage:
# https://www.techrepublic.com/article/parsing-xml-documents-with-perls-xmlsimple/
# Getopt::Long usage
# https://perlmaven.com/how-to-process-command-line-arguments-in-perl
# File::Fetch usage:
# http://perldoc.perl.org/File/Fetch.html