Ma règle pour protéger les documents que je partage

Lorsque vous partagez vos photos en ligne, vous transférez des informations à un tiers mais ne maitrisez pas ce qu’il en adviendra, et ce pour toute la durée de la vie du document partagé. Que ce soit sur les réseaux sociaux, votre site web ou encore les sites du gouvernement, il est crucial de prendre des mesures pour protéger votre travail ou votre identité contre une utilisation non autorisée.

C’est là qu’intervient le watermarking.

Pourquoi avez-vous besoin d’un watermark ?

Les watermarks sont des superpositions de texte ou d’images discrètes ajoutées à vos photos pour indiquer leur propriété. Voici quelques raisons pour lesquelles vous pourriez vouloir utiliser un watermark :

  1. Protection du droit d’auteur : En apposant un watermark sur vos images, vous indiquez clairement que vous êtes le propriétaire légitime de ces œuvres. Cela dissuade les utilisateurs malveillants de les utiliser sans votre autorisation.
  2. Promotion de la marque : Un watermark bien conçu peut également servir de moyen de promotion pour votre marque ou votre entreprise. En ajoutant votre logo ou votre nom à vos images, vous augmentez la visibilité de votre marque chaque fois que vos photos sont partagées.
  3. Identification facile : En cas de vol ou d’utilisation non autorisée de vos images, un watermark peut faciliter l’identification de l’origine de la photo. Cela peut être particulièrement utile si vous devez prendre des mesures légales pour protéger vos droits.

Comment utiliser notre outil de watermark ?

Notre outil de watermark est conçu pour être simple et intuitif à utiliser. Voici les étapes à suivre :

  1. Accédez à ma page de watermark en ligne .
  2. Sélectionnez l’image que vous souhaitez protéger. Vous pouvez télécharger une image depuis votre ordinateur ou utiliser une URL si l’image est déjà en ligne.
  3. Personnalisez votre watermark. Vous pouvez choisir d’ajouter du texte, comme votre nom ou le nom de votre entreprise ou la date du jour.
  4. Validez et téléchargez l’image protégée. Une fois effectué, récupérez l’image avec le watermark et la télécharger sur votre ordinateur.

En suivant ces étapes simples, vous pouvez rapidement et efficacement protéger vos images en ligne avec un watermark personnalisé. N’hésitez pas à utiliser cet outil chaque fois que vous partagez des photos en ligne pour assurer la sécurité et la reconnaissance de votre travail créatif.

Fonction de nommage !
Ma règle de nommage pour -tous- mes fichiers

Lorsqu’il s’agit de gérer efficacement nos fichiers, qu’il s’agisse de documents importants, de photos précieuses ou de tout autre type de contenu numérique, il est essentiel d’avoir une méthode organisée et cohérente. Une approche que j’ai adoptée et qui a considérablement simplifié ma vie numérique est l’utilisation d’un préfixe de nom de fichier.

Qu’est-ce que la méthode yyyymmdd ?

Le concept est simple : chaque fois que vous créez ou renommez un fichier, commencez par ajouter la date au format yyyymmdd en préfixe au nom du fichier. Ici, « yyyy » représente l’année en quatre chiffres, « mm » le mois et « dd » le jour. Je ne rajoute pas de points entre les jours et les mois, pour réduire la taille du nom de fichier à l’essentiel; par contre, les espaces créant parfois des incompatibilités j’ajoute un ‘tiret du bas’ ou ‘underscore’ entre le préfixe et le nom du fichier, par soucis de lisibilité. Bref, par exemple, si aujourd’hui est le 14 février 2024, le préfixe serait « 20240214_ ». C’est encore plus logique quand on regarde les fichiers issus des appareils photo, qui suivent la même norme !

J’ajoute ensuite le thème du fichier, l’organisme qui à émis le document, que ça soit une facture, une quittance, voire un emplacement; Tout détail me permettant de retrouver facilement le document juste à parti du nom !

Fonction de nommage !
Fonction de nommage !

Les avantages de cette méthode sont multiples :

  1. Facilité de recherche : En commençant par la date, vos fichiers sont automatiquement triés chronologiquement. Cela signifie que vous pouvez rapidement retrouver un fichier en vous souvenant simplement de la date à laquelle il a été créé ou modifié.
  2. Organisation cohérente : Avec cette méthode, tous vos fichiers sont nommés de la même manière, ce qui rend la gestion globale de votre système de fichiers beaucoup plus fluide et intuitive. D’un simple coup d’œil, on peut aussi deviner le contenu du fichier et son âge !
  3. Évitement des doublons : En ajoutant la date au nom du fichier, vous réduisez considérablement le risque de créer des doublons. Chaque fichier a un nom unique dès sa création, ce qui facilite la distinction entre différentes versions ou variantes du même document.
  4. Compatibilité mondiale : Finalement, c’est un peu international. En Europe on est plus dd.mm.yyyy pour Jour.Mois.Année. Aux Etat Unis, c’est davantage mm.dd.yyyy, ce qui déroute. En utilisant yyyymmdd, on obtient quelque chose de logique et, peu importe l’emplacement ou vous vous trouvez, dans le monde, le système fonctionnera de la même façon… !

Comment appliquer cette méthode à votre propre système de fichiers ?

  1. Soyez consistant : Assurez-vous d’appliquer cette méthode de manière cohérente à tous vos fichiers. Cela inclut non seulement les documents sur votre ordinateur, mais aussi les photos, les vidéos et tout autre type de contenu numérique.
  2. Automatisez si possible : Si vous utilisez un logiciel de gestion de fichiers ou de photos, recherchez des options permettant d’automatiser le processus de nommage des fichiers. Cela vous fera gagner du temps et garantira une application uniforme de la méthode yyyymmdd_.
  3. Restez flexible : Bien que la méthode yyyymmdd_ soit extrêmement utile, il peut y avoir des cas où vous préférez un autre système de nommage. L’essentiel est de trouver ce qui fonctionne le mieux pour vous et de rester fidèle à cette approche.

En adoptant la méthode yyyymmdd_ pour la gestion de vos fichiers, vous simplifierez grandement votre vie numérique. Plus de temps perdu à chercher des documents égarés ou à essayer de démêler un système de fichiers désorganisé. Essayez-le dès aujourd’hui et découvrez à quel point il peut être facile de rester organisé dans un monde numérique en constante évolution.

Inbox Zero
Ma règle « 0 inbox » (Gestion de boite e-mail)
Inbox Zero
Inbox Zero

L’idée principale derrière la Politique ‘0 Inbox‘ ou ‘Inbox Zero‘ est d’améliorer l’efficacité de la gestion des courriels, en évitant l’encombrement et en s’assurant que chaque message est traité de manière opportune. C’est une des règles utilisées par la méthode ‘GTD’ pour ‘Getting Things Done’.

Sur la partie messagerie du coup, il convient de faire un tri régulier des e-mails, pour effectuer une réponse rapide aux messages importants, et effectuer un classement des e-mails dans des dossiers appropriés, tout en supprimant les courriels inutiles.

Ma notion de ‘Inbox Zero‘ est associée à cette approche de gestion des e-mails visant à maintenir ma boîte de réception vide ou proche de zéro. Ce qui y réside est ce qu’li me reste à faire. Cela signifie que ans ma routine quotidienne, j’organise chaque courriel reçu, de manière à ne laisser aucun message non traité dans ma boîte de réception.

Cela ne veut pas dire que je suis en permanence dans ma boite mail mais par contre, ce qui est fait est marqué en lu, et ce qui reste à faire, que je ne peux gérer en instantané est souvent lu mais tant que non traité, non répondu, est de nouveau marqué en ‘non lu‘ voire, ajouté à un filtre ‘important‘ ou ‘à suivre‘.

Il m’arrive de repousser une tache, et du coup garder ce mail dans ma boite de réception. Parfois, cette procrastination pousse à reconsidérer ce mail et parfois à le supprimer… oui.. ça arrive 😀

Cela fait plus de 15 ans que j’utilise cette technique tant au niveau personnel que professionnel et cette méthode me permet de pouvoir correctement suivre mes courriels mais aussi visualiser les messages et parfois actions, en attente de réponse !

Image Sonos
Envoyer du son sur Sonos via Crontab

Posséder des enceintes connectées et une domotique, c’est avoir la possibilité d’automatiser des annonces.

Image Sonos
Image Sonos

Au quotidien, il y a des choses que nous ne voulons pas rater, et je vais parler pour un exemple bête, du jour ou il faut sortir les poubelles pour que le camion les récupère. Chez moi, c’est le lundi soir pour une levée le mardi matin.

Le lien avec la domotique, l’automatisation : quoi qu’il se passe dans ma journée, le soir, une annonce sera diffusée dans la maison et ce grâce à python et au module « soco-cli »

Les pré requis, du moins dans ma version : une enceinte sonos et un actionneur domotique (j’utilise une tache Cron) , voici la préparation du puzzle :

A- Installer les outils sonos et trouver la commande

sudo apt-get update
sudo apt-get install -y pip
sudo -H pip install -U soco-cli 

B- Créer les sons et les tester

À défaut d’avoir un mp3 qui vous plaise, vous pouvez créer un son vous même avec une voix de synthèse. Pour cela, utilisons la commande espeak : (qui peut etre installée via « apt-get install espeak »)

espeak -v fr "les enfants, il faut mettre le couvert !" --stdout | ffmpeg -y -i - -acodec libmp3lame mettrelecouvert.mp3

Pour jouer ce mp3, il faut une enceinte, alors exécutez la commande « sonos-discover » pour lister les enceintes du réseau local. Un beau tableau avec le nom, l’adresse IP, le modèle apparaîtra..

Ensuite, par exemple, pour envoyer le fichier mettrelecouvert.mp3 sur l’enceinte Bureau :

sonos Bureau play_file mettrelecouvert.mp3

Il existe plein d’options, pour ajouter une temporisation, grouper ou séparer des enceintes, gérer le volume.. par exemple pour grouper, gérer le volume, lancer un mp3, les re-séparer et remettre un volume acceptable (j’ai ajouté une pause d’une seconde à chaque fois pour les délais liés aux commandes) :

sonos Cuisine if_stopped party_mode : wait 1s : _all_ volume 45 : wait 1s : Cuisine if_stopped play_file ilest20h30.mp3 : wait 1s : _all_ volume  15 : wait 1s : Parent ungroup : wait 1s : Chambre ungroup

Lister les favoris et jouer le premier :
sonos Cuisine list_favourite
sonos Cuisine play_favourite 1

C- Ajouter les taches dans Cron

Pour la v1 de mon installation, j’utilisais intégralement Cron, comme ce ci :

# Sonos Crontab pour rappel - sortir les poubelles -
## Le lundi soir 20h05 et 20h30
0,25 20 * * 1  /usr/local/bin/sonos Kitchen play_file  /home/pi/firewalla/config/ilfautsortirlapoubelle.mp3 

A titre d’information, voici les autres entrée ..

## Programme du matin en semaine
0 7 * * 1-5  sonos Kitchen if_stopped play_file ilest7hBonjour.mp3
0 8 * * 1-5  sonos Kitchen play_file ilest8h.mp3
## Programme du soir en semaine
30 18 * * 1-5  sonos Kitchen play_file ilest18h20.mp3 
0 19 * * 1-5  sonos Kitchen play_file mettrelatable.mp3
## Programme du weekend
0 19 * * 6,0  sonos Kitchen play_file ilest19h.mp3 
30 20 * * *    sonos Kitchen play_file ilest20h30.mp3 
45 11 * * 6,0  sonos Kitchen 

J’ai vite rencontré des limites car sur mon système, la Crontab est chargée au démarrage et nést ensuite, pas modifiable. Pour la prendre en compte, il basiquement, redémarrer le PC pour qu’elle soit actualisée.

J’ai donc décidé de lancer une commande bash chaque 10 minutes, ce bash va lui vérifier l’heure et effectuer la tache souhaitée. Voici la tache Cron

*/10 * * * *    /home/pi/sonos.sh  > /dev/null

Et le fichier sonos.sh :

#!/bin/bash
# Programme du matin en semaine

alias sbd="sonos Cuisine : 'living room' group Cuisine : wait 1s : Cheminee group Cuisine : wait 1s : Bureau group Cuisine"
alias bye="sonos Cuisine if_stopped volume 10 : wait 1s : Bureau if_stopped ungroup : wait 1s : Chambre if_stopped ungroup"

#Set default configuration
sonos 'living room' group Cuisine : wait 1s : Cheminee group Cuisine 

if [[ $(date +%u) -le 5 ]]; then
    if [[ $(date +%H%M) -eq 700 ]]; then
        sonos Cuisine play_file ilest7hBonjour.mp3
    elif [[ $(date +%H%M) -eq 800 ]]; then
		sonos Cuisine 31 : Cuisine play_file ilest8h.mp3
    fi
fi

# Programme de tous les midis & soirs
if [[ $(date +%H%M) -eq 1150 ]]; then
	sonos Bureau group Cuisine
	sonos Cuisine if_stopped volume 40 : Cuisine if_stopped play_file mettrelatable.mp3
elif [[ $(date +%H%M) -eq 2030 ]]; then
	sonos Cuisine if_stopped volume 31 : Cuisine if_stopped play_file ilest20h30.mp3
fi

# Programme du weekend
#if [[ $(date +%u) -eq 6 || $(date +%u) -eq 7 ]]; then
    #if [[ $(date +%H%M) -eq 1145 ]]; then
    #fi
#fi

# Le lundi soir 19h10 et 19h20 et 20h10 et 20h20
if [[ $(date +%u) -eq 1 ]]; then
    if [[ $(date +%H%M) -eq 1940 || $(date +%H%M) -eq 2010 || $(date +%H%M) -eq 2020 ]]; then
		sonos Cuisine if_stopped volume 12 : Cuisine if_stopped play_file ilfautsortirlapoubelle.mp3
    fi
fi
#Reset default configuration
sonos Cuisine if_stopped volume 10 : wait 1s : Bureau if_stopped ungroup : wait 1s : Chambre if_stopped ungroup

C’est déjà pas mal, mais c’est tout.. vous pouvez maintenant il n’y a qu’à profiter 😉

Piloter GRBL à Distance (Ortur Laser Master 3 en WiFi) avec Tibbo Virtual Serial Port Driver (VSPD)

Le but de ce tuto est de connecter votre équipement compatible GRBL en WiFi, puis de le contrôler à distance, via un port Com virtual (redirigé vers l’adresse IP du contrôleur GRBL) dans le cas ou votre logiciel préféré ne le permettrait pas !

Sur le Laser Master 3 et j’imagine les autres périphériques connectés, il y a bien sur une interface Web, qui vous permet de faire le pilotage à distance, mais autant utiliser la technologie sans fil pour éviter de dédier une machine au laser, ou d’exporter le Gcode et le réimporter de l’autre côté ⇒ Nous pourrons piloter intégralement l’équipement à distance et je vais ici parler de mon nouveau Laser Master 3.

À noter que depuis quelques temps, Lightburn permet déjà cette fonctionalité 😉

Tout d’abord, se connecter au laser avec le cable USB, et le configurer pour un acès à distance via les commandes :

$74=mywifissid # Votre point d’accès
$75=mywifipassword # Votre mot de passe
$WRS # Recharger la configuration réseau

Vous devriez, si tout va bien, vous devriez visualiser dans l’interface de commande, la nouvelle adresse IP assignée à votre laser.

Passons maintenant au PC qui sera utilisé à distance et évidement sur le même réseau IP. Téléchargement de Tibbo Virtual Serial Port Driver (VSPD) x64 pour ma part. Installation puis configuration via la création d’un port virtuel en utilisant les paramètres suivants :

Tibbo – Ajout d’un port virtuel – Cliquer sur ‘Elevate‘ puis ‘Add
Propriété du port Com, de l’IP et du port distant
Propriétés du port Com (vitesse 115k)

C’est tout. Merci Tibbo..

Votre équipement GRBL connecté à votre réseau WiFi est maintenant virtuellement connecté à votre PC distant.

Résumé des outils pour piloter GRBL à distance dans la mesure ou il est connecté à un réseau :

  • Site auto hébergé sur Laser Master 3
  • Lightburn (intégré)
  • App Laser Explorer (Android / iOS)
  • Tous les autres logiciels (via port Com virtuel – Tibbo)

Avez-vous trouvé cet article utile ? pertinent ? Je suis preneur de retours 🙂

interrupteur
Timelapse pendant une impression 3D sans Octoprint pour 0 euros !

Amis lecteurs, voici un tutoriel plus technique que les précédents, et il sera ici question de la mise en place d’un outil permettant de faire des timelapse sans y dédier un ordinateur (même si ce n’est qu’un Raspberry Pi) à ce rôle.

De mon coté, j’ai déjà un ordinateur pour effectuer des Timelapse, je me suis donc demandé, comment mutualiser ce besoin sans associer davantage de resources mais surtout comment partager l’état d’avancement si internet est accessible 😉

Info : Le timelapse, c’est une technique permettant la prise de photos à intervalles de temps définies dans l’idée d’en faire un film à effet ‘rapide’. J’ai déjà fait un article dessus ici.

But : Via un script python, via le contact d’un port GPIO, effectuer une capture d’image via l’appareil photo et envoyer des notifications sur l’avancement. Il est important de rentre le Raspberry pi amovible, tout comme la rapidité d’installation, cruciale.

Le temps d’installation / préparation dépendra de vos compétences mais ne devrait pas excéder 10 minutes !

Octoprint via Octolapse fait cela très bien mais demande l’utilisation d’un Raspberry Pi dédié à l’impression. Octoprint permet de gérer l’imprimante à distance, mais, je n’ai pas besoin de tout cela.. et je n’ai qu’un pi zéro dispo de toutes façons, ne permettant pas l’exécution d’Octoprint+Octolapse.

Pré requis :

  • un raspberry Pi avec un OS installé
  • une Pi caméra connectée au Pi
  • une imprimante 3D, Cura comme slicer
  • une paire de cables
  • un fer à souder

1- Imprimante 3D :

Pour de se déplacer dans un volume, toutes les imprimantes 3D sont initialisées via des capteurs de fin (début) de course. C’est douvent un interrupteur, à contact sec définissant l’origine est x=0, y=0, z=0.

Sur ces capteurs, la plupart du temps, il y a 3 bornes, la masse, et contacts NO / NC (normalement ouvert ou normalement fermé).

interrupteur
Exemple d’interrupteur de fin de course

L’imprimante utilise le moment ou la tête d’impression appuie sur l’interrupteur pour s’initialiser. Cela fait un contact entre deux des pattes et le signale (normalement ouvert devient fermé). Pour ce projet de 3dlapse, et initialiser l’ordre de prise de photo, nous allons donc, pour ne pas embetter l’imprimante ni le Pi dans les contacts, utiliser le même interrupteur, mais contact inverse (normalement ouvert, qui envoie un signal quand le contact se défait).

Après avoir testé avec un multimétre quels contacts utiliser, voici la soudure de deux cables sur l’interrupteur de fin de course de X. Utilisant des connecteur Dupont sur le Pi, j’ai laissé une fiche male au bout du cable de chaque coté. C’est tout.

Capteur de fin de course est relié à la carte mère (câbles noirs) et à la camera Timelapse (câbles rouge+noir)

2- Sur le Raspberry Pi :

Voici le script de Timelapse/ 3dlapse. Ce script de 120 lignes, est partagé sur mon Github et je ne vais pas le détailler, étant donné qu’il est déjà extrémement commenté. Si vous y voyez des soucis, je suis preneur de commentaires cependant.

Copier le script Timelapse.py sur le Pi, dans le dossier ‘home’ via l’outil de votre choix (j’utilise FileZilla)

Exécution : Ce script une fois lancé en fonction de l’état du GPIO 27, arbitrairement choisi (borne 13&14), va démarrer en mode Timelapse (photo toutes les 3 secondes) ou 3dlapse (photo lors d’un contact GPIO27)

Bornes GPIO pour Raspberry Pi

Le Raspberry Pi Zero dans sa splandeur :

Pi Zero avec port GPIO 27 pour Timelapse / 3dlapse – Coque sur mesure designée par mes soins !

Lancer et tester pour valider que les dépendances sont présentes (keyboard, requests, socket, RPi.GPIO, gpiozero, Picamera2)

Chaque nouveau lancement crée un nouveau dossier, incrémentalement, dans /home/pi/pictures et y enregistre les clichés, ainsi qu’un fichier de log.

Pour tester chaque option, vous pouvez commuter la borne GPIO27, aussi le lancer avec l’argument « 3d » / « 3dlapse » ou « tl » / « timelapse ».

Exemple : Python3 Timelapse.py 3dlapse

Note: Vous pourrez constater que j’ai utilisé sur ce projet une camera à AutoFocus, et défini sa position en ‘automatique’ pour la partie Timelapse (ligne 99), et focale fixe pour la partie 3dlapse (ligne 102). Dans le cas ou vous souhaiteriez tester le focus à différentes ouvertures, manipulez le script pour utiliser la fonction ‘testFocus’ )

Libre à vous de changer l’ID notify (lignes 28/39/40) si vous souhaitez l’utiliser mais aussi recevoir les photos à chaque centaine, ou les notifications sur l’espace disque restant.

Option : lancer le script automatiquement au démarrage

Faire en sorte que le raspberry pi démarre en mode ligne de commande avec ouverture de session automatique, ajouter en dernière ligne du fichier /home/pi/.bashrc la commande de lancement du script Python « Python3 Timelapse.py »

3- Dernière partie : le Slicer (Cura)

Cura dispose de modules pour modifier les impressions. En l’occurence nous allons installer le module Timelapse, qui permet le staitonnement de la tête à chaque niveau d’impression pendant une durée définie.

  1. Menu Extensions -> Post Processing -> Modifier G-Code
  2. “Ajouter un script”
  3. Selectionner « Time Lapse »

Avant de lancer la création du G-code valider les paramètres du script, voici les miens :

Configuration Cura

Note: Le ‘park print head’ va demander à aller au point donné X/Y, mais comme nous avons utilisé un capteur NC (normallement fermé), il faut décaller la tête d’impression au delà du capteur, et donc, modifier le script de Cura (pour Windows, dans le dossier C:\Program Files\Ultimaker Cura 5.VERSION\share\cura\plugins\PostProcessingPlugin\scripts). Voici ma version modifiée:

  • Le changement est un ajout des lignes 107&108 pour libérer le capteur et attendre que l’opération se finisse.

Pour finir, cet ajout de prise photos, va nécéssairement rajouter du temps d’impression, quelques secondes par niveau, et risque de provoquer du ‘stringing’. Pour contrer cela, il est nécéssaire de comprendre la rétractation 😉

Voilà, une fois que le Pi à trouvé sa place sur l’imprimante, et que le focus à été ajusté correctement, il suffit juste de le brancher et alimenter pour qu’il démarre.. et prenne les photos, alternativement, démarré avec un powerbank en direction d’un coucher de soleil, il pendra tranquillement en photo une fin de journée et ca, un appareil pour deux utilisations, c’est la cerise sur le gâteau !!!

J’espère que cette partie un peu plus technique aura apporté un peu de lumière sur cette solution, portable, pratique et rapide à mettre en place pour immortaliser vos impressions; Dans tous les cas, n’hésitez pas à me contacter pour tout commentaire, ou toute idée !

Développement- Fichiers ICS et Calendrier – Partie 3

Série de 3 articles sur les fichiers ICS : (1) Définition; (2) Création et Partage; (3) Automatisation Excel > Outlook

Partie 3: Créer une Interface entre Excel et Outlook

Mon but : exporter la cellule Excel sélectionnée vers un rendez-vous Outlook pour éviter de devoir rentrer mes rendez-vous en double.

Pré requis :

Exemple de Fichier Excel

Ce fichier Excel contenant un calendrier en mode colonne de mois et lignes de jours.

Ignorez l’anglais car peu importe la langue utilisée nous travaillerons avec les chiffres. Admettons donc :

  • Cellule H1 contenant l’année (2022)
  • Colone L et P – Ligne 1 : mois en chiffre
  • Colone L et P – Lignes 2 à 32 : jour du mois en chiffres
  • Les réunions toujours formattées en utilisant HH:MM Texte (Heure et Minutes sur 2 chiffres)
  • Utilisation : sélectionner cellule M17 > appuyer sur générer > Outlook ouvert avec les champs pré remplis.

Pour effectuer cette action, il faut passer en mode « développeur » sur Excel : Cliquer sur ‘View’ et ‘Macro’ . Voici les macros utilisées.

---- 
Sub Export_ICS_Vers_Outlook()
Dim ICS_str As String
    ICS_str = "BEGIN:VCALENDAR" & vbCrLf
    ICS_str = ICS_str & "VERSION:2.0" & vbCrLf
    ICS_str = ICS_str & "PRODID:-//68600.fr//iCal Event Maker" & vbCrLf
    ICS_str = ICS_str & "CALSCALE:GREGORIAN" & vbCrLf
    ICS_str = ICS_str & "BEGIN:VTIMEZONE" & vbCrLf
    ICS_str = ICS_str & "TZID:Europe/Berlin" & vbCrLf
    ICS_str = ICS_str & "BEGIN:STANDARD" & vbCrLf
    ICS_str = ICS_str & "TZNAME:CET" & vbCrLf
    ICS_str = ICS_str & "TZOFFSETFROM:+0200" & vbCrLf
    ICS_str = ICS_str & "TZOFFSETTO:+0100" & vbCrLf
    ICS_str = ICS_str & "DTSTART:19701025T030000" & vbCrLf
    ICS_str = ICS_str & "RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU" & vbCrLf
    ICS_str = ICS_str & "END:STANDARD" & vbCrLf
    ICS_str = ICS_str & "BEGIN:DAYLIGHT" & vbCrLf
    ICS_str = ICS_str & "TZNAME:CEST" & vbCrLf
    ICS_str = ICS_str & "TZOFFSETFROM:+0100" & vbCrLf
    ICS_str = ICS_str & "TZOFFSETTO:+0200" & vbCrLf
    ICS_str = ICS_str & "DTSTART:19700329T020000" & vbCrLf
    ICS_str = ICS_str & "RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU" & vbCrLf
    ICS_str = ICS_str & "END:DAYLIGHT" & vbCrLf
    ICS_str = ICS_str & "END:VTIMEZONE" & vbCrLf
    ICS_str = ICS_str & "LAST-MODIFIED:20201011T015911Z" & vbCrLf
    ICS_str = ICS_str & "TZURL:http://tzurl.org/zoneinfo-outlook/Europe/Berlin" & vbCrLf
    ICS_str = ICS_str & "X-LIC-LOCATION:Europe/Berlin" & vbCrLf
    ICS_str = ICS_str & "BEGIN:VEVENT" & vbCrLf
    ICS_str = ICS_str & "ATTENDEE;CN=" & """" & "Papa" & """" & ";RSVP=TRUE:mailto:papi@gmail.com" & vbCrLf
    ICS_str = ICS_str & "CLASS:PRIVATE" & vbCrLf
    ICS_str = ICS_str & "CATEGORIES:Important" & vbCrLf
    ICS_str = ICS_str & "DTSTAMP:20220823T131634Z" & vbCrLf
    ICS_str = ICS_str & "UID:'D6D" & Int((100000000 * Rnd) + 1) & "'" & vbCrLf
    ICS_str = ICS_str & "DTSTART;TZID=Europe/Berlin:MyDateStart" & vbCrLf
    ICS_str = ICS_str & "DTEND;TZID=Europe/Berlin:MyDateEnd" & vbCrLf
    ICS_str = ICS_str & "SUMMARY;LANGUAGE=en-us:MyTitle" & vbCrLf
    ICS_str = ICS_str & "DESCRIPTION:MyDescription" & vbCrLf
    ICS_str = ICS_str & "LOCATION:MyLocation" & vbCrLf
    ICS_str = ICS_str & "TRANSP:OPAQUE" & vbCrLf
    ICS_str = ICS_str & "X-MICROSOFT-CDO-BUSYSTATUS:FREE" & vbCrLf
    ICS_str = ICS_str & "BEGIN:VALARM" & vbCrLf
    ICS_str = ICS_str & "ACTION:DISPLAY" & vbCrLf
    ICS_str = ICS_str & "DESCRIPTION:Reminder" & vbCrLf
    ICS_str = ICS_str & "TRIGGER:-PT15M" & vbCrLf
    ICS_str = ICS_str & "END:VALARM" & vbCrLf
    ICS_str = ICS_str & "END:VEVENT" & vbCrLf
    ICS_str = ICS_str & "END:VCALENDAR" & vbCrLf

'MsgBox ICS_str

MyRow = ActiveCell.Row
MyCol = ActiveCell.Column
MeetDay = 0
MeetMonth = 1
MeetTime = 18                                           'Default Meeting Time
MeetText = ActiveCell.Value                             'Default Meeting Text
If (Len(ActiveCell.Value) > 2) Then                      'If more than  digits then we run the rest
    If (Left(ActiveCell.Value, 2) < 24) Then                'If 2 digits then it is a valid info for time
        MeetTime = Left(MeetText, 2)                        'Extract new Meeting Time
        MeetText = Right(MeetText, Len(MeetText) - 3)       'Extract new Meeting Text
        If (Left(MeetText, 2) < 60) Then
            MeetTime = MeetTime & Left(MeetText, 2)
            MeetText = Right(MeetText, Len(MeetText) - 3)
        End If
        If Len(MeetTime > 3) Then
            MeetTime = MeetTime & "00"
        Else
            MeetTime = MeetTime & "0000"
        End If
        
    End If
    'MsgBox (MeetTime)
    If Len(MeetTime < 3) Then MeetTime = MeetTime & "00"    'Complement to have Time on 6 digits (HHMMSS)
    ActiveCell.Offset(0, -1).Select                         'Select Day date in left column
    While MeetDay = 0
     If (ActiveCell.Value > 0 And ActiveCell.Value < 32) Then
       MeetDay = ActiveCell.Value
      Else
       ActiveCell.Offset(0, -1).Select                      'Else Select Day date in one more left column
        If (ActiveCell.Value > 0 And ActiveCell.Value < 32) Then
            MeetDay = ActiveCell.Value
        End If
        'MsgBox ActiveCell.Value & " " & ActiveCell.Row & " " & ActiveCell.Column
      End If
      If (MeetDay < 10) Then MeetDay = "0" & MeetDay
    Wend
    
    ActiveCell.Offset((1 - ActiveCell.Row), 0).Select       'Select Month date in top row same column
    MeetMonth = ActiveCell.Value
    If (MeetMonth < 10) Then MeetMonth = "0" & MeetMonth
    
    Range("J1").Select                                      'Select Year date in top row same column
    MeetYear = ActiveCell.Value
    
    ICS_str = Replace(ICS_str, "MyDescription", MeetText)
    ICS_str = Replace(ICS_str, "MyTitle", MeetText)
    ICS_str = Replace(ICS_str, "MyLocation", "Volgelsheim")
    '20221006T100000
    ICS_str = Replace(ICS_str, "MyDateStart", MeetYear & MeetMonth & MeetDay & "T" & MeetTime & "00")
    ICS_str = Replace(ICS_str, "MyDateEnd", MeetYear & MeetMonth & MeetDay & "T" & MeetTime & "10")
    
    Range(Cells(MyRow, MyCol), Cells(MyRow, MyCol)).Select
    
    ICS_Filename = MeetYear & MeetMonth & MeetDay & "_" & Replace(MeetText, " ", "_") & ".ics"
    lg = Ecrire_Txt(ActiveWorkbook.Path & "\" & ICS_Filename, ICS_str)
    
    Call convertTxttoUTF(ActiveWorkbook.Path & "\" & ICS_Filename, ActiveWorkbook.Path & "\" & "UTF" & ICS_Filename)
    
      'MsgBox "Export vers .ics = Ok"
    If lg = 0 Then Shell ("C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE" & " /ical " & ActiveWorkbook.Path & "\" & "UTF" & ICS_Filename)
    '/ical <icsfilename>
    
   End If
End Sub

Enregister la macro, repartir sur une cellule du tableau Excel et essayer.
Note : Le fichier ICS et fichier ICS format UTF seront sauvegardés dans le meme dossier que fichier Excel utilisé.
Note 2: La durée n’étant pas spécifiée dans le calendrier Excel, la réunion aura une durée d’une seconde; c’est arbitraire et il me suffit de changer cela dans Outlook quand tout le reste sera déjà en place !

Étape finale, ajouter un moyen de lancement facile (plutot que naviguer dans les menus) : ajouter un bouton :

  1. Passez en mode développeur
    • Sous l’onglet Fichier , accédez à Options Personnaliser le ruban.
    • Sous Personnaliser le ruban et Onglets principaux, activez la case à cocher Développeur.
  2. Sélectionnez le menu développeur, insérer > bouton
  3. Dessinez la taille et position du bouton (un gros rectangle )
  4. Définissez la macro « Export_ICS_Vers_Outlook »qui lui sera affecté.
Insertion d’un bouton (étape 3)

Bilan

Comme pour la version HTML ou plutot PHP, j’ai adapté les champs à mon besoin, réunion privée, en mode important, avec rappel et qui ne bloque pas mon calendrier, envoi de l’invitation par courriel à un contact.

Cela conclue cette aventure un peu poilue dans le monde des fichier iCalendar, totalement hors sujet de D6D mais tout de même proche de l’automatisation 😉

Développement- Fichiers ICS et Calendrier – Partie 2

Série de 3 articles sur les fichiers ICS : (1) Définition; (2) Création et Partage; (3) Automatisation Excel > Outlook

Partie 2: Création et partage

Il y a des évènements qui sont importants et pour les garder en mémoire, ou plutôt dans la mémoire de nos assistants numériques, il faut cliquer sur ‘nouveau rendez-vous’ choisir une date de début, de fin, un texte, cliquer, cliquer et encore cliquer. J’ai tellement de paramètres à définir que cela me fatigue, mais aussi qu’il faut parfois partager sans pour autant l’entrer dans mon calendrier. Voici donc le générateur ICS

Simple page PHP, qui demande du texte par ligne, bien entendu formaté correctement, et génère en sortie un fichier ICS automatiquement poussé sur le navigateur client.

Fonctionnement simple, basique dont voilà la source :

<?php
 
setlocale(LC_TIME, 'fr_FR'); //setlocale (LC_TIME, 'fr_FR.utf8','fra'); 

 function test_input($data) {
	 // nettoyer le texte qui sera envoyé
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}

 date_default_timezone_set('Europe/Paris');
 if (!isset($_POST['date_start'])) {  ?> 
// si le formulaire est vierge.. alors continue
 <!doctype html>
 <html lang="fr">

 <head>
 <meta http-equiv="content-type" content="text/html; charset=utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 <title>Générateur de fichiers ICS</title>
 <link rel="icon" type="image/x-icon" href="favicon.png">
 </head>
 <body>
 <link rel="stylesheet" href="style.css" />
  <h1>Générateur de fichiers ICS<br> <?
    echo '<form method="post">';
 	echo '<h2>Complétez les champs puis validez<h2>';
	echo "<input class='form-control' type='text' placeholder='".ucfirst(utf8_encode(strftime('%A %d %B %Y, %H:%M'))) ."' readonly>"; 
	echo 'Titre - objet du rendez vous<input type=text id="invalidCheck" required class="form-control" name=titre value="titre">';
	echo 'Début - format Année Mois Jour "T" Heure Minute<input type="text" id="invalidCheck" required class="form-control" name="date_start" value="20221006T100000">';
	echo 'Fin - format Année Mois Jour "T" Heure Minute<input type="text" id="invalidCheck" required class="form-control" name="date_end" value="20221006T110000">';
	echo 'Description - détails sur le rendez-vous<input type="text" id="invalidCheck" class="form-control" name="description" value="description longue">';
	echo 'Emplacement - adresse complète <input type="text" id="invalidCheck" class="form-control" name="emplacement" value="adresse ou lien">';
	echo 'Privé - détails invisibles par les personnes ayant délégation sur votre calendrier <input type="checkbox" id="invalidCheck" class="form-control" name="privat">';
	echo 'Important - rendez vous marqué comme tel <input type="checkbox" id="invalidCheck" class="form-control" name="important">';
?>

 <div class="col-12">  <button class="btn btn-primary" type="submit">Générer</button>  </div>
 </form>
 </body>
</html>
<?php 
}else{
// si le formulaire n'est par vierge.. alors crée le fichier ICS
    $_POST[titre]=test_input($_POST[titre]);
    $_POST[date_start]=test_input($_POST[date_start]);
    $_POST[date_end]=test_input($_POST[date_end]);
    $_POST[emplacement]=test_input($_POST[emplacement]);
    $_POST[description]=test_input($_POST[description]);
    $ics_props =  'BEGIN:VCALENDAR'."\r\n";
    $ics_props .= 'VERSION:2.0'."\r\n";
    $ics_props .= 'PRODID:-//68600.fr//iCal Event Maker'."\r\n";
    $ics_props .= 'CALSCALE:GREGORIAN'."\r\n";
    $ics_props .= 'BEGIN:VTIMEZONE'."\r\n";
    $ics_props .= 'TZID:Europe/Berlin'."\r\n";
    $ics_props .= 'BEGIN:STANDARD'."\r\n";
    $ics_props .= 'TZNAME:CET'."\r\n";
    $ics_props .= 'TZOFFSETFROM:+0200'."\r\n";
    $ics_props .= 'TZOFFSETTO:+0100'."\r\n";
    $ics_props .= 'DTSTART:19701025T030000'."\r\n";
    $ics_props .= 'RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU'."\r\n";
    $ics_props .= 'END:STANDARD'."\r\n";
    $ics_props .= 'BEGIN:DAYLIGHT'."\r\n";
    $ics_props .= 'TZNAME:CEST'."\r\n";
    $ics_props .= 'TZOFFSETFROM:+0100'."\r\n";
    $ics_props .= 'TZOFFSETTO:+0200'."\r\n";
    $ics_props .= 'DTSTART:19700329T020000'."\r\n";
    $ics_props .= 'RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU'."\r\n";
    $ics_props .= 'END:DAYLIGHT'."\r\n";
    $ics_props .= 'END:VTIMEZONE'."\r\n";
    $ics_props .= 'LAST-MODIFIED:20201011T015911Z'."\r\n";
    $ics_props .= 'TZURL:http://tzurl.org/zoneinfo-outlook/Europe/Berlin'."\r\n";
    $ics_props .= 'X-LIC-LOCATION:Europe/Berlin'."\r\n";
    $ics_props .= 'BEGIN:VEVENT'."\r\n";
	if (isset($_POST[privat]))     { $ics_props .= 'CLASS:PRIVATE'."\r\n";}
	if (isset($_POST[important]))  { $ics_props .= 'CATEGORIES:Important'."\r\n";}
	$ics_props .= 'DTSTAMP:20220823T131634Z'."\r\n";
    $ics_props .= 'UID:'.uniqid()."\r\n";
    $ics_props .= 'DTSTART;TZID=Europe/Berlin:'.$_POST[date_start]."\r\n";
    $ics_props .= 'DTEND;TZID=Europe/Berlin:'.$_POST[date_end]."\r\n";
    $ics_props .= 'SUMMARY:'.$_POST[titre]."\r\n";
    $ics_props .= 'DESCRIPTION:'.$_POST[description]."\r\n";
    $ics_props .= 'LOCATION:'.$_POST[emplacement]."\r\n";
    $ics_props .= 'TRANSP:OPAQUE'."\r\n";
    $ics_props .= 'X-MICROSOFT-CDO-BUSYSTATUS:BUSY'."\r\n";
    $ics_props .= 'BEGIN:VALARM'."\r\n";
    $ics_props .= 'ACTION:DISPLAY'."\r\n";
    $ics_props .= 'DESCRIPTION:Reminder'."\r\n";
    $ics_props .= 'TRIGGER:-PT15M'."\r\n";
    $ics_props .= 'END:VALARM'."\r\n";
    $ics_props .= 'END:VEVENT'."\r\n";
    $ics_props .= 'END:VCALENDAR'."\r\n";
// créee le fichier
    $uniqueFileName = uniqid(mt_rand(), true) . '.ics';

// affiche le fichier ICS et force le navigateur à le télécharger

    header('Content-type: text/calendar; charset=utf-8');
    header("Content-Disposition: attachment; filename=".$uniqueFileName);
    echo $ics_props;	
}

?> 

Si tout va bien, vous devriez pouvoir générer vos fichiers rdv et les partager !

Mais cela n’est pas tout : ceux qui me connaissent savent que je ne jure que par Excel. C’est mon outil de prédilection. Voyons comment utiliser Excel comme source > Suite Partie 3

Développement- Fichiers ICS et Calendrier – Partie 1

Série de 3 articles sur les fichiers ICS : (1) Définition; (2) Création et Partage; (3) Automatisation Excel > Outlook

Partie 1 : Définition

Qu’est-ce qu’un fichier ICS ? 

Un fichier ICS est un fichier iCalendar. Ce sont des fichiers en texte brut qui incluent des détails d’événement de calendrier comme une description, les heures de début et de fin, l’emplacement, etc. Le format ICS est généralement utilisé pour envoyer des demandes de réunion à des personnes, mais également un moyen populaire pour s’abonner à des calendriers de vacances ou d’anniversaire. Ces fichiers sont utilisés et échangés entre les applications de calendrier et courriels tels que

  • Microsoft Outlook,
  • Mozilla Thunderbird,
  • Le calendrier Apple,
  • Le calendrier Google,
  • … plein d’autres …

En résumé, quand quelqu’un vous envoie une réunion par courriel, il est fort à parier que ce courriel contient un fichier ICS.

Le type MIME utilisé par les données d’iCalendar est « text/calendar » et son format normé les arguments définis. Il est architecturé en blocs de paramètres. Vous trouverez sur cette page des détails techniques;

Voici le squelette du fichier:

BEGIN:VCALENDAR
   BEGIN:VTIMEZONE
      BEGIN:STANDARD
      END:STANDARD
      BEGIN:DAYLIGHT
      END:DAYLIGHT
   END:VTIMEZONE
   BEGIN:VEVENT
      BEGIN:VALARM
      END:VALARM 
   END:VEVENT
END:VCALENDAR

Tous ces champs ne sont pas nécessaires ! Il faut retenir que le langage est formé de blocs déclarés par « BEGIN » et « END » ainsi que des paramètres entre chacun. Pour les dates, plusieurs formats sont acceptés, ainsi, certaines balises seront nécessaires uniquement sur l’utilisation d’un format donné. Pour ma part j’ai choisi le format 2022126T18250000 et la déclaration de changement d’heure. Chacun verra son opportunité !

Pour aller plus loin, voici un fichier type :

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//68600.fr//D6D//ics/ Event Maker
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:Europe/Berlin
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE
LAST-MODIFIED:20201011T015911Z
TZURL:http://tzurl.org/zoneinfo-outlook/Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:VEVENT
ATTENDEE;CN="Papa";RSVP=TRUE:mailto:pipo@gmail.com
CLASS:PRIVATE
CATEGORIES:Important
DTSTAMP:20220823T131634Z
UID:'D6D30194802'
DTSTART;TZID=Europe/Berlin:2022126T18150000
DTEND;TZID=Europe/Berlin:2022126T18250000
SUMMARY;LANGUAGE=en-us:Réunion
DESCRIPTION:Réunion
LOCATION:Collège 
TRANSP:OPAQUE
X-MICROSOFT-CDO-BUSYSTATUS:FREE
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:Reminder
TRIGGER:-PT15M
END:VALARM
END:VEVENT
END:VCALENDAR

Ici, on peut voir une invitation pour un évènement le 6 décembre de 18h15 à 18h25, qui sera envoyée à ‘Papa’, catégorisée importante, dont un rappel sera effectué 15 minutes avant et qui ne bloquera pas le calendrier (dans le cadre d’un calendrier visible par autrui via TRANSP:OPAQUE & X-MICROSOFT-CDO-BUSYSTATUS:FREE). La portion du code « BEGIN:VTIMEZONE » définit en outre le changement horaire.

Copiez le code, enregistrez le dans un fichier en extension ‘.ics’, puis cliquez dessus pour l’ouvrir, vous devriez voir votre calendrier se remplir d’un nouveau rendez-vous – enfin, si votre appareil possède un des logiciels précédemment évoqué.

Vous pouvez en outre changer les dates de début, fin, et divers textes pour adapter le calendrier à vos besoin… c’est ce que j’ai fait ici – https://www.68600.fr/D6D/ics/

Maintenant que nous avons la base > Suite Partie 2