Please see this page for the latest version
Don't we all like braindumping important stuff with the relaxing certainty of not losing track of it?
Sending yourself an email is a possibility. But your email program doesn't remind you of that approaching deadline, automatically. Also, that email with that brilliant idea for a birthday gift doesn't pop up by itself. And finally, the link to that interesting article you could not finish reading in the subway will most likely get lost in the daily flood tide of mails we all love so much.
But still, the idea of sending a short email is charming. So, why not adding a little intelligence? It would be cool to just send a link and receive a copy of that interesting article via email. Also, a daily summary of all approaching deadlines and ideas for birthday gifts would be really helpful. That is what this collection of scripts is for.
The whole idea is to send an email to this program which then creates a reminder, stores that idea of a birthday gift, or downloads the web-article. This short introduction will focus on sending and receiving daily reminders, though.
daily reminders¶
This module manages a remind-compatible file with all reminders for important (and not-so-important) deadlines coming up. It also puts together a summary of all reminders remind
reminds you of.
what is remind?¶
From the remind wiki we learn that remind
is a
- UNIX command-line tool that reads a text file for its database
- Sophisticated tool for date calculation
- Scripting-language interpreter
A remind
-file may look like this:
REM 26 Mar MSG David's birthday
REM 19 Jan 2017 +3 MSG README finally finished? %x days left!
REM 6 Jan 2017 *14 MSG Go have a beer!
With those reminders you are notified about David's birthday on every 26th of March every year. Also, you are notified on that upcoming deadline for finishing this README. The deadline was set to 19th of January 2017 and notification starts 3 days in advance. On 16th of January 2017 the reminder-message will interpret to "README finally finished? 3 days left!". And finally, starting on January 6 in 2017, you will be notified to go have a beer on every second Friday (if you really need a reminder for that...).
Saving those reminders to a file and calling the UNIX command-line tool with remind /path/to/that/file
will interpret the scripting-language and output the given messages with %
-directives being replaced. Calling the above-given example on January 16, 2017, for example will output
README finally finished? 3 days left!
For a list of possible substitutions, go to the man page and look for the chapter "The Substitution Filter".
what does this 'daily'-module do?¶
This module takes your email and creates a remind
-compatible line. Also, it puts together a summary of all your reminders (based on the output of remind
).
First of all, why do I speak about "modules" all the time? Well, because daily
is only one part of my pim
-toolkit. The pim
-toolkit itself is only a wrapper for different modules. All modules reside as a subpackage in the Python-package pim_modules
. The submodules will be loaded dynamically at runtime. Every module needs at least two files: a __init__.py
, and a receive.py
. The __init__.py
gives some hints on the functionality of the module, e.g. does it accept answers. The receive.py
needs to specify one method receive(msg, isreply=False)
to handle incoming mails. If a module's information should be included in a summary-mail, the __init__.py
needs to point to an additional Python-file in the field MODULE_OUTPUT
. But, let's move on to an example to illustrate its functionality:
Inside the daily
-module's folder you will find the above-mentioned __init__.py
, a receive.py
, and an additional getreminders.py
. The receive.py
takes an email as an argument, fetches the message text from it and creates one or more reminders. All those reminders will then be appended to OUTFILE
wich is, again, specified inside the __init__.py
.
The __init__.py
in its field MODULE_OUTPUT
points to getreminders
. So, the summary of your reminders is put together by the function getreminders
inside getreminders.py
. The summary originates from a sys-call to remind
, of course. The getreminders
task is basically to call remind
to interpret the reminders.
how to send in reminders¶
Generally, I didn't change the syntax of the remind
-scripting-language. I just added some help in creating a remind
-compatible line: Especially when sending in several reminders at once from your mobile, typing "REM" and "MSG" every time can be cumbersome. Therefore, your mail must contain an even number of lines. The first line of every pair of lines will be prefixed with "REM" and glued together with the second line seperated by that "MSG"-tag. So, for example, if you want to send in two of the above-given example reminders, put together the following email:
26 Mar
David's birthday
6 Jan 2017 *14
Go have a beer
Very important: The eMail needs to have the subject 'daily', because the module handling your eMail is selected by the subject of your mail!
Another extension is to calculate certain dates. This was motivated from being reminded of cancelation periods. Often, these are mentioned like "6 weeks before 31 Jan 2021". To being reminded on the day (or some days before) you need to cancel the contract, send in the following email:
6 weeks before 31 Jan 2021 +10
Cancel that contract %b!
If you want to do your calculations with days or years, go ahead:
132 days before 15 Feb 2020
There are 132 days until %e
3 years before 15 Feb 2028
In three years, you know what to do!
where are your reminders stored?¶
Have a look into the config.ini
in /etc/pim/
. It contains all configuration for the pim
-toolkit and all its modules. The Base
-section contains eMail-addresses that are allowed to send in stuff, the eMail address that receives a daily summary as well as status messages, and some other infos.
[Base]
allowed_senders = a@b.cd
receiver = me@somwhere.de
dummy_sender = reminder@somewhere.de
subject_in_reply = [reminder] Status
[daily]
subject = Teux Deux
my_name = Me
[daily_1]
title=Let yourself be reminded of some important stuff
command=#REMINDFROMFILE# /path/to/your/reminders
The daily
-section refers to the daily
-module. The subject will be the subject of your daily summary, and your name will be used to address you. The daily_1
-section contains information about where your reminders are stored. The given file contains all reminders that you sent in. This file needs to be writable by your mailserver, by the way.
receiving reminders...and more!¶
All your reminders will be processed by getreminders.py
which puts together a nice daily summary of important deadlines and appointments. I use a cron
-job to let this summary being sent to me every morning.
But wait, there is more!
You can create reminders from iCal files and be reminded of upcoming dates as well. Therefore, add a section like this to the config.ini
in /etc/pim/
:
[daily_2]
title=Upcoming conference deadlines
command=/usr/bin/wget -q -O- http://wikicfp.com/cfp/servlet/event.showcal?list=50295 | #ical2rem.pl# --lead-time +90 | grep Deadline | #REMINDPIPE#
This, for example, fetches my conferences from wikiCFP as an iCal file, pipes the file to the nifty script ical2rem.pl
I found at dsoulayrol's github, selects the Deadlines from the resulting reminders, and pipes them to remind
. Everything between hashtags will be parsed by getreminders
, basically, because it knows absolute paths to the ical2rem.pl
-script, and the neccessary parameters to remind
.
This is also an example on how to add more reminders. Simply add a section daily_X
where X
is an ongoing number, and add the fields title
and command
to it.
installation¶
Cool, you're still here. You really want to know, huh?
To install the pim
-toolkit with the daily
-module, checkout the git repository or download the release tar-ball. In the directory of the git or the extracted (tar -xvf pim-0.1.tar.gz
) tar-archive, call
./configure
make
sudo make install
Use the parameters --prefix=
, --localstatedir=
, and --sysconfdir=
to the call to ./configure
to specify the installation directory as well as the location of the configuration file. The installation directory defaults to /usr/local/
, the local state directory to [PREFIX]/var/
, and the configuration directory to [PREFIX]/etc/
. You might want to set --prefix=/
.
Also make sure to check out ./configure --help
to see what else you can adjust to your needs:
Some influential environment variables:
PYTHON the Python interpreter
RCV_BASE_PATH 'set location of log output dir'
DAILY_BASE_PATH 'set location of reminders file'
CRONPATTERN 'set cron pattern to configure sending of reminder'
MAILALIAS 'set mailalias for receiving mails'
PIM_CONFDIR 'set directory for config file'
MAIL_USER 'username of mailserver'
The installation routine will add an alias to your [PREFIX]/etc/aliases
:
pim: "| /path/to/mainreceiver"
This ensures that mails to pim@yourdoma.in
will be handled by the pim
entry point. Of course, pim
will be set to the value of MAILALIAS
specified in the call to configure
.
requirements¶
- Python >= 3.5
- Python-package
dateparser
(install usingpip3 install dateparser
) - Perl-package
iCal::Parser
(install usingcpan iCal::Parser
) - mailserver accepting mails
sendmail
- remind
a detail made explicit¶
As stated above, this whole pim
-toolkit is based upon email-communication. Therefore, this program together with the daily
-module has two main entry-points: the mainreceiver
and sendreminder
.
The mainreceiver
processes emails. At this point, it takes an email from stdin
, decides which module is responsible for further processing, activates that module, and passes on the email. The decision on which module to choose is based on the subject of the email. Precisely, the subject has to be the name of the submodule. That is, to save a reminder would require an email with the subject daily
because the corresponding submodule is located in a folder with that name.
The second entry-point of the program is sendreminder
. This script doesn't take any input but puts together an email with the summary of the modules that state a method in the field MODULE_OUTPUT
of the respective __init__.py
. The output of the modules is collected and sent via a sys-call to sendmail
. The call to sendreminder
is best to be outsourced to cron
.