Calendrier Nextcloud


#1

Salut tout le monde,

J’utilise pas mal nextcloud pour les agendas, contact, fichier, mail, etc etc, et je me dis que ça pourrais être sympa d’avoir un module agenda nextcloud en alternative à google :slight_smile:

Seulement voila le petit hic, niveau nodejs je suis proche de zéro, même si j’ai fais quelques bidouille ce week end à prendre des bouts de code à droite et à gauche pour faire des scripts et les modifier un peu pour faire ce que je voulais.

Moi qui voulait me mettre à apprendre un peu nodejs, je me dis que le mieux c’est de prendre direct un petit truc que je voudrais rajouter dans gladys :slight_smile:

J’ai regarder quelques librairie pour caldav, et je vais faire quelques tests pour voir jusqu’ou je peux aller ^^ J’pense que à mon avis j’aurais des questions stupide d’ici peu @piznel @spenceur @MathieuA @VonOx vous ne m’en voudrez pas ? :roll_eyes:

(D’ailleurs en passant j’ai été absorbé par pas mal de chose ce week end, donc des scripts gladys, que je n’ai pas pris le temps de faire un truc sur la sécurisation du parefeu, mais je vais me rattraper mercredi après midi j’ai un peu de temps pour :smiley: )


#2

Personnelement non :),
Ce sera le meilleurs moyen d’apprendre effectivement :slight_smile: !
Je tenterais de me connecté une fois par jour (j’ai pas mal de taff [perso / pro] :smiley: )
Bon courage @Totof :wink:


#3

Thank’s,

Je ferais les premiers test dans la semaine si je peux, sinon dimanche.
En faisant une rechercher rapide, j’ai trouver ces liens pour caldav :

Je testerais déjà sur un raspberry de dev que j’arrive bien à resortir les infos des calendriers, ce qui sera déjà un grand pas en avant :slight_smile:
Une fois que ce sera fait, c’est la que j’aurais des questions sur comment l’intégrer avec Gladys :smiley:

Après j’aurais d’autres idées en tête, comme faire un bot sur mon serveur XMPP, et de le coupler à Gladys pour ne plus passer par télégram, mais par mon propre serveur :slight_smile:


#4

Top tout ça! C’est clairement quelque chose qui manque l’intégration caldav, je serais content de voir ça :slight_smile:


#5

@pierre-gilles, j’espère que tu n’es pas pressé :smiley:


#6

Hello !
Ma question con est arrivé :slight_smile:

J’ai trouver un petit quelque chose comme ça :

/**
 * Get the events from a CalDAV calendar for a specific range of dates
 * @param {string} url - CalDAV Calendar URL
 * @param {string} username - CalDAV Username
 * @param {string} password - CalDAV password
 * @param {string} startDate - Date from which to start, format: YYYYMMDDTHHmmsZ (example: 20140101T120000Z)
 * @param {string} endDate - CalDAV password
 * @param {function} callback - Callback function
 * @function
 */
var caldav = require("node-caldav-mod");
caldav.getEvents("URL_SERVER", "totof", "MDP", "20190101T000000Z","20190601T000000Z")

Lorsque je l’exécute, j’ai un retour qui fonctionne, sans fonctionné :smiley:

<?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/" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns"><d:response><d:href>/remote.php/dav/calendars/totof/astreinte/Nextcloud-44B007A0V4JWGIFS45NIB.ics</d:href><d:propstat><d:prop><cal:calendar-data>BEGIN:VCALENDAR
PRODID:-//Nextcloud calendar v1.6.4
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20181226T133503
DTSTAMP:20181226T133503
LAST-MODIFIED:20181226T133503
UID:7PHLK4EL67XN3M9HIU1TJI
SUMMARY:Astreinte
DTSTART;VALUE=DATE:20190211
DTEND;VALUE=DATE:20190218
END:VEVENT
END:VCALENDAR</cal:calendar-data></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response><d:response><d:href>/remote.php/dav/calendars/totof/astreinte/Nextcloud-7H39IREOJ2RDAKM256SNO.ics</d:href><d:propstat><d:prop><cal:calendar-data>BEGIN:VCALENDAR
PRODID:-//Nextcloud calendar v1.6.4
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20181226T132825
DTSTAMP:20181226T132825
LAST-MODIFIED:20181226T132825
UID:KTZTHFXQ6AKAS4ECCSW1ZQ
SUMMARY:Atreinte
DTSTART;VALUE=DATE:20190121
DTEND;VALUE=DATE:20190128
END:VEVENT
END:VCALENDAR</cal:calendar-data></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response></d:multistatus>
Parsing.....
{ '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/',
        'xmlns:oc': 'http://owncloud.org/ns',
        'xmlns:nc': 'http://nextcloud.org/ns' },
     'd:response': [ [Object], [Object] ] } }
Error parsing response
TypeError: Cannot read property 'D:response' of undefined
    at parseString (/home/pi/node_modules/node-caldav-mod/index.js:194:47)
    at Parser.<anonymous> (/home/pi/node_modules/xml2js/lib/parser.js:303:18)
    at emitOne (events.js:116:13)
    at Parser.emit (events.js:211:7)
    at SAXParser.onclosetag (/home/pi/node_modules/xml2js/lib/parser.js:261:26)
    at emit (/home/pi/node_modules/sax/lib/sax.js:624:35)
    at emitNode (/home/pi/node_modules/sax/lib/sax.js:629:5)
    at closeTag (/home/pi/node_modules/sax/lib/sax.js:889:7)
    at SAXParser.write (/home/pi/node_modules/sax/lib/sax.js:1436:13)
    at Parser.exports.Parser.Parser.parseString (/home/pi/node_modules/xml2js/lib/parser.js:322:31)

Quelqu’un aurais une petite idée ?


#7

Salut @Totof,

Jette un coup d’oeil Ici :
https://github.com/jachwe/node-caldav/issues/3


#8

Salut @piznel,

euh oui oui… ça ne m’a pas aider :smiley:

J’ai essayé autre chose du coup

var dav = require('dav');

var xhr = new dav.transport.Basic(
  new dav.Credentials({
    username: 'xxxx',
    password: 'xxxx'
  })
);

dav.createAccount({ server: 'https://xxxx/remote.php/dav/calendars/totof/', xhr: xhr })
.then(function(account) {
 //  account instanceof dav.Account
  account.calendars.forEach(function(calendar) {
    console.log('Found calendar named ' + calendar.displayName);
    // etc.
  });
});

Et cela me ressort bien ça dans la console

Found calendar named Personnel
Found calendar named Anniversaires des contacts
Found calendar named Informatique
Found calendar named Travail
Found calendar named Astreinte

Par contre je n’ai pas encore trouver comment voir les événements d’un agenda


#9

Ben si, le lien te disait que le fork était pas à jour par rapport au repo d’origine sur cette fonction.
Du coup, c’est cette lib qui pouvait fonctionner.


#10

J’ai voulu installer la node-caldav, mais j’ai eu quelques erreurs, pour ça que je suis passer sur l’autre

  NanNew<v8::StringObject, v8::Handle<v8::String> >(
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:410:3: note: ‘v8::Local<T> NanNew(P) [with T = v8::StringObject; P = v8::Local<v8::String>]’ previously declared here
   NanNew<v8::StringObject, v8::Local<v8::String> >(
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:435:36: error: redefinition of ‘template<class T> v8::Local<v8::RegExp> NanNew(v8::Local<v8::String>, v8::RegExp::Flags)’
   NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                    ^~~~~~
../../nan/nan.h:429:36: note: ‘template<class T> v8::Local<v8::RegExp> NanNew(v8::Handle<v8::String>, v8::RegExp::Flags)’ previously declared here
   NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                    ^~~~~~
../../nan/nan.h:447:36: error: redefinition of ‘template<class T, class P> v8::Local<v8::RegExp> NanNew(v8::Local<v8::String>, v8::RegExp::Flags)’
   NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                    ^~~~~~
../../nan/nan.h:441:36: note: ‘template<class T, class P> v8::Local<v8::RegExp> NanNew(v8::Handle<v8::String>, v8::RegExp::Flags)’ previously declared here
   NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                    ^~~~~~
../../nan/nan.h: In function ‘v8::Local<T> NanNew(P) [with T = v8::Uint32; P = int]’:
../../nan/nan.h:455:51: warning: ‘v8::Local<v8::Uint32> v8::Value::ToUint32() const’ is deprecated: Use maybe version [-Wdeprecated-declarations]
         v8::Isolate::GetCurrent(), val)->ToUint32();
                                                   ^
In file included from ../src/libxmljs.cc:3:0:
/home/pi/.node-gyp/8.9.4/include/node/v8.h:9737:15: note: declared here
 Local<Uint32> Value::ToUint32() const {
               ^~~~~
In file included from ../src/libxmljs.h:7:0,
                 from ../src/libxmljs.cc:7:
../../nan/nan.h: In function ‘v8::Local<T> NanNew(P) [with T = v8::Uint32; P = unsigned int]’:
../../nan/nan.h:461:51: warning: ‘v8::Local<v8::Uint32> v8::Value::ToUint32() const’ is deprecated: Use maybe version [-Wdeprecated-declarations]
         v8::Isolate::GetCurrent(), val)->ToUint32();
                                                   ^
In file included from ../src/libxmljs.cc:3:0:
/home/pi/.node-gyp/8.9.4/include/node/v8.h:9737:15: note: declared here
 Local<Uint32> Value::ToUint32() const {
               ^~~~~
In file included from ../src/libxmljs.h:7:0,
                 from ../src/libxmljs.cc:7:
../../nan/nan.h: In function ‘v8::Local<T> NanNew(P) [with T = v8::Int32; P = int]’:
../../nan/nan.h:466:68: warning: ‘v8::Local<v8::Int32> v8::Value::ToInt32() const’ is deprecated: Use maybe version [-Wdeprecated-declarations]
     return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();

#11

Trouver la bonne librairie est souvent la recherche du Graal !!! :joy:


#12

Hello @piznel

J’ai une petite question, je zieute un peu le code, et du coup je vois bien cette partie la pour récupérer les calendriers je suppose

/**
 * @param {dav.Account} account to fetch calendars for.
 */
export let listCalendars = co.wrap(function *(account, options) {
  debug(`Fetch calendars from home url ${account.homeUrl}`);
  var req = request.propfind({
    props: [
      { name: 'calendar-description', namespace: ns.CALDAV },
      { name: 'calendar-timezone', namespace: ns.CALDAV },
      { name: 'displayname', namespace: ns.DAV },
      { name: 'getctag', namespace: ns.CALENDAR_SERVER },
      { name: 'resourcetype', namespace: ns.DAV },
      { name: 'supported-calendar-component-set', namespace: ns.CALDAV },
      { name: 'sync-token', namespace: ns.DAV }
    ],
    depth: 1
}); 

Celle ci, j’ai l’impression que c’est pour récupérer les objets d’un calendrier

/**
 * @param {dav.Calendar} calendar the calendar to fetch objects for.
 *
 * Options:
 *
 *   (Array.<Object>) filters - optional caldav filters.
 *   (dav.Sandbox) sandbox - optional request sandbox.
 *   (dav.Transport) xhr - request sender.
 */
export let listCalendarObjects = co.wrap(function *(calendar, options) {
  debug(`Doing REPORT on calendar ${calendar.url} which belongs to
         ${calendar.account.credentials.username}`);

  let filters = options.filters || [{
    type: 'comp-filter',
    attrs: { name: 'VCALENDAR' },
    children: [{
      type: 'comp-filter',
      attrs: { name: 'VEVENT' }
    }]
  }];

  let req = request.calendarQuery({
    depth: 1,
    props: [
      { name: 'getetag', namespace: ns.DAV },
      { name: 'calendar-data', namespace: ns.CALDAV }
    ],
    filters: filters
  });

  let responses = yield options.xhr.send(req, calendar.url, {
    sandbox: options.sandbox
  });

  return responses.map(res => {
    debug(`Found calendar object with url ${res.href}`);
    return new CalendarObject({
      data: res,
      calendar: calendar,
      url: url.resolve(calendar.account.rootUrl, res.href),
      etag: res.props.getetag,
      calendarData: res.props.calendarData
    });
  });
});

Mais je ne vois pas comment m’en servir pour récup les objets d’un calendrier. J’ai essayer ceci pour avoir un retour

var dav = require('dav');

var xhr = new dav.transport.Basic(
  new dav.Credentials({
    username: 'totof',
    password: 'MDP'
  })
);

dav.createAccount({ server: 'https://xxxremote.php/dav/calendars/totof/', xhr: xhr })
.then(function(account) {
 //  account instanceof dav.Account
  account.calendars.forEach(function(calendar) {
    //console.log('Found calendar named ' + calendar.object);
    console.dir(calendar, {depth: null});
// etc.
  });
});

Voici un élément du retour que j’ai eu

calendars: 
      [ Calendar {
          data: 
           { href: '/remote.php/dav/calendars/totof/personal/',
             props: 
              { displayname: 'Personnel',
                getctag: 'http://sabre.io/ns/sync/90',
                resourcetype: [ 'collection', 'calendar' ],
                supportedCalendarComponentSet: [ 'VEVENT', 'VTODO' ],
                syncToken: 'http://sabre.io/ns/sync/90' } },
          objects: null,
          account: [Circular],
          ctag: 'http://sabre.io/ns/sync/90',
          description: undefined,
          displayName: 'Personnel',
          reports: 
           [ 'expand-property',
             'principal-match',
             'principal-property-search',
             'principal-search-property-set',
             'calendar-multiget',
             'calendar-query',
             'filter-comments',
             'filter-files' ],
          resourcetype: [ 'collection', 'calendar' ],
          syncToken: 'http://sabre.io/ns/sync/90',
          url: 'https://xxxxx/remote.php/dav/calendars/totof/personal/',
          timezone: undefined,
          components: [ 'VEVENT', 'VTODO' ] },

Tu aurais une suggestion ? :slight_smile:


#13

Hello,

J’ai (bien) regardé la lib, j’y ai pas compris grand chose non plus :wink:
Et j’ai rien pour pouvoir tester…

Il me semble que cette lib est plus faite pour synchroniser avec un calendrier local qu’autre chose, mais bon, là, c’est bien plus fort que moi :frowning:

Désolé …


#14

Après, j’essayerais bien un truc comme ça :

dav.createAccount({ server: 'https://xxxremote.php/dav/calendars/totof/', xhr: xhr, loadCollections: true, loadObjects: true })
  .then(function (account) {
    if (!account.calendars) {
      console.error('Nextcloud:CalDAV -> no calendars found.')
      return
    }
    // account instanceof dav.Account
    account.calendars.forEach(function (calendar) {
      let calName = msg.calendar || node.calendar
      if (!calName || !calName.length || (calName && calName.length && calName === calendar.displayName)) {
        dav.listCalendarObjects(calendar, { xhr: xhr, filters: filters })
          .then(function (calendarEntries) {
            console.log('calendar name', calendar.displayName)
            calendarEntries.forEach(function (calendarEntry) {
              try {
                console.log(calendarEntry)
              } catch (error) {
                console.error(error)
              }
            })
          }, function () {
            console.error('Nextcloud:CalDAV -> get ics went wrong.')
          })
      }
    })
  }, function () {
    console.error('Nextcloud:CalDAV -> get calendars went wrong.')
  })

Pas testé, certainement buggé, mais l’idée est là : parcourir en gros des collections.