Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65e352e8a4 | |||
| 38083d8a46 | |||
| ce676dea72 | |||
| 8548cc1f0f | |||
| 63202b53f1 | |||
| 2836a40616 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.venv/
|
||||
@@ -73,7 +73,7 @@ class readable_dir(argparse.Action):
|
||||
# check distance values are valid
|
||||
class distance_values(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
m = re.match('^(\d+)\s?(m|km)$', values)
|
||||
m = re.match(r'^(\d+)\s?(m|km)$', values)
|
||||
if m:
|
||||
# convert to int in meters
|
||||
values = int(m.group(1))
|
||||
@@ -128,7 +128,7 @@ def reverseGeolocateInit(longitude, latitude):
|
||||
'error_message': ''
|
||||
}
|
||||
# error if long/lat is not valid
|
||||
latlong_re = re.compile('^\d+\.\d+$')
|
||||
latlong_re = re.compile(r'^\d+\.\d+$')
|
||||
if not latlong_re.match(str(longitude)) or not latlong_re.match(str(latitude)):
|
||||
geolocation['status'] = 'ERROR'
|
||||
geolocation['error_message'] = 'Latitude {} or Longitude {} are not valid'.format(latitude, longitude)
|
||||
@@ -201,7 +201,7 @@ def reverseGeolocateOpenStreetMap(longitude, latitude):
|
||||
# dict with location, city, state, country, country code
|
||||
# if not fillable, entry is empty
|
||||
# SAMPLE: http://maps.googleapis.com/maps/api/geocode/json?latlng=<latitude>,<longitude>&language=<lang>&sensor=false&key=<api key>
|
||||
def reverseGeolocateGoogle(longitude, latitude):
|
||||
def reverseGeolocateGoogle(longitude, latitude): # noqa: C901
|
||||
# init
|
||||
geolocation = reverseGeolocateInit(longitude, latitude)
|
||||
temp_geolocation = geolocation.copy()
|
||||
@@ -238,7 +238,7 @@ def reverseGeolocateGoogle(longitude, latitude):
|
||||
'CountryCode': ['country'],
|
||||
'Country': ['country'],
|
||||
'State': ['administrative_area_level_1', 'administrative_area_level_2'],
|
||||
'City': ['locality'],
|
||||
'City': ['locality', 'administrative_area_level_3'],
|
||||
'Location': ['sublocality_level_1', 'sublocality_level_2', 'route'],
|
||||
}
|
||||
# print("Error: {}".format(response.json()['status']))
|
||||
@@ -328,7 +328,7 @@ def convertLongToDMS(lat_long):
|
||||
# number used in google/lr internal
|
||||
def longLatReg(longitude, latitude):
|
||||
# regex
|
||||
latlong_re = re.compile('^(\d+),(\d+\.\d+)([NESW]{1})$')
|
||||
latlong_re = re.compile(r'^(\d+),(\d+\.\d+)([NESW]{1})$')
|
||||
# dict for loop
|
||||
lat_long = {
|
||||
'longitude': longitude,
|
||||
@@ -520,7 +520,7 @@ def formatLen(string, length):
|
||||
# RETURN: number found in the BK string or 0 for none
|
||||
# DESC : gets the BK number for sorting in the file list
|
||||
def fileSortNumber(file):
|
||||
m = re.match('.*\.BK\.(\d+)\.xmp$', file)
|
||||
m = re.match(r'.*\.BK\.(\d+)\.xmp$', file)
|
||||
return int(m.group(1)) if m is not None else 0
|
||||
|
||||
|
||||
@@ -644,45 +644,55 @@ parser = argparse.ArgumentParser(
|
||||
|
||||
# xmp folder (or folders), or file (or files)
|
||||
# note that the target directory or file needs to be writeable
|
||||
parser.add_argument('-i', '--include-source',
|
||||
parser.add_argument(
|
||||
'-i',
|
||||
'--include-source',
|
||||
required=True,
|
||||
nargs='*',
|
||||
action=writable_dir_folder,
|
||||
dest='xmp_sources',
|
||||
metavar='XMP SOURCE FOLDER',
|
||||
help='The source folder or folders with the XMP files that need reverse geo encoding to be set. Single XMP files can be given here'
|
||||
)
|
||||
)
|
||||
# exclude folders
|
||||
parser.add_argument('-x', '--exclude-source',
|
||||
parser.add_argument(
|
||||
'-x',
|
||||
'--exclude-source',
|
||||
nargs='*',
|
||||
action=writable_dir_folder,
|
||||
dest='exclude_sources',
|
||||
metavar='EXCLUDE XMP SOURCE FOLDER',
|
||||
help='Folders and files that will be excluded.'
|
||||
)
|
||||
)
|
||||
|
||||
# LR database (base folder)
|
||||
# get .lrcat file in this folder
|
||||
parser.add_argument('-l', '--lightroom',
|
||||
parser.add_argument(
|
||||
'-l',
|
||||
'--lightroom',
|
||||
# required=True,
|
||||
action=readable_dir,
|
||||
dest='lightroom_folder',
|
||||
metavar='LIGHTROOM FOLDER',
|
||||
help='Lightroom catalogue base folder'
|
||||
)
|
||||
)
|
||||
|
||||
# strict LR check with base path next to the file base name
|
||||
parser.add_argument('-s', '--strict',
|
||||
parser.add_argument(
|
||||
'-s',
|
||||
'--strict',
|
||||
dest='lightroom_strict',
|
||||
action='store_true',
|
||||
help='Do strict check for Lightroom files including Path in query'
|
||||
)
|
||||
)
|
||||
|
||||
# set behaviour override
|
||||
# FLAG: default: only set not filled
|
||||
# other: overwrite all or overwrite if one is missing, overwrite specifc field (as defined below)
|
||||
# fields: Location, City, State, Country, CountryCode
|
||||
parser.add_argument('-f', '--field',
|
||||
parser.add_argument(
|
||||
'-f',
|
||||
'--field',
|
||||
action='append',
|
||||
type=str.lower, # make it lowercase for check
|
||||
choices=['overwrite', 'location', 'city', 'state', 'country', 'countrycode'],
|
||||
@@ -692,9 +702,11 @@ parser.add_argument('-f', '--field',
|
||||
'Overwrite (write all new), Location, City, State, Country, CountryCode. '\
|
||||
'Multiple can be given for combination overwrite certain fields only or set only certain fields. '\
|
||||
'If with overwrite the field will be overwritten if already set, else it will be always skipped.'
|
||||
)
|
||||
)
|
||||
|
||||
parser.add_argument('-d', '--fuzzy-cache',
|
||||
parser.add_argument(
|
||||
'-d',
|
||||
'--fuzzy-cache',
|
||||
type=str.lower,
|
||||
action=distance_values,
|
||||
nargs='?',
|
||||
@@ -704,77 +716,106 @@ parser.add_argument('-d', '--fuzzy-cache',
|
||||
help='Allow fuzzy distance cache lookup. Optional distance can be given, '\
|
||||
'if not set default of 10m is used. '\
|
||||
'Allowed argument is in the format of 12m or 12km'
|
||||
)
|
||||
)
|
||||
|
||||
# Google Maps API key to overcome restrictions
|
||||
parser.add_argument('-g', '--google',
|
||||
parser.add_argument(
|
||||
'-g',
|
||||
'--google',
|
||||
dest='google_api_key',
|
||||
metavar='GOOGLE API KEY',
|
||||
help='Set a Google API Maps key to overcome the default lookup limitations'
|
||||
)
|
||||
)
|
||||
|
||||
# use open street maps
|
||||
parser.add_argument('-o', '--openstreetmap',
|
||||
parser.add_argument(
|
||||
'-o',
|
||||
'--openstreetmap',
|
||||
dest='use_openstreetmap',
|
||||
action='store_true',
|
||||
help='Use openstreetmap instead of Google'
|
||||
)
|
||||
)
|
||||
|
||||
# email of open street maps requests
|
||||
parser.add_argument('-e', '--email',
|
||||
parser.add_argument(
|
||||
'-e',
|
||||
'--email',
|
||||
dest='email',
|
||||
metavar='EMIL ADDRESS',
|
||||
help='An email address for OpenStreetMap'
|
||||
)
|
||||
)
|
||||
|
||||
# write api/email settings to config file
|
||||
parser.add_argument('-w', '--write-settings',
|
||||
parser.add_argument(
|
||||
'-w',
|
||||
'--write-settings',
|
||||
dest='config_write',
|
||||
action='store_true',
|
||||
help='Write Google API or OpenStreetMap email to config file'
|
||||
)
|
||||
)
|
||||
|
||||
# only read data and print on screen, do not write anything
|
||||
parser.add_argument('-r', '--read-only',
|
||||
parser.add_argument(
|
||||
'-r',
|
||||
'--read-only',
|
||||
dest='read_only',
|
||||
action='store_true',
|
||||
help='Read current values from the XMP file only, do not read from LR or lookup any data and write back'
|
||||
)
|
||||
)
|
||||
|
||||
# only list unset ones
|
||||
parser.add_argument('-u', '--unset-only',
|
||||
parser.add_argument(
|
||||
'-u',
|
||||
'--unset-only',
|
||||
dest='unset_only',
|
||||
action='store_true',
|
||||
help='Only list unset XMP files'
|
||||
)
|
||||
)
|
||||
|
||||
# only list unset GPS codes
|
||||
parser.add_argument(
|
||||
'-p',
|
||||
'--unset-gps-only',
|
||||
dest='unset_gps_only',
|
||||
action='store_true',
|
||||
help='Only list unset XMP files for GPS fields'
|
||||
)
|
||||
|
||||
# don't try to do auto adjust in list view
|
||||
parser.add_argument('-a', '--no-autoadjust',
|
||||
parser.add_argument(
|
||||
'-a',
|
||||
'--no-autoadjust',
|
||||
dest='no_autoadjust',
|
||||
action='store_true',
|
||||
help='Don\'t try to auto adjust columns'
|
||||
)
|
||||
)
|
||||
|
||||
# compact view, compresses columns down to a minimum
|
||||
parser.add_argument('-c', '--compact',
|
||||
parser.add_argument(
|
||||
'-c',
|
||||
'--compact',
|
||||
dest='compact_view',
|
||||
action='store_true',
|
||||
help='Very compact list view'
|
||||
)
|
||||
)
|
||||
|
||||
# Do not create backup files
|
||||
parser.add_argument('-n', '--nobackup',
|
||||
parser.add_argument(
|
||||
'-n',
|
||||
'--nobackup',
|
||||
dest='no_xmp_backup',
|
||||
action='store_true',
|
||||
help='Do not create a backup from the XMP file'
|
||||
)
|
||||
)
|
||||
|
||||
# verbose args for more detailed output
|
||||
parser.add_argument('-v', '--verbose',
|
||||
parser.add_argument(
|
||||
'-v',
|
||||
'--verbose',
|
||||
action='count',
|
||||
dest='verbose',
|
||||
help='Set verbose output level'
|
||||
)
|
||||
)
|
||||
|
||||
# debug flag
|
||||
parser.add_argument('--debug', action='store_true', dest='debug', help='Set detailed debug output')
|
||||
@@ -837,7 +878,7 @@ if args.email and not args.use_openstreetmap:
|
||||
error = True
|
||||
# if email and not basic valid email (@ .)
|
||||
if args.email:
|
||||
if not re.match('^.+@.+\.[A-Za-z]{1,}$', args.email):
|
||||
if not re.match(r'^.+@.+\.[A-Za-z]{1,}$', args.email):
|
||||
print("Not a valid email for OpenStreetMap: {}".format(args.email))
|
||||
error = True
|
||||
# on error exit here
|
||||
@@ -980,6 +1021,8 @@ if args.lightroom_folder:
|
||||
cur = lrdb.cursor()
|
||||
# flag that we have Lightroom DB
|
||||
use_lightroom = True
|
||||
if args.debug:
|
||||
print("### USE Lightroom {}".format(use_lightroom))
|
||||
|
||||
# on error exit here
|
||||
if error:
|
||||
@@ -1088,7 +1131,7 @@ if args.read_only:
|
||||
|
||||
# ### MAIN WORK LOOP
|
||||
# now we just loop through each file and work on them
|
||||
for xmp_file in work_files:
|
||||
for xmp_file in work_files: # noqa: C901
|
||||
if not args.read_only:
|
||||
print("---> {}: ".format(xmp_file), end='')
|
||||
|
||||
@@ -1111,7 +1154,7 @@ for xmp_file in work_files:
|
||||
print("### => XMP: {}:{} => {}".format(xmp_fields[xmp_field], xmp_field, data_set[xmp_field]))
|
||||
if args.read_only:
|
||||
# view only if list all or if data is unset
|
||||
if not args.unset_only or (args.unset_only and '' in data_set.values()):
|
||||
if (not args.unset_only and not args.unset_gps_only) or (args.unset_only and '' in data_set.values()) or (args.unset_gps_only and (not data_set['GPSLatitude'] or not data_set['GPSLongitude'])):
|
||||
# for read only we print out the data formatted
|
||||
# headline check, do we need to print that
|
||||
count['read'] = printHeader(header_line.format(page_no=page_no, page_all=page_all), count['read'], header_repeat)
|
||||
@@ -1287,7 +1330,7 @@ for xmp_file in work_files:
|
||||
with open(xmp_file, 'w') as fptr:
|
||||
fptr.write(xmp.serialize_to_str(omit_packet_wrapper=True))
|
||||
else:
|
||||
print("[TEST] Would write {} ".format(data_set, xmp_file), end='')
|
||||
print("[TEST] Would write {} {}".format(data_set, xmp_file), end='')
|
||||
if from_cache:
|
||||
print("[UPDATED FROM CACHE]")
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user