Many services seem to provide automatic email reminders these days – notably Google Calendar; however what I need is something that can send me daily reminders about things, and setting up a Google calendar with daily repeats seems an altogether inelegant solution. Virgin Media operates a throttling policy in which downloading is limited between 10am and 3pm, and again between 4pm and 9pm. As far as I’m concerned, all this means is I need to make sure I’m not downloading much between those times. I thought of setting up my various alarm clocks and watches to ring at 10am, 3pm, 4pm and 9pm to remind me – but considering I’d have to use four different devices (none of my alarm clocks support multiple alarms) and the fact that it would all be useless if I’m not at home, the best solution is to use a daily email reminder which would alert me even if I’m working off my laptop at school (for example).
I also jumped at the opportunity to find out more about Linux and PHP; besides I didn’t want to sign up for several free email reminder services hunting for a good one so opted simply to write my own. For the sake of anyone attempting to implement any of the features of PHP and Linux I used, here is my solution which can essentially be broken down into four parts:
1. Emailing script
It was fairly easy to find out how to send an email via SMTP in PHP so I set up a script to connect to my gmail and send an email from there to myself. After turning it all into a function, in accordance with the modular approach to development, I was ready to proceed.
This was more difficult. PHP can’t by itself do anything on a schedule so it was necessary to delve into Debian’s scheduling system. I tried to look up how to make the damn thing work and eventually found (amongst other irrelevant info – hurry up Wolfram Alpha and add support for coders!) how to use it. It seems like cron is already pre-installed upon Debian installation, and is constantly running as a daemon. It checks a file every minute to check whether it should be executing a scheduled task. To edit this file you type ‘crontab -e’ and get a plaintext editing interface (looks like vi). The format of the file is a list of lines, each one representing a scheduled task. Each line’s format is:
[minute : int] [hour : int] [day of month : int] [month of year : int] [year : int] [script pathname : string]
So to run the program ‘rtorrent’ at 17:30 every 3rd of the month, you go:
30 17 3 * * rtorrent
Asterisks are, as always, wildcards. To execute a process every minute, the first 5 terms look like ‘* * * * *’. There is a slight problem with this: you can’t use vi from a PHP script (at least it’s not possible using exec). It turns out there’s an alternative way of using crontab – by importing a file. So the command looks like:
Great. So the PHP script creates a text file containing the new line then executes a command to add that file to the cron file. Eventually I set it to run the script every minute and have the script itself check for whether it should be doing anything by referencing a MySQL database.
So in the end the PHP looked like this:
$fh = fopen(“foo.txt”, ‘w’) or die(“can’t open file”);
$stringData = “* * * * * /opt/lampp/bin/php /opt/lampp/htdocs/php/ereminders/s_mail.php &> /dev/null\n”;
exec(“crontab foo.txt” . ‘ 2>&1’, $output);
The &> /dev/null is just to stop it ‘helpfully’ sending email to root every time it runs (i.e. every minute) containing a log of exactly what happened.
It’s a fairly simple MySQL thing – nothing fancy. I wrote a nice function in PHP to tabulate the results of a query which I use in my screenshot. It’s a single table and I haven’t bothered to normalise it or anything. Nothing to see here. Move on.
4. Admin panel
This was, like with most good things, the final stage of development. I was also getting lazy and bored so it’s pretty rudimentary; I wrote it just so I don’t have to go into PHPMyAdmin to change things. It makes use of that rather neat ‘tabulate’ function that I had written which tabulates the MySQL query. The var_dump is the contents of the cron file.
In hindsight, this is pretty good for two hours’ work, especially considering about half an hour was spent writing scripts to automate things from an admin panel. I’ve also actually found it quite useful (pardon the surprise) – the other day I wanted to download
an episode of Lost Windows 7 but the throttling period had already started and that one download would probably have pushed me over the download limit. At exactly 9pm I got an email reminding me to download so was able to watch the episode install the OS that very night. Though I doubt it’ll be much use to anyone other than me since there exist systems out there that do the same thing, just much better (probably).