Je souhaite que mon fond d'écran soit saisonnier (été, automne, hiver, printemps), mais également mis à jour quotidiennement avec un fond d'écran à thème saisonnier.
Donc, je pense avoir 4 répertoires (summer, fall, winter, spring
). Pendant l'été, mon fond d'écran tournait tous les jours dans les images du répertoire summer
. Puis, le 21 septembre, le répertoire de fond d'écran deviendrait fall
, et le fond d'écran passerait ensuite en revue ces images quotidiennement, etc.
Je suis à l'aise pour écrire un script, mais par où commencer?
Edit: Pour clarifier davantage ce qui rend cette question unique. Bien qu'il existe de nombreuses méthodes pour créer un diaporama, elles dépendent toutes du paramétrage du répertoire d'images. Ce que je demande, c'est comment changer dynamiquement le répertoire des images. Ainsi, le diaporama sort aujourd'hui du répertoire /images/winter/
et le diaporama au printemps sort du répertoire /images/spring/
. Je pouvais le faire manuellement en changeant simplement le répertoire dans les paramètres d'apparence chaque saison, mais je ne veux pas avoir à cela quand je peux dire à l'ordinateur de le faire pour moi.
La question fondamentale est de savoir comment faire quelque chose au début du printemps, de l'été, de l'automne et de l'hiver. Pour cela, je créerais un script bash qui s'exécutait au démarrage plutôt que d'encrasser cron
avec des entrées.
J'ai abordé cette réponse en utilisant la question du PO "Comment développer un script?". Donc, je me suis écarté de la méthode habituelle de simplement poster un script bash et ai amélioré la réponse avec:
De la almanach de fermier :
Season Astronomical Start Meteorological Start
====== ===================================== =====================
SPRING Tuesday, March 20, 12:15 P.M. EDT Thursday, March 1
SUMMER Thursday, June 21, 6:07 A.M. EDT Friday, June 1
FALL Saturday, September 22, 9:54 P.M. EDT Saturday, September 1
WINTER Friday, December 21, 5:23 P.M. EST Saturday, December 1
Pour que notre script bash
fonctionne, nous devons savoir quel jour de l'année chaque saison commence.
$ echo $(date --date="March 20" '+%j')
079
$ echo $(date --date="June 21" '+%j')
172
$ echo $(date --date="Sep 22" '+%j')
265
$ echo $(date --date="Dec 21" '+%j')
355
# Reference: https://unix.stackexchange.com/questions/352176/take-input-arguments-and-pass-them-to-date
season.sh
Ouvrez le terminal en utilisant: Ctrl+Alt+T
Créez le répertoire s'il n'existe pas: mkdir -p ~/bin
Editez le script en utilisant: gedit ~/bin/season.sh
leafpad
au lieu de gedit
Copiez et collez les lignes suivantes dans gedit
:
#!/bin/bash
# NAME: season.sh
# PATH: ~/bin
# DATE: December 15, 2018
# NOTE: Written for: https://askubuntu.com/questions/1100934/change-dynamic-wallpaper-directory-every-season/1102084#1102084
# User defined variables, change to suit your needs
# Our directory names, lines indented for cosmetic reasons only
SlideShowDir="~/Season Slide Show"
SpringDir="~/Pictures/Spring Slide Show"
SummerDir="~/Pictures/Summer Slide Show"
FallDir="~/Pictures/Fall Slide Show"
WinterDir="~/Pictures/Winter Slide Show"
CheckTripWire () {
# Our last season is in "~/Season Slide Show/CurrentSeason"
LastSeasonFilename="$SlideShowDir"/CurrentSeason
LastSeason=$(cat "$LastSeasonFilename")
[[ "$LastSeason" == "$Season" ]] && return 0 # Season still the same
# We now know our season has changed.
rm -f "$SlideShowDir"/{*,.*} # Erase all files in target
# Reference: https://askubuntu.com/questions/60228/how-to-remove-all-files-from-a-directory
echo "$Season" > "$LastSeasonFilename" # Record new season in target
# Copy new slide show based on season
if (( "$Season" == SPRING)) ; then
cp -R "$SpringDir"/. "$SlideShowDir"/
# Reference: https://stackoverflow.com/questions/3643848/copy-files-from-one-directory-into-an-existing-directory
Elif (( "$Season" == SUMMER)) ; then
cp -R "$SummerDir"/. "$SlideShowDir"/
Elif (( "$Season" == FALL)) ; then
cp -R "$FallDir"/. "$SlideShowDir"/
else
cp -R "$WinterDir"/. "$SlideShowDir"/
fi
} # End of CheckTripWire () function.
# Start of Mainline
DOY=$(date '+%j') # DOY = Current Day of Year
# Reference: https://stackoverflow.com/questions/10112453/how-to-get-day-of-the-year-in-Shell
if ((DOY>=079 && DOY<172)) ; then
Season="SPRING" # Spring has sprung!
# Reference: https://stackoverflow.com/questions/12614011/using-case-for-a-range-of-numbers-in-bash
Elif ((DOY>=172 && DOY<265)) ; then
Season="SUMMER" # Hit the beach!
Elif ((DOY>=265 && DOY<355)) ; then
Season="FALL" # Rake those leaves!
else
Season="WINTER" # Shovel the snow!
fi
# Current season establish, now see if we tripped the wire
CheckTripWire
exit 0 # Command not necessary but good habit to signify no Abend.
Enregistrez le fichier dans gedit
. Maintenant, marquez-le comme exécutable en utilisant:
chmod a+x ~/bin/season.sh
Ensuite, nous devons l'ajouter aux applications de démarrage. Référence: Comment démarrer les applications automatiquement lors de la connexion?
Remarque: Vous avez probablement déjà configuré votre diaporama dans des applications de démarrage. Vous voudrez utiliser season.sh
AVANT votre diaporama normal car il supprime et copie les fichiers qui planteraient le programme du diaporama s'il commencé en premier.
Vous voudrez tester le script season.sh
lorsque vous le créez et ne pas attendre un an pour voir s'il fonctionne correctement ou non. Référence: https://serverfault.com/questions/138325/faking-the-date-for-a-specific-Shell-session
Après avoir initialement développé un script, il est courant de l’améliorer en jours, en semaines, en mois et même en années. Cette section présente certaines améliorations que vous pourriez souhaiter apporter à session.sh
plus tard.
Pensez à conserver les images hors saison compressées au format TAR (Archive de bandes) pour économiser de l'espace disque. Remplacez ensuite la commande cp
(Copier) par la commande tar
pour décompresser les fichiers. Référence: https://www.rootusers.com/23-tar-command-examples-for-linux/ :
Par exemple, nous changerions:
cp -R "$SpringDir"/. "$SlideShowDir"/
À:
tar -xf "$SpringDir"archive.tar -C "$SlideShowDir"/
... et ainsi de suite pour les autres saisons.
L'utilisation de variables pour les jours de début de saison facilite la modification du script et facilite la lecture du code (aka lisibilité du code ).
Envisagez de définir des variables pour le début de saison:
SpringStart=079
SummerStart=179
FallStart=265
WinterStart=355
Définissez les variables en haut du script pour les rendre plus faciles à repérer et à modifier. Vous voudrez peut-être faire cela pendant des années bissextiles. Vous voudrez peut-être passer au début de la saison "météorologique" au lieu des dates de début "astronomiques".
Puis changez ces lignes:
if ((DOY>=079 && DOY<172)) ; then
Elif ((DOY>=172 && DOY<265)) ; then
Elif ((DOY>=265 && DOY<355)) ; then
Pour ça:
if ((DOY>="$SpringStart" && DOY<"$SummerStart")) ; then
Elif ((DOY>="$SummerStart" && DOY<"$FallStart")) ; then
Elif ((DOY>="$FallStart" && DOY<"$WinterStart")) ; then
REMARQUE: J'espérais finir cette réponse en une heure, mais cela fait deux heures et je dois faire du shopping le samedi. À suivre...
C'est peut-être un moyen plus facile:
Créez un lien symbolique de ~/images/mybackgrounds
à ~/images/spring
:
ln -s ~/images/spring ~/images/mybackgrounds
Utilisez ne de ces méthodes pour afficher un diaporama en arrière-plan à l’aide des images de ~/images/mybackgrounds
.
Configurez les entrées de la crontab pour changer le lien symbolique certains jours. Créez un fichier appelé ~/mycrontab
avec le contenu suivant:
# min hr day mon dow
0 9 21 3 * ln -sf ~/images/spring ~/images/mybackgrounds
0 9 21 6 * ln -sf ~/images/summer ~/images/mybackgrounds
0 9 21 9 * ln -sf ~/images/fall ~/images/mybackgrounds
0 9 21 12 * ln -sf ~/images/winter ~/images/mybackgrounds
Courir
crontab ~/mycrontab
enregistrer les entrées crontab. Le 21 mars à 9 heures, crond
exécutera la commande
ln -sf ~/images/spring ~/images/mybackgrounds
liant ainsi ~/images/mybackgrounds
à ~/images/spring
. Le 21 juin à 9h00, crond
modifiera le lien symbolique de sorte que ~/images/mybackgrounds
pointe sur ~/images/summer
. Le programme de diaporama est configuré pour sélectionner un fichier dans ~/images/mybackgrounds
. Le chemin d'accès à ~/images/mybackgrounds
reste le même, mais maintenant tout le contenu est différent car le lien symbolique pointe vers un emplacement différent. Les entrées crontab des 21 et 21 décembre font la même chose.
Enregistrez ceci dans un fichier nommé ~/bin/slideshow.py
:
#!/usr/bin/env python
import os
import datetime as DT
import itertools as IT
import bisect
import random
import subprocess
# customize cutoffs and image_dirs however you like, but note that there must be
# the same number of items in each, and the items in cutoffs must be in sorted order.
cutoffs = [(3, 21), (6, 21), (9, 21), (12, 21)]
image_dirs = ['~/images/winter', '~/images/spring', '~/images/summer', '~/images/fall']
image_dirs = list(map(os.path.expanduser, image_dirs))
today = DT.date.today()
year = today.year
# convert the cutoffs to actual dates
cutoff_dates = [DT.date(year, m, d) for m, d in cutoffs]
# find the index into cutoff_dates where today would fit and still keep the list sorted
idx = bisect.bisect(cutoff_dates, today)
# use idx to get the corresponding image directory
image_dir = next(IT.islice(IT.cycle(image_dirs), idx, idx+1))
# list all the files in image_dir (even in subdirectories, and following symlinks)
files = [os.path.join(root, filename)
for root, dirs, files in os.walk(image_dirs[idx], followlinks=True)
for filename in files]
# pick a file at random
imagefile = os.path.abspath(random.choice(files))
# find the current process's effective user id (EUID)
euid = str(os.geteuid())
# find the pid of the current EUID's gnome-session
pid = subprocess.check_output(['pgrep', '--euid', euid, 'gnome-session']).strip().decode()
# load all the environment variables of gnome-session
env = open('/proc/{}/environ'.format(pid), 'rb').read().strip(b'\x00')
env = dict([item.split(b'=', 1) for item in env.split(b'\x00')])
# get the value of DBUS_SESSION_BUS_ADDRESS environment variable
key = b'DBUS_SESSION_BUS_ADDRESS'
env = {key: env[key]}
# call gsettings to change the background to display the selected file
# with the DBUS_SESSION_BUS_ADDRESS environment variable set appropriately
subprocess.call(['gsettings', 'set', 'org.gnome.desktop.background', 'picture-uri',
'file://{}'.format(imagefile)], env=env)
chmod 755 ~/bin/slideshow.py
Pour vérifier que tout fonctionne comme prévu, vous pouvez ouvrir un terminal et exécuter plusieurs fois slideshow.py
. Vous devriez voir le fond changer. Notez que slideshow.py
recherche des images dans l'un des 4 répertoires, ~/images/spring
, ~/images/summer
, ~/images/fall
ou ~/images/winter
, en fonction de la saison.
Vous pouvez utiliser cron pour exécuter périodiquement une commande permettant de modifier l’arrière-plan, par exemple, une fois par jour ou toutes les minutes.
Créez un fichier appelé, par exemple, ~/mycrontab
, et mettez quelque chose comme ceci à l'intérieur:
# min hr day mon dow
# 0 9 * * * ~/bin/slideshow.py # run once at 9AM
* * * * * ~/bin/slideshow.py # run once every minute
Puis courir
crontab ~/mycrontab
enregistrer le changement dans votre crontab.
Vous devriez maintenant voir le fond changer une fois par minute. (Vous pourriez même aimer le garder de cette façon.)
crontab
ignorera les lignes commençant par #
. Donc, si vous voulez changer l’arrière-plan une fois par jour, décommentez la deuxième ligne et commentez la troisième afin que ~/mycrontab
ressemble maintenant à ceci:
# min hr day mon dow
0 9 * * * ~/bin/slideshow.py # run once at 9AM
# * * * * * ~/bin/slideshow.py # run once every minute
Notez cependant que cron n'exécutera cette commande que si vous êtes connecté à la machine à 9 heures ce jour-là.
home
~/SeasonalWallPapers
~/SeasonalWallPapers
Automne, Printemps, Été & Hiver. .jpg
dans les quatre dossiers ci-dessus, car le script n'est modifié que pour prendre les fichiers .jpg
..xml
ci-dessous sont générés par des scripts. Vous n'avez pas besoin de créer/vous en préoccuper.FWP.sh
, RWP.sh
, SWP.sh
& WWP.sh
Remarque: modifiez la 3ème ligne du script ci-dessous FILE="FWP.xml"
dans trois autres fichiers de script pour les transformer en FILE=RWP.xml
, FILE=SWP.xml
& FILE=WWP.xml
.
Remarque: dans le script ci-dessous, la durée est définie sur 2
secondes seulement. pour changer chaque jour le papier peint, réglez-le sur 86400
#!/bin/bash
FILE="FWP.xml"
DURATION=2.0
TRANSITION=0.0
CURRENTDIR=$PWD
TRANSITION_XML="
<static>
<duration>$DURATION</duration>
<file>$CURRENTDIR/%s</file>
</static>
<transition>
<duration>$TRANSITION</duration>
<from>$CURRENTDIR/%s</from>
<to>$CURRENTDIR/%s</to>
</transition>
"
# Random order
IMGS=( *.jpg )
INDICES=( $(shuf -e ${!IMGS[@]}) ) # randomize indices of images
INDICES+=(${INDICES[0]}) # go back to first image after last
COUNTER=${#IMGS[@]}
exec > "$FILE" # all further output to the XML file
echo "<background><starttime></starttime>"
for ((i = 0; i < COUNTER; i++))
do
index=${INDICES[i]}
printf "$TRANSITION_XML" "${IMGS[index]}" "${IMGS[index]}" "${IMGS[index + 1]}"
done
echo "</background>"
chmod +x ~/SeasonalWallPapers/Fall/FWP.sh
chmod +x ~/SeasonalWallPapers/Spring/RWP.sh
chmod +x ~/SeasonalWallPapers/Summer/SWP.sh
chmod +x ~/SeasonalWallPapers/Winter/WWP.sh
WP.sh
avec le contenu ci-dessous.#! /bin/bash
cd ~/SeasonalWallPapers/Summer/ && ./SWP.sh
cd ~/SeasonalWallPapers/Fall/ && ./FWP.sh
cd ~/SeasonalWallPapers/Winter && ./WWP.sh
cd ~/SeasonalWallPapers/Spring && ./RWP.sh
WP.sh
exécutable avec chmod +x ~/SeasonalWallPapers/WP.sh
* Ce script WP.sh
est la source principale pour nous maintenant.
chaque fois que nous ajoutons ou supprimons des modifications dans ces 4 dossiers pour les images .. nous devons exécuter ce script pour mettre à jour les fichiers .xml
.xml files
~/SeasonalWallPapers/WP.sh
Exemple:
$ ~/SeasonalWallPapers/WP.sh
$
* Lorsque nous exécutons ce script WP.sh
, il génère les fichiers .xml
dans chaque dossier contenant des fonds d'écran mis à jour nommés FWP.xml
, RWP.xml
, SWP.xml
& WWP.xml
nous devons maintenant définir l’un quelconque de ces quatre fichiers .xml
selon nos besoins.
gsettings set org.gnome.desktop.background picture-uri 'file:///home/user-name/SeasonalWallPapers/Fall/FWP.xml'
#changez le nom d'utilisateur avec le vôtre.Exemple:
$ gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Fall/FWP.xml'
$
maintenant, quand vous le souhaitez, vous pouvez définir les fonds d'écran requis avec les commandes ci-dessous
gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Fall/FWP.xml'
gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Winter/WWP.xml'
gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Spring/RWP.xml'
gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Summer/SWP.xml'
Si vous envisagez toujours d'automatiser cette opération, elle intervient tous les trois mois.
créez un travail cron selon vos besoins avec les exemples de commandes suivants.
0 0 1 12 * root gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Fall/FWP.xml'
0 0 1 6 * root gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Winter/WWP.xml'
0 0 1 9 * root gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Spring/RWP.xml'
0 0 1 3 * root gsettings set org.gnome.desktop.background picture-uri 'file:///home/pratap/SeasonalWallPapers/Summer/SWP.xml'