commit bfb0c4cb18192133b63d11c8a48d7b44fb7ee2c3 Author: Gabriel Radureau Date: Thu Oct 9 23:46:41 2025 +0200 on Airdrop Download trigger diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..73540c0 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Dance Videos + +L'utilisateur prend des vidéos de ses cours de danses avec son iPhone, +en télécharge depuis son application whatsapp quand on lui partage +et enregistre l'écran de son téléphone quand certaines vidéos de danses apparaissent. + +Les vidéos de l'iPhone sont au format .mov et possèdent des tags permettant d'identifier le lieu et le datetime de l'enregistrement. +Les autres sont en général au format .mp4 et le datetime correspond à la réception et non au moment de la danse. + +L'utilisateur souhaite dans un premier temps organiser ces vidéos (vidéos de cours, de démo). +Dans un deuxième temps les convertir à un format adapté à son projecteur pour ses répétitions. + +Un début de solution a été imaginé:Quand l'utilisateur "air drop" ses vidéos vers son MacBook pro M4, +cela déclenche un script qui déplacera toutes les vidéos du dossier Téléchargement vers un premier dossier de travail +et enclenchera le programme que l'on concevra ensemble. + +Ce programme se chargera de convertir chaque vidéos en .mp4 (en conservant les tags si possibles) +et en renomant les vidéos aussi bien que possible avec un label parlant. + +On développera plus tard la manière de construire les règles d'organisation (une combinaison de machine learning et de llm assisté par l'utilisateur). + +Quand l'utilisateur branche sa carte SD avec un nom bien défini ("SD Danse" par exemple), +un programme se déclenche pour synchroniser son contenu avec le dossier de sortie où les vidéos sont organisées. + +## Prérequis + +1. Mac +2. Une carte SD nommée SD_DANSE formatée en `MS-DOS (FAT32)` pour un meilleur support des projecteurs + +## [Déclencher au téléchargement](./doc/01.OnAirdropDownload.md) + +- `./trigger/trigger.sh` \ No newline at end of file diff --git a/doc/01.OnAirdropDownload.md b/doc/01.OnAirdropDownload.md new file mode 100644 index 0000000..f556827 --- /dev/null +++ b/doc/01.OnAirdropDownload.md @@ -0,0 +1,58 @@ +# On Airdrop Download + +## Déclencheur + +(voir [registerApp.sh](../registerApp.sh)) + +1. Créer une application Automator manuellement et la dupliquer par script + 1. Ouvre Automator (/Applications/Automator). + 2. Crée un nouveau document de type Application. + 3. Ajoute une action Exécuter un script shell et colle : + `echo hello world` + 4. Enregistre l'application sous /Applications/HelloWorldTemplate.app. + ![automator HelloWorldTemplate.app](./01.createEchoHelloWorldTemplateApp.png) +2. Dupliquer l'application +```sh +#!/bin/bash + +# Chemin de l'application template +TEMPLATE_APP="/Applications/HelloWorldTemplate.app" +# Chemin de la nouvelle application +NEW_APP="/Applications/HelloWorld.app" + +# Supprime l'ancienne application si elle existe +rm -rf "$NEW_APP" + +# Duplique l'application template +cp -R "$TEMPLATE_APP" "$NEW_APP" + +# (Optionnel) Modifie le script shell dans l'application si nécessaire +# Par exemple, pour remplacer le chemin du script : +sed -i '' "s|echo hello world|/chemin/vers/ton/script.sh|g" "$NEW_APP/Contents/document.wflow" +``` + +3. Donner les permissions Full Disk Access +Après avoir dupliqué l'application, tu dois ajouter manuellement HelloWorld.app dans Préférences Système > Sécurité et confidentialité > Confidentialité > Accès complet au disque. + +4. Mettre à jour le fichier .plist +Modifie ton fichier com.user.HelloWorld.plist pour qu'il lance la nouvelle application : +```xml +ProgramArguments + + open + /Applications/HelloWorld.app + +``` +5. Recharger le service launchd +```sh +launchctl unload ~/Library/LaunchAgents/com.user.HelloWorld.plist +launchctl load ~/Library/LaunchAgents/com.user.HelloWorld.plist +launchctl start com.user.HelloWorld +``` + +### Changer l'icone de l'app (bonus) + +```sh +sips -s format icns icone.jpeg --out /tmp/monIcone.icns +mv /tmp/monIcone.icns "$NEW_APP/Contents/Resources/ApplicationStub.icns" +``` diff --git a/doc/01.createEchoHelloWorldTemplateApp.png b/doc/01.createEchoHelloWorldTemplateApp.png new file mode 100644 index 0000000..76ee6f3 Binary files /dev/null and b/doc/01.createEchoHelloWorldTemplateApp.png differ diff --git a/trigger/com.user.template.plist b/trigger/com.user.template.plist new file mode 100644 index 0000000..0ff25dc --- /dev/null +++ b/trigger/com.user.template.plist @@ -0,0 +1,25 @@ + + + + + Label + template_label + + UserName + template_username + + ProgramArguments + + open + template_app_path + + + WatchPaths + + template_disk_path + + + + + diff --git a/trigger/icone.png b/trigger/icone.png new file mode 100644 index 0000000..f141de8 Binary files /dev/null and b/trigger/icone.png differ diff --git a/trigger/onAirdropDownload.sh b/trigger/onAirdropDownload.sh new file mode 100755 index 0000000..7a97ab4 --- /dev/null +++ b/trigger/onAirdropDownload.sh @@ -0,0 +1,18 @@ +#! /bin/bash +set -eux +date +echo `date` >> /tmp/heho +find ${HOME}/Downloads +mkdir -p ${HOME}/Documents/.DanceVideos +find ${HOME}/Documents/.DanceVideos + +DLDIR=${HOME}/Downloads + +DESTDIR=${HOME}/Documents/.DanceVideos + +DL_VIDEOS=`find $DLDIR -type f -iname "*.mp4" -or -iname "*.mov" -maxdepth 1` +[ -z "$DL_VIDEOS" ] || { +for v in "$DL_VIDEOS"; do + echo `basename "$v"` >> /tmp/foo +done +} \ No newline at end of file diff --git a/trigger/onSD_DANSEMount.sh b/trigger/onSD_DANSEMount.sh new file mode 100755 index 0000000..dcb6e12 --- /dev/null +++ b/trigger/onSD_DANSEMount.sh @@ -0,0 +1,7 @@ +#! /bin/bash +set -eux +if [ -d '/Volumes/SD_DANSE/' ]; then +echo "`date` mounted SD Dance" >> /tmp/foo +else +echo "`date` unmounted SD Dance" >> /tmp/foo +fi \ No newline at end of file diff --git a/trigger/registerApp.sh b/trigger/registerApp.sh new file mode 100755 index 0000000..8231ab8 --- /dev/null +++ b/trigger/registerApp.sh @@ -0,0 +1,47 @@ +#!/bin/bash +set -eux +SCRIPTS_DIR=$(dirname `realpath ${BASH_SOURCE[0]}`) + +# Arguments +SCRIPT=${1:-onAirdropDownload.sh} +if [ "$SCRIPT" = `basename $SCRIPT` ]; then + SCRIPT="${SCRIPTS_DIR}/${SCRIPT}" +fi + +DISK_PATH_TO_WATCH=${2:-${HOME}/Downloads} + +# create App + +APP_NAME=`basename $SCRIPT | sed 's#\..*$##' | awk '{print toupper(substr($0,1,1)) substr($0,2)}'` +TEMPLATE_APP="/Applications/HelloWorldTemplate.app" +NEW_APP="/Applications/DanceVideos${APP_NAME}.app" +rm -rf "$NEW_APP" +cp -R "$TEMPLATE_APP" "$NEW_APP" +sed -i '' "s|echo hello world|bash ${SCRIPT}|g" "$NEW_APP/Contents/document.wflow" + +sips -s format icns ${SCRIPTS_DIR}/icone.png --out /tmp/monIcone.icns +mv /tmp/monIcone.icns "$NEW_APP/Contents/Resources/ApplicationStub.icns" + +# register trigger + +PLIST_label=`tr '[:upper:]' '[:lower:]' <<< "com.user.watch_${APP_NAME}"` +PLIST_TEMPLATE_username=${USER} +PLIST_TEMPLATE_app_path=${NEW_APP} +PLIST_TEMPLATE_disk_path=${DISK_PATH_TO_WATCH} + +PLIST_FILEPATH="${HOME}/Library/LaunchAgents/${PLIST_label}.plist" + +launchctl unload "${PLIST_FILEPATH}" | : + +touch ${PLIST_FILEPATH} + +cat ${SCRIPTS_DIR}/com.user.template.plist \ + | sed "s#template_label#${PLIST_label}#" \ + | sed "s#template_username#${PLIST_TEMPLATE_username}#" \ + | sed "s#template_app_path#${PLIST_TEMPLATE_app_path}#" \ + | sed "s#template_disk_path#${PLIST_TEMPLATE_disk_path}#" \ +> "${PLIST_FILEPATH}" + +launchctl load "${PLIST_FILEPATH}" +# launchctl list | grep watch_ +launchctl start ${PLIST_label} \ No newline at end of file diff --git a/trigger/trigger.sh b/trigger/trigger.sh new file mode 100755 index 0000000..e54f3b1 --- /dev/null +++ b/trigger/trigger.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -eux +SCRIPTS_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" +default_disk_path="${HOME}/Downloads" + +for script in "$SCRIPTS_DIR"/on*.sh; do + [ -f "$script" ] || continue + script_name="$(basename "$script")" + + case "$script_name" in + onSD_DANSEMount.sh) disk_path="/Volumes/SD_DANSE" ;; + *) disk_path="$default_disk_path" ;; + esac + + "$SCRIPTS_DIR/registerApp.sh" "$script" "$disk_path" +done