lunedì 30 dicembre 2013

Sfondi di BING su Gnome Shell



 

(Scripta Manent IV)

BING e i suoi sfondi 

Bing, come quasi tutti sanno, è il motore di ricerca di casa Microsoft.

Per motivi personali, di recente ho voluto provare questo mondo alternativo di servizi, la cui qualità non vuole essere oggetto di questo eloquio.

Una cosa che però indubbiamente colpisce di BING è la bellezza dei suoi sfondi, che cambiano quotidianamente e che sembrano presi da un vastissimo pool di immagini di alta qualità.

Probabilmente l'usabilità di tali sfondi è vincolata da quintali di clausule e copyright, quindi dovrebbero essere prudenzialmente usati solo in sede alle pagine di Bing, ma pare anche come sfondi per l'ultima versione del loro sistema operativo.

D'altra parte non se la prenderà la grande M, se motivato da fervente ammirazione e dalle quattro pagine di questo blog autarchico, nell'intenzione di far capire ciò che si può fare con power sh... ehm con bash , suggerirò un piccolo script per cambiare di conseguenza gli sfondi di Gnome Shell .

Passo dopo passo

Per essere certo che la procedura sia valida anche in futuro e anche, perché no, per altre pagine e altri sfondi a venire, spiegherò passo dopo passo "come lo feci".

Come lo feci

Prima di tutto ci serve un sistema per interrogare il sito di Bing, nell'intenzione di capire se lo sfondo è cambiato.

Un uomo di poche parole, si accontenterebbe di una voce in crontab o di un semplice sleep, ma i più arditi sapranno che ormai ben pochi spengono i laptop o i netbook e la maggior parte usano il comodissimo "suspend".

E qui casca lo sleep, nel senso che se mettiamo uno sleep, questo si sospende per un certo tempo, poi si sospende la sospensione quando il computer è sospeso, e alla fine riprende la sospensione, così che ogni sleep dura da T a infinito, e noi non vogliamo che questo accada, vero ?

Se trasformiamo lo script in un daemon di sistema,  non dobbiamo preoccuparci di farlo partire o finire, ci basterà fidarci, quindi scriviamo qualche riga :




#!/bin/bash
OLDTIME=0
 

{
while true
do

  # Ten minutes ...
  /bin/sleep 600

 
  NEWTIME=`date +%s`

  # Try to download after 12 hours only
  if [ $(($NEWTIME-$OLDTIME)) -ge 43200 ]
  then

    OLDTIME=$NEWTIME

    # Place your code here 
    # ..... fi
   
done
} &


Se lanciamo questo script da sh, magari all'interno di rc.local, lui per prima cosa va in background e diventa un daemon, figlio di 1 cioè di init e inizia un infinito loop ad intervalli di 10 minuti.

In questo loop, si legge il valore +%s di date, cioè il numero di secondi assoluti da EPOCH ([GMT]1/1/1970:00:00:00) e si compara, all'inizio con 0 e poi con i valori letti di volta in volta.

Un sistema di questo tipo, ogni 10 minuti circa, a partire dal primo loop, verificherà la scadenza di 12 ore ed eseguirà il codice in mezzo.

Notate bene che al massimo sarà sospeso lo sleep di 10 minuti. Il motivo per cui ne faccio eseguire uno all'inizio e non alla fine del primo loop, è perché il computer appena acceso, se è connesso col Wi-Fi, di solito non è ancora in rete e la rete ci servirà sicuramente per quello che stiamo per fare.

Quello che stiamo per fare è questo :

       ...   
    # Get the bing home page and search for g_img tag
    page=`/usr/bin/curl --user-agent "$USERAGENT" www.bing.com | /bin/grep g_img`
    # Get the token after g_img
    page=${page##*g_img=}
    # Check the url argument
    page=${page#*url:\'}
    # Extract the url until '
    page=${page%%\'*}

    /usr/bin/curl --user-agent "$USERAGENT" "http://www.bing.com/$page" > $FOLDER/current_background.jpg

    ...

Per capirlo bene, dobbiamo innanzi tutto precisare che per il momento Bing fornisce una pagina con codice javascript, che a sua volta contiene degli oggetti json. Un oggetto json si chiama g_img e contiene alcuni attributi, tra i quali il classico url, ossia una stringa json tra apici semplici.

La prima riga legge la pagina da www.bing.com, ed estrae il blocco contenente g_img e lo mette in una semplice variabile di memoria, chiamata page.

Il risultato sarà parecchio garbage con il nucleo di quello che ci interessa, cioè :

... g_img={url:'az/hprichbg/rb/immagine.jpg';id...

Ecco quindi gli abili colpi di bash, per pulire un po` il contenuto :

page=${page##*g_img=}
page=${page#*url:\'} 
page=${page%%\'*}

e che si traducono in :
  1. prendi tutto ciò che c'è dopo g_img= 
  2. di questo prendi solo quello che c'è subito dopo la prima parola url:' e qui notate che ho usato un solo #, cioè il minimo match dell'espressione regolare (il massimo porterebbe in fondo al file)
  3. di quello che hai ottenuto scarta tutto quello che trovi dal primo ' fino alla fine.
Se ci pensate un po` su capite che ora in page abbiamo qualcosa tipo :

az/hprichbg/rb/immagine.jpg

dove al posto di immagine, c'è uno bel URL col nome e la risoluzione dell'immagine stessa, basta accodarlo a al sito originale e lanciare il curl quindi su :

http://it.bing.com/az/hprichbg/rb/immagine.jpg

che scaricherà l'URL in standard output, da noi rediretto in un fantomatico :

$FOLDER/current_background.jpg

Gnome Shell e il suo sfondo

L'immagine di sfondo di Gnome Shell, punta solitamente ad una jpeg specifica.

Nonostante l'immagine sia naturalmente su disco da qualche parte, essa è considerata dinamica, cioè appena la si cambia, Gnome Shell se ne accorge e cambia lo sfondo di conseguenza, con un gradevole effetto fade-out,fade-in.

Per noi la situazione è perfetta, infatti se pensiamo di usare quello che abbiamo appena scritto come daemon di sistema, lanciato da rc.local, in modo che ne possano usufruire tutti gli utenti, possiamo riservarci un posto d'onore per esempio nella /opt , qualcosa tipo /opt/background e lì metterci la current_background.jpg.

Per far questo, presa una qualsiasi genericaimmagine.jpg, si può eseguire da su, cioè da utente root, la seguente operazione :

# mkdir /opt/background
# cp genericaimmagine.jpg /opt/background/current_background.jpg

Ora non ci resta che indicare in /opt/background/current_background.jpg, l'immagine di sfondo corrente e questo lo dobbiamo fare come utente "normale" per esempio usando Nautilus nella cartella /opt/background e cliccare aprendola col normale Image Viewer, dove col menù popup (tasto destro) troviamo una opzione per usare tale immagine come sfondo :



Quando lo script, agirà, sovrascriverà l'immagine e il gioco sarà fatto.

Mettiamo insieme tutto

A questo punto approntiamo lo script completo, che è questo :


#!/bin/bash
# Bing Image Downloader
 

{
 

export OLDTIME=0
export FOLDER=/opt/background

export USERAGENT="Mozilla/5.0"

while true
do
  # Ten minutes loop
  /bin/sleep 600

  export NEWTIME=`date +%s`

  # Try to download after 12 hours only
  if [ $(($NEWTIME-$OLDTIME)) -ge 43200 ]
  then

    OLDTIME=$NEWTIME

    # Get the bing home page and search for g_img tag
    page=`/usr/bin/curl --user-agent "$USERAGENT" www.bing.com | /bin/grep g_img`
    # Get the token after g_img
    page=${page##*g_img=}
    # Check the url argument
    page=${page#*url:\'}
    # Extract the url until '
    page=${page%%\'*}

    /usr/bin/curl --user-agent "$USERAGENT" "http://www.bing.com/$page" > $FOLDER/current_background.jpg

   
  fi

done

} &

notate che ho specificato delle query come Mozilla/5.0, giusto per non far vedere che sto usando curl.

Questo script l'ho salvato come bingimg.sh e inserito in /usr/local/sbin, ovviamente come superuser, quindi ho messo la classica riga in /etc/rc.local :

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

...
/usr/local/sbin/bingimg.sh

...
exit 0

Riavviando il sistema dopo 10 minuti l'immagine è cambiata e così via, giorno per giorno ...

E se ...

E se volete salvare le immagini, allora potete giochicchiare come meglio preferite. Per esempio potete mettere nella cartella background una cartella history e con un abile colpo di tee, scrivere al posto del curl che scarica l'immagine, qualcosa tipo :

       ...
    /usr/bin/curl --user-agent "$USERAGENT" "http://www.bing.com/$page" > $FOLDER/current_background.jpg   
# Remote image name
    OUTPUT=${page##*/}

    # Download only if it does not exists 
    if [ ! -e "$FOLDER/history/$OUTPUT" ]
    then
      /usr/bin/curl --user-agent "$USERAGENT" "http://www.bing.com/$page" | /usr/bin/tee $FOLDER/history/$OUTPUT > $FOLDER/current_background.jpg
    fi

    ...

che in più ha il vantaggio di sovrascrivere l'immagine solo se questa non esiste già, e tante altre cose che vi lascio immaginare.


Nessun commento:

Posta un commento