1

So i have a code that i'm trying to run and when it finish it should display a message to the user saying what changes have happend. This works fine if i run it on terminal. But when i add it to a cronjob nothing happens and no error is shown. It seems to me that it is losing the display session, but cant figure it how to solve it. Here is the show message code:

def sendmessage(message):
    subprocess.Popen(['notify-send', message])
return

I also tried this version:

def sendmessage(message):
    Notify.init("Changes")
    n = Notify.Notification.new(message)
    n.show()
return

Which gives the error (only in background also):

cannot open display: Activated service 'org.freedesktop.Notifications' failed: Process org.freedesktop.Notifications exited with status

Would be very thankful for any help or alternative given.

Luis Campos
  • 93
  • 1
  • 10
  • 1
    You need access to run programs in another user's X session. See [this answer](https://stackoverflow.com/a/1584434/154762) for how to do this. – solarc Jul 13 '17 at 14:53

1 Answers1

2

I had a similar issue running a system daemon, where I wanted the user to be notified about a network bandwidth upload being exceeded.
The program was designed to run under systemd but at a push also under upstart.

You may get some mileage out of my configuration files:

systemd - bandwidth.service file

[Unit]
Description=Bandwidth traffic monitor
Documentation=man:bandwidth(7)
After=graphical.target

[Service]
Type=simple
Environment="DISPLAY=:0" "XAUTHORITY=/home/#USER#/.Xauthority"
PIDFile=/var/run/bandwidth.pid
ExecStart=/usr/bin/dbus-launch /usr/sbin/bandwidth_logd
ExecReload=/bin/kill -HUP $MAINPID
User=root

[Install]
WantedBy=graphical.target

upstart - bandwidth.conf file

#
# These are the scripts that run when a network appears.
# Use this on an upstart system in /etc/init
# test for systemd or upstart system with
# ps -p1 | grep systemd && echo systemd || echo upstart
# better
# ps -p1 | grep systemd >/dev/null && echo systemd || echo upstart
# Using upstart the script will need to daemonise which is a bugger
# so test for it and import Daemon_server.py
description "Bandwidth upstart events"

start on net-device-up     # Start a daemon or run a script
stop on net-device-down  # (Optional) Stop a daemon, scripts already self-terminate.
# Automatically restart process if crashed
respawn

# Essentially lets upstart know the process will detach itself to the background
expect fork

#Set environment variables
env DISPLAY=":0"
export DISPLAY
env XAUTHORITY="/home/#USER#/.Xauthority"
export XAUTHORITY 

script
# You can put shell script in here, including if/then and tests.
# replace #USER# with your name and ensure that you have .Xauthority in $HOME

/usr/sbin/bandwidth_logd
end script

You will note that in both configuration files the environment becomes key and #USER# is replaced by a real user name with a valid .Xauthority file in their $HOME directory.
In the python code I use the following to emit the message(import notify2).

def warning(msg):
    result = True
    try:
        notify2.init("Bandwidth")
        mess = notify2.Notification("Bandwidth",msg,'/usr/share/bandwidth/bandwidth.png')
        mess.set_urgency(2)
        mess.set_timeout(0)
        mess.show()
    except:
        result = False
    return result
Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60