From f27c172a731ee8daacf33ef84b52dba63d211b3d Mon Sep 17 00:00:00 2001 From: Lucas Serverhost Date: Thu, 6 Aug 2026 10:33:59 +0200 Subject: [PATCH] convert heic functional script w docker add docker for new magic version on ubuntu 24 --- convert_heic.sh | 91 ++++++++++++++++++++++-------- serverhost/rename_camera_folder.py | 69 ++++++++++++++++------ serverhost/rename_camera_folder.sh | 2 +- serverhost/syncNC.sh | 68 ++++++++++++++-------- 4 files changed, 168 insertions(+), 62 deletions(-) diff --git a/convert_heic.sh b/convert_heic.sh index a65b3e3..e22db40 100644 --- a/convert_heic.sh +++ b/convert_heic.sh @@ -18,16 +18,35 @@ convert_one() { echo "Converting: $src" # Convert HEIC -> JPEG - if ! magick "$src" \ + if command -v magick >/dev/null 2>&1; then + if ! magick "$src" \ + -auto-orient \ + -quality 100 \ + -sampling-factor 4:4:4 \ + "jpg:$tmp"; then + echo "ERROR: local conversion failed: $src" + rm -f "$tmp" + return 1 + fi + else + if ! docker run --rm \ + -u "$(id -u):$(id -g)" \ + -v "$PWD:/work" \ + -w /work \ + --entrypoint magick \ + dpokidov/imagemagick \ + "$src" \ -auto-orient \ -quality 100 \ -sampling-factor 4:4:4 \ - "jpg:$tmp"; then - echo "ERROR: conversion failed: $src" - rm -f "$tmp" - return 1 + "jpg:$tmp"; then + echo "ERROR: docker conversion failed: $src" + rm -f "$tmp" + return 1 + fi fi + if [[ ! -s "$tmp" ]]; then echo "ERROR: output JPEG is empty: $tmp" rm -f "$tmp" @@ -76,20 +95,20 @@ convert_mov() { echo "Converting: $src" # MOV -> MP4, keep video/audio, drop unsupported data streams - if ! ffmpeg \ - -hide_banner \ - -loglevel error \ - -i "$src" \ - -map 0:0 \ - -map 0:1 \ - -map_metadata 0 \ - -c copy \ - -movflags use_metadata_tags+faststart \ - "$tmp"; then - echo "ERROR: conversion failed: $src" - rm -f "$tmp" - return 1 -fi + if ! ffmpeg \ + -hide_banner \ + -loglevel error \ + -i "$src" \ + -map 0:0 \ + -map 0:1 \ + -map_metadata 0 \ + -c copy \ + -movflags use_metadata_tags+faststart \ + "$tmp"; then + echo "ERROR: conversion failed: $src" + rm -f "$tmp" + return 1 + fi if [[ ! -s "$tmp" ]]; then echo "ERROR: output MP4 is empty: $tmp" @@ -140,17 +159,43 @@ process_file() { } +HOSTNAME_EXPECTED="serverhost" +SOURCE_DIR="/torrent/alina/Dropfolder" +TARGET_DIR="/torrent/camera" + +# If running on serverhost, perform initial sync +if [[ "$(hostname)" == "$HOSTNAME_EXPECTED" ]]; then + /home/lucas/scripts/serverhost/syncNC.sh -d -c + cd "$SOURCE_DIR" || exit 1 +fi + + if [[ $# -gt 0 ]]; then process_file "$1" else + shopt -s nullglob files=( *.heic *.mov ) if [[ ${#files[@]} -eq 0 ]]; then echo "No HEIC or MOV files found." - exit 0 + else + for f in "${files[@]}"; do + process_file "$f" + done fi +fi - for f in "${files[@]}"; do - process_file "$f" +# Run sync again if on serverhost +if [[ "$(hostname)" == "$HOSTNAME_EXPECTED" ]]; then + shopt -s nullglob + for ext in jpg mp4; do + files=("$SOURCE_DIR"/*."$ext") + if ((${#files[@]})); then + mv -n "${files[@]}" "$TARGET_DIR"/ + fi done -fi \ No newline at end of file + shopt -u nullglob + + /home/lucas/scripts/serverhost/syncNC.sh -d -c +fi + diff --git a/serverhost/rename_camera_folder.py b/serverhost/rename_camera_folder.py index 6c5bc1d..25d54a7 100755 --- a/serverhost/rename_camera_folder.py +++ b/serverhost/rename_camera_folder.py @@ -100,30 +100,65 @@ def local_safe_rename(src_path, new_filename): def get_exif_creation_datetime(filepath): """Try to extract creation datetime from image EXIF metadata""" try: - if 'heic' in filepath.lower(): - - heif_file = open_heif(filepath) - img = Image.fromarray(heif_file.data) - exif = img.getexif() - - for tag_id, value in exif.items(): - print(tag_id, value) + if filepath.lower().endswith((".mp4", ".mov", ".m4v")): + # WhatsApp videos: use filesystem modification time + if "WA" in os.path.basename(filepath): + return datetime.datetime.fromtimestamp( + os.path.getmtime(filepath) + ) + + tags = ["CreateDate", "MediaCreateDate", "TrackCreateDate"] + + result = subprocess.run( + [ + "exiftool", + "-j", + "-CreateDate", + "-MediaCreateDate", + "-TrackCreateDate", + filepath, + ], + capture_output=True, + text=True, + check=True, + ) + + metadata = json.loads(result.stdout)[0] + + for tag in tags: + if metadata.get(tag): + return datetime.datetime.strptime( + metadata[tag], + "%Y:%m:%d %H:%M:%S" + ) + + # Fallback: use filesystem modification time + return datetime.datetime.fromtimestamp( + os.path.getmtime(filepath) + ) + else: with Image.open(filepath) as img: exif = img._getexif() if not exif: print("Exif failed") return None - - # Map tag ids to tag names - tag_label = {ExifTags.TAGS.get(k): v for k, v in exif.items() if k in ExifTags.TAGS} - + + tag_label = { + ExifTags.TAGS.get(k): v + for k, v in exif.items() + if k in ExifTags.TAGS + } + for tag in EXIF_DATE_TAGS: print(tag) if tag in tag_label: print(tag) - # EXIF date format: 'YYYY:MM:DD HH:MM:SS' - return datetime.datetime.strptime(tag_label[tag], '%Y:%m:%d %H:%M:%S') + return datetime.datetime.strptime( + tag_label[tag], + '%Y:%m:%d %H:%M:%S' + ) + except Exception as e: print(f"Exif Error {e}") @@ -141,13 +176,15 @@ def get_manufacturer(file_path): # Parse JSON output metadata = json.loads(result.stdout)[0] - # Extract Author tag and remove spaces author = metadata.get("Author", "") if author == "": author = metadata.get("AndroidManufacturer", "") + if author == "": + author = metadata.get("Model", "") + if author == "": + author = "NoAuthor" author_no_spaces = author.replace(" ", "") - return author_no_spaces def process_images(folder): diff --git a/serverhost/rename_camera_folder.sh b/serverhost/rename_camera_folder.sh index f1e229e..8222970 100755 --- a/serverhost/rename_camera_folder.sh +++ b/serverhost/rename_camera_folder.sh @@ -1,6 +1,6 @@ #!/bin/bash PW=$(cat /home/lucas/.PW) -FOLDER=/torrent/Camera +FOLDER=/torrent/camera SERVER="https://someoneslinux.ddns.net" nextcloudcmd --trust --user lucas --password ${PW} --path Media/Pictures/Camera ${FOLDER} ${SERVER} 1>/dev/null 2>&1 export PYTHONPATH=/home/lucas/scripts diff --git a/serverhost/syncNC.sh b/serverhost/syncNC.sh index b4ed160..5e81e73 100755 --- a/serverhost/syncNC.sh +++ b/serverhost/syncNC.sh @@ -11,11 +11,14 @@ ret=0 count=20 PW=$(cat /home/lucas/.PW) PW_M="multimedia123" -SYNC_MEDIA=0 +SYNC_MEDIA=1 SYNC_RECIPIES=1 -SYNC_MEDIA_ONLY=0 SYNC_ALINA=1 -SYNC_THEMES=0 +SYNC_ALINA_DROP=1 +SYNC_THEMES=1 +SYNC_WALLPAPER=1 +SYNC_CAMERA=1 +SYNC_SERVER=0 SILENT=true SERVER="https://someoneslinux.ddns.net" while [[ ${1:0:1} == - ]]; do @@ -26,7 +29,18 @@ while [[ ${1:0:1} == - ]]; do continue; }; [[ $1 == -o ]] && { - SYNC_MEDIA_ONLY=1; + SYNC_SERVER=1; + SYNC_WALLPAPER=1 + shift 1; + continue; + }; + [[ $1 == -d ]] && { + SYNC_ALINA_DROP=0; + shift 1; + continue; + }; + [[ $1 == -c ]] && { + SYNC_CAMERA=0; shift 1; continue; }; @@ -36,25 +50,24 @@ while [[ ${1:0:1} == - ]]; do continue; }; [[ $1 == -m ]] && { - SYNC_MEDIA=1; + SYNC_MEDIA=0; shift 1; continue; }; - [[ $1 == -t ]] && { - SYNC_THEMES=1; + [[ $1 == -t ]] && { + SYNC_THEMES=0; shift 1; continue; - }; - - [[ $1 == -del ]] && { - if [ -f /tmp/nextcloud_sync ]; then - rm /tmp/nextcloud_sync - echo "File removed" - fi - shift 1; - continue; + }; + [[ $1 == -del ]] && { + if [ -f /tmp/nextcloud_sync ]; then + rm /tmp/nextcloud_sync + echo "File removed" + fi + shift 1; + continue; }; - echo "Parameter $1 discarded" + echo "Parameter $1 discarded" shift 1; done @@ -64,18 +77,24 @@ else echo "Sync Nextcloud" while true; do ret=0 - if [ ${SYNC_MEDIA} -eq 1 ];then + if [ ${SYNC_MEDIA} -eq 0 ];then echo "Sync Multmedia" run_cmd sudo /home/lucas/scripts/serverhost/tvbitch_user_cmd.sh nextcloudcmd --logdebug --trust --user multimedia --password ${PW_M} --path Filme/New /torrent/multimedia/Filme/New ${SERVER} ret=$(( ret + $? )) #echo Return: $ret fi - if [[ ${SYNC_THEMES} -eq 1 ]] && [[ ${SYNC_MEDIA_ONLY} -eq 0 ]]; then + if [[ ${SYNC_THEMES} -eq 0 ]] && [[ ${SYNC_MEDIA_ONLY} -eq 0 ]]; then echo "Sync Themes" run_cmd nextcloudcmd --trust --user lucas --password ${PW} --path Dokumente/Dokumente/Projekte/Handy/ThemeProject/SolarSystemTheme /home/lucas/Documents/Dokumente/Projekte/Handy/ThemeProject/SolarSystemTheme ${SERVER} ret=$(( ret + $? )) #echo Return: $ret fi + if [[ ${SYNC_ALINA_DROP} -eq 0 ]];then + echo "Sync Alina Share" + run_cmd nextcloudcmd --trust --user lucas --password ${PW} --path Media/Pictures/Alina\ Share/ /torrent/alina ${SERVER} + ret=$(( ret + $? )) + #echo Return: $ret + fi if [[ ${SYNC_ALINA} -eq 0 ]];then echo "Sync Alina" run_cmd nextcloudcmd --trust --user lucas --password ${PW} --path Dokumente/Dokumente/Shared/Alina/Wachstum /home/lucas/Documents/Dokumente/Shared/Alina/Wachstum ${SERVER} @@ -88,14 +107,19 @@ else ret=$(( ret + $? )) #echo Return: $ret fi - if [[ "$1" != "-W" ]] && [[ ${SYNC_MEDIA_ONLY} -eq 0 ]];then + if [[ ${SYNC_CAMERA} -eq 0 ]];then + echo "Sync Camera" + nextcloudcmd --trust --user lucas --password ${PW} --path Media/Pictures/Camera /torrent/camera ${SERVER} 1>/dev/null 2>&1 + ret=$(( ret + $? )) + #echo Return: $ret + fi + if [[ ${SYNC_SERVER} -eq 0 ]];then echo "Sync Server" - # echo "nextcloudcmd --trust --user lucas --password ${PW} --path Dokumente/Dokumente/Projekte/Server /home/lucas/Documents/Dokumente/Projekte/Server ${SERVER}" run_cmd nextcloudcmd --trust --user lucas --password ${PW} --path Dokumente/Dokumente/Projekte/Server /home/lucas/Documents/Dokumente/Projekte/Server ${SERVER} ret=$(( ret + $? )) #echo Return: $ret fi - if [[ ${SYNC_MEDIA_ONLY} -eq 0 ]]; then + if [[ ${SYNC_WALLPAPER} -eq 0 ]]; then echo "Sync Wallpaper" run_cmd nextcloudcmd --trust --user lucas --password ${PW} --path Media/Stuff/Wallpaper /torrent/WallpaperChanger ${SERVER} ret=$(( ret + $? ))