Форум » [x]Harbour » Облачные сервисы (WebDAV, CalDAV &Co) » Ответить

Облачные сервисы (WebDAV, CalDAV &Co)

Dr. Oldwarez: После некоторого разбирательства с прогой удалось организовать импорт из ICAL-файлов и экспорт в оные. Но тут шеф захотел, чтобы был прямой контакт с CalDav через интернет. Я знаю, что на питоне такое возможно. На дельфине и даже Xojo (RealBasic) тоже - через спецбиблиотеку. Но как реализовать подключение к облачному сервису в Harbour/Minigui? Возможно ли это вообще?

Ответов - 174, стр: 1 2 3 4 5 6 7 8 9 All

Петр: Dr. Oldwarez пишет: Этак вот Спасибо, прямо вот так взять процедуру и использовать не получится, но все же. Позвольте дать несколько советов. 1) Вот так будет лучше PROCEDURE SyncDlg(cTempDIR,cTempLW,cCALLOgin,cCALPWD,cCALName) Если вы захотите использовать функцию еще где-нибудь, сделать это будет проще. 2) Используйте опции компилятора -w3 -es2 Это позволит вам избежать ошибок и код, возможно, работать будет быстрее. Например мы получили Variable 'NN' is assigned but not used in function 'SYNCDLG(9)' Действительно, LOCAL nN:=1 и дальше nN := 0 Значение nN, присвоенное при инициализации переменной не используется. Вы можете в MinGUI добавить опции в батфайл для сборки compile.bat myprogram /s -w3 /s -es2 %1 %2 %3 %4 %5 %6 %7 %8 %9 или прямо указать в коде #pragma -w3 #pragma -es2

Петр: 3) По возможности используйте стандартные функции Harbour. Это поможет избежать ошибок, свойственных пользовательскому коду, а также увеличит переносимость программ (кода) на другие платформы. Ну и часто код выглядит лучше LOCAL cXML:=cTempDIR+IIF(RIGHT(cTempLW,1)="\",'','\')+'listall_ics.xml' == LOCAL cXML:=cTempDIR+hb_DirSepAdd(cTempLW)+'listall_ics.xml'

Dr. Oldwarez: SergKis пишет: Для этого, вроде, все есть c := DtoS(Date()) m := {} FOR i := 1 TO 12 ; AAdd(m, left(cMonth(StoD( left(c,4)+strzero(i,2)+"01" )), 3)) NEXT a := hb_ATokens("Mon, 15 Mar 2021 12:56:41 GMT"," ") cDay := a[2] cMes := a]3] cGod := a[4] cTim := a[5] cMes := StrZero(AScan(m, cMes), 2) cTim := StrTran(cTim, ":", "") cDat := cGod+cMes+cDay+cTim Вот что-то у меня совсем не то. aICS[ i ][2] - это и есть полный формат даты с днями недели и месяцами. [pre2] FOR i:=1 TO LEN(aICS) IF DTIMETOS(aICS[ i ][2],1)>DTOS(dSyncDate)+'T'+STRTRAN(cSyncTime,":","")+'00Z' AADD(aStrings,SUBSTR(aICS[ i ][1],RAT("/",aICS[ i ][1])+1)) ENDIF NEXT i [/pre2] И функция конвертации [pre2]FUNCTION DTIMETOS(cFull,nUTC) LOCAL c := DtoS(Date()),m := {},a:=ARRAY(7),cDat:='',cDay:='',cMonth:='',cYear:='',cTime:='' FOR i := 1 TO 12 AAdd(m, left(cMonth(StoD( left(c,4)+strzero(i,2)+"01" )), 3)) NEXT a := hb_ATokens(cFull," ") IF LEN(a)>=5 cDay := a[2] cMonth := a[3] cYear := a[4] cTime := a[5] cMonth := StrZero(AScan(m, cMonth), 2) cTime := StrTran(cTime, ":", "") ENDIF cDat := cYear+cMonth+cDay+'T'+cTime+'00Z' RETURN CDat [/pre2] При попытке обратиться к ней из IF выдаёт дикие ошибки обращения к массиву. Хотя значения в поле BROWSE выводит нормально. Это почему так?


Dr. Oldwarez: Петр пишет: 3) По возможности используйте стандартные функции Harbour. Это поможет избежать ошибок, свойственных пользовательскому коду, а также увеличит переносимость программ (кода) на другие платформы. Ну и часто код выглядит лучше LOCAL cXML:=cTempDIR+IIF(RIGHT(cTempLW,1)="\",'','\')+'listall_ics.xml' == LOCAL cXML:=cTempDIR+hb_DirSepAdd(cTempLW)+'listall_ics.xml' Да, намного удобнее использовать готовые функции, а не изобретать велосипед. Но где к ним найти мануал?

Петр: Dr. Oldwarez пишет: Да, намного удобнее использовать готовые функции, а не изобретать велосипед. Но где к ним найти мануал? Например здесь

Петр: Dr. Oldwarez пишет: При попытке обратиться к ней из IF выдаёт дикие ошибки обращения к массиву. Хотя значения в поле BROWSE выводит нормально. Это почему так? А что у вас в программе с настройками set language to ?? или hb_langSelect(??) А заодно и set date to проверьте

SergKis: Dr. Oldwarez пишет При попытке обратиться к ней из IF выдаёт дикие ошибки обращения к массиву. Хотя значения в поле BROWSE выводит нормально. Это почему так? [pre2] FUNCTION DTIMETOS(cFull,nUTC) LOCAL c := DtoS(Date()),m := {},a:=ARRAY(7),cDat:='',cDay:='',cMonth:='',cYear:='',cTime:='' LOCAL i FOR i := 1 TO 12 i перекрылось из процедуры выше с FOR i:=1 TO LEN(aICS) [/pre2]

rvu: SergKis пишет: В Windows 10 build 17063 и более поздних версиях теперь включен Curl Я раньше использовал внешний Curl, потом в Минигуи перешел на внутренний, пока что проблем нет. Есть ли у внешнего преимущества?

Петр: rvu пишет: Я раньше использовал внешний Curl, потом в Минигуи перешел на внутренний, пока что проблем нет. Есть ли у внешнего преимущества? Внутренний - это libcurl?

Петр: Короче, curl написан с использованием функций libcurl Парсер командной строки + функциональность libcurl Понятно, что curl могут использовать не только программисты. curl удобно использовать на этапе отладки. С curl меньше шансов словить ошибку, не предусмотрев обработку результата выполнения библиотечных функций или неправильно заполнив какую-то структуру. Вот и все.

Петр: SergKis пишет: FUNCTION DTIMETOS(cFull,nUTC) LOCAL c := DtoS(Date()),m := {},a:=ARRAY(7),cDat:='',cDay:='',cMonth:='',cYear:='',cTime:='' LOCAL i FOR i := 1 TO 12 i перекрылось из процедуры выше с FOR i:=1 TO LEN(aICS) Кстати, вот вам наглядный пример почему нужно использовать -w3 -es2

Петр: Dr. Oldwarez пишет: IF DTIMETOS(aICS[ i ][2],1)>DTOS(dSyncDate)+'T'+STRTRAN(cSyncTime,":","")+'00Z' Мне кажется - это не правильный подход. В добавок к используемому еще со времен Clipper скалярному типу данных date, в Harbour добавлена поддержка типа timestamp (datetime). tValue := t"2013-11-06;15:14:45" tValue := hb_DateTime() Вы можете создать поля баз данных этого типа, есть куча встроенных функций, можна применять разные операции, в т.ч. сравнения. Поэтому правильнее будет написать функции конвертации ICS DateTime в Harbour TIMESTAMP (DateTime) и наоборот.

Петр: Один из возможных вариантов реализации [pre2]// "Mon, 15 Mar 2021 12:56:41 GMT" FUNCTION DTimeToTS(cFull, cLang) LOCAL m := GET_MONTHS(cLang) LOCAL cMonth LOCAL aDateTime aDateTime := hb_ATokens(hb_defaultValue(cFull, "")," ") IF LEN(aDateTime) >= 5 cMonth := StrZero(AScan(m, aDateTime[3]), 2) RETURN hb_StrToTS(hb_strFormat("%s-%s-%s %s", aDateTime[4], cMonth, aDateTime[2], aDateTime[5])) ENDIF RETURN hb_StrToTS("") STATIC FUNCTION GET_MONTHS(cL) LOCAL cLang LOCAL i, n, aMonths[12], dt := Date() dt -= Day(dt) - 1 cLang := hb_langSelect(cL) FOR i := 1 TO 12 n := Month( dt ) aMonths[ n ] := Left(CMonth(dt), 3) dt += 31 dt -= Day(dt) - 1 NEXT hb_langSelect(cLang) RETURN aMonths[/pre2]

Петр: Проверочный код (консоль) [pre2] //C:\MiniGUI\SAMPLES\MySamples\DateTime\demo.prg REQUEST HB_LANG_RU REQUEST HB_CODEPAGE_RU1251 REQUEST HB_CODEPAGE_RU866 FUNCTION main() hb_cdpSelect( "RU1251" ) hb_langSelect("RU") hb_setTermCP( "RU866", "RU1251" ) ?? CMonth(hb_DateTime()) ? ? hb_DateTime() ? DTimeToTS("Mon, 15 Mar 2021 12:56:41 GMT", "en") ? hb_DateTime() > DTimeToTS("Mon, 15 Mar 2021 12:56:41 GMT", "en") RETURN 0 [/pre2] Если вы используете harbour из поставки MiniGUI ваш compile.bat должен выглядеть так call ..\..\..\batch\compile.bat demo /c %1 %2 %3 %4 %5 %6 %7 %8 %9 PS. почему я спрашивал про set language to .. догадаетесь сами.

Петр: 4) Вызов внешних программ RUN (cRun) Вызов внешних программ без проверки возвращаемых ими кодов ошибок является неиссякаемым источником ошибок. Тем более если такие программы работают с сетью. Но команда RUN - это обертка встроенной __Run(), а эта функция совместима с Clipper и результатов не возвращает. Значит нужно использовать hb_Run() #define CURLE_OK 0 nResult := hb_Run(cRun) IF nResult == CURLE_OK // Все хорошо, начинаем обработку данных ELSE // Обработчик ошибок END Список кодов ошибок, которые может вернуть curl P.S. Для своего проекта можно позаимствовать hbcurl.ch из contrib\hbcurl даже не используя hbcurl

Петр: 5) Использование hb_StrFormat [pre2] #define _DIR_BIN_ (hb_DirBase() + "utils") .. LOCAL cArgs LOCAL cCurlOpt := "--no-progress-meter -k" LOCAL cLogin := "illya@kleeblatt.com" LOCAL cPwd := "**********" LOCAL cCalDav := "https://webmail.kleeblatt.com" LOCAL cHRef := "rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7" ... // Формируем строку вызова cArgs := hb_StrFormat(; '%s\curl %s -u%s:%s -X PROPFIND "%s%s"', _DIR_BIN_, cCurlOpt, cLogin, cPwd, cCalDav, cHRef) ? cArgs [/pre2] Крайне удобно и позволяет переопределять строку аргументов on the fly.

SergKis: Петр пишет Один из возможных вариантов реализации TimeStamp возможный вариант , но он содержит миллисекунды за Timestamp.123, т.е. нельзя делать hhb_DateTime() == DTimeToTS("Mon, 15 Mar 2021 12:56:41 GMT", "en") На мой взгляд, с ics больше подходит строковый формат, только без всяких T и 00Z внутри, если иметь ввиду индексы с участием строковых дат и событий календаря, то ключ получается проще в работе, если учесть хранение в dbf данных в символьном виде (физически), то нет лишних телодвижений rdd по преобразованию данных. Вид даты "2021031512541" больше подходит в данном случае, а TimeStamp в типах =@T или производных от них. Но это мое понимание ситуации.

Петр: SergKis пишет: нельзя делать hhb_DateTime() == DTimeToTS("Mon, 15 Mar 2021 12:56:41 GMT", "en") Это еще почему? ts := hb_StrToTS("2021-03-15 12:56:41") ? ts == DTimeToTS("Mon, 15 Mar 2021 12:56:41 GMT", "en") TimeStamp в harbour поддерживает ISO 8601 и совместим с большинством реализаций. Операции с TimeStamp быстрее строковых операций. Но вольному воля..

SergKis: Петр пишет ? hb_datetime() результат 2021-03-27 01:04:47.133 Операции с TimeStamp быстрее строковых операций Разговор о решениях с isc. Составьте выражения ключей индекса и ключей для scope - выбрать выполненное за год\месяц\квартал\неделя\день ... - выбрать не выполненное за год\месяц\квартал\неделя\день ... ... строковые решения будут проще. А так конечно, решать не нам, что и как делать

Dr. Oldwarez: SergKis пишет: FUNCTION DTIMETOS(cFull,nUTC) LOCAL c := DtoS(Date()),m := {},a:=ARRAY(7),cDat:='',cDay:='',cMonth:='',cYear:='',cTime:='' LOCAL i FOR i := 1 TO 12 i перекрылось из процедуры выше с FOR i:=1 TO LEN(aICS) Вот спасибо!!! Заработало! Теперь надо встречное движение делать - из DBF в календарь. Это означает, генерить пакет ics-ов и забрасывать их в календарь уже хорошо знакомым CURLом. Выбирать все, чья автозаносимая дата создания позже даты последней синхронизации. Можно их в один ics запихнуть, или опять каждому событию - по своему ICSу, и потом уже циклом закидывать их в календарь.



полная версия страницы