Every time now and then we want to automate tasks. Sometimes it is just a repetitive task and sometimes we want to do a complex task without having to remember each particular step. If the task is not general enough (say – applies to a single workflow) it does not have specialised GUI. On the other hand if one of steps involve GUI it cannot be done from commandline (shell script) alone.
There are a few requirements I consider basic to operation of scripting in GNOME:
- Language agnostic. Person who writes script might now one language and (s)he might not want to learn another one. (S)he might have other scripts (s)he wants to integrate – if possible the scripting framework should not force the user to change the programming language. Such framework would allow to write even new, user-oriented languages or even ‘GUI’ scripting (programming by blocks dragged’n’dropped instead of text)
- Live ‘outside’ program. It might be useful to script one application but the usecase I have in mind might involve more than one application. For example I might want to open an attachment from Evolution in Evince and print it.
- Hide ‘memory problems’. Text editor might contain thousands of words in a single document – it’s bad idea to have one object per character or even per word even if we want the client to be able to operate on single characters or even ranges of characters. On the other hand we don’t want to leak objects just because someone have forgotten to unref object on client, client crashed or get into infinite loop.
- Support hooks. For example I might want to run script when I receive an email or when battery is low.
It seems that it would be possible to build the system on top of DBUS. It already have good cross language support, does not involve any other dependencies and with tricks can avoid mentioned before memory problems.
The biggest problem right now is that most binding support only export of heavy objects – i.e. general assumption is that a dbus object corresponds to language object (both in bindings as well as standard interfaces). Fortunately it is not an assumption made neither by dbus routing nor by dbus protocol (or in fact dbus). It is possible to register a wildcard handler in libdbus (but not, for example, in gdbus) to receive all messages that have not been received by anything else.
The last part is sending – such wildcard would require (from what I understand) to send to specific endpoint. It would not only be inconvenient for user but also seems to not be supported by many bindings. Again fortunately the dbus protocol supports filtering messages by beginning of path (for example all to /org/gnome/Evolution/Script).
Well – to start with I haven’t written any prototype even – just read the documentation of dbus and libdbus. There are a few things omitted in the text – for example the script might be run in application or by daemon. Each approach have certain benefits/drawbacks.
Running in application might be faster if script just operate on objects in given application. On the other hand spawning a few VM in application might hurt the performance (say we have one script in perl and one in python to run on each message). Also a script might crash/hang whole application
Daemon on the other hand might spawn a pool of VMs (if they are sandboxed) and respawn them if any crashes. The scripts might run asynchronously (at least to some extend) as well. However it makes the architecture a bit more complex and distinguish between one time scripts (which don’t use daemon) and hooks (running in daemon).