Python - send KDE knotify message with cron job on linux? - python

I'm trying to send a notification to KDE's knotify from a cron job. The code below works fine but when I run it as a cron job the notification doesnt appear.
#!/usr/bin/python2
import dbus
import gobject
album = "album"
artist = "artist"
title = "title"
knotify = dbus.SessionBus().get_object("org.kde.knotify", "/Notify")
knotify.event("warning", "kde", [], title, u"by %s from %s" % (artist, album), [], [], 0, 0, dbus_interface="org.kde.KNotify")
Anyone know how I can run this as a cron job?

You need to supply an environment variable called DBUS_SESSION_BUS_ADDRESS.
You can get the value from a running kde session.
$ echo $DBUS_SESSION_BUS_ADDRESS
unix:abstract=/tmp/dbus-iHb7INjMEc,guid=d46013545434477a1b7a6b27512d573c
In your kde startup (autostart module in configuration), create a script entry to run after your environment starts up. Output this environment variable value to a temp file in your home directory and then you can set the environment variable within your cron job or python script from the temp file.
#!/bin/bash
echo $DBUS_SESSION_BUS_ADDRESS > $HOME/tmp/kde_dbus.session
As of 2019 KDE5, it still works but is slightly different results:
$ echo $DBUS_SESSION_BUS_ADDRESS
unix:path=/run/user/1863/bus
To test it, you can do the following:
$ qdbus org.freedesktop.ScreenSaver /ScreenSaver SimulateUserActivity
You may need to use qdbus-qt5 if you still have the old kde4 binaries installed along with kde5. You can determine which one you should use with the following:
export QDBUS_CMD=$(which qdbus-qt5 2> /dev/null || which qdbus || exit 1)
I run this with a sleep statement when I want to prevent my screensaver from engaging and it works. I run it remotely from another computer beside my main one.
For those who want to know how I lock and unlock the remote screensaver, it's a different command...
loginctl lock-session 1
or
loginctl unlock-session 1
That is assuming that your session is the first one. You can add scripts to the KDE notification events for screensaver start and stop. Hope this information helps someone who wants to synchronize their screen savers across more than one computer.
I know this is long answer, but I wanted to provide an example for you to test with and a practical use case where I use it today.

Related

How to write check_mk manual checks

I have a python scripts which checks for the processes
import subprocess
s = subprocess.check_output('tasklist', shell=True)
if "cmd.exe" in s:
if "java.exe" not in str(s):
print "selenium server is not up"
if "FreeSSHDService.exe" not in str(s):
print "SSH is not up"
else:
print "Everything is awesome"
I want to add a check on check_mk dashboard, what are the steps to add this check and where I have to up this script.
import subprocess
s = subprocess.check_output('tasklist', shell=True)
if "cmd.exe" in s:
if "java.exe" not in str(s):
return 2, "selenium server is not up")
if "FreeSSHDService.exe" not in str(s):
return 2, "SSH is not up"
else:
return 0, "Everything is awesome"
First of all I'm assuming the node you want to check is MS Windows based, in which case I cannot help you much because my expertise is about UNIX and Linux.
This web link will help you to check your Windows based nodes, especially the paragrah 10. Extending the Windows agent.
In Linux, once the check_mk_agent is installed, there are three ways according to how deep you want to get into the check_mk guts. In Windows I think there are the same methods.
As a local service: you copy your python code into the local folder, whatever it is located in Windows, and edits the [global] section of the check_mk.ini configuration file to make run the py and pyc file name extensions.
As a MRPE check: you make your python program print its output according to the Nagios output check format and edit the [mrpe] section of the check_ini configuration file according to the notes in the paragraph 10.2. As a disadvantage, the WARNING and CRITICAL values/ranges are fixed in the check_ini file -- they cannot be changed in WATO.
As a check_mk agent: you turn your python program into a check_mk agent. I think this is the most difficult way because each check_mk agent has to have a counterpart definition/declaration/inventory file in the check_mk server in order to be used in WATO and to configure its parameters. I never wrote down one, but if you are keen on, you should read this guidelines.
Best regards.
If you want to execute such script you just need to put it (with the correct rights, chmod +755) in the ~/local/lib/nagios/plugins directory.
Then you have to create a rule from the "host and services parameters -> active checks -> Classical active & passive checks"
Once done, you need to enter the command line "python ~/local/lib/nagios/plugins/nameofyourscript.py"
I am not sure about the output though, still working on it for python scripts.

python code to add jobs to crontab not working

I have written a small python script to automate the process of adding jobs to crontab but the job added via the script is not working and same job when given manually working fine
HERE IS THE CODE:
#!/usr/bin/python3
def scheduler(time=["*","*","*","*","*"],message="no message set"):
crontab_pointer=open('/var/spool/cron/crontabs/sky','a')
schedule_string="\n"+" ".join(time)+" "+message+"\n"
crontab_pointer.write(schedule_string)
crontab_pointer.close()
if __name__=="__main__":
scheduler(time=["52","18","*","*","*"],message="env DISPLAY=:0 /home/sky/scripts/notify2.sh")
Permissions
Make sure the user you're running your python script as root. I did some quick testing and other users can't access their /var/spool/cron/crontabs/$username files. This is by design if I can remember correctly. You're supposed to use the crontab -e command to edit your crontab.
sudo python editcron.py
Really, the Python you've written isn't exactly wrong. It opens the file, adds the string, then closes it. Nothing ground-breaking here. I just added some file system checks in to make sure you can get to that file.
Code
import os
def scheduler(time=['*', '*', '*', '*', '*'], message='no message set', username='sky'):
crontab_fn = '/var/spool/cron/crontabs/{!s}'.format(username)
if not os.path.exists(crontab_fn):
raise StandardError("File {} missing".format(crontab_fn))
if not os.access(crontab_fn, os.W_OK):
raise StandardError("Cannot write to file, run as root")
crontab_fh = open(crontab_fn, 'a')
schedule_string = "\n{t:s} {m:s}\n".format(
t=' '.join(time),
m=message
)
crontab_fh.write(schedule_string)
crontab_fh.close()
if __name__ == "__main__":
time = ["52","18","*","*","*"]
message = "env DISPLAY=:0 /home/sky/scripts/notify2.sh"
scheduler(time, message)
NOTES from man cron:
cron searches its spool area (/var/spool/cron/crontabs) for crontab files (which are named after accounts in
/etc/passwd); crontabs found are loaded into memory. Note that crontabs in this directory should not be
accessed directly - the crontab command should be used to access and update them.
Question: ... same job when given manually working fine
I assume you use crontab <filename> here!
Search for a python module or use module subprocess.run(...) to start crontab <filename> from within your .py.
using-the-subprocess-module
Come back and Flag your Question as answered if this is working for you or comment why not.

Cron Job File Creation - Created File Permissions

I'm running an hourly cron job for testing. This job runs a python file called "rotateLogs". Cron can't use extensions, so the first line of the file is #!/usr/bin/python. This python file(fileA) then calls another python file(fileB) elsewhere in the computer. fileB logs out to a log file with the time stamp, etc. However, when fileB is run through fileA as a cron job, it creates its log files as rw-r--r-- files.
The problem is that if I then try to log to the files from fileB, they can't write to it unless you run them with sudo permissions. So I am looking for some way to deal with this. Ideally, it would be nice to simply make the files as rw-rw-r-- files, but I don't know how to do that with cron. Thank you for any help.
EDIT: rotateLogs(intentionally not .py):
#!/usr/bin/python
#rotateLogs
#Calls the rotateLog function in the Communote scripts folder
#Designed to be run as a daily log rotation cron job
import sys,logging
sys.path.append('/home/graeme/Communote/scripts')
import localLogging
localLogging.localLog("Hourly log",logging.error)
print "Hello"
There is no command in crontab, but it is running properly on the hourly cron(at 17 minutes past the hour).
FileB's relevant function:
def localLog(strToLog,severityLevel):
#Allows other scripts to log easily
#Takes their log request and appends it to the log file
logging.basicConfig(filename=logDirPath+getFileName(currDate),format="%(asctime)s %(message)s")
#Logs strToLog, such as logging.warning(strToLog)
severityLevel(strToLog)
return
I'm not sure how to find the user/group of the cronjob, but it's simply in /etc/cron.hourly, which I think is root?
It turns out that cron does not source any shell profiles (/etc/profile, ~/.bashrc), so the umask has to be set in the script that is being called by cron.
When using user-level crontabs (crontab -e), the umask can be simply set as follows:
0 * * * * umask 002; /path/to/script
This will work even if it is a python script, as the default value of os.umask inherits from the shell's umask.
However, placing a python script in /etc/cron.hourly etc., there is no way to set the umask except in the python script itself:
import os
os.umask(002)

Odoo - how to use it interactively in python interpreter?

I read here that it might be possible to use python interpreter to access Odoo and test things interactively (https://www.odoo.com/forum/help-1/question/how-to-get-a-python-shell-with-the-odoo-environment-54096), but doing this in terminal:
ipython
import sys
import openerp
sys.argv = ['', '--addons-path=~/my-path/addons', '--xmlrpc-port=8067', '--log-level=debug', '-d test',]
openerp.cli.main()
it starts Odoo server, but I can't write anything in that terminal tab to use it interactively. If for example I write anything like print 'abc', I don't get any output. Am I missing something here?
Sometime I use "logging" library for print output on the console/terminal.
For example:
import logging
logging.info('Here is your message')
logging.warning('Here is your message')
For more details, You may checkout this reference link.
The closest thing I have found to interactive is put the line
import pdb; pdb.set_trace()
in the method I want to inspect, and then trigger that method.
It's clunky, but it works.
As an example, I was just enhancing the OpenChatter implementation for our copy of OpenERP, and during the "figure things out" stage I had that line in .../addons/mail/mail_thread.py::mail_thread.post_message so I could get a better idea of what was happening in that method.
The correct way to do this is with shell:
./odoo-bin shell -d <yourdatabase>
Please, be aware that if you already have an instance of odoo, the port will be busy. In that case, the instance you are opening should be using a different port. So the command should be something like this:
./odoo-bin shell --xmlrpc-port=8888 -d <yourdatabase>
But if you want to have your addons available in the new instance, yo can make something similar to the following:
./odoo-bin shell -c ~/odooshell.conf -d <yourdatabase>
This way you can have in your odooshell.conf whatever you need to have configured (port, addons_path, etc). This way you can work smoothly with your shell.
As I always use docker, this is what I do to have my shell configured in docker:
docker exec -ti <mycontainer> odoo shell -c /etc/odoo/odooshell.conf -d <mydatabase>
You will have the env available to do anything. You can create express python code to make whatever you need. The syntax is very similar to server actions. For example:
partner_ids = env['res.partner'].search([])
for partner in partner_ids:
partner['name'] = partner.name + '.'
env.cr.commit()
Remember to env.cr.commit() if you make any data change.

Bash at and $DISPLAY, howto?

I'm working on a Python GUI application and at some point I need to be defering the execution of big parts of Python code. I have tried using at for doing it :
line = 'echo "python ./executor.py ibm ide graph" | at -t 1403211632'
subprocess.Popen(line,Shell=True)
This line gives no error and effectively starts the job at the given time.
Now, each option for executor.py is a job it has to do, and each job is protected with a try/catch log. In some cases I catch this error :
14-03-21_17:07:00 starting ibm for Simulations/140321170659
Failed to execute ibm : no display name and no $DISPLAY environment variable
Aborted the whole execution.
I have tried the following, thinking I could provide the $DISPLAY to the environement, with no success (same error):
line = 'DISPLAY=:0.0;echo "python ./executor.py Simulations/140321170936 eid defer" | at -t 1403211711'
From man at :
The working directory, the environment (except for the variables BASH_VERSINFO, DISPLAY, EUID, GROUPS, SHELLOPTS, TERM, UID, and _) and the umask are retained from the time of invocation.
Question :
What can possibly be causing this error to raise ?
How do I provide the $DISPLAY variable to at's environement ?
Solution :
I actually needed to put export DISPLAY=:0.0 inside echo so that it is set after at had started his environnement.
line = echo "export DISPLAY=:0.0; python..." | at...
subprocess.Popen(line,Shell=True)
You will need to set DISPLAY in the python script by taking the current environment, adding the DISPLAY setting and passing the new environment to the sub-shell created by Popen.
import os;
new_env = dict(os.environ)
new_env['DISPLAY'] = '0.0'
...
...
subprocess.Popen(line, env=new_env, Shell=True)

Categories

Resources