diff options
| author | Christian Weiske <cweiske@cweiske.de> | 2023-12-20 21:49:43 +0100 |
|---|---|---|
| committer | Christian Weiske <cweiske@cweiske.de> | 2023-12-20 21:49:43 +0100 |
| commit | 4bbbffb1a2f194f85ae2629436dd9ac17b3c819f (patch) | |
| tree | 88d3f3ecaeefcc6a78d080f9e2d051a6d09fae20 | |
| parent | 38760b905941993189a83cf8450dcf160631f174 (diff) | |
| download | bdrem-4bbbffb1a2f194f85ae2629436dd9ac17b3c819f.tar.gz bdrem-4bbbffb1a2f194f85ae2629436dd9ac17b3c819f.zip | |
Add support for .vcf vCard files
| -rw-r--r-- | README.rst | 2 | ||||
| -rw-r--r-- | composer.json | 3 | ||||
| -rw-r--r-- | composer.lock | 235 | ||||
| -rw-r--r-- | data/bdrem.config.php.dist | 8 | ||||
| -rw-r--r-- | src/bdrem/Source/vCard.php | 102 |
5 files changed, 348 insertions, 2 deletions
@@ -20,6 +20,8 @@ Data sources - An LDAP server with ``evolutionPerson`` records - `Birthday reminder <http://cweiske.de/birthday3.htm>`_ files (``.bdf``) - CSV files +- A directory of .vcf vCard files + Output formats ============== diff --git a/composer.json b/composer.json index 25a5ba7..9524114 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,7 @@ "pear/console_commandline": "^1.2", "pear/console_table": "^1.3", "pear/mail_mime": "^1.10", - "pear/net_ldap2": "^2.3" + "pear/net_ldap2": "^2.3", + "sabre/vobject": "^4.5" } } diff --git a/composer.lock b/composer.lock index 3545e49..7d7e616 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ecbd614a29db70e304521a06550a4326", + "content-hash": "39ce09afd7a686424abd7e671905368d", "packages": [ { "name": "pear/console_color2", @@ -431,6 +431,239 @@ "source": "https://github.com/pear/PEAR_Exception" }, "time": "2021-03-21T15:43:46+00:00" + }, + { + "name": "sabre/uri", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/uri.git", + "reference": "1774043c843f1db7654ecc93368a98be29b07544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/uri/zipball/1774043c843f1db7654ecc93368a98be29b07544", + "reference": "1774043c843f1db7654ecc93368a98be29b07544", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.17", + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "^9.6" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\Uri\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "Functions for making sense out of URIs.", + "homepage": "http://sabre.io/uri/", + "keywords": [ + "rfc3986", + "uri", + "url" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/uri/issues", + "source": "https://github.com/fruux/sabre-uri" + }, + "time": "2023-06-09T07:04:02+00:00" + }, + { + "name": "sabre/vobject", + "version": "4.5.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/vobject.git", + "reference": "a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/vobject/zipball/a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772", + "reference": "a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0", + "sabre/xml": "^2.1 || ^3.0 || ^4.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1", + "phpstan/phpstan": "^0.12", + "phpunit/php-invoker": "^2.0 || ^3.1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + }, + "suggest": { + "hoa/bench": "If you would like to run the benchmark scripts" + }, + "bin": [ + "bin/vobject", + "bin/generate_vcards" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sabre\\VObject\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Dominik Tobschall", + "email": "dominik@fruux.com", + "homepage": "http://tobschall.de/", + "role": "Developer" + }, + { + "name": "Ivan Enderlin", + "email": "ivan.enderlin@hoa-project.net", + "homepage": "http://mnt.io/", + "role": "Developer" + } + ], + "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects", + "homepage": "http://sabre.io/vobject/", + "keywords": [ + "availability", + "freebusy", + "iCalendar", + "ical", + "ics", + "jCal", + "jCard", + "recurrence", + "rfc2425", + "rfc2426", + "rfc2739", + "rfc4770", + "rfc5545", + "rfc5546", + "rfc6321", + "rfc6350", + "rfc6351", + "rfc6474", + "rfc6638", + "rfc6715", + "rfc6868", + "vCalendar", + "vCard", + "vcf", + "xCal", + "xCard" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/vobject/issues", + "source": "https://github.com/fruux/sabre-vobject" + }, + "time": "2023-11-09T12:54:37+00:00" + }, + { + "name": "sabre/xml", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/xml.git", + "reference": "99caa5dd248776ca6a1e1d2cfdef556a3fa63456" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/99caa5dd248776ca6a1e1d2cfdef556a3fa63456", + "reference": "99caa5dd248776ca6a1e1d2cfdef556a3fa63456", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "lib-libxml": ">=2.6.20", + "php": "^7.4 || ^8.0", + "sabre/uri": ">=2.0,<4.0.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.38", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Deserializer/functions.php", + "lib/Serializer/functions.php" + ], + "psr-4": { + "Sabre\\Xml\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Markus Staab", + "email": "markus.staab@redaxo.de", + "role": "Developer" + } + ], + "description": "sabre/xml is an XML library that you may not hate.", + "homepage": "https://sabre.io/xml/", + "keywords": [ + "XMLReader", + "XMLWriter", + "dom", + "xml" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/xml/issues", + "source": "https://github.com/fruux/sabre-xml" + }, + "time": "2023-11-09T10:47:15+00:00" } ], "packages-dev": [], diff --git a/data/bdrem.config.php.dist b/data/bdrem.config.php.dist index 3689d1b..1e877e8 100644 --- a/data/bdrem.config.php.dist +++ b/data/bdrem.config.php.dist @@ -53,6 +53,14 @@ $source = array( ) ); +//Source: Directory of .vcf vCard files (2 subfolder levels supported) +$source = [ + 'vCard', + [ + 'folder' => '/home/cweiske/dev/contacts-backup/contacts' + ] +]; + $daysPrev = 3; $daysNext = 14; diff --git a/src/bdrem/Source/vCard.php b/src/bdrem/Source/vCard.php new file mode 100644 index 0000000..98b8e00 --- /dev/null +++ b/src/bdrem/Source/vCard.php @@ -0,0 +1,102 @@ +<?php +/** + * Part of bdrem + * + * PHP version 7 + * + * @category Tools + * @package Bdrem + * @author Christian Weiske <cweiske@cweiske.de> + * @copyright 2023 Christian Weiske + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 + * @link http://cweiske.de/bdrem.htm + */ +namespace bdrem; + +use Sabre\VObject; +use Sabre\VObject\Component\VCard; + +/** + * Read a folder of vcard files + * 2 subfolder levels are supported. + * + * @category Tools + * @package Bdrem + * @author Christian Weiske <cweiske@cweiske.de> + * @copyright 2023 Christian Weiske + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 + * @link http://cweiske.de/bdrem.htm + */ +class Source_vCard +{ + /** + * Full path to a folder with .vcf files + */ + protected string $folder; + + /** + * Set the VCard folder path + */ + public function __construct(array $config) + { + $this->folder = $config['folder']; + if (!is_dir($this->folder)) { + throw new \Exception( + 'VCard folder does not exist: ' . $this->folder + ); + } + } + + /** + * Return all events for the given date range + * + * @param string $strDate Date the events shall be found for, + * YYYY-MM-DD + * @param integer $nDaysPrevious Include number of days before $strDate + * @param integer $nDaysNext Include number of days after $strDate + * + * @return Event[] Array of matching event objects + */ + public function getEvents($strDate, $nDaysPrevious, $nDaysNext) + { + $vcfFiles = glob($this->folder . '/{*,*/*,*/*/*}.vcf', GLOB_BRACE); + if (count($vcfFiles) == 0) { + throw new \Exception('No .vcf files found in folder'); + } + + $arEvents = []; + foreach ($vcfFiles as $vcfFile) { + $vcard = VObject\Reader::read(file_get_contents($vcfFile)); + + if (isset($vcard->BDAY)) { + $event = new Event( + $this->getName($vcard), + 'Birthday', + $vcard->BDAY->getDateTime()->format('Y-m-d') + ); + if ($event->isWithin($strDate, $nDaysPrevious, $nDaysNext)) { + $arEvents[] = $event; + } + } + + if (isset($vcard->{'X-ANNIVERSARY'})) { + $event = new Event( + $this->getName($vcard), + 'Anniversary', + $vcard->{'X-ANNIVERSARY'}->getDateTime()->format('Y-m-d') + ); + if ($event->isWithin($strDate, $nDaysPrevious, $nDaysNext)) { + $arEvents[] = $event; + } + } + } + + return $arEvents; + } + + protected function getName(VCard $vcard) + { + return (string) $vcard->FN; + } +} +?> |
