Davical

Aus SchnallIchNet
Version vom 28. Dezember 2011, 17:41 Uhr von Cbs (Diskussion | Beiträge) (cardDAV mass import)

Wechseln zu: Navigation, Suche

Setup

since the documentation is quite good, look at project page for installation.
http://davical.org


Hints

Some hints regarding davical...


bind

create bindings:

curl --basic --user 'user1' -X BIND -H 'Content-Type: text/xml; charset="UTF-8"' \
--url 'https://davical.example.com/caldav.php/user1/' \
-d '<?xml version="1.0" encoding="utf-8"?> <bind xmlns="DAV:"><segment>collection</segment> <href>/caldav.php/sourceprincipal/collection</href> </bind>';


cardDAV mass import

because it's bullshit filling every card by the phone or carddavMATE or so, i wrote a simple (absolute) importer in php...
tested with a .vcf-File exported from my email-client btw. from my iPhone/iTunes

Achtung.jpeg Make sure the .vcf-file has std. unix line-endings


you may run the file from command-line:

php /path/to/davicalVcfImporter.php /path/to/your/contacts-file.vcf


or put it to the webroot of any webserver:

http://localhost/davicalVcfImporter.php?vcfFileName=/path/to/your/contacts-file.vcf

if you use the webserver method of calling the script, make sure the file is accessable and readable
by the user running your httpd!

<?php

/**
* CarddavImporter
* for CalDAV Server - daviCal
*
* (may be works with other servers with little modifications)
*
* TODO:
* - add checks against collection to avoid duplicates...
* - check syntax of input-vcards against some rfc
*
* @package   davical-carddav-import
* @copyright Christoph Steidl <chris@rubbish.de>
* @license   http://gnu.org/copyleft/gpl.html GNU GPL V2
*/

/// configuration
$user            = 'USERNAME';
$pass            = 'securePASSWORD';
$cardsCollection = 'contacts';
$serverURL       = 'https://caldav.example.com/caldav.php/' . $user . '/' . $cardsCollection;

if(PHP_SAPI === 'cli') {
    $vcfFileName = $argv[1];
} else {
    echo "<pre>\n";
    $vcfFileName = $_REQUEST['vcfFileName'];
}

if( file_exists($vcfFileName) ) {
    $vcfFile = file_get_contents($vcfFileName);
} else {
    die("File not found: " . $vcfFileName . "\n");
}


$is_multivcard = false;

class uuid {
    protected $uuidobject;

    protected function create() {
        if(!is_resource($this->uuidobject))
            uuid_create(&$this->uuidobject);
    }

    public function v4() {
        $this->create();
        uuid_make($this->uuidobject, UUID_MAKE_V4);
        uuid_export($this->uuidobject, UUID_FMT_STR, &$uuidstring);
        return trim($uuidstring);
    }
}

function vcard_split($vcf) {
    $result = array();
    $is_started = false;
    $is_finished = false;
    $cardcnt = 0;

    foreach($vcf as $line) {
        if($is_started === false) {
            if(preg_match('/BEGIN:VCARD/', $line) > 0) {
                $is_started = true;
                $cardcnt = $cardcnt + 1;
            }
        } else if($is_started === true && $is_finished === false) {
            if(preg_match('/END:VCARD/', $line) > 0) {
                $is_finished = true;
            }
        }

        if($is_started === true && $is_finished === false) {
            $result[$cardcnt] .= $line;
        } else if($is_started === true && $is_finished === true) {
            $is_started = false;
            $is_finished = false;
            $uuid = new uuid;
            $UID = $uuid->v4();

            $result[$cardcnt] .= "UID:$UID\n";
            $result[$cardcnt] .= "PRODID:-//SiliconHome IT-Systems//CardDavImporter 0.1.0//EN\n";
            $result[$cardcnt] .= $line; // <-- this should be 'END:VCARD'
        }
    }

    return $result;
}

$begin_cnt = preg_match_all('/BEGIN:VCARD/', $vcfFile, $matches);
$end_cnt   = preg_match_all('/END:VCARD/', $vcfFile, $matches);

// very simple validation of file
// TODO: should be checked against RFC or so...
if($begin_cnt > 0) {
    if($begin_cnt == $end_cnt) {
        if($begin_cnt > 1) {
            $is_multivcard = true;
        } else {
            $is_multivcard = false;
        }
    } else {
        echo "Counted BEGIN:VCARD are not equal counted END:VCARD";
        exit(2);
    }
} else {
    echo "No VCARD-File?? BEGIN:VCARD not found in file...";
    exit(1);
}

// create an array of lines
$vcfFile = file($vcfFileName);

// split cards if multiple cards in file
if($is_multivcard === true) {
    $cards = vcard_split($vcfFile);
} else {
    $cards[0] = $vcfFile;
}

// now we have one card per array member...
// storing it to davical-carddav...
foreach($cards as $vcard) {
    $fileName = hash( 'sha256', $vcard . time(void) ) . ".vcf";

    $url = $serverURL . "/" . $fileName;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,               "$url");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,    false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,    false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,    true);
    // post vals
    curl_setopt($ch, CURLOPT_HTTPHEADER,        array('Content-type: text/vcard; charset="UTF-8"', 'Content-Length: ' . strlen($vcard)));
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST,     'PUT');
    curl_setopt($ch, CURLOPT_POSTFIELDS,        $vcard);
    curl_setopt($ch, CURLOPT_USERPWD,           "$user:$pass");
    // exec request
    $chresponse = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // TODO: check curl-status
}

// you want to see what was imported?
// comment in next 2 lines
//print_r( $cards );
//print "\n";

exit(0);