2016-11-22 2 views
0

J'ai un projet django très simple qui consiste en un modèle d'application appelé Quote. L'application a simplement un travail cron qui s'exécute toutes les 1 minute pour obtenir une citation aléatoire de la base de données et utiliser la commande notify-send pour afficher une notification avec cette citation. J'utilise django-crontab pour atteindre cet objectif.Le travail django crontab ne fonctionne pas

Le cron.py est très simple comme indiqué ci-dessous

from random import randint 
from models import Quote 
import subprocess, time, os 

def notify(): 
    latestQuote = Quote.objects.all().order_by("-id")[0] 
    max_id = latestQuote.id 
    quote = Quote.objects.get(pk=randint(1,max_id)) 
    subprocess.Popen(['notify-send',quote.quote]) 
    time.sleep(1) 

Et voici les paramètres Cron dans le module Paramètres

CRONJOBS = [('*/1 * * * *', 'core.cron.notify')] 

Lors de l'exécution ./manage crontab add, une commande Cron est ajouté à mon crontab comme suit

*/1 * * * * /usr/bin/python /home/anas/storage/motinder/manage.py crontab run 5ade4dc167538a33802640eeb92219ad # django-cronjobs for motinder 

Si j'ai exécuté la commande à partir du système crontab, la notification est affichée avec succès MAIS le travail cron ne s'exécute pas automatiquement.

Modifier

J'ai changé le code dans le fichier cron.py pour envoyer une notification statique au lieu d'obtenir la citation de la DB. Vérifiez ci-dessous

from random import randint 
from models import Quote 
import subprocess, time, os 

def notify(): 
    #latestQuote = Quote.objects.all().order_by("-id")[0] 
    #max_id = latestQuote.id 
    #quote = Quote.objects.get(pk=randint(1,max_id)) 
    #subprocess.Popen(['notify-send',quote.quote]) 
    subprocess.Popen(['notify-send',"TEST"]) 
    time.sleep(1) 

Malheureusement, la situation est la même.

+0

Vous n'avez vraiment pas besoin d'applications tierces pour configurer un conjob, toutes ces complications peuvent être évitées en configurant simplement votre notify.py en tant que CLI et en l'ajoutant directement à crontab http://stackoverflow.com/documentation/django/5848/django-from-the-command-line # t = 201611230712189521958 – e4c5

+0

appréciant votre commentaire @ e4c5 mais mon point ici est d'utiliser Django ORM pour faciliter l'interrogation sur la base de données.Une note de plus, j'ai essayé la même approche en utilisant un simple script python qui ne fait rien sauf exécuter la commande 'notify-send' mais la situation reste la même. – Fanooos

+0

Et c'est exactement ce que je suggère aussi. sans tout ce hocus pocus de popen. – e4c5

Répondre

0

Avez-vous essayé d'avoir la bonne ligne Shebang au-dessus de votre script python et rendre votre fichier exécutable avec chmod +x?

#!/usr/bin/env python 

from random import randint 
from models import Quote 
import subprocess, time, os 

def notify(): 
    latestQuote = Quote.objects.all().order_by("-id")[0] 
    max_id = latestQuote.id 
    quote = Quote.objects.get(pk=randint(1,max_id)) 
    subprocess.Popen(['notify-send',quote.quote]) 
    time.sleep(1) 
+0

La commande exécute le script manage.py de Django avec une commande personnalisée 'crontab' et le fichier manage.py contient déjà la ligne que vous avez publiée et est également exécutable par défaut. – Fanooos

+0

Avez-vous des erreurs CRON dans '/ var/log/syslog'? – molivier

+0

nop, Voici la sortie apparaît dans le syslog 'Nov 22 11:55:01 DEVPC-01 CRON [25401]: (anas) CMD (/ usr/bin/python/home/anas/stockage/motinder/gérer .py crontab exécuté 5ade4dc167538a33802640eeb92219ad # &>/tmp/mycommand.log # django-cronjobs pour motinder) ' – Fanooos

0

Où est 'notify-send'? cron ne fonctionne pas dans le même environnement que votre shell de connexion, et python peut donc ne pas savoir où le trouver.

Vous pouvez vous aider en forçant quelque chose à se produire si l'appel Popen() échoue. Actuellement, rien ne se passera, car vous n'en capturez aucune sortie.

(De plus, il est généralement mauvais de ne pas attendre que vos appels Popen pour terminer, sauf si vous avez une bonne raison.)

Il existe différentes fonctions d'utilité dans subprocess pour vous aider. Essayez ceci:

def notify(): 
    subprocess.check_call(['notify-send',"TEST"]) 

Cela bloque jusqu'à ce que le processus se termine, et lever une exception qui sera imprimé à stderr si elle échoue, par exemple parce qu'il ne peut pas trouver 'notify-send', qui devrait aller à /var/log/cron (ou éventuellement /var/log/syslog sur votre système?) et qui vous permettra de déboguer plus loin.