From 4c358456ec4129e8c27c5b0274fd92277795bf00 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Thu, 20 Mar 2014 17:23:15 +0100 Subject: [PATCH 1/1] update README --- README.rst | 128 +++++++++++++++++++++++++++++++++++++++++++++++++- docs/html.png | Bin 0 -> 10608 bytes 2 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 docs/html.png diff --git a/README.rst b/README.rst index 2fcf4a2..b0cb9c1 100644 --- a/README.rst +++ b/README.rst @@ -5,6 +5,7 @@ Birthday reminder that sends out e-mails. It can also generate ASCII tables on your console/shell and normal HTML pages. +.. contents:: ======== Features @@ -25,6 +26,69 @@ Output formats - Email (text + HTML parts) +===== +Usage +===== + +Command line +============ +After configuration_, you can test and use *bdrem* via command line:: + + $ bdrem + ----------------------------------------------------------- + Days Age Name Event Date Day + ----------------------------------------------------------- + 0 32 Foo Bar Birthday 20.03.1982 Do + 1 33 Andrea Milestone Birthday 21.03.1981 Fr + 7 32 Hugh Success Birthday 27.03.1982 Do + 12 Welt Scherztag 01.04.???? Di + +Help +---- +To find out about all supported command line options, use ``--help``:: + + Usage: + ./bin/bdrem.php [options] + ./bin/bdrem.php [options] [options] + + Options: + -n NUM, --next=NUM Show NUM days after date + -p NUM, --prev=NUM Show NUM days before date + -r renderer, --renderer=renderer Output mode + --list-renderer lists valid choices for option renderer + -e, --stoponempty Output nothing when list is empty + -d date, --date=date Date to show events for + -c FILE, --config=FILE Path to configuration file + -h, --help show this help message and exit + -v, --version show the program version and exit + + Commands: + readme Show README.rst file + config Extract configuration file + + +E-Mail +====== +To send birthday reminder e-mails, use the ``mail`` renderer:: + + $ bdrem --renderer=mail + +If you only want an email if there is a birthday, use ``--stoponempty``:: + + $ bdrem --renderer=mail --stoponempty + +Make sure your config file contains ``$mail_from`` and ``$mail_to`` settings. + + +HTML page +========= +Simply point your web browser to the ``.phar`` file, or ``index.php``. +You will get a colorful HTML table: + +.. image:: docs/html.png + + + ============= Configuration ============= @@ -36,8 +100,68 @@ When running the ``.phar``, extract the configuration file first:: $ php dist/bdrem-0.1.0.phar config > bdrem-0.1.0.phar.config.php -MS SQL server +Birthday file ============= +If you have a ``.bdf`` file from `birthday reminder`__ or `birthday reminder 3`__, +you can use it with *bdrem*. + +Configure your source as follows:: + + $source = array('Bdf', '/path/to/birthday.bdf'); + +__ http://cweiske.de/birthday.htm +__ http://cweiske.de/birthday3.htm + + +LDAP server +=========== +*bdrem* can read birthdays and other events from persons in an LDAP server. +It is known to work fine with ``evolutionPerson`` objects. +Attributes ``birthDate`` and ``anniversary`` are read. + +Configure it as follows:: + + $source = array( + 'Ldap', + array( + 'host' => 'ldap.example.org', + 'basedn' => 'ou=adressbuch,dc=example,dc=org', + 'binddn' => 'cn=FIXME,ou=users,dc=example,dc=org', + 'bindpw' => 'FIXME' + ) + ); + + +SQL database +============ +Events can be fetched from any SQL database supported by PHP's +PDO extension - MySQL, SQLite, PostgreSQL and so on. + +You may configure every little detail of your database:: + + $source = array( + 'Sql', + array( + 'dsn' => 'mysql:dbname=bdrem;host=127.0.0.1', + 'user' => 'FIXME', + 'password' => 'FIXME', + 'table' => 'contacts', + 'fields' => array( + 'date' => array( + //column name => event title + 'c_birthday' => 'Birthday' + ), + //column with name, or array with column names + 'name' => array('c_name'), + //sprintf-compatible name formatting instruction + 'nameFormat' => '%s', + ) + ) + ); + + +MS SQL server +------------- Configure the date format in ``/etc/freetds/locales.conf``:: [default] @@ -65,9 +189,9 @@ Dependencies - PEAR packages: - Console_CommandLine + - Console_Table - Mail - Mail_mime - - Console_Table - Net_LDAP2 diff --git a/docs/html.png b/docs/html.png new file mode 100644 index 0000000000000000000000000000000000000000..b8c4238f39a8a0bb6c080b69e05bb4be904cbb6b GIT binary patch literal 10608 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