1
0
Fork 0

Merge pull request #26 from Salvoxia/dev

Merge features from Dev branch
This commit is contained in:
Salvoxia 2024-07-30 19:29:59 +00:00 committed by GitHub
commit 65c1d551e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 50 additions and 6 deletions

View file

@ -28,8 +28,7 @@ pip3 install -r requirements.txt
``` ```
3. Run the script 3. Run the script
``` ```
python3 ./immich_auto_album.py -h usage: immich_auto_album.py [-h] [-r ROOT_PATH] [-u] [-a ALBUM_LEVELS] [-s ALBUM_SEPARATOR] [-c CHUNK_SIZE] [-C FETCH_CHUNK_SIZE] [-l {CRITICAL,ERROR,WARNING,INFO,DEBUG}] [-k] [-i IGNORE] root_path api_url api_key
usage: immich_auto_album.py [-h] [-r ROOT_PATH] [-u] [-a ALBUM_LEVELS] [-s ALBUM_SEPARATOR] [-c CHUNK_SIZE] [-C FETCH_CHUNK_SIZE] [-l {CRITICAL,ERROR,WARNING,INFO,DEBUG}] root_path api_url api_key
Create Immich Albums from an external library path based on the top level folders Create Immich Albums from an external library path based on the top level folders
@ -44,8 +43,8 @@ options:
Additional external libarary root path in Immich; May be specified multiple times for multiple import paths or external libraries. (default: None) Additional external libarary root path in Immich; May be specified multiple times for multiple import paths or external libraries. (default: None)
-u, --unattended Do not ask for user confirmation after identifying albums. Set this flag to run script as a cronjob. (default: False) -u, --unattended Do not ask for user confirmation after identifying albums. Set this flag to run script as a cronjob. (default: False)
-a ALBUM_LEVELS, --album-levels ALBUM_LEVELS -a ALBUM_LEVELS, --album-levels ALBUM_LEVELS
Number of sub-folders or range of sub-folder levels below the root path used for album name creation. Positive numbers start from top of the folder structure, negative numbers from the bottom. Cannot be 0. If a range should be set, the start level and end level must be separated by a comma Number of sub-folders or range of sub-folder levels below the root path used for album name creation. Positive numbers start from top of the folder structure, negative numbers from the bottom. Cannot be 0. If a range should be set, the
like '<startLevel>,<endLevel>'. If negative levels are used in a range, <startLevel> must be less than or equal to <endLevel>. (default: 1) start level and end level must be separated by a comma like '<startLevel>,<endLevel>'. If negative levels are used in a range, <startLevel> must be less than or equal to <endLevel>. (default: 1)
-s ALBUM_SEPARATOR, --album-separator ALBUM_SEPARATOR -s ALBUM_SEPARATOR, --album-separator ALBUM_SEPARATOR
Separator string to use for compound album names created from nested folders. Only effective if -a is set to a value > 1 (default: ) Separator string to use for compound album names created from nested folders. Only effective if -a is set to a value > 1 (default: )
-c CHUNK_SIZE, --chunk-size CHUNK_SIZE -c CHUNK_SIZE, --chunk-size CHUNK_SIZE
@ -54,6 +53,9 @@ options:
Maximum number of assets to fetch with a single API call (default: 5000) Maximum number of assets to fetch with a single API call (default: 5000)
-l {CRITICAL,ERROR,WARNING,INFO,DEBUG}, --log-level {CRITICAL,ERROR,WARNING,INFO,DEBUG} -l {CRITICAL,ERROR,WARNING,INFO,DEBUG}, --log-level {CRITICAL,ERROR,WARNING,INFO,DEBUG}
Log level to use (default: INFO) Log level to use (default: INFO)
-k, --insecure Set to true to ignore SSL verification (default: False)
-i IGNORE, --ignore IGNORE
A string containing a list of folders, sub-folder sequences or file names separated by ':' that will be ignored. (default: )
``` ```
__Plain example without optional arguments:__ __Plain example without optional arguments:__
@ -83,6 +85,8 @@ The environment variables are analoguous to the script's command line arguments.
| CHUNK_SIZE | no | Maximum number of assets to add to an album with a single API call (default: 2000) | | CHUNK_SIZE | no | Maximum number of assets to add to an album with a single API call (default: 2000) |
| FETCH_CHUNK_SIZE | no | Maximum number of assets to fetch with a single API call (default: 5000) | | FETCH_CHUNK_SIZE | no | Maximum number of assets to fetch with a single API call (default: 5000) |
| LOG_LEVEL | no | Log level to use (default: INFO), allowed values: CRITICAL,ERROR,WARNING,INFO,DEBUG | | LOG_LEVEL | no | Log level to use (default: INFO), allowed values: CRITICAL,ERROR,WARNING,INFO,DEBUG |
| INSECURE | no | Set to `true` to disable SSL verification for the Immich API server, useful for self-signed certificates (default: `false`), allowed values: `true`, `false` |
| INSECURE | no | A string containing a list of folders, sub-folder sequences or file names separated by ':' that will be ignored. |
#### Run the container with Docker #### Run the container with Docker
@ -167,6 +171,11 @@ Albums created for `root_path = /external_libs/photos` (`--album-levels` is impl
- `Birthdays` (containing all images from Birthdays itself as well as `John` and `Jane`) - `Birthdays` (containing all images from Birthdays itself as well as `John` and `Jane`)
- `Skiing 2023` - `Skiing 2023`
Albums created for `root_path = /external_libs/photos` (`--album-levels` is implicitly set to `1`) and `--ignore "Vacation"`:
- `2020` (containing all images from `2020`, `2020/02 Feb` and `2020/08 Aug`, but __NOT__ `2020/02 Feb/Vacation` or `2020/08 Aug/Vacation`)
- `Birthdays` (containing all images from Birthdays itself as well as `John` and `Jane`)
- `Skiing 2023`
Albums created for `root_path = /external_libs/photos/Birthdays`: Albums created for `root_path = /external_libs/photos/Birthdays`:
- `John` - `John`
- `Jane` - `Jane`

View file

@ -38,6 +38,14 @@ if [ ! -z "$LOG_LEVEL" ]; then
args="-l $LOG_LEVEL $args" args="-l $LOG_LEVEL $args"
fi fi
if [ "$INSECURE" = "true" ]; then
args="-k $args"
fi
if [ ! -z "$IGNORE" ]; then
args="-i \"$IGNORE\" $args"
fi
BASEDIR=$(dirname "$0") BASEDIR=$(dirname "$0")
echo $args | xargs python3 -u $BASEDIR/immich_auto_album.py echo $args | xargs python3 -u $BASEDIR/immich_auto_album.py

View file

@ -4,6 +4,7 @@ import logging
import sys import sys
import datetime import datetime
from collections import defaultdict from collections import defaultdict
import urllib3
# Trying to deal with python's isnumeric() function # Trying to deal with python's isnumeric() function
# not recognizing negative numbers # not recognizing negative numbers
@ -25,6 +26,8 @@ parser.add_argument("-s", "--album-separator", default=" ", type=str, help="Sepa
parser.add_argument("-c", "--chunk-size", default=2000, type=int, help="Maximum number of assets to add to an album with a single API call") parser.add_argument("-c", "--chunk-size", default=2000, type=int, help="Maximum number of assets to add to an album with a single API call")
parser.add_argument("-C", "--fetch-chunk-size", default=5000, type=int, help="Maximum number of assets to fetch with a single API call") parser.add_argument("-C", "--fetch-chunk-size", default=5000, type=int, help="Maximum number of assets to fetch with a single API call")
parser.add_argument("-l", "--log-level", default="INFO", choices=['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'], help="Log level to use") parser.add_argument("-l", "--log-level", default="INFO", choices=['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'], help="Log level to use")
parser.add_argument("-k", "--insecure", action="store_true", help="Set to true to ignore SSL verification")
parser.add_argument("-i", "--ignore", default="", type=str, help="A string containing a list of folders, sub-folder sequences or file names separated by ':' that will be ignored.")
args = vars(parser.parse_args()) args = vars(parser.parse_args())
# set up logger to log in logfmt format # set up logger to log in logfmt format
logging.basicConfig(level=args["log_level"], stream=sys.stdout, format='time=%(asctime)s level=%(levelname)s msg=%(message)s') logging.basicConfig(level=args["log_level"], stream=sys.stdout, format='time=%(asctime)s level=%(levelname)s msg=%(message)s')
@ -40,6 +43,8 @@ album_levels = args["album_levels"]
# Album Levels Range handling # Album Levels Range handling
album_levels_range_arr = () album_levels_range_arr = ()
album_level_separator = args["album_separator"] album_level_separator = args["album_separator"]
insecure = args["insecure"]
ignore_albums = args["ignore"]
logging.debug("root_path = %s", root_paths) logging.debug("root_path = %s", root_paths)
logging.debug("root_url = %s", root_url) logging.debug("root_url = %s", root_url)
logging.debug("api_key = %s", api_key) logging.debug("api_key = %s", api_key)
@ -49,12 +54,17 @@ logging.debug("unattended = %s", unattended)
logging.debug("album_levels = %s", album_levels) logging.debug("album_levels = %s", album_levels)
#logging.debug("album_levels_range = %s", album_levels_range) #logging.debug("album_levels_range = %s", album_levels_range)
logging.debug("album_level_separator = %s", album_level_separator) logging.debug("album_level_separator = %s", album_level_separator)
logging.debug("insecure = %s", insecure)
logging.debug("ignore = %s", ignore_albums)
# Verify album levels # Verify album levels
if is_integer(album_levels) and album_levels == 0: if is_integer(album_levels) and album_levels == 0:
parser.print_help() parser.print_help()
exit(1) exit(1)
if insecure:
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Verify album levels range # Verify album levels range
if not is_integer(album_levels): if not is_integer(album_levels):
album_levels_range_split = album_levels.split(",") album_levels_range_split = album_levels.split(",")
@ -86,6 +96,10 @@ if not is_integer(album_levels):
album_levels_range_arr[0] -= 1 album_levels_range_arr[0] -= 1
album_levels_range_arr[1] -= 1 album_levels_range_arr[1] -= 1
if not ignore_albums == "":
ignore_albums = ignore_albums.split(":")
else:
ignore_albums = False
# Request arguments for API calls # Request arguments for API calls
requests_kwargs = { requests_kwargs = {
@ -93,7 +107,8 @@ requests_kwargs = {
'x-api-key': api_key, 'x-api-key': api_key,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json' 'Accept': 'application/json'
} },
'verify' : not insecure
} }
# Yield successive n-sized # Yield successive n-sized
@ -308,6 +323,17 @@ for asset in assets:
for root_path in root_paths: for root_path in root_paths:
if root_path not in asset_path: if root_path not in asset_path:
continue continue
# Check ignore_albums
ignore = False
if ignore_albums:
for ignore_entry in ignore_albums:
if ignore_entry in asset_path:
ignore = True
break
if ignore:
logging.debug("Ignoring asset %s due to ignore_albums setting!", asset_path)
continue
# Chunks of the asset's path below root_path # Chunks of the asset's path below root_path
path_chunks = asset_path.replace(root_path, '').split('/') path_chunks = asset_path.replace(root_path, '').split('/')
# A single chunk means it's just the image file in no sub folder, ignore # A single chunk means it's just the image file in no sub folder, ignore

View file

@ -1 +1,2 @@
requests requests
urllib3