Ankündigung

Einklappen
Keine Ankündigung bisher.

nextCloud (ownCloud) Kalender per CalDAV einbinden

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #31
    Das dürfte an den Landeseinstellungen liegen auf dem Server. Ich weiß nicht, ob man das für PHP getrennt einstellen kann? Bei mir ist es "normal".

    Kommentar


      #32
      Ich hab mit englisch kein Problem. Halt WAF. Wenn alles andere in deutsch ist halt nicht so schön
      Meine Installation: VM Debian Jessie SH NG 1.4, SmartVISU 2.9, KNX, DMX, 1-wire, Cisco ASA 5512X IPS, VMware vSphere 6

      Kommentar


        #33
        Zitat von Morg Beitrag anzeigen
        Das dürfte an den Landeseinstellungen liegen auf dem Server.
        Lag an der Confg.php

        Code:
            define('config_lang', 'de');
        Damit passt es jetzt

        Meine Installation: VM Debian Jessie SH NG 1.4, SmartVISU 2.9, KNX, DMX, 1-wire, Cisco ASA 5512X IPS, VMware vSphere 6

        Kommentar


          #34
          Die Sprache in der config.php kann man übrigens auch über die Website setzen, ist auf drer Config-Page etwas versteckt im Block "Interface" unter "Texts"

          Kommentar


            #35
            Ich wollte nun auch endlich mal meinen Kalender in die Visu bringen. Leider stoße ich auf das Problem, dass nextcloud scheinbar keine Daten zurückliefert

            Meine Konfiguration ist wie folgt:
            • Nextcloud 10.0.2
            • php Script aus Post #1
            • Config:
              Code:
              	define('config_calendar_service', 'nextcloud');
              	define('config_calendar_url', 'http://myuser:mypass@myhost/remote.php/caldav/calendars/');
              	define('config_calendar_username', 'myuser');
              	define('config_calendar_password', 'mypass');
              	define('config_calendar_name', 'mycalendar');

            Ich erhalte damit keine Daten, im Error-Log des Webservers findet sich stattdessen folgende Meldung:
            Code:
            PHP Warning:  array_multisort(): Argument #1 is expected to be an array or a sort flag in /srv/smarthome/smartvisu/lib/calendar/service/nextcloud.php on line 206
            Wenn ich mir über eine Debug-Ausgabe ausgeben lasse, was von Nextcloud kommt, sehe ich folgendes:
            Code:
            <?xml version="1.0"?>
            <d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/"/>
            Die Nextcloud liefert also nichts zurück, daher kann auch nichts sortiert werden ...

            Testweise in der URL das "/caldav/" durch "/dav/" zu ersetzen, hat keine Änderung gebracht.

            Habe ich einen Fehler in meiner Konfiguration oder ist das ein Nextcloud-Problem?

            Grüße
            offline

            Kommentar


              #36
              Zitat von offline Beitrag anzeigen
              Code:
              define('config_calendar_url', 'http://myuser:mypass@myhost/remote.php/caldav/calendars/');
              Die URL sieht zumindest bei mir ein bisschen anders aus:
              define('config_calendar_url', 'http://myuser:mypass@192.168.178.4/owncloud/remote.php/caldav/calendars/myuser/');

              Hast Du NC tatsächlich im Webroot installiert? Auch muss bei mir der User im Pfad angegeben werden, der dann seinerseits mehrere Kalender haben kann ...

              /tom

              Kommentar


                #37
                NC ist tatsächlich im Webroot von "myhost" installiert (ich arbeite mit Subdomains) ...

                Nachdem ich den User in der URL ergänzt habe, bekam ich folgenden Fehler
                Code:
                PHP Warning:  file_get_contents(http://...@myhost/remote.php/caldav/calendars/myuser/mycalendar): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request\r\n in /srv/smarthome/smartvisu/lib/calendar/service/nextcloud.php on line 125, referer: http://smartvisuhost/index.php?page=calendar/widget_calendar.list
                Ich habe daraufhin mal in der Nextcloud den Loglevel auf "Debug" gesetzt und prompt auch dort eine Fehlermeldung bekommen:
                Code:
                [...]HTTP\\\/1.1 400 A calendar-query REPORT on a calendar with a Depth: 0 is undefined. Set Depth to 1[...]
                Die Ursache dafür habe ich dann in der nextcloud.php gefunden. Es muss dort in der Methode get_caldav_calendar wie folgt heißen
                Code:
                        $ctxopts =     array('http' =>
                                        array(    'method' => 'REPORT',
                                                'header' => "Depth: 1\r\n".  // Zeilenwechsel nach der Header-Zeile
                                                            "Content-Type: application/xml\r\n",
                                                'content' => $postdata
                                        )
                                    );
                Damit hat es dann funktioniert.

                Danke für deine Hilfe, Tom
                offline

                P.S.: Freigegebene Kalender bekommt man über den Kalendernamen "[Name des Kalenders]_shared_by_[Name des Kalendereigentümers]"

                Kommentar


                  #38
                  Hallo zusammen,
                  ich habe mich auch mal dran gesetzt, meine Owncloud in die SmartVisu einzubinden. Leider ohne Erfolg. Das Widget bleibt leer.
                  Daher hoffe ich, dass ihr mir ein paar Tipps zum debuging geben könnt.
                  Meine SmartVisu Version 2.8 läuft wie in der Wiki-Anleitung beschrieben unter Debian, die Owncloud 9.1.1. auf einem anderen System (Ubuntu), aber auch lokal und im gleichen Netz. Die Unterschiede zwischen Owncloud und Nextcloud dürften doch eigentlich nicht so weit auseinandergehen, oder beginnt hier schon mein Fehler?

                  Wenn ich die URL zum Kalender im Browser öffne, bekomme ich folgenden Hinweis, ein Indiz, dass die URL auf meinen Müll-Kalender schon mal korrekt ist.
                  Code:
                  This is the WebDAV interface. It can only be accessed by WebDAV clients such as the ownCloud desktop sync client.
                  Ich habe, wie in diesem Thread beschrieben, eine neue Konfig-Datei unter smartvisu/lib/calendar/service angelegt und die config entsprechend angepasst.

                  Die Änderung von yachti hat leider nichts gebracht
                  Und auch den Zeilenwechsel, wie von offline beschrieben, habe ich erfolglos ausprobiert.

                  In den Logs der Owncloud finde ich keinen Hinweis, wo könnte ich sonst noch suchen?
                  Bin für jeden Rat dankbar.

                  Vielen Dank und frohes Neues
                  Jan

                  Kommentar


                    #39
                    Zitat von gnarrf Beitrag anzeigen

                    Ich habe, wie in diesem Thread beschrieben, eine neue Konfig-Datei unter smartvisu/lib/calendar/service angelegt und die config entsprechend angepasst.
                    Deine Infos sind ein bisschen dürftig umHilfestellung zu geben.
                    Wie sieht Deine Config und die entsprechende Zeile in der plugin.php aus?
                    Meine Installation: VM Debian Jessie SH NG 1.4, SmartVISU 2.9, KNX, DMX, 1-wire, Cisco ASA 5512X IPS, VMware vSphere 6

                    Kommentar


                      #40
                      Zitat von gnarrf Beitrag anzeigen
                      Wenn ich die URL zum Kalender im Browser öffne, bekomme ich folgenden Hinweis, ein Indiz, dass die URL auf meinen Müll-Kalender schon mal korrekt ist.
                      Da muss ich Dir widersprechen - es zeigt nur, dass OC dort tatsächlich läuft. Wenn Du die 100% korrekte URL im Browser öffnest, wird Dir die .ics zum Download angeboten.

                      Sieh Dir mal #36 an - da ist ein Beispiel aus nextCloud (von offline), und eins aus ownCloud (von mir).

                      Hast Du den Namen des ownCloud-Users am Ende zu stehen? Wenn nicht, macht Deine Fehlermeldung Sinn, da OC nicht weiss, welchen der ggf. vielen Kalender es überhaupt ausliefern soll.

                      /tom

                      Kommentar


                        #41
                        Hallo und Danke,

                        dann hier mal etwas ausführlicher, was ich bislang gemacht habe:

                        Die URL, die mir die Owncloud im Kalender als Pfad anzeigt:
                        muell ist der Username, test der Kalendername
                        https://192.168.xxx.xxx/remote.php/d...rs/muell/test/
                        Diese URL liefert sowohl im FireFox wie auch Chrome
                        This is the WebDAV interface. It can only be accessed by WebDAV clients such as the ownCloud desktop sync client.
                        Wenn ich die URL z.B.in Thunderbird/Lightning einbinde, dann bekomme ich nach Abfrage von Benutzername und Kennwort die Termine.
                        Wenn ich die URL verfälsche, dann bekomme ich im FireFox eine andere Fehlermeldung:
                        ownCloud
                        Not Found
                        Technical details
                        Remote Address: 192.168.xxx.xxx
                        Request ID: WFHfDndspFgXnjQ4aeR2
                        ownCloud – Web-Dienste unter Deiner Kontrolle
                        Von daher wundert mich deine Aussage Tom...
                        Rufe ich die URL https://192.168.xxx.xxx/remote.php/caldav/calendars/muell/test/ auf, dann bekomme ich im Browser auch eine Fehlermeldung:
                        <d:error><s:sabredav-version>3.0.9</s:sabredav-version><s:exception>Sabre\DAV\Exception\NotImplem ented</s:exception><s:message>There was no handler found for this "GET" method</s:message></d:error>
                        owncloud\3rdparty\sabre\dav\lib\CalDAV\Plugin.php Line 579 ff:
                        Code:
                                if ($node instanceof ICalendarObjectContainer && $depth === 0) {
                        
                                    if (strpos($this->server->httpRequest->getHeader('User-Agent'), 'MSFT-') === 0) {
                                        // Microsoft clients incorrectly supplied depth as 0, when it actually
                                        // should have set depth to 1. We're implementing a workaround here
                                        // to deal with this.
                                        //
                                        // This targets at least the following clients:
                                        //   Windows 10
                                        //   Windows Phone 8, 10
                                        $depth = 1;
                                    } else {
                                        // throw new BadRequest('A calendar-query REPORT on a calendar with a Depth: 0 is undefined. Set Depth to 1');
                                        $depth = 1;
                                    }
                        
                                }
                        SmartVisu:
                        smartvisu/config.php
                        Code:
                            define('config_calendar_service', 'nextcloud');
                            define('config_calendar_url', 'https://muell:schwertfisch@192.168.xxx.xxx/remote.php/dav/calendars/muell/');
                            define('config_calendar_username', 'muell');
                            define('config_calendar_password', 'schwertfisch');
                            define('config_calendar_name', 'test');
                        smartvisu/pages/meinProjekt/testcal.html
                        Code:
                        /**
                        * -----------------------------------------------------------------------------
                        * @package     smartVISU
                        * @author      Martin Gleiß
                        * @copyright   2012
                        * @license     GPL [http://www.gnu.de]
                        * -----------------------------------------------------------------------------
                        */
                        {% extends "base.html" %}
                        
                        {% block sidebar %}
                            {% import "clock.html" as clock %}
                            {{ clock.digiclock('clock') }}   
                        {% endblock %}
                        
                        {% block content %}
                            {% import "calendar.html" as calendar %}
                            {{ calendar.list('muellcal', 'Müllkalender') }}
                        {% endblock %}

                        smartvisu/lib/calendar/service/nextcloud.php
                        Code:
                        <?php
                        /**
                         * -----------------------------------------------------------------------------
                         * @package     smartVISU
                         * @author      Johannes Willnecker, Sebastian Helms
                         * @copyright   2015
                         * @license     GPL [http://www.gnu.de]
                         * -----------------------------------------------------------------------------
                         */
                        
                        
                        require_once '../../../lib/includes.php';
                        require_once const_path_system.'calendar/calendar.php';
                        
                        /**
                         * This class reads a caldav calendar
                         */
                        class calendar_caldav extends calendar
                        {
                        
                            private function startElement($element)
                            {
                                if(strcmp($element,"VEVENT") == 0)
                                {
                                    $this->vevent = array(
                                        'start' => date('y-m-d', 0).' '.gmdate('H:i:s', 0),
                                        'end' => date('y-m-d', 0).' '.gmdate('H:i:s', 0),
                                        'title' => (string)(""),
                                        'content' => (string)(""),
                                        'where' => (string)(""),
                                        'link' => (string)("")
                                    );
                                    $this->startts = 0;
                                    $this->inVEVENT = true;
                                }
                            }
                        
                            private function endElement($element)
                            {
                                if($element == 'VEVENT')
                                {
                                    $this->startdatearray[] = $this->startts;
                                    $this->data[] = $this->vevent;
                                    $this->inVEVENT = false;
                                }
                            }
                        
                            private function Value($name, $value)
                            {
                                if($this->inVEVENT == true)
                                {
                                    if($name == 'SUMMARY')
                                    {
                                        $this->vevent['title'] = (string)($value);
                                    }
                                    if($name == 'DESCRIPTION')
                                    {
                                        $this->vevent['content'] = (string)($value);
                                        foreach (explode("\\n", $value) as $line)
                                        {
                                            preg_match_all('/@([^ ]+) +(.*)$/', $line, $items);
                                            if ($items[1][0] == "icon" or $items[1][0] == "color")
                                            {
                                                $this->vevent[$items[1][0]] = (string)$items[2][0];
                                            }
                                        }
                                    }
                                    if($name == 'LOCATION')
                                    {
                                        $this->vevent['where'] = (string)($value);
                                    }
                                    if($name == 'DTSTART')
                                    {
                                        preg_match('/((.*)=(.*):)?(.*)/', $value, $matches);
                                        //TODO TZID handling
                                        date_default_timezone_set('Europe/Berlin');
                                        $ts = strtotime($matches[4]) + date("Z", strtotime($matches[4]));
                                        $this->startts = $ts;
                                        $this->vevent['start'] = date('y-m-d', $ts).' '.gmdate('H:i:s', $ts);
                                    }
                                    if($name == 'DTEND')
                                    {
                                        preg_match('/((.*)=(.*):)?(.*)/', $value, $matches);
                                        //TODO TZID handling
                                        date_default_timezone_set('Europe/Berlin');
                                        $ts = strtotime($matches[4]) + date("Z", strtotime($matches[4]));
                                        $this->vevent['end'] = date('y-m-d', $ts).' '.gmdate('H:i:s', $ts);
                                    }
                                }
                            }
                        
                        
                            private function get_caldav_calendar($url)
                            {
                        
                                $calStart = gmdate("Ymd\THis\Z");
                                $calEnd = gmdate("Ymd\THis\Z", strtotime("+4 weeks"));
                        
                                $postdata = "<C:calendar-query xmlns:D=\"DAV:\" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">
                         <D:prop>
                           <C:calendar-data>
                             <C:expand start=\"".$calStart."\"
                                       end=\"".$calEnd."\"/>
                           </C:calendar-data>
                         </D:prop>
                         <C:filter>
                           <C:comp-filter name=\"VCALENDAR\">
                             <C:comp-filter name=\"VEVENT\">
                               <C:time-range start=\"".$calStart."\"
                                             end=\"".$calEnd."\"/>
                             </C:comp-filter>
                           </C:comp-filter>
                         </C:filter>
                        </C:calendar-query>";
                        
                                $ctxopts =     array('http' =>
                                                array(    'method' => 'REPORT',
                        'header' => "Depth: 1\r\n".
                                                                    "Content-Type: application/xml\r\n",
                                                        'content' => $postdata
                                                )
                                            );
                                $context = stream_context_create($ctxopts);
                        
                                $content = file_get_contents($url, false, $context);
                        
                                return $content;
                            }
                        
                            public function run()
                            {
                        
                                $srcurl = $this->url;
                        
                                if (strpos(config_calendar_name, ",") > 0)
                                {
                                    $snippets = explode(",", config_calendar_name);
                                }
                                else
                                {
                                    $snippets[] = config_calendar_name;
                                }
                        
                                if (substr($srcurl,-1) !== "/" and $snippets[0] !== "")
                                {
                                    $srcurl .= "/";
                                }
                        
                                foreach ($snippets as $snippet)
                                {
                                    $urls[] = $srcurl . $snippet;
                                }
                        
                                foreach ($urls as $url)
                                {
                                    $content = $this->get_caldav_calendar($url);
                                    $this->debug($content);
                        
                                    if ($content !== false)
                                    {
                                        $xmls[] = simplexml_load_string($content);
                                    }
                                }
                        
                                foreach($xmls as $xml)
                                {
                                    if ($xml !== false)
                                    {
                        
                                        $this->i = 1;
                                        foreach ($xml->children('d', true) as $entry)
                                        {
                                            foreach ($entry->propstat->prop->children('cal',true) as $cal)
                                            {
                                                if($cal->getName() == 'calendar-data')
                                                {
                                                    $cal = str_replace (array("\r\n ", "\n ", "\r "), '', $cal);
                                                    preg_match_all('/(.[^;|:]*)?(;|:)(.*)/', $cal, $matches, PREG_SET_ORDER);
                        
                                                    foreach($matches as $values)
                                                    {
                                                        if($values[1] == 'BEGIN')
                                                        {
                                                            $this->startElement(trim($values[3]));
                                                        }
                                                        else if($values[1] == 'END')
                                                        {
                                                            $this->endElement(trim($values[3]));
                                                        }
                                                        else
                                                        {
                                                            $this->Value($values[1], trim($values[3]));
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }        
                                    else
                                    {
                                        $this->error('Calendar: caldav', 'caldav: Calendar read request failed!');
                                    }
                                }
                        
                                //order events:
                                array_multisort($this->startdatearray, SORT_ASC, $this->data);
                                $i = 1;
                                foreach($this->data as $key => $value)
                                {
                                    $this->data[$key]['pos'] = $i++;
                                }
                        
                                $this->data = array_slice($this->data, 0, $this->count);
                            }
                        }
                        
                        
                        // -----------------------------------------------------------------------------
                        // call the service
                        // -----------------------------------------------------------------------------
                        
                        $service = new calendar_caldav(array_merge($_GET, $_POST));
                        echo $service->json();
                        
                        ?>
                        Außerdem habe ich gestern nach all meinen Experimenten noch die OwnCloud aus dem Repository auf 9.1.3 aktualisiert und danach natürlich die Plugin.php wieder angepasst.

                        Was mir eben noch aufgefallen ist während ich das alles zusammentrage und den Link im Chrome getestet habe:
                        Ich habe einen https-redirect und "nur" ein selbsterstelltes Zertifikat für die owncloud. Kann es sein, dass die Visu darüber stolpert?

                        Viele Grüße und besten Dank
                        Jan

                        Kommentar


                          #42
                          PS: Morg, ich glaube, in deiner lib/calendar/service/nextcloud.php von #1 hat sich ein Fehler eingeschlichen den ich c&p übernommen habe:
                          Code:
                          'header' => "Depth: 1".
                          Der Punkt müsste ein Komma sein.
                          Viele Grüße
                          Jan

                          Kommentar


                            #43
                            Hast Du es mal mit http: statt https: probiert? Mein Testaufruf in der funktionierenden Config unter OC8.1 lautet:

                            Code:
                            http://192.168.178.4/owncloud/remote.php/caldav/calendars/tom/
                            Also ohne Kalendernamen am Ende. Nach dem manuellen Login solltest Du die Kalender als Verzeichnisse sehen.

                            Funktioniert das?

                            /tom

                            Kommentar


                              #44
                              Hallo Tom,
                              ich glaube, genau das ist mein Problem: Durch den Redirect wird http auf https umgeleitet und weil es sich um ein selbsterstelltes Zertifikat handelt, gibt es keine gültige Zertifikatskette.

                              Ich habe die Logfiles vom Apache der SmartVisu-Instanz gefunden und das bestätigt meinen Verdacht:
                              Code:
                              [Tue Jan 03 07:15:46.471453 2017] [:error] [pid 4861] [client 192.168.xxx.<laptop-ip>:49834] PHP Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:\nerror:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /var/www/html/smartvisu/lib/calendar/service/nextcloud.php on line 125, referer: http://192.168.xxx.<smartvisu-ip>/smartvisu/index.php?page=testcal
                              [Tue Jan 03 07:15:46.471483 2017] [:error] [pid 4861] [client 192.168.xxxx.xxx:49834] PHP Warning: file_get_contents(): Failed to enable crypto in /var/www/html/smartvisu/lib/calendar/service/nextcloud.php on line 125, referer: http://192.168.xxx.xxx/smartvisu/index.php?page=testcal
                              [Tue Jan 03 07:15:46.471531 2017] [:error] [pid 4861] [client 192.168.xxx.xxx:49834] PHP Warning: file_get_contents(https://...@192.168.xxx.xxx/remote.php/dav/calendars/muell/test): failed to open stream: operation failed in /var/www/html/smartvisu/lib/calendar/service/nextcloud.php on line 125, referer: http://192.168.xxx.xxx/smartvisu/index.php?page=testcal
                              Hinweis für die Nachwelt:
                              Code:
                              sudo tail -f /var/log/apache2/error.log
                              wenn man dann ein paar Leerzeilen in die Konsole haut, dann kann man recht gut die Meldungen filtern, die beim aktuellen Seitenaufruf ausgelöst werden.

                              Da ich zu blöd bin, dem Apache mein Zertifikat unterzuschieben habe ich den URL-Aufruf aus der nextcloud.php von Seite 1 modifiziert:
                              Code:
                              $ctxopts =  array(
                                                  'ssl' =>
                                                      array (    'verify_peer' => false,
                                                              'verify_peer_name' => false
                                                          ),
                                                  'http' =>
                                                      array(    'method' => 'REPORT',
                                                              'header' => "Depth: 1",
                                                                          "Content-Type: application/xml\r\n",
                                                              'content' => $postdata
                                                      )
                                                  );
                                      $context = stream_context_create($ctxopts);
                              
                                      $content = file_get_contents($url, false, $context);
                              damit sollte nach meinem Verständnis die Kette nicht mehr geprüft werden.

                              Vielleicht kanns ja noch jemand brauchen. Gegen eine schönere Lösung hätte ich aber auch nichts einzuwenden :-)

                              Jetzt werden mir die Termine angezeigt... Vielen Dank für die richtungsweisende Unterstützung.

                              Gruß
                              Jan

                              Kommentar


                                #45
                                Guten Abend zusammen,

                                ich ziehe mir nun erfolgreich vier Kalender aus der owncloud 9.1.3.
                                Gibt es eine Möglichkeit, in einzelnen Ansichten nur auf einzelne Kalender zugreifen? Beim Müllkalender klappt das ganz gut mit der Anleitung von Tom Bombadil
                                https://knx-user-forum.de/forum/supp...lles-m%C3%BCll
                                Aber da habe ich auch Schlüsselwörter im Titel auf die ich filtern kann bzw. auf die Tom filtert und die ich nur anpassen musste.

                                Nun würde ich mich gerne an dieDarstellung eines Geburtstagskalenders machen. Ich dachte zunächst, dass ich das äquivalent zum Müllkalender machen könnte. Im Kalender steht aber nur "Vorname Nachname (*19xx)". Ich könnte natürlich mit einem Regex auf " (*" filtern. Aber sauberer wäre es eigentlich, wenn man irgendwie die Kalendergruppe.

                                Hat das schon jemand hinbekommen oder einen Ansatz für mich?

                                Vielen Dank und Grüße
                                Jan

                                Kommentar

                                Lädt...
                                X