First Python based prototype ported from the Ruby version. Not completed yet. README update.
This commit is contained in:
parent
a5e08eaea0
commit
5e4124e651
5 changed files with 196 additions and 15 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,5 +1,4 @@
|
||||||
.idea
|
.idea
|
||||||
cache/*
|
|
||||||
photo/*
|
photo/*
|
||||||
photos/*
|
photos/*
|
||||||
tmp/*.dump.json
|
tmp/*.dump.json
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -8,12 +8,14 @@ More to come...
|
||||||
|
|
||||||
## To do:
|
## To do:
|
||||||
|
|
||||||
- Save as most cached data as JSON files as possible. Object dumps are related to Ruby only at the moment.
|
- Error handling. Not done in any way so far... :|
|
||||||
So limit the use of Marshal to a minimum!
|
- ~~Save as most cached data as JSON files as possible. Object dumps are related to Ruby only at the moment.
|
||||||
- Rewrite fgg in Python. **Ruby is a weird language o_O!**
|
So limit the use of Marshal to a minimum!~~ Nor marshal nor pickle is used anymore. All cache is JSON.
|
||||||
|
- ~~Rewrite fgg in Python. **Ruby is a weird language o_O!**~~ Python is the now the language of choice.
|
||||||
- Use a template engine for HTML output generation, but not before the rewrite in Python.
|
- Use a template engine for HTML output generation, but not before the rewrite in Python.
|
||||||
- Add more photo sources, not only Flickr.
|
|
||||||
- Add more targets, not only Jekyll. Nikola preferred!
|
- Add more targets, not only Jekyll. Nikola preferred!
|
||||||
- Define what is definitely need in metadata to generate a gallery even when offline.
|
- Maybe add more photo sources, not only Flickr.
|
||||||
|
- ~~Define what is definitely needed in metadata to generate a gallery even when offline.~~ Should be done but maybe
|
||||||
|
needs more enhancements.
|
||||||
- Add API call to delete a photo in the source after downloading and creating metadata file.
|
- Add API call to delete a photo in the source after downloading and creating metadata file.
|
||||||
- Tons of stuff...
|
- Tons of stuff... :)
|
||||||
|
|
|
||||||
195
fgg
195
fgg
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
# fgg - A free gallery generator for static site generators like Hugo, Jekyll,
|
# fgg - A free gallery generator for static site generators like Hugo, Jekyll,
|
||||||
# Nikola etc. using Flickr as data source.
|
# Nikola etc. using Flickr as data source.
|
||||||
#
|
|
||||||
# This is a port from a prototype (fgg.rb) written in Ruby I have running since
|
|
||||||
# some years.
|
|
||||||
|
|
||||||
# Copyright (c) 2022 Johannes Findeisen
|
# Copyright (c) 2022 Johannes Findeisen
|
||||||
#
|
#
|
||||||
|
|
@ -32,15 +29,197 @@
|
||||||
# https://github.com/alexis-mignon/python-flickr-api/wiki/API-reference
|
# https://github.com/alexis-mignon/python-flickr-api/wiki/API-reference
|
||||||
# This will become the next generation of fgg!
|
# This will become the next generation of fgg!
|
||||||
|
|
||||||
import flickr_api
|
import crc32c
|
||||||
|
import flickr_api as flickr
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import pathlib
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
print("Next-gen fgg written in Python... ;)")
|
__version__ = "0.0.2"
|
||||||
|
|
||||||
flickr_api_key = os.environ['FLICKR_API_KEY']
|
flickr_api_key = os.environ['FLICKR_API_KEY']
|
||||||
flickr_api_secret = os.environ['FLICKR_API_SECRET']
|
flickr_api_secret = os.environ['FLICKR_API_SECRET']
|
||||||
|
flickr.set_keys(api_key=flickr_api_key,
|
||||||
|
api_secret=flickr_api_secret)
|
||||||
|
|
||||||
print(flickr_api_key)
|
auth_handler = flickr.auth.AuthHandler(
|
||||||
print(flickr_api_secret)
|
access_token_key=os.environ['FLICKR_ACCESS_TOKEN'],
|
||||||
|
access_token_secret=os.environ['FLICKR_ACCESS_SECRET'])
|
||||||
|
|
||||||
flickr_api.set_keys(api_key=flickr_api_key, api_secret=flickr_api_secret)
|
flickr.set_auth_handler(auth_handler)
|
||||||
|
user = flickr.test.login()
|
||||||
|
|
||||||
|
|
||||||
|
def get_photo_count(f, pp, p):
|
||||||
|
return len(f.Photo.getWithoutGeoData(sort='date-taken-desc',
|
||||||
|
per_page=pp,
|
||||||
|
page=p))
|
||||||
|
|
||||||
|
|
||||||
|
debug_max_photos = 10
|
||||||
|
timezone = 'UTC+01:00'
|
||||||
|
|
||||||
|
print('Creating gallery...')
|
||||||
|
print('Counting pages...')
|
||||||
|
|
||||||
|
page_count = 0
|
||||||
|
photo_count = 0
|
||||||
|
photo_page = 1
|
||||||
|
photos_per_page = 500
|
||||||
|
while get_photo_count(flickr, photos_per_page, photo_page):
|
||||||
|
count = get_photo_count(flickr, photos_per_page, photo_page)
|
||||||
|
photo_count = photo_count + count
|
||||||
|
print('.', flush=True, end='')
|
||||||
|
photo_page += 1
|
||||||
|
page_count += 1
|
||||||
|
|
||||||
|
print()
|
||||||
|
print('Page count: ' + str(page_count))
|
||||||
|
print('Photo count: ' + str(photo_count))
|
||||||
|
|
||||||
|
i = photo_count
|
||||||
|
overall_tags = []
|
||||||
|
photo_page = 1
|
||||||
|
while photo_page <= page_count:
|
||||||
|
print("Page: " + str(photo_page))
|
||||||
|
|
||||||
|
flickr_photo_list = user.getPhotos(sort='date-taken-desc',
|
||||||
|
per_page=photos_per_page,
|
||||||
|
page=photo_page)
|
||||||
|
|
||||||
|
for flickr_photo in flickr_photo_list:
|
||||||
|
print(str(i) + "/" + str(photo_count))
|
||||||
|
photo = {}
|
||||||
|
if os.path.exists('db/' + flickr_photo.id + '/meta.json'):
|
||||||
|
with open('db/' + flickr_photo.id + '/meta.json', 'rb') as photo_json_file:
|
||||||
|
##print('Loading from cache: cache/flickr/' + flickr_photo.id + '/meta.json')
|
||||||
|
photo = json.load(photo_json_file)
|
||||||
|
else:
|
||||||
|
flickr_photo_info = flickr.Photo.getInfo(flickr_photo)
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
# START ################################################################################
|
||||||
|
# NEVER CHANGE THE FOLLOWING LINES (UNTIL "# END") EXPECT YOU REALLY NEED OR WANT TO
|
||||||
|
# CHANGE THE PHOTO ID!!! ALL LINKS TO THE PHOTO PAGE WILL BECOME BROKEN!!! - hanez
|
||||||
|
digest1 = hashlib.sha256(str.encode(str(flickr_photo.id) +
|
||||||
|
str(flickr_photo_info['taken']))).hexdigest()
|
||||||
|
|
||||||
|
digest2 = hashlib.sha512(str.encode(str(flickr_photo.id) +
|
||||||
|
str(flickr_photo_info['taken']))).hexdigest()
|
||||||
|
|
||||||
|
digest3 = hashlib.sha3_256(str.encode(str(flickr_photo.id) +
|
||||||
|
str(flickr_photo_info['taken']))).hexdigest()
|
||||||
|
|
||||||
|
digest4 = hashlib.sha3_512(str.encode(str(flickr_photo.id) +
|
||||||
|
str(flickr_photo_info['taken']))).hexdigest()
|
||||||
|
|
||||||
|
digest = str(str(digest1) + str(digest2) + str(digest3) + str(digest4))
|
||||||
|
digest = str(hex(crc32c.crc32c(bytes(digest, 'ascii')))).replace('0x', '')
|
||||||
|
photo['digest'] = digest
|
||||||
|
# END ##################################################################################
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
pathlib.Path('db/' + flickr_photo.id).mkdir(parents=True, exist_ok=True)
|
||||||
|
with open('db/' + flickr_photo.id + '/meta.json', 'w') as photo_json_file:
|
||||||
|
photo['title'] = flickr_photo.title
|
||||||
|
photo['date_updated_timestamp'] = int(flickr_photo_info['lastupdate'])
|
||||||
|
photo['date_posted_timestamp'] = int(flickr_photo_info['posted'])
|
||||||
|
photo['date_taken'] = flickr_photo_info['taken']
|
||||||
|
photo['date_taken_timestamp'] = int(time.mktime(
|
||||||
|
time.strptime(flickr_photo_info['taken'], '%Y-%m-%d %H:%M:%S')))
|
||||||
|
|
||||||
|
photo['date_uploaded_timestamp'] = int(flickr_photo_info['dateuploaded'])
|
||||||
|
photo['description'] = flickr_photo_info['description']
|
||||||
|
|
||||||
|
photo['fgg_id'] = str(photo['date_taken_timestamp']) + '-' + str(i).rjust(7, '0')
|
||||||
|
photo['flickr_id'] = flickr_photo.id
|
||||||
|
|
||||||
|
photo['photo_number'] = i
|
||||||
|
|
||||||
|
flickr_photo_tags = []
|
||||||
|
for flickr_photo_tag in flickr_photo_info['tags']:
|
||||||
|
flickr_photo_tags.append(flickr_photo_tag['text'])
|
||||||
|
|
||||||
|
photo['tags'] = flickr_photo_tags
|
||||||
|
photo['tags'].sort()
|
||||||
|
# TODO: This does not work and need be fixed...!
|
||||||
|
overall_tags = list(set(overall_tags + photo['tags']))
|
||||||
|
|
||||||
|
photo['timezone'] = timezone
|
||||||
|
|
||||||
|
flickr_photo_sizes = flickr_photo.getSizes()
|
||||||
|
photo['sizes'] = {}
|
||||||
|
for flickr_photo_size in flickr_photo_sizes:
|
||||||
|
flickr_size = flickr_photo_sizes[flickr_photo_size]['url'].split("/")[-2]\
|
||||||
|
.replace('/', '')
|
||||||
|
|
||||||
|
if flickr_photo_sizes[flickr_photo_size]['label'] == "Square":
|
||||||
|
flickr_size = "x"
|
||||||
|
|
||||||
|
photo['sizes'][flickr_size] = {}
|
||||||
|
|
||||||
|
# Remove all unneeded keys
|
||||||
|
flickr_photo_sizes[flickr_photo_size].pop('media')
|
||||||
|
flickr_photo_sizes[flickr_photo_size].pop('source')
|
||||||
|
flickr_photo_sizes[flickr_photo_size].pop('url')
|
||||||
|
photo['sizes'][flickr_size] = flickr_photo_sizes[flickr_photo_size]
|
||||||
|
|
||||||
|
photo['sizes'][flickr_size]['size'] = flickr_size
|
||||||
|
|
||||||
|
# Create target photo folder dir and filenames
|
||||||
|
# TODO: The string replacement should be optimized to make better file names.
|
||||||
|
target_file_name = flickr_photo.title.replace(':)', '')
|
||||||
|
target_file_name = target_file_name.replace(':D', '')
|
||||||
|
target_file_name = target_file_name.replace(';)', '')
|
||||||
|
target_file_name = target_file_name.replace('\'', '')
|
||||||
|
target_file_name = target_file_name.replace('\"', '')
|
||||||
|
target_file_name = target_file_name.replace('.', '')
|
||||||
|
target_file_name = target_file_name.replace('!', '')
|
||||||
|
target_file_name = target_file_name.replace('/', '')
|
||||||
|
target_file_name = target_file_name.replace(':', '')
|
||||||
|
target_file_name = target_file_name.replace('(', '')
|
||||||
|
target_file_name = target_file_name.replace(')', '')
|
||||||
|
target_file_name = target_file_name.replace('[', '')
|
||||||
|
target_file_name = target_file_name.replace(']', '')
|
||||||
|
target_file_name = target_file_name.replace('{', '')
|
||||||
|
target_file_name = target_file_name.replace('}', '')
|
||||||
|
target_file_name = target_file_name.replace(';', '')
|
||||||
|
target_file_name = target_file_name.replace('?', '')
|
||||||
|
target_file_name = target_file_name.replace('&', '')
|
||||||
|
target_file_name = target_file_name.replace('<', '')
|
||||||
|
target_file_name = target_file_name.replace('>', '')
|
||||||
|
target_file_name = target_file_name.replace('$', '')
|
||||||
|
target_file_name = target_file_name.replace('%', '')
|
||||||
|
target_file_name = target_file_name.rstrip()
|
||||||
|
target_file_name = target_file_name.replace(' ', '-')
|
||||||
|
|
||||||
|
target_file_name = target_file_name + '-' + photo['fgg_id'] + \
|
||||||
|
'-' + flickr_photo_sizes[flickr_photo_size]['label'].replace(' ', '-')
|
||||||
|
target_file_name = target_file_name + '.jpg'
|
||||||
|
|
||||||
|
photo['sizes'][flickr_size]['target_file_name'] = target_file_name
|
||||||
|
photo['sizes'][flickr_size]['target_file'] = 'photo/' + \
|
||||||
|
photo['digest'] + '/' + \
|
||||||
|
photo['sizes'][flickr_size]['target_file_name']
|
||||||
|
|
||||||
|
# TODO: Download photo file if not exist
|
||||||
|
|
||||||
|
# TODO: Create SHA sums for each photo file and add them to
|
||||||
|
photo['sizes'][flickr_size]['sha1'] = 'SHA1 of file: ' + \
|
||||||
|
photo['sizes'][flickr_size]['target_file']
|
||||||
|
|
||||||
|
photo['sizes'][flickr_size]['sha256'] = 'SHA256 of file: ' + \
|
||||||
|
photo['sizes'][flickr_size]['target_file']
|
||||||
|
|
||||||
|
photo['sizes'][flickr_size]['sha512'] = 'SHA512 of file: ' + \
|
||||||
|
photo['sizes'][flickr_size]['target_file']
|
||||||
|
|
||||||
|
json.dump(photo, photo_json_file, ensure_ascii=False, indent=2, sort_keys=True)
|
||||||
|
|
||||||
|
i -= 1
|
||||||
|
if i == photo_count - debug_max_photos:
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
photo_page += 1
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
crc32c==2.3
|
||||||
flickr-api==0.7.5
|
flickr-api==0.7.5
|
||||||
Loading…
Add table
Add a link
Reference in a new issue