AGMSScriptOCron is a BeOS / Haiku OS program which runs templated command lines on a schedule.
AGMSScriptOCron maintains a library of Commands which can be executed when requested or when a specified time of day arrives.
The Commands are edited using BeOS / Haiku OS scripting messages, usually sent by using the "hey" command line tool. There is also a commercial version of AGMSScriptOCron with a Graphical User Interface, if you find command lines tedious.
A specialist sets up a command line template for each Model of a Command, specifying the full command line arguments and marking out key Fields within those arguments for end-user modification. Some Models come built-in, and you can create your own.
For example, a Model that pops up an alert box with an end-user defined
message would have a template something like alert --info "Message
Text"
, and a Field named Message Text with some default text that
the end-user can change to be their message.
The end-user creates their Commands by copying the Model Command and filling in the Field values with their own text, for example with AGMSScriptOCron running in the background, try this:
hey application/scriptocron get model hey application/scriptocron create command with "name=My Alert" and model=alert hey application/scriptocron set value of field "Message Text" of command "My Alert" to "Time to put on the tea kettle." hey application/scriptocron set trigger of command "My Alert" to "* * * * 0,15,30,45" hey application/scriptocron do edit of command "my alert"Most of those do the obvious thing. The first line lists the available Models, the middle ones create a Command that displays a message every quarter of an hour, the last line "do edit" saves the changes (as compared to "delete edit" which reverts to the previously saved version). Double quotes are needed around elements with spaces.
Commands are triggered either by a cron style time specification or by BeOS/Haiku scripting operations. For example, if the end-user doesn't want to wait for the next quarter hour to happen, they can manually run it like this:
hey application/scriptocron do run of command "my alert"
The alert box will pop up with the user's message. Coincidentally, a log file will be written to "settings/AGMSScriptOCron/Logs/My Alert" with time stamped output from running the Command.
A commercial program named Fetchit! with a graphical user interface built on top of AGMSScriptOCron is available from Tune Tracker Systems. The GUI covers most end user operations (though you still need to use "hey" for advanced things like creating new Fields). It lists of all your Commands, with colour coded state and progress bars for each one. Clicking on one lets you edit the values of the Fields of the Command, set the trigger time, view logs, and so on. See http://tunetrackersystems.com/fetchit.html for details and screen-shots.
Here's a longer example, showing how to create your own novel Commands. In this one, we'll make a Command to rename a file.
There will be two input Fields, one with the full path name to the file, and the other with the new name. We'll use the "mv" command line tool to do it, though it won't work across different disk volumes ("copyattr -d" would be needed, since regular "cp" doesn't copy BFS attributes). First we'll change the current directory to the location of the file (it starts out somewhere useless), then do the move.
Here are the command lines you would type in:
date > /boot/home/Junk.txt hey application/scriptocron create command with "name=Rename a File" hey application/scriptocron let command "Rename a File" do create field with name=Path hey application/scriptocron let command "Rename a File" do create field with "name=New Name" hey application/scriptocron set value of field path of command "Rename a File" to "/boot/home/Junk.txt" hey application/scriptocron set value of field "new name" of command "Rename a File" to "Trashy.txt" hey application/scriptocron set template of command "Rename a File" to "cd \"PathAsDir\" ; pwd ; mv -v \"PathAsName\" \"New Name\"" hey application/scriptocron get template of command "Rename a File" hey application/scriptocron get CommandLine of command "Rename a File" hey application/scriptocron do run of command "rename a file" hey application/scriptocron do edit of command "rename a file" hey application/scriptocron do run of command "rename a file" hey application/scriptocron get log of command "rename a file" hey application/scriptocron do run of command "rename a file" hey application/scriptocron get log of command "rename a file"
Here is what it looks like when doing it for real:
Wed Dec 30 18:04:32 605 /tmp>date > /boot/home/Junk.txt Wed Dec 30 18:05:17 606 /tmp>hey application/scriptocron create command with "name=Rename a File" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:05:24 607 /tmp>hey application/scriptocron let command "Rename a File" do create field with name=Path Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:05:31 608 /tmp>hey application/scriptocron let command "Rename a File" do create field with "name=New Name" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:05:39 609 /tmp>hey application/scriptocron set value of field path of command "Rename a File" to "/boot/home/Junk.txt" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:05:46 610 /tmp>hey application/scriptocron set value of field "new name" of command "Rename a File" to "Trashy.txt" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:05:53 611 /tmp>hey application/scriptocron set template of command "Rename a File" to "cd \"PathAsDir\" ; pwd ; mv -v \"PathAsName\" \"New Name\"" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:06:02 612 /tmp>hey application/scriptocron get template of command "Rename a File" Reply BMessage(B_REPLY): "result" (B_STRING_TYPE) : "cd "PathAsDir" ; pwd ; mv -v "PathAsName" "New Name"" "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:06:12 613 /tmp>hey application/scriptocron get CommandLine of command "Rename a File" Reply BMessage(B_REPLY): "result" (B_STRING_TYPE) : "cd "/boot/home/" ; pwd ; mv -v "Junk.txt" "Trashy.txt"" "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:06:19 614 /tmp>hey application/scriptocron do run of command "rename a file" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : -2147483634 (0x8000000E) "message" (B_STRING_TYPE) : "Can't run Command named "Rename a File" because it is Editing instead of Ready to Run" Wed Dec 30 18:06:27 615 /tmp>hey application/scriptocron do edit of command "rename a file" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:06:34 616 /tmp>hey application/scriptocron do run of command "rename a file" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:06:42 617 /tmp>hey application/scriptocron get log of command "rename a file" Reply BMessage(B_REPLY): "result" (B_STRING_TYPE) : " ================================================================================ Command "Rename a File" started on Wed Dec 30 18:06:42 2015. cd "/boot/home/" ; pwd ; mv -v "Junk.txt" "Trashy.txt" /boot/home Junk.txt -> Trashy.txt Command "Rename a File" finished on Wed Dec 30 18:06:43 2015. It provided an exit code of 0 (by convention zero means OK). " "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:06:49 618 /tmp>hey application/scriptocron do run of command "rename a file" Reply BMessage(B_REPLY): "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:07:00 619 /tmp>hey application/scriptocron get log of command "rename a file" Reply BMessage(B_REPLY): "result" (B_STRING_TYPE) : " ================================================================================ Command "Rename a File" started on Wed Dec 30 18:06:59 2015. cd "/boot/home/" ; pwd ; mv -v "Junk.txt" "Trashy.txt" /boot/home /bin/mv: Junk.txt: No such file or directory Command "Rename a File" finished on Wed Dec 30 18:07:00 2015. It provided an exit code of 1 (by convention zero means OK). " "error" (B_INT32_TYPE) : 0 (0x00000000) Wed Dec 30 18:07:07 620 /tmp>
To see what scripting operations are currently available, run
AGMSScriptOCron from the command line. The ones described here are as of
version 1.132. You can also use hey application/scriptocron
getsuites
to get the usage help text for the top level scripting
operations. For other levels, you'll have to create a Command and then do
hey application/scriptocron getsuites of command [0]
. Similarly,
hey application/scriptocron getsuites of field [0] of command [0]
will tell you what Fields can do.
Both Commands and Fields have UserData capability. This lets you store arbitrary data identified by a key word, and retrieve it later using the same key word.
Description/string. Supplies a verbose description of the Command.
DisplayType/["LocalDir"|"String"|"URL"] Specifies how to display a Field in the GUI version of the program. If not specified, you get the usual String display. The LocalDir one uses a file requester to select a directory, the resulting path always ends with a slash. The URL one breaks apart the URL (only FTP and HTTP(S) ones) into all the parts and lets the user edit each part individually before reassembling the result into a new URL (with encoding of odd characters too).
GUITitles/string. Changes the title of various GUI elements used in displaying a Field like the LocalDir one from the default of "To", "Browse" and "Save files to" to be whatever the strings are. The different elements separated by "|" characters and the order of the elements is Field DisplayType specific.
OriginalModel/string. If present then the user has not edited the template (they may have changed fields etc). The original Model's name is given by the string. Later on when doing software updates, we can replace the Template of the Command with the more recent Template from the Model of the same name. When the user changes the Template, this entry is deleted.
It's somewhat awkward to poke and prod with scripting messsages to see what's going on. You can get a quick view of what you have by looking at the settings file. It's a flattened BMessage, which you can examine with the right tools.
If you use ViewIt, with the "Dig Files" checkbox turned on, you can drag and drop the "AGMSScriptOCron Settings" file into it (and then select all with the keyboard and drag and drop the text into a text editor). The results look like this:
File: /boot/home/config/settings/AGMSScriptOCron/AGMSScriptOCron Settings BMessage file: > What='ASOC' > B_MESSAGE_TYPE "CommandList" > | What=B_ARCHIVED_OBJECT > | B_STRING_TYPE "class" "Command" > | B_STRING_TYPE "_name" "My Alert" > | B_MESSAGE_TYPE "UserData" #1 > | | What=B_SIMPLE_DATA > | | B_STRING_TYPE "key" "Description" > | | B_STRING_TYPE "result" "Pops up an alert box with your message. Set the Trigger string to be the name of some other command and this one will run when that one has finished successfully." > | B_MESSAGE_TYPE "UserData" #2 > | | What=B_SIMPLE_DATA > | | B_STRING_TYPE "key" "Original Model" > | | B_STRING_TYPE "result" "Alert" > | B_BOOL_TYPE "LogFileEnabled" 1 > | B_STRING_TYPE "Template" "alert --info "Message Text"" > | B_STRING_TYPE "Trigger" "* * * * 0,15,30,45" > | B_MESSAGE_TYPE "FieldList" > | | What=B_ARCHIVED_OBJECT > | | B_STRING_TYPE "class" "Field" > | | B_STRING_TYPE "_name" "Message Text" > | | B_STRING_TYPE "Value" "Time to put on the tea kettle."
QuickRes can also show you flattened BMessages. Start a new resource file in QuickRes, drag and drop the "AGMSScriptOCron Settings" file into it, then edit the resulting resource entry line changing its type from "RAWT" to "MSGG" (you need to click a few times on the RAWT to make it editable). Use the menu to Save As, and in the file requester "File Format" menu, pick "Source (.rdef)" and save it somewhere. Open the resulting file in a text editor to see something like this:
/* ** /boot/var/tmp/x ** ** Automatically generated by BResourceParser on ** Wednesday, December 30, 2015 at 16:21:50. ** */ #include "x.h" resource(1, "AGMSScriptOCron Settings") message('ASOC') { "CommandList" = archive(, 'ARCV') Command { "_name" = "My Alert", "UserData" = message('DATA') { "key" = "Description", "result" = #'CSTR' array { "Pops up an alert box with your message. Set the Trigger string " "to be the name of some other command and this one will run when " "that one has finished successfully." } }, "UserData" = message('DATA') { "key" = "Original Model", "result" = "Alert" }, "LogFileEnabled" = true, "Template" = "alert --info \"Message Text\"", "Trigger" = "* * * * 0,15,30,45", "FieldList" = archive(, 'ARCV') Field { "_name" = "Message Text", "Value" = "Time to put on the tea kettle." } } };
You could hack up Haiku's "rc" or the similar "beres" and "deres" tools included in the QuickRes package to convert between .rdef text files and flattened BMessages rather than resource files.
If you have questions, comments, suggestions send them to me. I'm AGMS on BeShare, agmsmith@ncf.ca by e-mail. I've got a web site too where you can find more of my BeOS / Haiku software. If it has moved due to the passage of time, try searching for "Alexander G. M. Smith". My PGP key is known as 2A2CFFBB, with key fingerprint = FB3D 3722 F680 8D23 3F2F 5B5A 653F D057 2A2C FFBB.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Hope you find AGMSScriptOCron useful! -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJWhHTnAAoJEGU/0FcqLP+7W6cP/2jkI/wiTw+GYt9drKuxq8MG CzjvYSqJ0SEySTB8O1ja5GsPfxQ249xBH2pq73L0PC85Pe2RWsFDKV/m2WKmbOC9 kUSxUaSMDcyUD0854Pe8WZEsx2wU1iKnQHsP5x0mb1gXqKFSMkvAVxX7MCQOU8W2 1af7LHkS5zggOtE6fsXujrJLU+kFjdq51EXyzmBdFwBi9P6TadxP+Hj8v727SYv9 IYaNllMFDlIewxpQdCTpMNl8JPwHFyLBA5+w1ucXJlB1GsVhq1m1A3v33UYeEGB9 If4rVidtnPsddchmIc+D6OVYHe0UbbDKcYVNwODq7zHxoXXm21M7JO3eDeYGFHim zWrO3AsxHJZ+94oTEt1ILJCTxUPzVpY1AEBh6Qdm8RbjXciaQq+T/6PWiB7lTT+A V5jCtu+poWKft/rh/+BLJf4DnD9DF+yS4Ft91NCLcdsiVTVKzWJrsINtO8qytqL2 Rl9tEcemZvuX8u+n4jorEPxVG4saIUBkgUxBg2UHzpi9jjFwOrdn1BP65fvG9ocV ME8JcYDMz1RL77iQcWDgZBHNirjpnoIjwFK1lemWyDyM4VQzXBT6kB3ab1Lt73Gz xiG5l9J4YGtAnVSdfwSwyEWjbIgN3AeMfqf0GKGiHQhTBfh5nzPWsY+6QnUbalY0 FcrT1gRt4KLcnyrX4UfC =TOlS -----END PGP SIGNATURE-----
Copyright © 2015 by Alexander G. M. Smith.