aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Weiske <cweiske@cweiske.de>2023-12-20 21:49:43 +0100
committerChristian Weiske <cweiske@cweiske.de>2023-12-20 21:49:43 +0100
commit4bbbffb1a2f194f85ae2629436dd9ac17b3c819f (patch)
tree88d3f3ecaeefcc6a78d080f9e2d051a6d09fae20
parent38760b905941993189a83cf8450dcf160631f174 (diff)
downloadbdrem-4bbbffb1a2f194f85ae2629436dd9ac17b3c819f.tar.gz
bdrem-4bbbffb1a2f194f85ae2629436dd9ac17b3c819f.zip
Add support for .vcf vCard files
-rw-r--r--README.rst2
-rw-r--r--composer.json3
-rw-r--r--composer.lock235
-rw-r--r--data/bdrem.config.php.dist8
-rw-r--r--src/bdrem/Source/vCard.php102
5 files changed, 348 insertions, 2 deletions
diff --git a/README.rst b/README.rst
index 81a729d..1257d36 100644
--- a/README.rst
+++ b/README.rst
@@ -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;
+ }
+}
+?>