One of the first exercises of the Unix (then: Linux) books of yore was using the "at" command to create reminders (or, alarms). If memory serves, it went like this:
$ echo "echo \"Go home!\" > /dev/tty " | at 17:00
Because this is way too much typing, you were then taught how to plop it in a /usr/local/bin script:
alarm.sh:
#!/bin/sh
echo "echo \"$1\" > /dev/tty" | at $2
Those were the tty days. Enter the GUI (or, even, multiple terminals) and your nifty alarm utility does not cut it any more, essentially because you're not usually looking at the right window when the alarm is echoed. Using xdialog or knotify in place of echo does not cut it either, as both rely on being able to connect to the X display (which they cannot do, because they are activated by atd outside the current desktop session).
Of course there must be thousands of fancy reminder/alarm apps from the desktop to the web-based, but none (that I could find) that'd allow me to set a simple reminder by typing it in the terminal I happen to have my focus on.
Enter libnotify and its command line minion notify-send:
alarm.sh:
#!/bin/bash
TITLE=$3
[[ x$TITLE == x ]] && TITLE="Sveglia!!!!"
echo /usr/bin/notify-send -u critical \"$TITLE\" \"$2\"\
|at -m "$1"
And then:
$ alarm.sh 13:00 "Aren't you hungry?" "Lunch time"
The -m switch tells at to send you mail when it fires - Fedora pre 20 users may want to take notice of this bug report and compensate accordingly. Of course, the atd service must be running for this to work.
L'uso di questo sito
autorizza anche l'uso dei cookie
necessari al suo funzionamento.
(Altre informazioni)
Showing posts with label CLI. Show all posts
Showing posts with label CLI. Show all posts
Friday, August 8, 2014
Tuesday, June 17, 2014
Running Django scripts from the CLI (Command Line Interface)
Like many frameworks embedding an ORM, Django offers an attractive SQL-less interface to your DBMS, whose worth transcends its usefulness in the traditional web interface.
Which one do you like better:
SELECT n.name m.type FROM nodes n, model m WHERE n.mid=m.id AND m.make='Qfwfq';
or
them=Node.objects.filter(model__name='Qfwfq')
for q in them:
...
Yes, I thought so.
However, python's inclusion rules combine with Django's deployment rules to make writing general scripts of this sort a little awkward. The problem is that, for the above goodies to work, all of the django instrumentation surrounding your app has to be available to the python interpreter, a job that is usually taken up by manage.py when invoked from the deployment folder. That is the effect we want to achieve within our own scripts.
After some mulling, this is what i came up with:
#!/usr/bin/python
#File: prologue.py
import os
import sys
#assumes we are in DJANGO_DIR/sbin
#find our own location
_pdir=os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
#find DJANGO_DIR
_cdir=os.path.dirname(_pdir)
#prepend to include path
sys.path.insert(0,_cdir)
#tell django where settings.py is
os.environ['DJANGO_SETTINGS_MODULE']='settings'
I keep all the django related scripts in a sbin/ subdirectory of the directory where manage.py is located and they all start with:
#!/usr/bin/python
Obviously, prologue.py must live in the same folder. I then symlink them to somewhere in system's $PATH (that's usually /usr/local/bin).
This way, every script will get the correct sys.path and the right DJANGO_SETTINGS_MODULE from prologue.py; prologue.py is always found because it's in the same path as the script. The abspath(realpath()) incantation does away with finding the actual path of the prologue.py file under symlinks and other surprises.
Some folks may prefer inserting at the end of, rather then in front of, sys.path. They should use sys.path.append(_cdir).
Et voilĂ .
Edit:
Discussions on reddit on this this topic prompted me to clarify the purpose a bit.
The whole gist of all this is the toolification of Django. This does not (solely) mean being able to type django commands from the (Linux) command line (though that is nice, too). It rather means creating scripts that can then be used by other tools, without needing to know where the particular Django app lives, not even within the script code. (Picture wanting to relocate your django app to some other folder.)
Which one do you like better:
SELECT n.name m.type FROM nodes n, model m WHERE n.mid=m.id AND m.make='Qfwfq';
or
them=Node.objects.filter(model__name='Qfwfq')
for q in them:
...
Yes, I thought so.
However, python's inclusion rules combine with Django's deployment rules to make writing general scripts of this sort a little awkward. The problem is that, for the above goodies to work, all of the django instrumentation surrounding your app has to be available to the python interpreter, a job that is usually taken up by manage.py when invoked from the deployment folder. That is the effect we want to achieve within our own scripts.
After some mulling, this is what i came up with:
#!/usr/bin/python
#File: prologue.py
import os
import sys
#assumes we are in DJANGO_DIR/sbin
#find our own location
_pdir=os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
#find DJANGO_DIR
_cdir=os.path.dirname(_pdir)
#prepend to include path
sys.path.insert(0,_cdir)
#tell django where settings.py is
os.environ['DJANGO_SETTINGS_MODULE']='settings'
#!/usr/bin/python
import prologue
Obviously, prologue.py must live in the same folder. I then symlink them to somewhere in system's $PATH (that's usually /usr/local/bin).
This way, every script will get the correct sys.path and the right DJANGO_SETTINGS_MODULE from prologue.py; prologue.py is always found because it's in the same path as the script. The abspath(realpath()) incantation does away with finding the actual path of the prologue.py file under symlinks and other surprises.
Some folks may prefer inserting at the end of, rather then in front of, sys.path. They should use sys.path.append(_cdir).
Et voilĂ .
Edit:
Discussions on reddit on this this topic prompted me to clarify the purpose a bit.
The whole gist of all this is the toolification of Django. This does not (solely) mean being able to type django commands from the (Linux) command line (though that is nice, too). It rather means creating scripts that can then be used by other tools, without needing to know where the particular Django app lives, not even within the script code. (Picture wanting to relocate your django app to some other folder.)
This is why the execfile('myfile.py') feature of manage.py is not relevant in this context, nor is the possibility of adding commands to manage.py via the management commands feature of Django: in both instances, one has to run the correct manage.py, which lives in the app dir hierarchy. The django-extensions package, which allows to run jobs from manage.py, succumbs to the same objection here (at least, I suppose: I haven't reaaly looked extensively into django-extensions, though I will as it looks pretty cool in its own right).
Subscribe to:
Posts (Atom)