Files
unsplash/unsplash (SFConflict zino@zinomedia.de 2020-10-30-17-18-57).pl
2022-10-23 01:57:17 +02:00

216 lines
8.2 KiB
Perl
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!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";
}