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

Jan Schneider jan at horde.org
Thu Feb 11 15:23:01 UTC 2016


Zitat von Daniel <horde at daniu.de>:

> Zitat von Jan Schneider <jan at horde.org>:
>
>> Zitat von Daniel <horde at daniu.de>:
>>
>>> 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."}}
>>
>> Because your parameters are not an array or object:
>> 'params' => $id
>
> Hi,
>
> thanks for the reply - I had tried to change it to:
>       $input = array('version' => '1.1', 'method' =>  
> 'calendar.delete', 'params' => array($id));
>
> which does not work either ...
>
> {"version":"1.1","error":{"name":"JSONRPCError","code":999,"message":{"details":null,"logged":false}}}
>
> any more ideas? I wonder that I am not asked for a calendar id ...  
> Or is the uid independant of calendar id?
>
> regards

See the logs for errors.

-- 
Jan Schneider
The Horde Project
http://www.horde.org/



More information about the horde mailing list