После некоторого разбирательства с прогой удалось организовать импорт из ICAL-файлов и экспорт в оные. Но тут шеф захотел, чтобы был прямой контакт с CalDav через интернет. Я знаю, что на питоне такое возможно. На дельфине и даже Xojo (RealBasic) тоже - через спецбиблиотеку. Но как реализовать подключение к облачному сервису в Harbour/Minigui?
Отправлено: 21.03.21 16:39. Заголовок: Dr. Oldwarez пишет А..
Dr. Oldwarez пишет
цитата:
А мне надо именно, что ВСЕ события получить. Дата модификации неинформативна. Не дата модификации мне нужна, а дата и время события. Это и есть первичный ключ в моём локальном календаре
Причем здесь, информативно\не информативно и ваш первичный ключ. Есть архитектура, устройство календаря и оно такое какое есть. Есть правила доступа и вы их соблюдаете или нет. Как минимум, надо сделать все запросы для понимания ситуевины и от нее переходить к вашему устройству базы, но точно не наоборот
BEGIN:VCALENDAR VERSION:2.0 X-WR-CALNAME:Kalender von illya@kleeblatt.com PRODID:-//The Horde Project//Horde iCalendar Library//EN BEGIN:VEVENT DTSTART:20210318T140000Z DTEND:20210318T150000Z DTSTAMP:20210321T192856Z UID:20210315125442.qQtI4Rdk7FakWsfY8RiLVTg@webmail.kleeblatt.com CREATED:20210315T125442Z LAST-MODIFIED:20210315T125641Z SUMMARY:Testing of Import DESCRIPTION:Not so easy, but I will try to do it LOCATION:Somewhere on the Earth CLASS:PUBLIC STATUS:CONFIRMED TRANSP:OPAQUE END:VEVENT END:VCALENDAR
Отправлено: 23.03.21 20:21. Заголовок: Dr. Oldwarez пишет И..
Dr. Oldwarez пишет
цитата:
И что дальше?
Теперь, как минимум, знаете устройство календаря (по запросам), т.е. 1. Список календарей (пост 259) 2. Оглавление календаря (список событий, предыдущий ваш пост 267). Идентификатор события <d:getetag>"fa79fe0b28dea03c0db457af39980eae"</d:getetag> 3. Содержимое календаря (GET запрос), правда вы дали его в усеченном виде, т.к. нет идентификатора события События оглавления содержат дату <d:getlastmodified>Mon, 15 Mar 2021 12:56:41 GMT</d:getlastmodified> и Содержимое события содержит дату LAST-MODIFIED:20210315T125641Z Т.е. получая Оглавление календаря, а не все содержимое, можно знать менялось событие в календаре на сервере, сравнивая со значением в dbf и брать с сервера только измененные данные (содержимое).
Содержимое события содержит дату LAST-MODIFIED:20210315T125641Z Т.е. получая Оглавление календаря, а не все содержимое, можно знать менялось событие в календаре на сервере, сравнивая со значением в dbf и брать с сервера только измененные данные (содержимое).
О, точно, как же я сразу до этого не додумался? Надо всё фильтровать по дате последнего обновления, которая также должна храниться в INI Тогда фильтруются только те ICSы, которые не были актуализированы в прошлый раз. И ещё маленький вопрос напоследок. Как с помощью CURL GET сделать так, чтобы НЕСКОЛЬКО событий вывелось в один файл
А то у меня так (Strings - список названий ics, TEMPDIR - директория временных файлов, создаваемых в процессе подключения к календарю):
... FOR k:=1 TO LEN(aStrings) cCURL2:='curl -o '+cTempDIR+IIF(RIGHT(cTempLW,1)="\",'','\')+'temp_'+STRZERO(k,4)+'.txt --user '+cCALLOgin+':'+cCALPWD+' -i -X GET '+cCalName+; IIF(RIGHT(cCalName,1)='/','','/')+aStrings[k] RUN(cCurl2) NEXT k ...
То есть, каждый ICS на одно событие генерит свой собственный файл. Нельзя ли так, чтобы несколько событий отправлялись в один файл? (Настроить вывод на дозапись вместо открытия нового файла)
Отлично! У меня получилось. Теперь вот вопрос по формату времени. Мой шеф проживает в зоне CET (Гринвич+1). Я - в зоне EET. И хотелось бы привести это всё к одному формату, принятому в ICS: YYYYMMDDTHHMMSSZ И тогда уже можно сделать выбор по дате - только тех, кто позже даты последней автосинхронизации, заносимой в регистр автоматически при нажатии на кнопку "Синхронизация"
Отправлено: 25.03.21 20:59. Заголовок: Петр пишет: В цикле..
Петр пишет:
цитата:
В цикле выполнить вызов curl? Поздравляю.
Этак вот
PROCEDURE SyncDlg() LOCAL cXML:=cTempDIR+IIF(RIGHT(cTempLW,1)="\",'','\')+'listall_ics.xml' LOCAL cRun:='curl -k -o '+cXML+' --user '+cCALLOgin+':'+cCALPWD+' -X PROPFIND "'+cCALName+'"' LOCAL cBuf:="",aBuf:={},nI:=1,aStrings:={},aICS:={},j:=1,cCURL2:="",aHeaders:={"CALENDAR","CHANGE DATE","NUMBER"},aLen:={700,150,80} LOCAL nN:=1,cK:="",cI:="" LOCAL aDimLen := {280,80,50,80,50,200,350} LOCAL aDimHeaders:={"Subject","Start Date", "Start Time","End Date","End Time","Location","Description"},aCalStr:={},aDim:={} LOCAL cLocation:="",cDescription:="",cSubject:="",dStartDate:=CTOD(""),cStartTime:="00:00",dEndDate:=CTOD(""),cEndTime:="00:00",; cStartDateTime:="",cEndDateTime:="" RUN (cRun) cBuf := hb_memoread(cXml)
IF CRLF $ cBuf cBuf := StrTran(cBuf, CRLF, "") ENDIF
aBuf := hb_ATokens(cBuf, "<d:response><d:href>")
nN := 0 FOR nI := 1 TO Len(aBuf) cI := aBuf[nI] nK := AT("</", cI) cK := trim(left(cI, nK-1)) IF right(cK, 4) == ".ics" nN += 1 AAdd(aIcs, { cK, "", "ics "+hb_ntos(nN) }) ENDIF
nN := 0 FOR nI := 1 TO Len(aBuf) cI := aBuf[nI] cK := "" IF ! "<?xml " $ cI nN += 1 nK := AT("</", cI) cK := left(cI, nK-1) aIcs[nN][2] := cK ENDIF
NEXT
FOR i:=1 TO LEN(aICS) //IF aICS[ i ][2]> AADD(aStrings,SUBSTR(aICS[ i ][1],RAT("/",aICS[ i ][1])+1)) //ENDIF NEXT i FOR k:=1 TO LEN(aStrings) cOut := cTempLW+IIF(RIGHT(cTempLW,1)="\",'','\')+'temp_'+STRZERO(k,4)+'.txt' fErase(cOut) cCURL2:='curl -o '+cOut+' --user '+cCALLOgin+':'+cCALPWD+' -i -X GET '+cCalName+; IIF(RIGHT(cCalName,1)='/','','/')+aStrings[k] RUN(cCurl2) IF FILE(cOut) aCalStr:=hb_ATokens(MEMOREAD(cOut),CRLF) FOR nBuf:=1 TO LEN(aCalStr) IF aCalStr[nBuf]="DTSTART" cDateTime:=SUBSTR(aCalStr[nBuf],AT(":",aCalStr[nBuf])+1) dStartDate:=STOD(LEFT(cDateTime,8)) cStartTime:=SUBSTR(cDateTime,10,2)+":"+SUBSTR(cDateTime,12,2) ENDIF IF aCalStr[nBuf]="DTEND" cEndDateTime:=SUBSTR(aCalStr[nBuf],AT(":",aCalStr[nBuf])+1) dEndDate:=STOD(LEFT(cEndDateTime,8)) cEndTime:=SUBSTR(cEndDateTime,10,2)+":"+SUBSTR(cEndDateTime,12,2) ENDIF IF aCalStr[nBuf]="SUMMARY" cSubject:=SUBSTR(aCalStr[nBuf],AT(":",aCalStr[nBuf])+1) ENDIF IF aCalStr[nBuf]="LOCATION" cLocation:=SUBSTR(aCalStr[nBuf],AT(":",aCalStr[nBuf])+1) ENDIF IF aCalStr[nBuf]="DESCRIPTION" cDescription:=SUBSTR(aCalStr[nBuf],AT(":",aCalStr[nBuf])+1) ENDIF NEXT nBuf AADD(aDim,{cSubject,dStartDate,cStartTime,dEndDate,cEndTime,cLocation,cDescription}) // Obrabotka ENDIF NEXT k
DEFINE WINDOW wndSync; AT 50,0; WIDTH 1020 HEIGHT 670; CHILD; TITLE "Calendar synchronization" IF LEN(aDim)>0 DEFINE TBROWSE brwImport; AT 10,10; WIDTH 950 HEIGHT 350; GRID brwImport:=SetArrayTo("brwImport","wndSync",aDim) END TBROWSE ENDIF END WINDOW ACTIVATE WINDOW wndSync
цитата: В Windows 10 build 17063 и более поздних версиях теперь включен Curl, так что вы можете запускать его непосредственно из Cmd.exe или PowerShell.exe.
И это радует. А то придётся уже через libcurl продираться.
Все даты в формате GMT
3 час. Хитов сегодня: 44
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет