python-notify module & cron: gio.Error

与世无争的帅哥 提交于 2021-01-29 04:55:52

问题


I'm asking some help to show notifications using python-crontab, because everything I've tried do not work. The display is not initilised when the script is launched by cron. When I start it manually, that's work. The codes I've tried:

    #!/usr/bin/env python
    # coding: utf8

    import subprocess
    import os

    #os.environ.setdefault("XAUTHORITY", "/home/guillaume" + "/.Xauthority")

    #os.environ.setdefault('DISPLAY', ':0.0')     # do not work
    #os.environ['DISPLAY'] = ':0.0'               # do not work
    print = os.environ

    cmd2 = 'notify-send test'
    subprocess.call(cmd2, shell=True)

    # more code, which is working (using VLC)
    cmd3 = "cvlc rtp://232.0.2.183:8200 --sout file/mkv:/path/save/file.mkv" # to download TV's flow
    with open("/path/debug_cvlc.log", 'w') as out:
        proc = subprocess.Popen(cmd3, stderr=out, shell=True, preexec_fn=os.setsid)
    pid = proc.pid                  # to get the pid
    with open("/path/pid.log", "w") as f:
       f.write(str(pid))            # to write the pid in a file
    # I'm using the pid to stop the download with another cron's task, and to display another notify message. 
    # Download and stop is working very well, and zenity too. But not notify-send

Thanks

Edit: here are the environment variables I have for this cron's script:

{'LANG': 'fr_FR.UTF-8', 'SHELL': '/bin/sh', 'PWD': '/home/guillaume', 'LOGNAME': 'guillaume', 'PATH': '/usr/bin:/bin', 'HOME': '/home/guillaume', 'DISPLAY': ':0.0'}

Edit2: I'm calling my script in cron like this:

45 9 30 6 * export DISPLAY=:0.0 && python /home/path/script.py > /home/path/debug_cron_on.log 2>&1

I precise I have two screens, so I think DISPLAY:0.0 is the way to display this notify.. But I don't see it.

Edit3: It appears that I've a problem with notify-send, because it's working using zenity:

subprocess.call("zenity --warning --timeout 5 --text='this test is working'", shell=True)

I have notify-send version 0.7.3, and I precise that notify-send is working with the terminal.

Edit4: Next try with python-notify.

import pynotify
pynotify.init("Basic")
n = pynotify.Notification("Title", "TEST")
n.show()

The log file show this: (in french)

    Traceback (most recent call last):
      File "/home/path/script.py", line 22, in <module>
        n.show()
    gio.Error: Impossible de se connecter : Connexion refusée 
 #Translating: Unable to connect : Connection refused

So, I have problem with dbus? what is this?

Solution: Get the DBUS_SESSION_BUS_ADDRESS before creating the cron order:

cron = CronTab()
dbus = os.getenv("DBUS_SESSION_BUS_ADDRESS")   # get the dbus
# creating cron  
cmd_start = "export DBUS_SESSION_BUS_ADDRESS=" + str(dbus) + " && export DISPLAY=:0.0 && cd /path && python /path/script.py > path/debug_cron.log 2>&1"
job = cron.new(cmd_start)
job = job_start.day.on(self.day_on) # and all the lines to set cron, with hours etc..
cron.write()             # write the cron's file

Finally, the cron's line is like that:

20 15 1 7 * export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-M0JCXXbuhC && export DISPLAY=:0.0 && python script.py

Then the notification is displaying. Problem resolved !! :)


回答1:


You are calling the cron like

45 9 30 6 * DISPLAY=:0.0 python /home/path/script.py > /home/path/debug_cron_on.log 2>&1

which is incorrect, since you are not exporting the DISPLAY variable, and the subsequent command does not run.

Try this instead

45 9 30 6 * export DISPLAY=:0.0 && cd /home/path/ && python script.py >> debug_cron.log 2>&1

Also, you are setting the DISPLAY variable within your cron job as well, so try if the cron job works without exporting it in the job line

45 9 30 6 * cd /home/path/ && python script.py >> debug_cron.log 2>&1

EDIT

While debugging, run the cron job every minute. Following worked for me:

Cron entry

* * * * *  cd /home/user/Desktop/test/send-notify && python script.py

script.py

#!/usr/bin/env python

import subprocess
import os

os.environ.setdefault('DISPLAY', ':0.0')
print os.environ

cmd2 = 'notify-send test'
subprocess.call(cmd2, shell=True)

EDIT 2

Using pynotify, script.py becomes

#!/usr/bin/env python

import pynotify
import os

os.environ.setdefault('DISPLAY', ':0.0')

pynotify.init("Basic")
n = pynotify.Notification("Title", "TEST123")
n.show()

and cron entry becomes

* * * * *  cd /home/user/Desktop/test/send-notify && python script.py

EDIT 3

One environment variable DBUS_SESSION_BUS_ADDRESS is missing from the cron environment. It can be set in this and this fashion




回答2:


crontab is considered an external host -- it doesn't have permission to write to your display.

Workaround: allow anyone to write to your display. Type this in your shell when you're logged in:

xhost +


来源:https://stackoverflow.com/questions/24468794/python-notify-module-cron-gio-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!