[horde] import calendar events into kronolith - using xmlRPC?

Daniel horde at daniu.de
Thu Feb 11 13:18:53 UTC 2016


Zitat von Daniel <horde at daniu.de>:

> Zitat von Michael J Rubinsky <mrubinsk at horde.org>:
>
>> Quoting Michael J Rubinsky <mrubinsk at horde.org>:
>>
>>> Quoting Daniel <horde at daniu.de>:
>>>
>>>> Zitat von Michael J Rubinsky <mrubinsk at horde.org>:
>>>>
>>>>> Quoting Daniel <horde at daniu.de>:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> Quoting Michael J Rubinsky <mrubinsk at horde.org>:
>>>>>>
>>>>>>> Quoting Daniel <horde at daniu.de>:
>>>>>>>
>>>>>>>> Zitat von Michael J Rubinsky <mrubinsk at horde.org>:
>>>>>>>>
>>>>>>>>> Quoting Michael J Rubinsky <mrubinsk at horde.org>:
>>>>>>>>>
>>>>>>>>>> Quoting Jan Schneider <jan at horde.org>:
>>>>>>>>>>
>>>>>>>>>>> Zitat von Daniel <horde at daniu.de>:
>>>>>>>>>>>
>>>>>>>>>>>> Hi,
>>>>>>>>>>>>
>>>>>>>>>>>> I am new to the list - hope my request is in the right place here:
>>>>>>>>>>>>
>>>>>>>>>>>> My final goal is to get a calendar from google into  
>>>>>>>>>>>> kronolith. Unfortunately my provider did not setup  
>>>>>>>>>>>> kronolith so that I can do that with kronolith itsself so  
>>>>>>>>>>>> I think of a cron-job that does that with a php script (I  
>>>>>>>>>>>> am not talking about syncing - just copying the google  
>>>>>>>>>>>> calendar to kronolith. Since the google calendar itsself  
>>>>>>>>>>>> gets populated with a cron-job itsself it's ok to have  
>>>>>>>>>>>> accurate data only after copying). I can already read all  
>>>>>>>>>>>> appointments from google (caldav still works) - so I got  
>>>>>>>>>>>> a string with Vevent infos. The plan is to purge the  
>>>>>>>>>>>> existing calendar in kronolith and write all events from  
>>>>>>>>>>>> the string into the existing calendar.
>>>>>>>>>>>>
>>>>>>>>>>>> I tried to adjust this: http://theupstairsroom.com/66 but  
>>>>>>>>>>>> don't seem to get it working at all. Partly because I  
>>>>>>>>>>>> don't have access to horde sources on the server from  
>>>>>>>>>>>> which I connect to the Horde - so I need to use another  
>>>>>>>>>>>> RPC-client. I would like to use the RPC-client built in  
>>>>>>>>>>>> php (epinion.com) which is turned on according to  
>>>>>>>>>>>> phpinfo. Somehow I cannot really find a good tutorial how  
>>>>>>>>>>>> to do that.
>>>>>>>>>>>>
>>>>>>>>>>>> Adjusting a script from php.net gave me the attached  
>>>>>>>>>>>> attempt. That one does nothing unfortunately ... (but at  
>>>>>>>>>>>> least no error message)
>>>>>>>>>>>>
>>>>>>>>>>>> Can someone point me in the right direction? Or is there  
>>>>>>>>>>>> a simpler way to achieve what I want to do?
>>>>>>>>>>>>
>>>>>>>>>>>> Is https a problem for what I want to do? Are my  
>>>>>>>>>>>> adjustments for that correct?
>>>>>>>>>>>>
>>>>>>>>>>>> Looking at the api it seems like the purge function from  
>>>>>>>>>>>> import in the GUI did not make it in there ... any chance  
>>>>>>>>>>>> to still do it or get it in the api?
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks for any input!
>>>>>>>>>>>>
>>>>>>>>>>>> (BTW: there is a sourceforge project with exactly that  
>>>>>>>>>>>> topic, but it does not work any more and the author did  
>>>>>>>>>>>> not maintain it - I even asked him and he says he cannot  
>>>>>>>>>>>> help - http://sourceforge.net/projects/kron2gcalsync/)
>>>>>>>>>>>>
>>>>>>>>>>>> ***
>>>>>>>>>>>> function do_call($host, $port, $request) {
>>>>>>>>>>>>
>>>>>>>>>>>> $url = "https://$host:$port/";
>>>>>>>>>>>> //echo $url;
>>>>>>>>>>>> $header[] = "Content-type: text/xml";
>>>>>>>>>>>> $header[] = "Content-length: ".strlen($request);
>>>>>>>>>>>> $to['user']='username';
>>>>>>>>>>>> $to['pass']='password';
>>>>>>>>>>>> $userpwd = $to['user'] .":". $to['pass'];
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> $ch = curl_init();
>>>>>>>>>>>> curl_setopt($ch, CURLOPT_URL, $url);
>>>>>>>>>>>> curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
>>>>>>>>>>>> curl_setopt($ch, CURLOPT_TIMEOUT, 1);
>>>>>>>>>>>> curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
>>>>>>>>>>>> curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
>>>>>>>>>>>> curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
>>>>>>>>>>>> curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
>>>>>>>>>>>> curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
>>>>>>>>>>>>
>>>>>>>>>>>> $data = curl_exec($ch);
>>>>>>>>>>>> if (curl_errno($ch)) {
>>>>>>>>>>>> print curl_error($ch);
>>>>>>>>>>>> } else {
>>>>>>>>>>>> curl_close($ch);
>>>>>>>>>>>> return $data;
>>>>>>>>>>>> }
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> $host="path/rpc.php";
>>>>>>>>>>>> $port=443;
>>>>>>>>>>>> $request =  
>>>>>>>>>>>> xmlrpc_encode_request('kronolith.listCalendars', array());
>>>>>>>>>>>> $response = do_call($host, $port, $request);
>>>>>>>>>>>> echo $response;
>>>>>>>>>>>> ***
>>>>>>>>>>>>
>>>>>>>>>>>> regards
>>>>>>>>>>>>
>>>>>>>>>>>> -- 
>>>>>>>>>>>> Horde mailing list
>>>>>>>>>>>> Frequently Asked Questions: http://horde.org/faq/
>>>>>>>>>>>> To unsubscribe, mail: horde-unsubscribe at lists.horde.org
>>>>>>>>>>>
>>>>>>>>>>> You want to use the kronolith-import-icals script that  
>>>>>>>>>>> comes with Kronolith.
>>>>>>>>>>
>>>>>>>>>> This is correct, if you have shell access. If you don't,  
>>>>>>>>>> you should probably change to JSON as Jan suggests below.  
>>>>>>>>>> In newer versions of Horde we no longer support xmlrpc.
>>>>>>>>>>
>>>>>>>>>> Also:
>>>>>>>>>> 1) Don't set the port number in CURL when you use https://  
>>>>>>>>>> already in the URL.
>>>>>>>>>> 2) The proper method name would be  
>>>>>>>>>> "calendar.listCalendars", not "kronolith.listCalendars".
>>>>>>>>>>
>>>>>>>>>> So, for example (this is VERY rough and quickly done, so  
>>>>>>>>>> you might need to tweak some things):
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> function do_call($host, $method, $params) {
>>>>>>>>>> $url = "https://$host";
>>>>>>>>>> $header[] = "Content-type: application/json";
>>>>>>>>>> $data = array('version' => '1.1', 'method' => $request);
>>>>>>>>>
>>>>>>>>> Sorry, this line should be (substitute $method for $request):
>>>>>>>>> $data = array('version' => '1.1', 'method' => $method);
>>>>>>>>
>>>>>>>> sure - I found that ... works great! THANKS a lot!
>>>>>>>>
>>>>>>>> So now how about the other things:
>>>>>>>> *do I need to delete all events manually or may I beg for a  
>>>>>>>> purge to be implemented in the api?
>>>>>>>
>>>>>>> Use the calendar.deleteCalendar method.
>>>>>>
>>>>>> I guess that should delete the calendar, not purge it? However  
>>>>>> I can't get that one to work ...
>>>>>
>>>>> Correct, which is the same thing that happens when you select  
>>>>> the purge checkbox in the UI.
>>>>
>>>> I don't think so ... that would mean that the calendar would get  
>>>> a new id after doing this or is it possible to define the id  
>>>> somehow? Are we talking about the same thing? I am talking about  
>>>> importing data (ical) in the ui and ticking "delete all data in  
>>>> the calendar" (sorry, my ui is german)
>>>
>>> It looks like our PHP doc is incorrect. Kronolith_Driver::delete()  
>>> is *supposed* to
>>> "Delete a calendar and all of it's events", but looking at the  
>>> actual source code,
>>> it only removes the events.
>>>
>>> In anticipation of your next question, the reason the events are  
>>> all removed individually (and not all at once as would be much  
>>> more efficient especially in a SQL backend) is because we need to  
>>> track the deletions in the Horde_History system for  
>>> synchronization clients.
>>>
>>>>>> ***
>>>>>> $request = 'calendar.deleteCalendar';
>>>>>>
>>>>>> $params = array('calendar-id');
>>>>>>
>>>>>> $response = do_call($host, $request, $params);
>>>>>> echo $response;
>>>>>> ***
>>>>>>
>>>>>> gives me:
>>>>>> {"version":"1.1","error":{"name":"JSONRPCError","code":999,"message":{"details":null,"logged":false}}}
>>>>>
>>>>> This looks like it should work (assuming it's the correct  
>>>>> calendar id and you have enough rights to remove it). Without  
>>>>> details from the server's log it's hard to say why it's not.
>>>>>
>>>>>>>> *Can I import the events with the api yet?
>>>>>>>>
>>>>>>>> I tried that one - (function and host omitted)
>>>>>>>>
>>>>>>>> ***
>>>>>>>> $request = 'calendar.import';
>>>>>>>> $input = <<<EOF
>>>>>>>> BEGIN:VEVENT
>>>>>>>> UID:20160901T130000Z-123401 at host.com
>>>>>>>> DTSTAMP:20160110T1300Z
>>>>>>>> DTSTART:20160110T163000Z
>>>>>>>> DTEND:20160110T190000Z
>>>>>>>> SUMMARY:Test1
>>>>>>>> END:VEVENT
>>>>>>>> UID:20160902T130000Z-123401 at host.com
>>>>>>>> DTSTAMP:20160111T1300Z
>>>>>>>> DTSTART:20160111T163000Z
>>>>>>>> DTEND:20160111T190000Z
>>>>>>>> SUMMARY:Test2
>>>>>>>> END:VEVENT
>>>>>>>> EOF;
>>>>>>>> $params = array($input,'text/calendar','calendar-id');
>>>>>>>> $response = do_call($host, $request, $params);
>>>>>>>> echo $response;
>>>>>>>> ***
>>>>>>>>
>>>>>>>> which imported just the first event ... any chance to make it  
>>>>>>>> import many events with one call? I am afraid that I get a  
>>>>>>>> timeout for the script otherwise ...
>>>>>>>
>>>>>>>
>>>>>>> Correct, you can only import one VEVENT at a time.
>>>>>>>
>>>>>>> I'm confused by your statement about a timeout. A single event  
>>>>>>> will import faster than a large calendar. You are likely to  
>>>>>>> get server timeouts importing the full calendar at once.
>>>>>>>
>>>>>>>> I'd love to see a function like this:
>>>>>>>> public function import_many($content, $contentType, $calendar  
>>>>>>>> = null, $purge = FALSE)
>>>>>>>>
>>>>>>>> while it won't help me since my provider would not update  
>>>>>>>> Horde just for me ...
>>>>>>
>>>>>> just for reference:
>>>>>> I was wrong - just as my string was - there was 1 BEGIN:VEVENT  
>>>>>> missing. Adding that missing part, I can import many events at  
>>>>>> once.
>>>>>
>>>>> Ah. Great. Not sure why I thought that :)
>>>>>
>>>>>
>>>>>> concerning timeout: I was refering to timeout of my php script,  
>>>>>> not the connection to the server within the php script. I guess  
>>>>>> it is faster if I send all events as 1 string than sending each  
>>>>>> event with a seperate call.
>>>>>
>>>>> True. Though it takes longer on the server to process it.  
>>>>> Probably not an issue, but keep that in mind (your host may have  
>>>>> a too-low timeout configured on the server).
>>>>>
>>>>>> I guess I'm going to see how long it takes and in case of a  
>>>>>> problem break the string in parts. Since I don't need the ids  
>>>>>> afterwards should be OK like that.
>>>>
>>>> changed the code slightly for better handling (don't need to  
>>>> remove any username, host or password). Now I got 2 functions:
>>>>
>>>> the first one does work, but gets timed out so that I gotta call  
>>>> it at least once more so that the calendar is empty (php timeout  
>>>> is 60sec I think and it's around 700 events). The second does  
>>>> nothing ...
>>>>
>>>> Would appreciate if someone could test, especially what  
>>>> delete_cal does - remove the calendar or delete all events in it.
>>>
>>> Ok. The calendar/deleteCalendar method does just that, it *only*  
>>> removes the actual calendar share - it doesn't touch the events  
>>> storage.
>>
>> *sigh* Sorry - this is incorrect. calendar/deleteCalendar does  
>> both. It removes
>> the events (by calling Kronolith_Driver::delete()) and then it  
>> removes the calendar
>> share itself. So, you only have to call that one method, you don't  
>> have to iterate over the events on your own.
>>
>> Sorry for the confusion.
>
> Hi
>
> do I get it right, that after calling deleteCalendar the calendar  
> should be gone?
>
> On the server I am talking to it does nothing.
>
> Basically my problem however is that I do not yet know how to really  
> read from a caldav (in this case google) server what has changed  
> lately. I wanted to spare myself that and just erase everything and  
> write it once more (I had found a php script that does that for  
> owncloud which is really fast because there is a command to erase  
> all events at once in owncloud).
>
> I tweaked the code now so that it does only write events that had  
> been changed today (could adjust that to "lately") but that does not  
> erase events from kronolith that had been deleted on google.
>
> well - seems like the remaining problem does not belong here any  
> more and I gotta learn howto talk caldav ...

Hi.

sorry - now I got some problem again:

I wrote this delete uid function:


function delete_id($host, $user, $pw, $id) {

       $url = "https://$host";
       $header[] = "Content-type: application/json";
       $input = array('version' => '1.1', 'method' =>  
'calendar.delete', 'params' => $id);
       $userpwd = $user . ':' . $pw;
       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $url);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
       curl_setopt($ch, CURLOPT_TIMEOUT, 1);
       curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
       curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
       curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
       curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
       curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($input));
       $data = curl_exec($ch);
       $processed=json_decode($data, true);
       if (curl_errno($ch)) {
           print curl_error($ch);
       } else {
           curl_close($ch);
           return $data;
       }
}

But unfortunately I get this reply (var_dump or $data):

{"version":"1.1","error":{"name":"JSONRPCError","code":999,"message":"Parameters must be JSON objects or  
arrays."}}

BTW: why does my error handling not work? I would suppose that  
"curl_errno($ch)" is TRUE for an error.

Not 100% sure but I think it did work before ...

I did other - quite similar - functions that work (besodes error  
handling ...):
function import($host, $user, $pw, $cal, $caldata) {
       $params = array($caldata,'text/calendar', $cal);
       $url = "https://$host";
       $header[] = "Content-type: application/json";
       $input = array('version' => '1.1', 'method' => 'calendar.import');
       if (!empty($params)) {
          $input['params'] = $params;
       }
       $userpwd = $user . ':' . $pw;
       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $url);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 100);
       curl_setopt($ch, CURLOPT_TIMEOUT, 100);
       curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
       curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
       curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
       curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
       curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($input));
       $data = curl_exec($ch);
       if (curl_errno($ch)) {
           print curl_error($ch);
       } else {
           curl_close($ch);
           return $data;
       }
}

any help would be appreciated!

regards



More information about the horde mailing list