•  » Installation
  •  » [Résolu] Générer les vignettes automatiquement via un cron

#1 2013-12-19 19:37:10

François Lafont
Invité

[Résolu] Générer les vignettes automatiquement via un cron

Bonjour à tous,

J'ai un Piwigo installé en version 2.5.3 sur une Debian Wheezy. Tout fonctionne très bien et ma question relève plutôt d'une optimisation de l'installation que de l'installation en elle-même.

Voilà, sur le serveur on envoie en masse des photos via ftp dans le répertoire "galleries", ensuite on synchronise et ça marche impeccable. Le souci, c'est que, lorsqu'on va visiter pour la première fois une photo dans un album, le serveur php va générer de nouveaux fichiers pour créer les vignettes etc (je ne connais pas vraiment le détail de ce que fais le serveur php à ce moment, mais il fait des choses qui lui demandent un petit peu de travail). Du coup, la toute première fois, la page est un petit longue à charger. Ensuite, les fois suivantes, ça va vite car les fichiers sont déjà créés une fois pour toutes.

Ce que je voudrais faire : mettre en place une petite tâche cron sur le serveur la nuit (par exemple de à 3h00 du matin) qui va visiter les photos qui n'ont jamais encore été visitées (sur la base de commandes genre « wget http://<url> -0 /dev/null ») afin que tous les fichiers soient bien générés et que, le jour, les visiteurs ne subissent pas cette petite lenteur due à la génération des fichiers images (le cron aura provoqué ce travail pour eux). En effet, notre serveur Piwigo ne fera pas grand chose 95% du temps et sera seulement sollicité ponctuellement le jour par des visiteurs non authentifiés. Du coup, je me dis que ce serait cool d'arriver à faire cette optimisation pour que ça « dépote » pour les visiteurs.

Voici ma question. Y a-t-il moyen, soit via des requêtes MySQL, soit via des recherches dans l'arborescence de fichiers, soit via les deux, de générer la liste des urls à visiter afin de forcer la génération des fichiers images uniquement pour les photos où ce n'est pas encore le cas ?

Je ne recherche pas de réponse forcément précise (je prends aussi les réponses précises :)). Si on m'explique un principe général pour faire cela, après je peux me débrouiller sur le comment de l'implémentation de l'algorithme.

J'espère avoir été clair dans ma question.
Merci d'avance pour votre aide.

François Lafont

#2 2013-12-25 10:51:41

Mascarille
Membre
Lyon Avignon
2009-12-21
785

Re: [Résolu] Générer les vignettes automatiquement via un cron

Bonjour et bonnes fêtes,

ce que je fais après avoir chargé les photos c'est d'aller dans gestion par lots > dernier import > rafraîchir > tout le lot > action > générer les tailles multiples... et vous laissez tourner, ce qui ne bloque pas l'accès à votre machine (sauf que la charge est assez forte !)

si vous lancez une tache (via un programme à écrire ?), vous allez lancer la regénération de la totalité des tailles sur toutes les photos, même celles qui existent déjà, sauf à imaginer quelque chose qui risque d'être un peu compliqué... alors que la première formule est vraiment très simple (vous pouvez la lancer le soir, comme vous le souhaitez)

Bonne journée

Hors ligne

#3 2013-12-30 15:20:20

François Lafont
Invité

Re: [Résolu] Générer les vignettes automatiquement via un cron

Bonjour Mascarille et merci de votre réponse.

Mascarille a écrit:

ce que je fais après avoir chargé les photos c'est d'aller dans gestion par lots > dernier import > rafraîchir > tout le lot > action > générer les tailles multiples... et vous laissez tourner, ce qui ne bloque pas l'accès à votre machine (sauf que la charge est assez forte !)

Ok, ça a l'air pas mal ça, il faudra que je teste avec l'admin de notre site piwigo (j'ai juste installé le serveur mais je n'ai pas de compte sur le piwigo en fait).

Mascarille a écrit:

si vous lancez une tache (via un programme à écrire ?), vous allez lancer la regénération de la totalité des tailles sur toutes les photos, même celles qui existent déjà, sauf à imaginer quelque chose qui risque d'être un peu compliqué...

Voilà, c'est ce fameux truc un peu compliqué que je cherchais, ie avoir la liste des urls à visiter seulement pour les photos dont la génération des différentes tailles de photos n'a pas encore été faite. Maintenant si la manip dont vous me parlez fait le travail, alors je pense que ça suffira largement.

Je reviendrai confirmer et clore ce fil une fois le test fait (ou bien le relancer si ça ne marche pas ;)).
Merci encore et bonnes fêtes.

François Lafont

#4 2013-12-30 15:24:45

mistic100
Ex Equipe Piwigo
Lyon
2008-09-27
3556

Re: [Résolu] Générer les vignettes automatiquement via un cron

l'API à une méthode pwg.getMissingDerivatives
voir http://votrepiwigo/tools/ws.htm

Hors ligne

#5 2013-12-30 15:30:39

Mascarille
Membre
Lyon Avignon
2009-12-21
785

Re: [Résolu] Générer les vignettes automatiquement via un cron

Mistic, le lien ne fonctionne pas
Bonnes fêtes !

Hors ligne

#6 2013-12-30 15:40:49

mistic100
Ex Equipe Piwigo
Lyon
2008-09-27
3556

Re: [Résolu] Générer les vignettes automatiquement via un cron

euh oui....

'votrepiwigo' c'est.... votre piwigo !

alors trop bu pendant les fêtes ? :-)

Hors ligne

#7 2013-12-30 15:44:41

Mascarille
Membre
Lyon Avignon
2009-12-21
785

Re: [Résolu] Générer les vignettes automatiquement via un cron

yes ! hips
pas bien réveillé !
Je venais de m'en apercevoir !
Bonnes fêtes à toi

Hors ligne

#8 2013-12-30 18:45:33

François Lafont
Invité

Re: [Résolu] Générer les vignettes automatiquement via un cron

mistic100 a écrit:

l'API à une méthode pwg.getMissingDerivatives
voir http://votrepiwigo/tools/ws.htm

Merci beaucoup pour l'info, je crois que c'est exactement ce que je cherche, j'ai juste encore un obstacle à franchir (cf ci-dessous). En fait, pour avoir la liste des urls à visiter, il faudrait que j'obtienne la sortie d'un :

curl "http://localhost/ws.php?format=json&method=pwg.getMissingDerivativess&max_urls=300"

ce qui me donne au format json la liste des urls à visiter ensuite. À partir de là, on doit pouvoir s'en sortir avec un petit script.

Le seul souci pour moi maintenant, c'est que le curl ne donne rien car je ne suis pas connecté en tant qu'admin (avec curl je ne suis qu'un simple visiteur lambda, forcément). Pour l'instant, n'étant pas un expert PHP, je ne vois pas comment faire, si ce n'est en hackant la fonction ws_getMissingDerivatives du fichier ./include/ws_functions.inc.php et en commentant la partie correspondant au test « if (!is_admin()) », mais c'est sans doute pas très propre.

Si jamais vous voyez une meilleure alternative, je suis preneur.

#9 2013-12-30 18:51:55

mistic100
Ex Equipe Piwigo
Lyon
2008-09-27
3556

Re: [Résolu] Générer les vignettes automatiquement via un cron

c'est parfait que vous utilisiez CURL parce qu'il permet de maintenir la session entre plusieurs requetes (session.login puis getMissingDervatives)

je ne vais pas m'ettendre sur le sujet, plein de tutos expliquent ça très bien :)

Hors ligne

#10 2013-12-31 01:22:17

François Lafont
Invité

Re: [Résolu] Générer les vignettes automatiquement via un cron

mistic100 a écrit:

c'est parfait que vous utilisiez CURL parce qu'il permet de maintenir la session entre plusieurs requetes (session.login puis getMissingDervatives)

je ne vais pas m'ettendre sur le sujet, plein de tutos expliquent ça très bien :)

Ok, merci beaucoup. Au départ, je ne comprenais pas que "session.login" faisait aussi référence à l'API de Piwigo, du coup j'étais un peu perdu. Maintenant je pense que je suis arrivé à mes fins. Voici la base de mon script cron des fois que ça puisse être utile à d'autres :

Code:

#!/bin/sh

CRON_LOGIN="admin_cron"
CRON_PWD="xxxxxx"

cookie_file=$(mktemp)

curl --silent --output /dev/null --cookie-jar "$cookie_file" \
  --data "method=pwg.session.login&username=${CRON_LOGIN}&password=${CRON_PWD}" \
  "http://localhost/ws.php?format=json"

json=$(curl --silent --cookie "$cookie_file" \
  "http://localhost/ws.php?format=json&method=pwg.getMissingDerivatives&max_urls=200")

rm -f "$cookie_file"

urls=$(echo "
import json
s = '$json'
j = json.loads(s)

for url in j['result']['urls']:
    print url

" | python) || {
    echo "Problem with the json output. End of the script."
    exit 1
}

for url in $urls
do
    echo "$url"
    curl --silent --output /dev/null "$url"
done

Je l'ai testé sur une Debian Wheezy (nécessite Python et curl). C'est juste une base. En fait, il faudra que je fasse en sorte que le script s'arrête au bout d'une heure ou deux quoi qu'il arrive, afin de ne pas surcharger le serveur et de limiter cette tâche à une partie de la nuit uniquement (par exemple de 3h à 5h). Mais tout ça, ce sont des détails qui ne concernent plus Piwigo.

Le fil est donc résolu. J'ai obtenu exactement ce que je cherchais.
Merci encore pour votre aide. :)

À+

#11 2014-01-01 13:02:13

Mascarille
Membre
Lyon Avignon
2009-12-21
785

Re: [Résolu] Générer les vignettes automatiquement via un cron

Bonne année à tous !

Petite remarque à François sur son code : rencontré pb avec un mot de passe comportant des caractères spéciaux "&" par ex. Facile à contourner.

Je suis parti sur l'idée de générer les vignettes - toutes les vignettes y compris celles de Gthumb+ :

Au départ l'idée d'utiliser le sitemap, récupérer les adresses et balayer tranquillement la base avec des pauses entre chaque appel, ce qui peut-être intéressant pour les hébergeurs "susceptibles".

J'ai écris un programme python basique, mon gendre a repris ça en plus compact (pratique les réunions de famille !)... mais ça ne marche pas même si on se balade effectivement correctement sur toute la base. Les  modules urllib2 ou CURL n'examinent pas le code javascript de piwigo donc n’interprètent pas tout ce qui est écriture des cookies, redirection, génération des images.

Si vous avez des pistes...

Très cordialement

Hors ligne

#12 2014-01-01 17:17:03

flaf
Membre
2014-01-01
1

Re: [Résolu] Générer les vignettes automatiquement via un cron

Bonjour et bonne année à tous également. :)

Mascarille a écrit:

Petite remarque à François sur son code : rencontré pb avec un mot de passe comportant des caractères spéciaux "&" par ex. Facile à contourner.

Oui en effet. Il faut encapsuler le mot de passe dans des simples quotes, ce sera beaucoup mieux. J'en profite au passage pour poster ici une version a priori définitive de mon script cron. Il récupère un paquet de 50 urls, les visite avec curl et ainsi de suite. Le script s'arrête quand il ne récupère plus aucune d'url, ou bien quand plus d'une heure (environ) se sera écoulée depuis le début du script, ou bien quand il rencontrera une erreur :

Code:

#!/bin/sh

# Cron script to generate pictures.
# See http://fr.piwigo.org/forum/viewtopic.php?pid=207043

set -e
export LC_ALL=C
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"


CRON_LOGIN='admin4cron'
CRON_PWD='xxxxxx'
DURATION=3600 # in seconds
URLS_PER_LOOP=50


get_urls () {
    cookie_file=$(mktemp)

    # Connection with the cron account via the Piwigo API.
    # See http://<piwigo hostname>/tools/ws.htm.
    curl --silent --output /dev/null --cookie-jar "$cookie_file" \
      --data "method=pwg.session.login&username=${CRON_LOGIN}&password=${CRON_PWD}" \
      "http://localhost/ws.php?format=json"

    # Get a json of the urls to visit with the "pwg.getMissingDerivatives" method.
    json=$(curl --silent --cookie "$cookie_file" \
      "http://localhost/ws.php?format=json&method=pwg.getMissingDerivatives&max_urls=${URLS_PER_LOOP}")

    rm -f "$cookie_file"

    python_script="import json
s = '$json'
j = json.loads(s)

for url in j['result']['urls']:
    print(url)
"

    # Extracting urls with Python and "json" module.
    if echo "$python_script" | python
    then
        return 0
    else
        return 1
    fi
}



begin=$(date "+%s")
loop_number=1

while true
do
    echo ">>> Loop number $loop_number"
    loop_number=$((loop_number + 1))

    # curl on each urls to generate pictures.
    if urls=$(get_urls)
    then
        for url in $urls
        do
            echo "$url"
            curl --silent --output /dev/null "$url"
        done
    else
        # If there is a problem, it's finished.
        echo "Problem with the json output, end of the script."
        exit 1
    fi

    # If there is no url, it's finished.
    if [ -z "$urls" ]
    then
        echo "There is no url, end of the script."
        exit 0
    fi

    now=$(date "+%s")
    elapsed_time=$((now - begin))

    # If the timeout is exceeded, it's finished.
    if [ $elapsed_time -ge $DURATION ]
    then
        echo "Timeout, end of the script."
        exit 0
    fi
done

Sinon, pour ton souci avec Gthumb+, j'ai peur de ne pas pouvoir t'aider car je ne savais même pas ce que c'était avant de faire une recherche Google il y a quelques instants auparavant. Mais je vais suivre la discussion car la problématique avec JavaScript est intéressante.

À+
François Lafont

Dernière modification par flaf (2014-01-02 15:38:54)

Hors ligne

#13 2014-01-01 20:22:47

Mascarille
Membre
Lyon Avignon
2009-12-21
785

Re: [Résolu] Générer les vignettes automatiquement via un cron

Suite...
Mon gendre a écrit une routine basée sur le principe suivant :

1. génération d'un fichier sh qui contient une suite de commandes pour chaque url du sitemap.
l
es commandes incluses sont:
    - création d'un répertoire dans tmp
    - déplacement dans ce dernier
    - téléchargement de l'url via un wget en indiquant de travailler comme un client mozilla avec exécution du code js
    - suppression du répertoire tmp

2. lancement du fichier sh généré

Je ne suis pas chez moi en ce moment, je n'ai pas testé (et je n'ai pas tout compris à son code très compact... ) mais il semble confiant. En fait l'objectif est d'arriver à exécuter le javascript contenu dans les pages pour générer toutes les vignettes.

A suivre

Cordialement

Hors ligne

#14 2014-01-05 17:53:55

Mascarille
Membre
Lyon Avignon
2009-12-21
785

Re: [Résolu] Générer les vignettes automatiquement via un cron

Bonsoir,
j'ai aménagé le code envoyé par mon gendre, d'une part pour le passer en python 3.3 (Attention les accès aux modules urrlib ne sont pas identiques en 2.7, ni 3.1, le gros défaut de python)

En fait, on récupère les url à traiter (ici avec sitemap, mais on peut imaginer autre chose...)
puis on lance le navigateur page par page (pensez à changer la ligne BROWSER en fonction de votre navigateur par défaut).
Entre chaque page un TIMESLEEP réglable (en secondes).

Le navigateur lit 10 url puis referme les pages après une nouvelle attente.
Avantages :
- indépendant des versions de Piwigo.
- génère toutes les vignettes y compris Gthumb+
- Très cool pour votre hébergeur, s'il est susceptible et trop attentif à votre consommation CPU instantanée. Il suffit d'avoir un TIMESLEEP assez long et vous devenez un utilisateur ordinaire de votre site.
Attention en utilisant le site map (généré par le plugin du même nom), on ne balaye que les pages publiques.

Code:

import xml.dom.minidom
import urllib
import webbrowser
import time
import os

global COUNT
# BROWSER = 'iexplore.exe'
BROWSER = 'chrome.exe'
TIMESLEEP = 15
COUNT = 0

def geturl(url):
  global COUNT
  sitemap = xml.dom.minidom.parse(urllib.urlopen(url)) 
  prg = ""
  for loc in sitemap.getElementsByTagName('loc'):
    try:
      print("open %s" % loc.childNodes[0].nodeValue)
      webbrowser.open(loc.childNodes[0].nodeValue)
    except:
      print("problem with %s" % loc.childNodes[0].nodeValue)
    time.sleep(TIMESLEEP)
    COUNT += 1
    if COUNT > 9:
      COUNT = 0
      time.sleep(TIMESLEEP)
      os.system("taskkill /IM %s" % BROWSER)

geturl('http://www.votresite.xxx/galerie/sitemap.xml')

Hors ligne

#15 2015-06-15 10:37:57

griffon
Invité

Re: [Résolu] Générer les vignettes automatiquement via un cron

merci pour le script de génération des miniatures. :-)

J'ai installé sur mon NAS synology la version en python 2.6 et ca tourne bien avec un cron... sauf quand il n'y a plus de miniature à créer lors de l'appel à 'pwg.getMissingDerivatives'. L'api ne répond pas à la requêtes du CURL en question, et celui-ci reste en process actif... les cron s’accumulent et finissent par s'arrêter.

J'ai rajouté '-m 5' à la requete curl, qui stoppe le curl après 5 secondes de non réponse, et permet de stopper le curl. Cela génère ensuite une erreur Python (car l'object $json n'existe pas ou est vide) que je ne suis pas parvenu à gérer proprement (mon niveau est très faible en python/bash).

Voici mon script adapté pour un nas DS107+ avec la gestion de l'authent htaccess, en lieu et place du login/mdp piwigo. il faut avoir préalablement installé le package 'mktemp'.
Je ne demande qu'une URL par requête, car si j'en met plus et qu'on arrive au bout des transformations, l'API bloque comme expliqué ci-dessus.

Code:

#!/bin/sh

# Cron script to generate pictures.
# See http://fr.piwigo.org/forum/viewtopic.php?pid=207043

set -e
export LC_ALL=C
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"


CRON_LOGIN='login_htaccess'
CRON_PWD='mdp_htaccess'
DURATION=35 # in seconds
URLS_PER_LOOP=1


get_urls () {
   cookie_file=$(/opt/bin/mktemp)
   # Connection with the cron account via the Piwigo API.
   # See http://<piwigo hostname>/tools/ws.htm.
   /opt/bin/curl -u "${CRON_LOGIN}:${CRON_PWD}" --silent --output /dev/null --cookie-jar "$cookie_file" --data "method=pwg.session.login&username=${CRON_LOGIN}&password=${CRON_PWD}" "http://localhost/catatheque/gallerie/ws.php?format=json" 
   
   # Get a json of the urls to visit with the "pwg.getMissingDerivatives" method.
   json=$(/opt/bin/curl -u "${CRON_LOGIN}:${CRON_PWD}" -m 5  --silent --cookie "$cookie_file" "http://localhost/catatheque/gallerie/ws.php?format=json&method=pwg.getMissingDerivatives&max_urls=${URLS_PER_LOOP}")

   rm -f "$cookie_file"

    python_script="import json
s = '$json'
j = json.loads(s)

for url in j['result']['urls']:
    print(url)
"

    # Extracting urls with Python and "json" module.
    if echo "$python_script" | /opt/bin/python2.6
    then
        return 0
    else
        return 1
    fi
}



begin=$(date "+%s")
loop_number=1

while [ $loop_number -lt 2 ]
do
    echo ">>> Loop number $loop_number"
    loop_number=$((loop_number + 1))

    # curl on each urls to generate pictures.
    if urls=$(get_urls)
    then
        for url in $urls
        do
            echo "$url"
            /opt/bin/curl -u "${CRON_LOGIN}:${CRON_PWD}" --silent --output /dev/null "$url"
        done
    else
        # If there is a problem, it's finished.
        echo "Problem with the json output, end of the script."
        exit 1
    fi

    # If there is no url, it's finished.
    if [ -z "$urls" ]
    then
        echo "There is no url, end of the script."
        exit 0
    fi

    now=$(date "+%s")
    elapsed_time=$((now - begin))

    # If the timeout is exceeded, it's finished.
    if [ $elapsed_time -ge $DURATION ]
    then
        echo "Timeout, end of the script."
        exit 0
    fi
done
  •  » Installation
  •  » [Résolu] Générer les vignettes automatiquement via un cron

Pied de page des forums

Propulsé par FluxBB

github twitter facebook newsletter Faire un don Piwigo.org © 2002-2020 · Contact