216 lines
8.2 KiB
Perl
Executable File
216 lines
8.2 KiB
Perl
Executable File
#!usr/bin/perl
|
||
use strict;
|
||
use warnings;
|
||
use Data::Dumper;
|
||
use JSON::XS qw(encode_json decode_json);
|
||
use LWP::Simple;
|
||
use File::Slurp qw(read_file write_file);
|
||
use Getopt::Long;
|
||
|
||
my (%db, %ParamHash);
|
||
my $dbKeysStart = 0;
|
||
my %config = (
|
||
'api_root_location' => 'https://api.unsplash.com/',
|
||
'api_search_root_location' => 'https://api.unsplash.com/search/photos',
|
||
# 'api_ratelimit_location' => 'https://api.unsplash.com/photos/curated?client_id=45ea109161a2cc78ea845bdca006473edd5a323b2c3802e31b423a672e312ed1&per_page=1',
|
||
'api_ratelimit_location' => 'https://api.unsplash.com/photos/?client_id=45ea109161a2cc78ea845bdca006473edd5a323b2c3802e31b423a672e312ed1&per_page=2',
|
||
'image_dir' => './images/',
|
||
'db_file' => './db/db.dat',
|
||
'image_download_size' => 'regular', # raw, full, regular, small, thumb
|
||
'credentials' => {
|
||
'access_key' => '45ea109161a2cc78ea845bdca006473edd5a323b2c3802e31b423a672e312ed1',
|
||
'secret_key' => '1f50382ddcbdb0d47b77faaff870cb0d2894b63589e3aeafbfd2a772d9f4684f',
|
||
},
|
||
'default_parameters' => {
|
||
'search' => {
|
||
'per_page' => 10, # Number of items per page. (Optional; default: 10)
|
||
'page' => 1, # Page number to retrieve. (Optional; default: 1)
|
||
# 'query' => ['luxury property', 'luxury real estate', 'villa', 'mansion', 'pool house', 'loft', 'dream house', 'resort luxury'], # Search terms.
|
||
'query' => [], # Search terms.
|
||
'collections' => '', # Collection ID(‘s) to narrow search. Optional. If multiple, comma-separated.
|
||
'orientation' => '', # Filter by photo orientation. Optional. (Valid values: landscape, portrait, squarish)
|
||
'order_by' => 'relevant', # How to sort the photos. (Optional; default: relevant). Valid values are latest and relevant.
|
||
'content_filter' => 'low', # Limit results by content safety. (Optional; default: low). Valid values are low and high.
|
||
'color' => '', # Filter results by color. Optional. Valid values are: black_and_white, black, white, yellow, orange, red, purple, magenta, green, teal, and blue.
|
||
},
|
||
},
|
||
);
|
||
|
||
# &CheckARGV();
|
||
&GetCommandFlags();
|
||
&UndumpFromFile();
|
||
&CheckRateLimit();
|
||
# &Search({ 'per_page' => 2 });
|
||
&Search(\%ParamHash);
|
||
&Summary();
|
||
|
||
|
||
sub GetCommandFlags {
|
||
GetOptions(
|
||
'per_page=i' => \$config{'default_parameters'}{'search'}{'per_page'},
|
||
'page=i' => \$config{'default_parameters'}{'search'}{'page'},
|
||
'query=s' => \@{$config{'default_parameters'}{'search'}{'query'}},
|
||
'collections=i' => \$config{'default_parameters'}{'search'}{'collections'},
|
||
'orientation=s' => \$config{'default_parameters'}{'search'}{'orientation'},
|
||
'order_by=s' => \$config{'default_parameters'}{'search'}{'order_by'},
|
||
'content_filter=s' => \$config{'default_parameters'}{'search'}{'content_filter'},
|
||
'color=s' => \$config{'default_parameters'}{'search'}{'color'},
|
||
'image_download_size=s' => \$config{'image_download_size'},
|
||
) or die;
|
||
|
||
|
||
if( !@{$config{'default_parameters'}{'search'}{'query'}} ) {
|
||
die "--query has no arguments.";
|
||
}
|
||
|
||
}
|
||
|
||
sub CheckARGV {
|
||
&Delimiter((caller(0))[3]);
|
||
|
||
if (@ARGV) {
|
||
print Dumper @ARGV;
|
||
|
||
for my $i (0 .. $#ARGV) {
|
||
my @words = split /=/, $ARGV[$i];
|
||
$ParamHash{$words[0]} = $words[1];
|
||
}
|
||
}
|
||
}
|
||
|
||
sub Summary {
|
||
&Delimiter((caller(0))[3]);
|
||
|
||
print "$config{'db_file'} has " . scalar(keys(%db)) . " keys (before $dbKeysStart).\n";
|
||
}
|
||
|
||
sub AddToDB {
|
||
# &Delimiter((caller(0))[3]);
|
||
my ($decoded_json, $i) = @_;
|
||
|
||
$db{@{$$decoded_json{'results'}[$i]}{'id'}} = $$decoded_json{'results'}[$i];
|
||
my $json = encode_json \%db;
|
||
write_file($config{'db_file'}, { binmode => ':raw' }, $json);
|
||
# print "@{$$decoded_json{'results'}[$i]}{'id'} added to DB file.\n";
|
||
}
|
||
|
||
sub UndumpFromFile {
|
||
&Delimiter((caller(0))[3]);
|
||
|
||
if (-e $config{'db_file'}) {
|
||
my $json = read_file($config{'db_file'}, { binmode => ':raw' });
|
||
if (!$json) {
|
||
warn "DB file $config{'db_file'} is empty.\n";
|
||
return;
|
||
}
|
||
%db = %{ decode_json $json };
|
||
$dbKeysStart = scalar(keys(%db));
|
||
print "INFO: $config{'db_file'} has " . $dbKeysStart . " keys.\n";
|
||
}
|
||
elsif (!-e $config{'db_file'}) {
|
||
warn "INFO: NO DB file found at $config{'db_file'}. Creating now... ";
|
||
write_file($config{'db_file'}, '');
|
||
print "done.\n";
|
||
|
||
}
|
||
}
|
||
|
||
sub CheckRateLimit {
|
||
&Delimiter((caller(0))[3]);
|
||
|
||
my $res = head($config{'api_ratelimit_location'});
|
||
print Dumper $res;
|
||
print "RATELIMIT: $$res{'_headers'}{'x-ratelimit-remaining'} / $$res{'_headers'}{'x-ratelimit-limit'}\n";
|
||
if ($$res{'_headers'}{'x-ratelimit-limit'} - $$res{'_headers'}{'x-ratelimit-remaining'} == 0) {
|
||
die "Ratelimit reached.";
|
||
}
|
||
}
|
||
|
||
|
||
sub Search {
|
||
&Delimiter((caller(0))[3]);
|
||
my $parameterRef = &CheckHashParameters($_[0]);
|
||
print Dumper $parameterRef;
|
||
|
||
my $url = &AppendParameter($config{'api_search_root_location'} . "?client_id=$config{'credentials'}{'access_key'}", $parameterRef);
|
||
my $json = get( $url );
|
||
die "Could not get $url" unless defined $json;
|
||
my $decoded_json = decode_json( $json );
|
||
&DownloadImages($decoded_json, $parameterRef);
|
||
}
|
||
|
||
sub DownloadImages {
|
||
&Delimiter((caller(0))[3]);
|
||
my ($decoded_json, $parameterRef) = @_;
|
||
|
||
my $query = $$parameterRef{'query'};
|
||
my $download_dir = $config{'image_dir'} . $query;
|
||
if( !-e $download_dir ) {
|
||
print "Download directory $download_dir does not exist. Creating now...\n";
|
||
mkdir $download_dir or die "Error creating directory: $!";
|
||
}
|
||
else {
|
||
print "Download directory $download_dir already exists. Nothing to create.\n";
|
||
}
|
||
|
||
for (my $i = 0; $i < scalar @{ $$decoded_json{'results'} }; $i++) {
|
||
if (!exists $db{@{$$decoded_json{'results'}[$i]}{'id'}}) {
|
||
print "Downloading @{$$decoded_json{'results'}[$i]}{'id'}... ";
|
||
my $response_code = getstore(@{$$decoded_json{'results'}[$i]}{'urls'}->{$config{'image_download_size'}}, ("$download_dir/" . "@{$$decoded_json{'results'}[$i]}{'id'}.jpg"));
|
||
if ($response_code == 200) {
|
||
print "successful.\n";
|
||
&AddToDB($decoded_json, $i);
|
||
}
|
||
else {
|
||
die "$response_code received.";
|
||
}
|
||
}
|
||
elsif (exists $db{@{$$decoded_json{'results'}[$i]}{'id'}}) {
|
||
print "ID @{$$decoded_json{'results'}[$i]}{'id'} already in DB -> Skipping download.\n";
|
||
}
|
||
}
|
||
}
|
||
|
||
sub AppendParameter {
|
||
&Delimiter((caller(0))[3]);
|
||
my ($url, $parameterRef) = @_;
|
||
|
||
for my $key (keys %$parameterRef) {
|
||
if ($$parameterRef{$key} ne '') {
|
||
$url .= "&$key=$$parameterRef{$key}";
|
||
}
|
||
}
|
||
print "URL: $url\n";
|
||
return $url
|
||
}
|
||
|
||
sub CheckHashParameters {
|
||
&Delimiter((caller(0))[3]);
|
||
my $parameterRef = shift;
|
||
|
||
if (!defined $parameterRef->{'query'}) {
|
||
print 'Chosing random query element...';
|
||
my $random_element = $config{'default_parameters'}{'search'}{'query'}[rand @{$config{'default_parameters'}{'search'}{'query'}}];
|
||
print " '$random_element'\n";
|
||
$parameterRef->{'query'} = $random_element;
|
||
}
|
||
for my $key (keys %$parameterRef) {
|
||
if (!defined $config{'default_parameters'}{'search'}{$key}) {
|
||
print "Parameter '$key' is not valid. Allowed parameter are: ";
|
||
print "'$_' " for keys(%{$config{'default_parameters'}{'search'}});
|
||
print "\n";
|
||
die;
|
||
}
|
||
}
|
||
for my $key (keys(%{$config{'default_parameters'}{'search'}})) {
|
||
if (!defined $parameterRef->{$key}) {
|
||
$parameterRef->{$key} = $config{'default_parameters'}{'search'}{$key};
|
||
}
|
||
}
|
||
return $parameterRef;
|
||
}
|
||
|
||
sub Delimiter {
|
||
my $SubName = shift;
|
||
print "\n" . "-" x 80 . "\nSUB " . $SubName . "\n" . '-' x 80 . "\n";
|
||
} |