web-dev-qa-db-fra.com

Changer le répertoire des fonds d'écran dynamiques chaque saison

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?

Comment cette question est unique

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.

5
Joseph Gilgen

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:

  • Les références sont incluses dans le code. Ils sont liés aux réponses Stack Exchange pour résoudre des problèmes spécifiques. Par exemple: comment copier des fichiers, comment obtenir le jour de l'année, etc.
  • Une section sur "Test" est fournie car c'est quelque chose que nous devons tous faire.
  • Une section sur les "Améliorations" est fournie car les logiciels sont généralement développés dans des versions où chacune d’elles est meilleure que la version précédente.

Quand les saisons commencent-elles?

De la almanach de fermier :

Saisons de 2018

 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

Convertir la date de début de saison en jour de l'année

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

Créer un script bash: 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

  • Remarque: besoin de l'utilisateur Lubuntu d'utiliser 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.shAVANT votre diaporama normal car il supprime et copie les fichiers qui planteraient le programme du diaporama s'il commencé en premier.


Essai

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


Améliorations

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.

Compressez les fichiers pour économiser de l'espace disque

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.

Variables d'installation pour le début de saison

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...

1
WinEunuuchs2Unix

C'est peut-être un moyen plus facile:

  1. Créez un lien symbolique de ~/images/mybackgrounds à ~/images/spring:

    ln -s ~/images/spring ~/images/mybackgrounds
    
  2. Utilisez ne de ces méthodes pour afficher un diaporama en arrière-plan à l’aide des images de ~/images/mybackgrounds.

  3. 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.

2
unutbu

Étape 1: créez un script slideshow.py

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)

Étape 2: Rendez-le exécutable:

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.

Étape 3: Configurez crontab

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à.

0
unutbu
  1. Créez un dossier SeasonalWallPapers dans le répertoire home~/SeasonalWallPapers
  2. Créez des sous-dossiers dans ~/SeasonalWallPapers Automne, Printemps, Été & Hiver.
    • Conservez uniquement les fichiers .jpg dans les quatre dossiers ci-dessus, car le script n'est modifié que pour prendre les fichiers .jpg.

enter image description here

  • Veuillez noter que les fichiers .xml ci-dessous sont générés par des scripts. Vous n'avez pas besoin de créer/vous en préoccuper.

enter image description here

enter image description here

enter image description here

enter image description here

  1. Créez 4 scripts avec le contenu ci-dessous dans chacun des quatre dossiers ci-dessus.
    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>"
  1. rendre les scripts exécutables avec

chmod +x ~/SeasonalWallPapers/Fall/FWP.sh
chmod +x ~/SeasonalWallPapers/Spring/RWP.sh
chmod +x ~/SeasonalWallPapers/Summer/SWP.sh
chmod +x ~/SeasonalWallPapers/Winter/WWP.sh

  1. Créez un script appelé 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
  1. Rendre le script 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

  1. Exécutez la commande pour générer requis .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.

  1. 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'

enter image description here

enter image description here

enter image description here

enter image description here

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'
0
PRATAP