Автор | Сообщение |
|
| постоянный участник
|
Пост N: 253
Зарегистрирован: 27.07.08
|
|
Отправлено: 16.03.21 21:55. Заголовок: Облачные сервисы (WebDAV, CalDAV &Co)
После некоторого разбирательства с прогой удалось организовать импорт из ICAL-файлов и экспорт в оные. Но тут шеф захотел, чтобы был прямой контакт с CalDav через интернет. Я знаю, что на питоне такое возможно. На дельфине и даже Xojo (RealBasic) тоже - через спецбиблиотеку. Но как реализовать подключение к облачному сервису в Harbour/Minigui? Возможно ли это вообще?
|
|
|
Ответов - 174
, стр:
1
2
3
4
5
6
7
8
9
All
[только новые]
|
|
|
| постоянный участник
|
Пост N: 3613
Зарегистрирован: 17.02.12
|
|
Отправлено: 17.03.21 07:00. Заголовок: Dr. Oldwarez Посмот..
Dr. Oldwarez Посмотрите hb ...\contrib\hbtip\... и поиск по *.prg "http " в MiniGui\samples
|
|
|
|
| постоянный участник
|
Пост N: 3614
Зарегистрирован: 17.02.12
|
|
Отправлено: 17.03.21 07:35. Заголовок: PS Если сервер htpps..
PS Если сервер htpps, то смотрите curl утилиту (в ней был сертификат ssl)
|
|
|
|
| постоянный участник
|
Пост N: 1601
Зарегистрирован: 09.10.06
|
|
Отправлено: 17.03.21 09:52. Заголовок: SergKis пишет: смот..
|
|
|
|
| |
Пост N: 304
Зарегистрирован: 05.10.06
|
|
Отправлено: 17.03.21 10:03. Заголовок: SergKis пишет: Если..
|
|
|
|
| постоянный участник
|
Пост N: 254
Зарегистрирован: 27.07.08
|
|
Отправлено: 18.03.21 13:03. Заголовок: Это по скачиванию ве..
Это по скачиванию веб-страниц и считыванию данных с них. У меня немножко другой случай. Не веб-страница, а календарь. И много классов, которые я не нахожу в своей документации. Например TIpClientHttp, THtmlDocument. Скачал специально harbour c примерами и там в contrib\hbcurl что-то про выгрузку данных на ftp, но никак уж про CalDav. Да и формат там отнюдь не веб-страничный.
|
|
|
|
| постоянный участник
|
Пост N: 1602
Зарегистрирован: 09.10.06
|
|
Отправлено: 18.03.21 14:04. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Скачал специально harbour c примерами и там в contrib\hbcurl что-то про выгрузку данных на ftp, но никак уж про CalDav. |
| Там что-то про использование libcurl (инициализация, заполнение структур) на примере работы с ftp. Другие примеры на C можно найти на странице проекта. Use a webdav service with curl - это о чем?
|
|
|
|
| moderator
|
Пост N: 1442
Зарегистрирован: 06.07.06
|
|
Отправлено: 18.03.21 16:08. Заголовок: Не знаю, что такое C..
Не знаю, что такое CalDav и не вспомню навскидку о webdav, но предложение SergKis использовать curl мне кажется перспективным. Поиск на Яндексе по 'curl webdav' дает кучу ссылок - т.е., curl с webdav работает. Я обычно советую использовать не hbcurl, чтобы не тратить время на его изучение, а запускать непосредственно утилиту командной строки curl.exe, передавая ей файл с нужными параметрами.
|
|
|
|
| постоянный участник
|
Пост N: 255
Зарегистрирован: 27.07.08
|
|
Отправлено: 18.03.21 20:57. Заголовок: Про CalDAV здесь Cal..
Про CalDAV здесь CalDAV Но мне бы всё-таки хотелось встроенную библиотеку для удобства дистрибуции. Изучить я смогу. Только дайте мне документацию, а то hbd я не знаю, чем прочесть. И несколько примеров.
|
|
|
|
| постоянный участник
|
Пост N: 3616
Зарегистрирован: 17.02.12
|
|
Отправлено: 18.03.21 22:45. Заголовок: Dr. Oldwarez Рекоме..
Dr. Oldwarez Рекомендую начать с curl, можно найти описание и даже примеры, а встроенную библиотеку, придется изучать по исходникам. Вот практически первый ответ на запрос google: "curl.exe и caldav запросы" https://www.atmail.com/blog/caldav-carddav/
|
|
|
|
| постоянный участник
|
Пост N: 256
Зарегистрирован: 27.07.08
|
|
Отправлено: 19.03.21 15:54. Заголовок: Скачал этот CURL теп..
Скачал этот CURL теперь вот вопрос, что ставить в PROPFIND curl -k --user "${login}:${password}" -X PROPFIND "https://owncloud.jujens.eu/remote.php/caldav/calendars/jujens/defaultcalendar" Вместо https://owncloud.jujens.eu/remote.php/caldav/calendars/jujens/defaultcalendar У меня в календаре на вкладке Subscription выходят пять адресов CalDAV Subscription URL CalDAV Account URL WebDAV/ICS Subscription URL Feed URL Embed Script Что именно ставить туда?
|
|
|
|
| постоянный участник
|
Пост N: 3619
Зарегистрирован: 17.02.12
|
|
Отправлено: 19.03.21 16:43. Заголовок: Попробуйте первых 3,..
Попробуйте первых 3, добавьте только параметр -O (в тек. каталоге файл)
|
|
|
|
|
| постоянный участник
|
Пост N: 257
Зарегистрирован: 27.07.08
|
|
Отправлено: 19.03.21 19:26. Заголовок: SergKis пишет: Попр..
SergKis пишет: цитата: | Попробуйте первых 3, добавьте только параметр -O (в тек. каталоге файл) |
| Выходит так c:\curl\bin>curl -k -o --user "${USERNAME}:${PASSWORD}" -X PROPFIND "https://webmail.kleeblatt.com/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7" Warning: The file name argument '--user' looks like a flag. curl: (3) URL using bad/illegal format or missing URL <?xml version="1.0" encoding="utf-8"?> <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"> <s:exception>Sabre\DAV\Exception\NotAuthenticated</s:exception> <s:message>No basic authentication headers were found</s:message> <s:sabredav-version>1.8.12</s:sabredav-version> </d:error>
|
|
|
|
| постоянный участник
|
Пост N: 3620
Зарегистрирован: 17.02.12
|
|
Отправлено: 19.03.21 20:59. Заголовок: Dr. Oldwarez флаг -..
Dr. Oldwarez флаг --user правильно задан ? curl -u username:password ...
|
|
|
|
| постоянный участник
|
Пост N: 1604
Зарегистрирован: 09.10.06
|
|
Отправлено: 19.03.21 22:06. Заголовок: SergKis пишет: флаг..
SergKis пишет: цитата: | флаг --user правильно задан ? |
| Скорее всего правильно: флаги -u и --user равноценны. "${USERNAME}:${PASSWORD}" - пытается получить значения из переменных окружения (хотя хз, что там на самом деле). а вот -o - вывод в файл, а не stdout после -o должен следовать аргумент имя локального файла, он не указан поэтому и получили Warning: The file name argument '--user' looks like a flag
|
|
|
|
| постоянный участник
|
Пост N: 3621
Зарегистрирован: 17.02.12
|
|
Отправлено: 19.03.21 22:29. Заголовок: Петр пишет хотя хз, ..
Петр пишет цитата: | хотя хз, что там на самом деле |
| Именно это и говорил, раз получили такое сообщение Warning:... цитата: | после -o должен следовать аргумент имя локального файла, он не указан |
| после -o да, после -O не обязательно, если не указан берет имя файла из адреса без пути (для пробы и тестов пробовать можно)
|
|
|
|
| постоянный участник
|
Пост N: 1605
Зарегистрирован: 09.10.06
|
|
Отправлено: 19.03.21 22:44. Заголовок: SergKis пишет: посл..
SergKis пишет: Ну так у него -o а вот "${USERNAME}:${PASSWORD}" - это что-то не из винды, непонятно может msys использует. Интересно что это значит: цитата: | curl: (3) URL using bad/illegal format or missing URL |
| У меня при curl -k -oout.txt -O --user "${USERNAME}:${PASSWORD}" -X PROPFIND "https://webmail.kleeblatt.com/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7" получилось <?xml version="1.0" encoding="utf-8"?> <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"> <s:exception>Sabre\DAV\Exception\NotAuthenticated</s:exception> <s:message>Username or password does not match</s:message> <s:sabredav-version>1.8.12</s:sabredav-version> </d:error> что в принципе правильно
|
|
|
|
| постоянный участник
|
Пост N: 3622
Зарегистрирован: 17.02.12
|
|
Отправлено: 19.03.21 23:00. Заголовок: Петр пишет Интересно..
Петр пишет цитата: | Интересно что это значит: |
| Из показанной выше ссылке curl и CalDav (google перевод) понял, что на сервере надо иметь рег. запись и по ней делать пошаговые запросы, получая адреса. Возможно, сообщение, как следствие не коннекта, не сталкивался с таким. Пробовал работу с ftp и передавать, получать json данные с чужим сервером.
|
|
|
|
| постоянный участник
|
Пост N: 258
Зарегистрирован: 27.07.08
|
|
Отправлено: 19.03.21 23:04. Заголовок: Петр пишет: У меня..
Петр пишет: цитата: | У меня при curl -k -oout.txt -O --user "${USERNAME}:${PASSWORD}" -X PROPFIND "https://webmail.kleeblatt.com/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7" получилось <?xml version="1.0" encoding="utf-8"?> <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"> <s:exception>Sabre\DAV\Exception\NotAuthenticated</s:exception> <s:message>Username or password does not match</s:message> <s:sabredav-version>1.8.12</s:sabredav-version> </d:error> что в принципе правильно |
| Вроде что-то получилось curl -k -o test.xml --user USERNAME:PASSWORD -X PROPFIND "https://webmail.kleeblatt.com/rpc.php/principals/illya@kleeblatt.com/" Вышло <?xml version="1.0" encoding="utf-8"?> <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:card="urn:ietf:params:xml:ns:carddav"> <d:response><d:href>/rpc.php/principals/illya@kleeblatt.com/</d:href><d:propstat><d:prop><d:getlastmodified>Fri, 19 Mar 2021 20:06:47 GMT</d:getlastmodified><d:resourcetype><d:principal/> </d:resourcetype></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response></d:multistatus> Теперь, как, собственно говоря, войти в календарь и просмотреть его содержимое?
|
|
|
|
| постоянный участник
|
Пост N: 1606
Зарегистрирован: 09.10.06
|
|
Отправлено: 19.03.21 23:11. Заголовок: SergKis пишет: Возм..
|
|
|
|
| постоянный участник
|
Пост N: 1607
Зарегистрирован: 09.10.06
|
|
Отправлено: 19.03.21 23:23. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Вроде что-то получилось curl -k -o test.xml --user USERNAME:PASSWORD -X PROPFIND "https://webmail.kleeblatt.com/rpc.php/principals/illya@kleeblatt.com/" |
| Куда этот url ссылается? Эту часть почему отбросили /calendar~GhGVum1xWexaffEfhiVkNN7
|
|
|
|
| постоянный участник
|
Пост N: 3623
Зарегистрирован: 17.02.12
|
|
Отправлено: 19.03.21 23:29. Заголовок: Dr. Oldwarez пишет Т..
Dr. Oldwarez пишет цитата: | Теперь, как, собственно говоря, войти в календарь и просмотреть его содержимое? |
| цитата: | <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:card="urn:ietf:params:xml:ns:carddav"> |
| Похожее видел в той статье <?xml version="1.0"?> <d:multistatus xmlns:d="DAV:" xmlns:s="https://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="https://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav"> ... Но у нас также есть еще одна интересная информация, возвращенная в теле запроса, а именно другая коллекция, которую мы можем изучить: /calendars/user@demo.atmail.com/ Мы будем выполнять рекурсию, насколько это возможно, с глубиной, установленной на бесконечность, но передаем некоторые данные запроса, чтобы указать, что нас интересуют только объекты календаря, и чтобы вернуть только URL-адрес, тип ресурса и отображаемое имя коллекции: $ curl --user "user@demo.atmail.com:ThePassword" -sD /dev/stderr -H "Content-Type: application/xml" -X PROPFIND -H "Depth: infinity" --data '<d:propfind xmlns:d="DAV:" xmlns:cs="https://calendarserver.org/ns/"><d:prop><d:resourcetype /><d:displayname /></d:prop></d:propfind>' https://demo-server.atmail.com:8443/calendars/user@demo.atmail.com/ | xmllint -format - ... и т.д. по статье, наверно, так
|
|
|
|
|
| постоянный участник
|
Пост N: 259
Зарегистрирован: 27.07.08
|
|
Отправлено: 19.03.21 23:43. Заголовок: Петр пишет: цитат..
Петр пишет: цитата: | цитата: Вроде что-то получилось curl -k -o test.xml --user USERNAME:PASSWORD -X PROPFIND "https://webmail.kleeblatt.com/rpc.php/principals/illya@kleeblatt.com/" Куда этот url ссылается? Эту часть почему отбросили /calendar~GhGVum1xWexaffEfhiVkNN7 |
| Добавил потерянную часть. И вот <?xml version="1.0" encoding="utf-8"?> <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:card="urn:ietf:params:xml:ns:carddav"><d:response> <d:href>/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/</d:href> <d:propstat><d:prop><d:resourcetype><d:collection/><cal:calendar/></d:resourcetype></d:prop> <d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response><d:response><d:href>/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/w7klsLDepGCBYAA7Gmr4GIe.ics</d:href> <d:propstat><d:prop><d:getlastmodified>Sat, 13 Mar 2021 16:58:11 GMT</d:getlastmodified> <d:getcontentlength>500</d:getcontentlength><d:resourcetype/><d:getetag>"bb0f09c6bf34469cad5f872725ed93b9"</d:getetag> <d:getcontenttype>text/calendar; charset=utf-8</d:getcontenttype></d:prop><d:status>HTTP/1.1 200 OK</d:status> </d:propstat></d:response> <d:response><d:href>/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/8gpZuoZBJQDnLlr-66brhHG.ics</d:href> <d:propstat><d:prop><d:getlastmodified>Thu, 04 Mar 2021 16:51:14 GMT</d:getlastmodified><d:getcontentlength>515</d:getcontentlength><d:resourcetype/> <d:getetag>"c1daa4a100ad72550dc468e539047aac"</d:getetag><d:getcontenttype>text/calendar; charset=utf-8</d:getcontenttype></d:prop> <d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response><d:response> <d:href>/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/VM3wwLrVEm3Zwn-UkKAzXra.ics</d:href> <d:propstat><d:prop><d:getlastmodified>Thu, 04 Mar 2021 16:51:33 GMT</d:getlastmodified><d:getcontentlength>577</d:getcontentlength> <d:resourcetype/><d:getetag>"da02d9cfbc83085498615e55e87d25ea"</d:getetag><d:getcontenttype>text/calendar; charset=utf-8</d:getcontenttype></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response> <d:response><d:href>/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/e5aab12a-1a2a-4309-96d4-cccb1b67d9ba.ics</d:href> <d:propstat><d:prop><d:getlastmodified>Mon, 08 Mar 2021 06:59:00 GMT</d:getlastmodified><d:getcontentlength>659</d:getcontentlength> <d:resourcetype/><d:getetag>"ff0f3e0392c3a16579e8b87442f60ff4"</d:getetag> <d:getcontenttype>text/calendar; charset=utf-8</d:getcontenttype></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response> <d:response><d:href>/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/seukIp8ajv0rOXXx8IG4Q9j.ics</d:href><d:propstat> <d:prop><d:getlastmodified>Mon, 15 Mar 2021 12:56:41 GMT</d:getlastmodified><d:getcontentlength>546</d:getcontentlength><d:resourcetype/> <d:getetag>"fa79fe0b28dea03c0db457af39980eae"</d:getetag><d:getcontenttype>text/calendar; charset=utf-8</d:getcontenttype></d:prop> <d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response><d:response> <d:href>/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/83sEK6nFBn4-TQ1XcZoPvWz.ics</d:href><d:propstat><d:prop> <d:getlastmodified>Mon, 15 Mar 2021 12:52:23 GMT</d:getlastmodified><d:getcontentlength>526</d:getcontentlength><d:resourcetype/> <d:getetag>"11735b683c59f7e3c0a60842c1df4101"</d:getetag><d:getcontenttype>text/calendar; charset=utf-8</d:getcontenttype></d:prop> <d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response></d:multistatus>
|
|
|
|
| постоянный участник
|
Пост N: 1608
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.03.21 00:02. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Я так понял, это список ICS файлов. Теперь надо открывать каждый ICS по отдельности, чтобы получить записи календаря? |
| Наверное. Попробуйте стащить один и поработать с ним оффлайн.
|
|
|
|
| постоянный участник
|
Пост N: 3624
Зарегистрирован: 17.02.12
|
|
Отправлено: 20.03.21 00:18. Заголовок: Dr. Oldwarez пишет Д..
Dr. Oldwarez пишет цитата: | Добавил потерянную часть. И вот |
| Смотреть без переноса трудно, но похоже (по статье) это коллекция календарей, опять по статье след. шаг цитата: | Итак, заглянем внутрь одной из этих коллекций (календарей). Выберем календарь «Дни рождения» и посмотрим, что там: $ curl --user "user@demo.atmail.com:ThePassword" -sD /dev/stderr -H "Content-Type: application/xml" -X PROPFIND -H "Depth: infinity" https://demo-server.atmail.com:8443/calendars/user@demo.atmail.com/02f29dd9516f1f0c415527e0a60cb3f7/ | xmllint -format - ...ответ В данном случае это календарное событие, и мы можем сказать об этом через свойство: <d: getcontenttype> текст / календарь; charset = utf-8; компонент = vevent </ d: getcontenttype> Наконец, давайте извлечем это событие с помощью обычного старого HTTP GET и посмотрим, что у нас есть: curl --user "user@demo.atmail.com:ThePassword" -i -X GET https://demo-server.atmail.com:8443/calendars/user@demo.atmail.com/02f29dd9516f1f0c415527e0a60cb3f7/33992bd8-d3fe-4b07-baaf-c43d0042fae8.ics HTTP/1.1 200 OK Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:28:59 GMT Content-Type: text/calendar; charset=utf-8; component=vevent Content-Length: 554 Connection: keep-alive Last-Modified: Sat, 09 May 2020 01:24:06 GMT ETag: "d34b216dac0dcf327a3cf2d79f95a226" X-Content-Type-Options: nosniff BEGIN:VCALENDAR VERSION:2.0 PRODID:-//apiserver//API Server DAV//EN BEGIN:VEVENT UID:33992bd8-d3fe-4b07-baaf-c43d0042fae8 DTSTART;VALUE=DATE:20200506 DTEND;VALUE=DATE:20200507 CREATED:20190124T104704Z DTSTAMP:20190128T234044Z LAST-MODIFIED;X-VOBJ-FLOATINGTIME-ALLOWED=TRUE:20200503T203005 RRULE:FREQ=YEARLY;INTERVAL=1;WKST=MO SEQUENCE:30 STATUS:CONFIRMED SUMMARY:Dad's Birthday TRANSP:OPAQUE BEGIN:VALARM ACKNOWLEDGED:20190128T234044Z ACTION:DISPLAY DESCRIPTION:Default Description TRIGGER:-P1D END:VALARM END:VEVENT END:VCALENDAR |
| по статье такие действия для извл. данных
|
|
|
|
| постоянный участник
|
Пост N: 1609
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.03.21 00:34. Заголовок: SergKis пишет: Смот..
|
|
|
|
| постоянный участник
|
Пост N: 3625
Зарегистрирован: 17.02.12
|
|
Отправлено: 20.03.21 00:54. Заголовок: Петр пишет Code Beau..
Петр пишет Через эту штуку и надо сюда выкладывать, а то страницы расползлись по ширине хз как, центрованные цитаты вправо улетели далеко за пределы экрана, не говоря о самом тексте
|
|
|
|
| постоянный участник
|
Пост N: 1610
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.03.21 10:01. Заголовок: Надеюсь топикстартер..
Надеюсь топикстартер (или модератор) пост №259 удалит, а №260 отформатирует как следует.
|
|
|
|
| постоянный участник
|
Пост N: 261
Зарегистрирован: 27.07.08
|
|
Отправлено: 20.03.21 21:14. Заголовок: Петр пишет: Отпр..
Петр пишет: цитата: | Отправлено: Сегодня 10:01. Заголовок: Надеюсь топикстартер.. - новое! Надеюсь топикстартер (или модератор) пост №259 удалит, а №260 отформатирует как следует. |
| Подформатировал пост 259. 260 удалил как дубликат. Извините за созданные проблемы - я просто не имею опыта с xml файлами
|
|
|
|
| постоянный участник
|
Пост N: 262
Зарегистрирован: 27.07.08
|
|
Отправлено: 21.03.21 09:56. Заголовок: SergKis пишет: Смот..
SergKis пишет: цитата: | Смотреть без переноса трудно, но похоже (по статье) это коллекция календарей, опять по статье след. шаг цитата: Итак, заглянем внутрь одной из этих коллекций (календарей). Выберем календарь «Дни рождения» и посмотрим, что там: $ curl --user "user@demo.atmail.com:ThePassword" -sD /dev/stderr -H "Content-Type: application/xml" -X PROPFIND -H "Depth: infinity" https://demo-server.atmail.com:8443/calendars/user@demo.atmail.com/02f29dd9516f1f0c415527e0a60cb3f7/ | xmllint -format - ...ответ В данном случае это календарное событие, и мы можем сказать об этом через свойство: <d: getcontenttype> текст / календарь; charset = utf-8; компонент = vevent </ d: getcontenttype> Наконец, давайте извлечем это событие с помощью обычного старого HTTP GET и посмотрим, что у нас есть: curl --user "user@demo.atmail.com:ThePassword" -i -X GET https://demo-server.atmail.com:8443/calendars/user@demo.atmail.com/02f29dd9516f1f0c415527e0a60cb3f7/33992bd8-d3fe-4b07-baaf-c43d0042fae8.ics HTTP/1.1 200 OK Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:28:59 GMT Content-Type: text/calendar; charset=utf-8; component=vevent Content-Length: 554 Connection: keep-alive Last-Modified: Sat, 09 May 2020 01:24:06 GMT ETag: "d34b216dac0dcf327a3cf2d79f95a226" X-Content-Type-Options: nosniff BEGIN:VCALENDAR VERSION:2.0 PRODID:-//apiserver//API Server DAV//EN BEGIN:VEVENT UID:33992bd8-d3fe-4b07-baaf-c43d0042fae8 DTSTART;VALUE=DATE:20200506 DTEND;VALUE=DATE:20200507 CREATED:20190124T104704Z DTSTAMP:20190128T234044Z LAST-MODIFIED;X-VOBJ-FLOATINGTIME-ALLOWED=TRUE:20200503T203005 RRULE:FREQ=YEARLY;INTERVAL=1;WKST=MO SEQUENCE:30 STATUS:CONFIRMED SUMMARY:Dad's Birthday TRANSP:OPAQUE BEGIN:VALARM ACKNOWLEDGED:20190128T234044Z ACTION:DISPLAY DESCRIPTION:Default Description TRIGGER:-P1D END:VALARM END:VEVENT END:VCALENDAR по статье такие действия для извл. данных |
| Да, я понял. Но сначала нужно весь список ics-ов считать в массив внешним циклом, а потом каждый ics ещё просмотреть, чтобы получить из него данные календарей. Это очень много вызовов curl и автоматически созданных промежуточных файлов получается. Нельзя ли так, чтобы сразу подключение и считывание прямо программой, минуя многочисленные промежуточные стадии? И как в Harbour считывать данные из XML в массив?
|
|
|
|
| постоянный участник
|
Пост N: 1611
Зарегистрирован: 09.10.06
|
|
Отправлено: 21.03.21 12:01. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Но мне бы всё-таки хотелось встроенную библиотеку для удобства дистрибуции. Изучить я смогу. Только дайте мне документацию, а то hbd я не знаю, чем прочесть. И несколько примеров. |
| Dr. Oldwarez пишет: цитата: | Нельзя ли так, чтобы сразу подключение и считывание прямо программой, минуя многочисленные промежуточные стадии? |
| Добейтесь конечного результата с curl, а тогда будете оптимизировать. Сейчас у вас нет ни знаний, ни умений на свои хотелки. Все придет, может быть, а может и не быть. К тому же инсталлятор весом меньше 1 Га в наше время моветон
|
|
|
|
| постоянный участник
|
Пост N: 1612
Зарегистрирован: 09.10.06
|
|
Отправлено: 21.03.21 12:15. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | И как в Harbour считывать данные из XML в массив? |
| Все просто - считываете данные из XML и добавляете в массив. В Harbour нет встроенных функций для роботы с XML, в отличии от того же json или cvs, ini. Значит у вас есть выбор 1) Можете просто разбирать строку с помощью строковых функций; 2) Можете использовать библиотеку hbexpat из contrib, примеры там же; 3) Можете использовать библиотеку hbmxml из contrib, примеры там же; 4) Можете использовать библиотеку hbxml из состава Minigui, пример SAMPLES\Advanced\XmlDemo и др; 5) Можете использовать стандартные технологии MS OLE и Msxml, пример SAMPLES\Advanced\GoogleCharts; и т.д. и т.п.
|
|
|
|
|
| постоянный участник
|
Пост N: 3627
Зарегистрирован: 17.02.12
|
|
Отправлено: 21.03.21 13:59. Заголовок: Петр пишет Можете пр..
Петр пишет цитата: | Можете просто разбирать строку с помощью строковых функций; |
| Простой пример выкусить из xml поста 259 LOCAL cXml := "_ics.xml" // файл с данными из поста 259 LOCAL cBuf := hb_memoread(cXml) LOCAL aBuf, nI IF CRLF $ cBuf ; cBuf := StrTran(cBuf, CRLF, "") ENDIF aBuf := hb_ATokens(cBuf, "<d:response><d:href>") ? aBuf FOR nI := 1 TO Len(aBuf) cBuf := aBuf[nI] ? nI, left(cBuf, AT("</", cBuf)-1) NEXT ... результат ARRAY[8] 1 '' 2 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/ 3 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/w7klsLDepGCBYAA7Gmr4GIe.ics 4 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/8gpZuoZBJQDnLlr-66brhHG.ics 5 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/VM3wwLrVEm3Zwn-UkKAzXra.ics 6 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/e5aab12a-1a2a-4309-96d4-cccb1b67d9ba.ics 7 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/seukIp8ajv0rOXXx8IG4Q9j.ics 8 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/83sEK6nFBn4-TQ1XcZoPvWz.ics
|
|
|
|
| постоянный участник
|
Пост N: 3628
Зарегистрирован: 17.02.12
|
|
Отправлено: 21.03.21 14:12. Заголовок: Dr. Oldwarez пишет Н..
Dr. Oldwarez пишет цитата: | Нельзя ли так, чтобы сразу подключение и считывание прямо программой, минуя многочисленные промежуточные стадии? |
| Если пройдете по статье еще раз, то увидите, что каждый вызов curl это запрос к серверу и обработка результата и снова запрос ..., т.е. и без curl будет точно такая же схема работы. Если оформите запрос в ф-ю (вызов curl и обработка результата) с возвратом результата, то если (может и не понадобится) потом надо будет переделаете на исп. lib
|
|
|
|
| постоянный участник
|
Пост N: 3629
Зарегистрирован: 17.02.12
|
|
Отправлено: 21.03.21 14:53. Заголовок: PS Давать календари ..
PS Давать календари надо будет в цивилизованном виде, т.е. таблица dbf\array - "список календарей" -> выбираем -> запрос[ы] curl к серверу -> ответ и таблица dbf\array - "события календаря" если работа online, при offline тот же путь выборки и куда то сохранить первичные запросы (потом обновлять, если ics меняли)
|
|
|
|
| постоянный участник
|
Пост N: 3630
Зарегистрирован: 17.02.12
|
|
Отправлено: 21.03.21 15:25. Заголовок: PS2 Чуть усложнил и ..
PS2 Чуть усложнил и получил таблицу календарей в массиве Скрытый текст
/* * MINIGUI - Harbour Win32 GUI library Demo */ #define _HMG_OUTLOG #include "hmg.ch" #define SHOW_TITLE "Read list ics calendar from xml" REQUEST HB_CODEPAGE_RU1251, HB_CODEPAGE_RU866 REQUEST HB_CODEPAGE_UTF8 REQUEST DBFCDX, DBFFPT REQUEST DBFNTX, DBFDBT //////////////////////////////////////////////////////////////////////////// FUNCTION Main() LOCAL cXml := "_ics.xml" LOCAL cBuf := hb_memoread(cXml) LOCAL aBuf, nI, cI, nK, cK, nN LOCAL aIcs := {} SET CODEPAGE TO RUSSIAN SET LANGUAGE TO RUSSIAN rddSetDefault( "DBFCDX" ) SET CENTURY ON SET DATE GERMAN SET DATE FORMAT "DD.MM.YY" SET DELETED OFF SET EXCLUSIVE ON SET EPOCH TO 2000 SET AUTOPEN ON SET EXACT ON SET SOFTSEEK ON SET NAVIGATION EXTENDED SET FONT TO "Arial", 11 SET OOP ON fErase(".\_MsgLog.txt") IF CRLF $ cBuf ; cBuf := StrTran(cBuf, CRLF, "") ENDIF aBuf := hb_ATokens(cBuf, "<d:response><d:href>") ? aBuf, "Адреса:" 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 ? nI, cK NEXT ? aBuf := hb_ATokens(cBuf, "<d:propstat><d:prop><d:getlastmodified>") ? aBuf, "Модификация:" 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 ? nI, cK NEXT ? ? "ICS =", aIcs ?v aIcs ? RETURN NIL Результат ARRAY[8] Адреса: 1 '' 2 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/ 3 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/w7klsLDepGCBYAA7Gmr4GIe.ics 4 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/8gpZuoZBJQDnLlr-66brhHG.ics 5 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/VM3wwLrVEm3Zwn-UkKAzXra.ics 6 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/e5aab12a-1a2a-4309-96d4-cccb1b67d9ba.ics 7 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/seukIp8ajv0rOXXx8IG4Q9j.ics 8 /rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/83sEK6nFBn4-TQ1XcZoPvWz.ics ARRAY[7] Модификация: 1 '' 2 Sat, 13 Mar 2021 16:58:11 GMT 3 Thu, 04 Mar 2021 16:51:14 GMT 4 Thu, 04 Mar 2021 16:51:33 GMT 5 Mon, 08 Mar 2021 06:59:00 GMT 6 Mon, 15 Mar 2021 12:56:41 GMT 7 Mon, 15 Mar 2021 12:52:23 GMT ICS = ARRAY[6] 1 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/w7klsLDepGCBYAA7Gmr4GIe.ics", "Sat, 13 Mar 2021 16:58:11 GMT", "ics 1"} 2 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/8gpZuoZBJQDnLlr-66brhHG.ics", "Thu, 04 Mar 2021 16:51:14 GMT", "ics 2"} 3 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/VM3wwLrVEm3Zwn-UkKAzXra.ics", "Thu, 04 Mar 2021 16:51:33 GMT", "ics 3"} 4 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/e5aab12a-1a2a-4309-96d4-cccb1b67d9ba.ics", "Mon, 08 Mar 2021 06:59:00 GMT", "ics 4"} 5 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/seukIp8ajv0rOXXx8IG4Q9j.ics", "Mon, 15 Mar 2021 12:56:41 GMT", "ics 5"} 6 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/83sEK6nFBn4-TQ1XcZoPvWz.ics", "Mon, 15 Mar 2021 12:52:23 GMT", "ics 6"}
|
|
|
|
|
| постоянный участник
|
Пост N: 263
Зарегистрирован: 27.07.08
|
|
Отправлено: 21.03.21 15:30. Заголовок: SergKis пишет: Дава..
SergKis пишет: цитата: | Давать календари надо будет в цивилизованном виде, т.е. таблица dbf\array - "список календарей" -> выбираем -> запрос[ы] curl к серверу -> ответ и таблица dbf\array - "события календаря" если работа online, при offline тот же путь выборки и куда то сохранить первичные запросы (потом обновлять, если ics меняли) |
| Спасибо за помощь! Я уже понял, примерно, как это. Но вот вопрос: если календарь заполнен и в нём 500 событий, это что, надо 500 раз соединяться? Такого DDOSа не выдержат ни сеть, ни комп. Профильтровать их тоже не получится - пока не откроешь ICS, его параметры будут неизвестны.
|
|
|
|
| постоянный участник
|
Пост N: 3631
Зарегистрирован: 17.02.12
|
|
Отправлено: 21.03.21 15:43. Заголовок: Dr. Oldwarez пишет Т..
Dr. Oldwarez пишет цитата: | Такого DDOSа не выдержат ни сеть, ни комп. |
| Это не DDOS, а REST API спец. механизм для доступа и обмена данными, смело используйте цитата: | Профильтровать их тоже не получится - пока не откроешь ICS, его параметры будут неизвестны. |
| Если сохранять в dbf, то можно опираться на дату модификации сначала ics, потом события при изм. календаря Если нет команды получить все события, получаем по одному
|
|
|
|
| постоянный участник
|
Пост N: 3632
Зарегистрирован: 17.02.12
|
|
Отправлено: 21.03.21 15:59. Заголовок: Dr. Oldwarez пишет Н..
Dr. Oldwarez пишет цитата: | Но вот вопрос: если календарь заполнен и в нём 500 событий, это что, надо 500 раз соединяться? |
| Вы не сделали запроса к конкретному ics, после списка, по статье, я так понял, должны получить на календарь список всех событий с датой создания и модификации. Т.е. если уже в dbf занесли данные, то можно выбрать из списка только изменненные и по ним делать запрос для получения данных VEVENT и изменять dbf только по ним
|
|
|
|
| постоянный участник
|
Пост N: 264
Зарегистрирован: 27.07.08
|
|
Отправлено: 21.03.21 16:04. Заголовок: SergKis пишет: Если..
SergKis пишет: цитата: | Если нет команды получить все события, получаем по одному |
| А мне надо именно, что ВСЕ события получить. Дата модификации неинформативна. Не дата модификации мне нужна, а дата и время события. Это и есть первичный ключ в моём локальном календаре
|
|
|
|
| постоянный участник
|
Пост N: 1613
Зарегистрирован: 09.10.06
|
|
Отправлено: 21.03.21 16:08. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | А мне надо именно, что ВСЕ события получить. |
| Так втащите весь календарь на локальный комп (за один запрос), а потом синхронизируйте его с сервером Пример с GET делали или нет?
|
|
|
|
| постоянный участник
|
Пост N: 3633
Зарегистрирован: 17.02.12
|
|
Отправлено: 21.03.21 16:39. Заголовок: Dr. Oldwarez пишет А..
Dr. Oldwarez пишет цитата: | А мне надо именно, что ВСЕ события получить. Дата модификации неинформативна. Не дата модификации мне нужна, а дата и время события. Это и есть первичный ключ в моём локальном календаре |
| Причем здесь, информативно\не информативно и ваш первичный ключ. Есть архитектура, устройство календаря и оно такое какое есть. Есть правила доступа и вы их соблюдаете или нет. Как минимум, надо сделать все запросы для понимания ситуевины и от нее переходить к вашему устройству базы, но точно не наоборот
|
|
|
|
|
| постоянный участник
|
Пост N: 265
Зарегистрирован: 27.07.08
|
|
Отправлено: 21.03.21 20:57. Заголовок: Петр пишет: Да втащ..
Петр пишет: цитата: | Да втащите весь календарь на локальный комп (за один запрос), а потом синхронизируйте его с сервером Пример с GET делали или нет? |
| Сделал curl -o test2.txt --user USERNAME:PASSWORD -i -X GET https://webmail.kleeblatt.com/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/ И вот... HTTP/1.1 200 OK Date: Sun, 21 Mar 2021 17:51:23 GMT Server: Apache X-Powered-By: PHP/7.3.27 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Vary: Accept-Encoding Set-Cookie: PHPSESSID=e5ud2bc6fab8mv59hf8hanbhd8; path=/ Set-Cookie: horde_secret_key=e5ud2bc6fab8mv59hf8hanbhd8; path=/; domain=webmail.kleeblatt.com; HttpOnly Set-Cookie: default_horde_view=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; domain=webmail.kleeblatt.com X-Powered-By: PleskLin Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8 <html> <head> <title>Index for calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/ - SabreDAV 1.8.12-stable</title> <style type="text/css"> body { Font-family: arial} h1 { font-size: 150% } </style> <link rel="shortcut icon" href="/rpc.php/?sabreAction=asset&assetName=favicon.ico" type="image/vnd.microsoft.icon" /></head> <body> <h1>Index for calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/</h1> <table> <tr><th width="24"></th><th>Name</th><th>Type</th><th>Size</th><th>Last modified</th></tr> <tr><td colspan="5"><hr /></td></tr><tr> <td><a href="/rpc.php/calendars/illya@kleeblatt.com"> <img src="/rpc.php/?sabreAction=asset&assetName=icons%2Fparent.png" width="24" alt="Parent" /></a></td> <td><a href="/rpc.php/calendars/illya@kleeblatt.com">..</a></td> <td>[parent]</td> <td></td> <td></td> </tr><tr> <td><a href="/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/w7klsLDepGCBYAA7Gmr4GIe.ics"> <img src="/rpc.php/?sabreAction=asset&assetName=icons%2Ffile.png" alt="" width="24" /></a></td> <td><a href="/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/w7klsLDepGCBYAA7Gmr4GIe.ics">w7klsLDepGCBYAA7Gmr4GIe.ics</a></td> <td>text/calendar; charset=utf-8</td> <td>500</td> <td>2021-03-13T16:58:11+00:00</td> </tr><tr> <td><a href="/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/8gpZuoZBJQDnLlr-66brhHG.ics"> <img src="/rpc.php/?sabreAction=asset&assetName=icons%2Ffile.png" alt="" width="24" /></a></td> <td><a href="/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/8gpZuoZBJQDnLlr-66brhHG.ics">8gpZuoZBJQDnLlr-66brhHG.ics</a> </td> <td>text/calendar; charset=utf-8</td>
|
|
|
|
| постоянный участник
|
Пост N: 1614
Зарегистрирован: 09.10.06
|
|
Отправлено: 21.03.21 21:21. Заголовок: Dr. Oldwarez пишет: ..
|
|
|
|
| постоянный участник
|
Пост N: 266
Зарегистрирован: 27.07.08
|
|
Отправлено: 21.03.21 22:30. Заголовок: Петр пишет: Присоб..
Петр пишет: Йееес!!! Получилось! 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
|
|
|
|
| постоянный участник
|
Пост N: 1616
Зарегистрирован: 09.10.06
|
|
Отправлено: 22.03.21 09:28. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: Вери велл.. Результат применения PROPFIND / GET к колекции мы видели. Сделайте еще PROPFIND для календаря ... PROPFIND https://webmail.kleeblatt.com/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/seukIp8ajv0rOXXx8IG4Q9j.ics
|
|
|
|
| постоянный участник
|
Пост N: 267
Зарегистрирован: 27.07.08
|
|
Отправлено: 23.03.21 19:16. Заголовок: Петр пишет: Вери ве..
Петр пишет: <?xml version="1.0" encoding="utf-8"?> <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:card="urn:ietf:params:xml:ns:carddav"> <d:response> <d:href>/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/seukIp8ajv0rOXXx8IG4Q9j.ics</d:href> <d:propstat> <d:prop> <d:getlastmodified>Mon, 15 Mar 2021 12:56:41 GMT</d:getlastmodified> <d:getcontentlength>546</d:getcontentlength> <d:resourcetype/> <d:getetag>"fa79fe0b28dea03c0db457af39980eae"</d:getetag> <d:getcontenttype>text/calendar; charset=utf-8</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> </d:multistatus> И что дальше?
|
|
|
|
| постоянный участник
|
Пост N: 1617
Зарегистрирован: 09.10.06
|
|
Отправлено: 23.03.21 20:16. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: Все. Спасибо. Дальше сами, согласно техзадания шефа.
|
|
|
|
| постоянный участник
|
Пост N: 3638
Зарегистрирован: 17.02.12
|
|
Отправлено: 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 и брать с сервера только измененные данные (содержимое).
|
|
|
|
| постоянный участник
|
Пост N: 268
Зарегистрирован: 27.07.08
|
|
Отправлено: 23.03.21 21:45. Заголовок: SergKis пишет: Соде..
SergKis пишет: цитата: | Содержимое события содержит дату 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 на одно событие генерит свой собственный файл. Нельзя ли так, чтобы несколько событий отправлялись в один файл? (Настроить вывод на дозапись вместо открытия нового файла)
|
|
|
|
| постоянный участник
|
Пост N: 3639
Зарегистрирован: 17.02.12
|
|
Отправлено: 23.03.21 21:57. Заголовок: Dr. Oldwarez пишет Н..
Dr. Oldwarez пишет цитата: | Нельзя ли так, чтобы несколько событий отправлялись в один файл? |
| Зачем ? Есть a := Directory(<маска>) и собирайте, если надо или проще по одному элементу отрабатывать массив a
|
|
|
|
| постоянный участник
|
Пост N: 3640
Зарегистрирован: 17.02.12
|
|
Отправлено: 23.03.21 22:27. Заголовок: PS А может так ? FO..
PS А может так ? FOR k:=1 TO LEN(aStrings) cOut := cTempDIR+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) // обработка ELSE ? k, "Error", cOut ENDIF NEXT k
|
|
|
|
| постоянный участник
|
Пост N: 269
Зарегистрирован: 27.07.08
|
|
Отправлено: 25.03.21 13:54. Заголовок: SergKis пишет: ICS..
SergKis пишет: цитата: | ICS = ARRAY[6] 1 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/w7klsLDepGCBYAA7Gmr4GIe.ics", "Sat, 13 Mar 2021 16:58:11 GMT", "ics 1"} 2 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/8gpZuoZBJQDnLlr-66brhHG.ics", "Thu, 04 Mar 2021 16:51:14 GMT", "ics 2"} 3 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/VM3wwLrVEm3Zwn-UkKAzXra.ics", "Thu, 04 Mar 2021 16:51:33 GMT", "ics 3"} 4 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/e5aab12a-1a2a-4309-96d4-cccb1b67d9ba.ics", "Mon, 08 Mar 2021 06:59:00 GMT", "ics 4"} 5 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/seukIp8ajv0rOXXx8IG4Q9j.ics", "Mon, 15 Mar 2021 12:56:41 GMT", "ics 5"} 6 {"/rpc.php/calendars/illya@kleeblatt.com/calendar~GhGVum1xWexaffEfhiVkNN7/83sEK6nFBn4-TQ1XcZoPvWz.ics", "Mon, 15 Mar 2021 12:52:23 GMT", "ics 6"} |
| Отлично! У меня получилось. Теперь вот вопрос по формату времени. Мой шеф проживает в зоне CET (Гринвич+1). Я - в зоне EET. И хотелось бы привести это всё к одному формату, принятому в ICS: YYYYMMDDTHHMMSSZ И тогда уже можно сделать выбор по дате - только тех, кто позже даты последней автосинхронизации, заносимой в регистр автоматически при нажатии на кнопку "Синхронизация"
|
|
|
|
| постоянный участник
|
Пост N: 3641
Зарегистрирован: 17.02.12
|
|
Отправлено: 25.03.21 15:35. Заголовок: Dr. Oldwarez пишет И..
Dr. Oldwarez пишет цитата: | И хотелось бы привести это всё к одному формату, принятому в ICS: |
| Для этого, вроде, все есть 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
|
|
|
|
| постоянный участник
|
Пост N: 1618
Зарегистрирован: 09.10.06
|
|
Отправлено: 25.03.21 17:16. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Отлично! У меня получилось. |
| В цикле выполнить вызов curl? Поздравляю.
|
|
|
|
| постоянный участник
|
Пост N: 270
Зарегистрирован: 27.07.08
|
|
Отправлено: 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 NEXT aBuf := hb_ATokens(cBuf, "<d:propstat><d:prop><d:getlastmodified>") 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
|
|
|
|
| постоянный участник
|
Пост N: 271
Зарегистрирован: 27.07.08
|
|
Отправлено: 25.03.21 21:00. Заголовок: Петр пишет: К тому ..
Петр пишет: цитата: | К тому же инсталлятор весом меньше 1 Га в наше время моветон |
| Вот только моему шефу этого не говорите. Для него это как красная тряпка для быка
|
|
|
|
| постоянный участник
|
Пост N: 3645
Зарегистрирован: 17.02.12
|
|
Отправлено: 26.03.21 07:51. Заголовок: Dr. Oldwarez Поправ..
Dr. Oldwarez Поправьте в посте 270 [ i ] без пробелов (это служебный тэг), на [ i ] с пробелами, искажение текста не будет
|
|
|
|
| постоянный участник
|
Пост N: 3646
Зарегистрирован: 17.02.12
|
|
Отправлено: 26.03.21 07:56. Заголовок: Dr. Oldwarez пишет В..
Dr. Oldwarez пишет цитата: | Вот только моему шефу этого не говорите. Для него это как красная тряпка для быка |
| цитата: | В Windows 10 build 17063 и более поздних версиях теперь включен Curl, так что вы можете запускать его непосредственно из Cmd.exe или PowerShell.exe. |
|
|
|
|
|
| |
Пост N: 7289
Зарегистрирован: 17.05.05
|
|
Отправлено: 26.03.21 10:10. Заголовок: SergKis пишет: Попр..
SergKis пишет: цитата: | Поправьте в посте 270 [ i ] без пробелов (это служебный тэг), на [ i ] с пробелами, искажение текста не будет |
| я поправил
|
|
|
|
| постоянный участник
|
Пост N: 272
Зарегистрирован: 27.07.08
|
|
Отправлено: 26.03.21 13:44. Заголовок: SergKis пишет: ци..
SergKis пишет: цитата: | цитата: В Windows 10 build 17063 и более поздних версиях теперь включен Curl, так что вы можете запускать его непосредственно из Cmd.exe или PowerShell.exe. |
| И это радует. А то придётся уже через libcurl продираться.
|
|
|
|
| постоянный участник
|
Пост N: 1619
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.03.21 17:59. Заголовок: Dr. Oldwarez пишет: ..
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
|
|
|
|
| постоянный участник
|
Пост N: 1620
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.03.21 18:08. Заголовок: 3) По возможности ис..
3) По возможности используйте стандартные функции Harbour. Это поможет избежать ошибок, свойственных пользовательскому коду, а также увеличит переносимость программ (кода) на другие платформы. Ну и часто код выглядит лучше LOCAL cXML:=cTempDIR+IIF(RIGHT(cTempLW,1)="\",'','\')+'listall_ics.xml' == LOCAL cXML:=cTempDIR+hb_DirSepAdd(cTempLW)+'listall_ics.xml'
|
|
|
|
| постоянный участник
|
Пост N: 273
Зарегистрирован: 27.07.08
|
|
Отправлено: 26.03.21 19:39. Заголовок: SergKis пишет: Для ..
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] - это и есть полный формат даты с днями недели и месяцами. 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 И функция конвертации 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 При попытке обратиться к ней из IF выдаёт дикие ошибки обращения к массиву. Хотя значения в поле BROWSE выводит нормально. Это почему так?
|
|
|
|
| постоянный участник
|
Пост N: 274
Зарегистрирован: 27.07.08
|
|
Отправлено: 26.03.21 19:41. Заголовок: Петр пишет: 3) По в..
Петр пишет: цитата: | 3) По возможности используйте стандартные функции Harbour. Это поможет избежать ошибок, свойственных пользовательскому коду, а также увеличит переносимость программ (кода) на другие платформы. Ну и часто код выглядит лучше LOCAL cXML:=cTempDIR+IIF(RIGHT(cTempLW,1)="\",'','\')+'listall_ics.xml' == LOCAL cXML:=cTempDIR+hb_DirSepAdd(cTempLW)+'listall_ics.xml' |
| Да, намного удобнее использовать готовые функции, а не изобретать велосипед. Но где к ним найти мануал?
|
|
|
|
| постоянный участник
|
Пост N: 1621
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.03.21 20:12. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Да, намного удобнее использовать готовые функции, а не изобретать велосипед. Но где к ним найти мануал? |
| Например здесь
|
|
|
|
| постоянный участник
|
Пост N: 1622
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.03.21 20:55. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | При попытке обратиться к ней из IF выдаёт дикие ошибки обращения к массиву. Хотя значения в поле BROWSE выводит нормально. Это почему так? |
| А что у вас в программе с настройками set language to ?? или hb_langSelect(??) А заодно и set date to проверьте
|
|
|
|
| постоянный участник
|
Пост N: 3647
Зарегистрирован: 17.02.12
|
|
Отправлено: 26.03.21 20:55. Заголовок: Dr. Oldwarez пишет П..
Dr. Oldwarez пишет цитата: | При попытке обратиться к ней из IF выдаёт дикие ошибки обращения к массиву. Хотя значения в поле BROWSE выводит нормально. Это почему так? |
| 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)
|
|
|
|
| |
Пост N: 317
Зарегистрирован: 05.11.05
|
|
Отправлено: 26.03.21 21:10. Заголовок: SergKis пишет: В Wi..
SergKis пишет: цитата: | В Windows 10 build 17063 и более поздних версиях теперь включен Curl |
| Я раньше использовал внешний Curl, потом в Минигуи перешел на внутренний, пока что проблем нет. Есть ли у внешнего преимущества?
|
|
|
|
| постоянный участник
|
Пост N: 1623
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.03.21 21:15. Заголовок: rvu пишет: Я раньше..
rvu пишет: цитата: | Я раньше использовал внешний Curl, потом в Минигуи перешел на внутренний, пока что проблем нет. Есть ли у внешнего преимущества? |
| Внутренний - это libcurl?
|
|
|
|
| постоянный участник
|
Пост N: 1624
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.03.21 21:35. Заголовок: Короче, curl написан..
Короче, curl написан с использованием функций libcurl Парсер командной строки + функциональность libcurl Понятно, что curl могут использовать не только программисты. curl удобно использовать на этапе отладки. С curl меньше шансов словить ошибку, не предусмотрев обработку результата выполнения библиотечных функций или неправильно заполнив какую-то структуру. Вот и все.
|
|
|
|
| постоянный участник
|
Пост N: 1625
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.03.21 22:31. Заголовок: SergKis пишет: FUNC..
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
|
|
|
|
| постоянный участник
|
Пост N: 1627
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 00:12. Заголовок: Dr. Oldwarez пишет: ..
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) и наоборот.
|
|
|
|
| постоянный участник
|
Пост N: 1628
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 00:18. Заголовок: Один из возможных ва..
Один из возможных вариантов реализации цитата: | // "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 |
|
|
|
|
|
| постоянный участник
|
Пост N: 1629
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 00:28. Заголовок: Проверочный код (кон..
Проверочный код (консоль) цитата: | //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 |
| Если вы используете harbour из поставки MiniGUI ваш compile.bat должен выглядеть так цитата: | call ..\..\..\batch\compile.bat demo /c %1 %2 %3 %4 %5 %6 %7 %8 %9 |
| PS. почему я спрашивал про set language to .. догадаетесь сами.
|
|
|
|
| постоянный участник
|
Пост N: 1632
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 01:06. Заголовок: 4) Вызов внешних про..
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
|
|
|
|
| постоянный участник
|
Пост N: 1633
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 01:20. Заголовок: 5) Использование hb..
5) Использование hb_StrFormat цитата: | #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 |
| Крайне удобно и позволяет переопределять строку аргументов on the fly.
|
|
|
|
| постоянный участник
|
Пост N: 3648
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 01:42. Заголовок: Петр пишет Один из в..
Петр пишет цитата: | Один из возможных вариантов реализации |
| TimeStamp возможный вариант , но он содержит миллисекунды за Timestamp.123, т.е. нельзя делать hhb_DateTime() == DTimeToTS("Mon, 15 Mar 2021 12:56:41 GMT", "en") На мой взгляд, с ics больше подходит строковый формат, только без всяких T и 00Z внутри, если иметь ввиду индексы с участием строковых дат и событий календаря, то ключ получается проще в работе, если учесть хранение в dbf данных в символьном виде (физически), то нет лишних телодвижений rdd по преобразованию данных. Вид даты "2021031512541" больше подходит в данном случае, а TimeStamp в типах =@T или производных от них. Но это мое понимание ситуации.
|
|
|
|
| постоянный участник
|
Пост N: 1635
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 01:54. Заголовок: SergKis пишет: нель..
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 быстрее строковых операций. Но вольному воля..
|
|
|
|
| постоянный участник
|
Пост N: 3649
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 02:20. Заголовок: Петр пишет ? hb_dat..
Петр пишет [quote]` ? hb_datetime() результат 2021-03-27 01:04:47 .133 цитата: | Операции с TimeStamp быстрее строковых операций |
| Разговор о решениях с isc. Составьте выражения ключей индекса и ключей для scope - выбрать выполненное за год\месяц\квартал\неделя\день ... - выбрать не выполненное за год\месяц\квартал\неделя\день ... ... строковые решения будут проще. А так конечно, решать не нам, что и как делать
|
|
|
|
| постоянный участник
|
Пост N: 275
Зарегистрирован: 27.07.08
|
|
Отправлено: 27.03.21 10:52. Заголовок: SergKis пишет: FUN..
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у, и потом уже циклом закидывать их в календарь.
|
|
|
|
| постоянный участник
|
Пост N: 276
Зарегистрирован: 27.07.08
|
|
Отправлено: 27.03.21 10:57. Заголовок: Петр пишет: TimeSta..
Петр пишет: цитата: | TimeStamp в harbour поддерживает ISO 8601 и совместим с большинством реализаций. Операции с TimeStamp быстрее строковых операций. Но вольному воля.. |
| TimeStamp - это хорошо, но в формате DBF, созданном в мохнатом 1983 году нет поддержки таких полей. Тогда было только отдельное поле типа даты и строковое короткое поле для времени. Можно создать переменную типа DateTime, а в базу данных её как сохранить? Это тебе не Oracle (ещё одна "любимая" программа моего шефа), где можно пользовательские типы лепить.
|
|
|
|
| постоянный участник
|
Пост N: 1636
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 14:18. Заголовок: SergKis пишет: стро..
SergKis пишет: цитата: | строковые решения будут проще |
| Возможно для кого-то и проще. Но и сложного там ничего нет Скрытый текст
цитата: | REQUEST HB_LANG_RU REQUEST HB_CODEPAGE_RU1251 REQUEST HB_CODEPAGE_RU866 REQUEST DBFCDX PROCEDURE Main() LOCAL tBottomDate, tTopDate USE events NEW INDEX ON hb_TSToStr(_FIELD->DUE) TO Due tTopDate := hb_DateTime(2021, 5, 1) tBottomDate := hb_DateTime(2021, 6, 15) SET SCOPETOP TO hb_TSToStr(tTopDate) SET SCOPEBOTTOM TO hb_TSToStr(tBottomDate) GO TOP DO WHILE .NOT. EOF() ? FIELD->UID, FIELD->DUE SKIP +1 ENDDO RETURN INIT PROCEDURE OnInit() LOCAL aStru LOCAL cFileDbf := hb_DirBase() + "events.dbf" LOCAL nI hb_cdpSelect( "RU1251" ) hb_langSelect("RU") hb_setTermCP( "RU866", "RU1251" ) rddSetDefault("DBFCDX") SET DATE FORMAT TO "DD.MM.YYYY" IF .NOT. DbExists(cFileDbf) aStru := {} AADD( aStru, {"UID", "C", 36, 0} ) AADD( aStru, {"DUE", "@", 8, 0} ) DbCreate(cFileDbf, aStru, "DBFCDX", .t., "EVENTS", , "RU1251" ) FOR nI := 1 TO 1000 dbAppend() FIELD->UID := "5981ddad-f421-47ea-bd2d-f442865b" + STRZERO(nI, 4) FIELD->DUE := hb_StrToTS(hb_strFormat("%04d-%02d-%02d", YEAR(DATE()), hb_RandomInt(1,12), hb_RandomInt(1,28))) NEXT nI dbCloseAll() ENDIF RETURN |
|
|
|
|
|
|
| постоянный участник
|
Пост N: 3650
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 17:26. Заголовок: Петр пишет Но и слож..
Петр пишет цитата: | Но и сложного там ничего нет |
| Что то не срослось ваш demo.prg чуть модифицированный под hmg сборку Скрытый текст
/* * MINIGUI - Harbour Win32 GUI library Demo */ #define _HMG_OUTLOG #include "hmg.ch" REQUEST HB_LANG_RU REQUEST HB_CODEPAGE_RU1251 REQUEST HB_CODEPAGE_RU866 REQUEST DBFCDX PROCEDURE Main() LOCAL tBottomDate, tTopDate hb_cdpSelect( "RU1251" ) hb_langSelect("RU") hb_setTermCP( "RU866", "RU1251" ) Sets() USE events NEW INDEX ON hb_TSToStr(_FIELD->DUE) TO Due tTopDate := hb_DateTime(2021, 5, 1) tBottomDate := hb_DateTime(2021, 6, 15) SET SCOPETOP TO hb_TSToStr(tTopDate) SET SCOPEBOTTOM TO hb_TSToStr(tBottomDate) ? "Scope =",tTopDate, tBottomDate, OrdKeyCount() GO TOP DO WHILE .NOT. EOF() ? RecNo(), FIELD->UID, FIELD->DUE SKIP 1 ENDDO RETURN FUNC Sets() LOCAL aStru LOCAL cFileDbf := hb_DirBase() + "events.dbf" LOCAL nI rddSetDefault("DBFCDX") SET DATE FORMAT TO "DD.MM.YYYY" IF .NOT. DbExists(cFileDbf) aStru := {} AADD( aStru, {"UID", "C", 36, 0} ) AADD( aStru, {"DUE", "@", 8, 0} ) AADD( aStru, {"DTM", "=", 8, 0} ) DbCreate(cFileDbf, aStru, "DBFCDX", .t., "EVENTS", , "RU1251" ) FOR nI := 1 TO 100 dbAppend() FIELD->UID := "5981ddad-f421-47ea-bd2d-f442865b" + STRZERO(nI, 4) FIELD->DUE := hb_StrToTS(hb_strFormat("%04d-%02d-%02d", YEAR(DATE()), hb_RandomInt(1,12), hb_RandomInt(1,28))) NEXT nI GO TOP ? cFileDbf, "LastRec =", LastRec() DO WHILE !EOF() ? RecNo(), FIELD->UID, FIELD->DUE, FIELD->DTM SKIP ENDDO ? dbCloseAll() ENDIF RETURN Nil
| Результат работы в _MsgLog.txt Скрытый текст
C:\MiniGuiBcc58\SAMPLES\_Test\_hb_datetime\events.dbf LastRec = 100 1 '' 00:00 2021-03-27 16:17:16.458 2 '' 00:00 2021-03-27 16:17:16.458 3 '' 00:00 2021-03-27 16:17:16.458 4 '' 00:00 2021-03-27 16:17:16.458 5 '' 00:00 2021-03-27 16:17:16.458 6 '' 00:00 2021-03-27 16:17:16.458 7 '' 00:00 2021-03-27 16:17:16.458 8 '' 00:00 2021-03-27 16:17:16.458 9 '' 00:00 2021-03-27 16:17:16.458 10 '' 00:00 2021-03-27 16:17:16.458 11 '' 00:00 2021-03-27 16:17:16.458 12 '' 00:00 2021-03-27 16:17:16.458 13 '' 00:00 2021-03-27 16:17:16.458 14 '' 00:00 2021-03-27 16:17:16.458 15 '' 00:00 2021-03-27 16:17:16.458 16 '' 00:00 2021-03-27 16:17:16.458 17 '' 00:00 2021-03-27 16:17:16.458 18 '' 00:00 2021-03-27 16:17:16.458 19 '' 00:00 2021-03-27 16:17:16.458 20 '' 00:00 2021-03-27 16:17:16.458 21 '' 00:00 2021-03-27 16:17:16.458 ... 90 '' 00:00 2021-03-27 16:17:16.458 91 '' 00:00 2021-03-27 16:17:16.458 92 '' 00:00 2021-03-27 16:17:16.458 93 '' 00:00 2021-03-27 16:17:16.458 94 '' 00:00 2021-03-27 16:17:16.458 95 '' 00:00 2021-03-27 16:17:16.458 96 '' 00:00 2021-03-27 16:17:16.458 97 '' 00:00 2021-03-27 16:17:16.458 98 '' 00:00 2021-03-27 16:17:16.458 99 '' 00:00 2021-03-27 16:17:16.458 100 '' 00:00 2021-03-27 16:17:16.459 Scope = 2021-05-01 2021-06-15 0
|
|
|
|
|
| постоянный участник
|
Пост N: 3651
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 17:35. Заголовок: Dr. Oldwarez пишет М..
|
|
|
|
| постоянный участник
|
Пост N: 1637
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 17:58. Заголовок: SergKis пишет: Что ..
SergKis пишет: цитата: | Что то не срослось ваш demo.prg |
| Мне не удалось повторить в консольном приложении ваш удивительный результат. И не удалось откомпилировать "модифицированный под hmg сборку"
|
|
|
|
| постоянный участник
|
Пост N: 3652
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 18:03. Заголовок: Петр пишет И не удал..
Петр пишет цитата: | И не удалось откомпилировать "модифицированный под hmg сборку" |
| demo.hbp # Keys compile #-prgflag=-w2 -es1 # Enable multi/single-thread Harbour VM -mt # Incremental-compilation mode -inc # folder where are all * .obj -workdir=OBJ # Name EXE-module -odemo # to list all * .prg demo.prg # project Resources #demo.rc # paths to the main and extension *.Lib -lminigui Compile.bat ..\..\..\BATCH\hbmk2.bat demo.hbp
|
|
|
|
| постоянный участник
|
Пост N: 3653
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 18:07. Заголовок: PS C:\MiniGuiBcc..
PS C:\MiniGuiBcc58\BATCH\minigui.cfg # Basic configuration for Compile.bat MG_CMP=harbour MG_BCC=c:\borland\bcc58 MG_ROOT=c:\miniguiBcc58
|
|
|
|
| постоянный участник
|
Пост N: 1638
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 18:34. Заголовок: Петр пишет: И не уд..
Петр пишет: цитата: | И не удалось откомпилировать "модифицированный под hmg сборку" |
| call ..\..\..\batch\compile.bat demo /c %1 %2 %3 %4 %5 %6 %7 %8 %9 Забыл /c удалить. Удалось Прикольно.. Закомментировал //#include "hmg.ch" Добавил /c И результат ожидаемый. Я честно не знаю, что там в minigui сломалось. В топку?!
|
|
|
|
| постоянный участник
|
Пост N: 1639
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 18:47. Заголовок: Замените FIELD по те..
Замените FIELD по тексту на _FIELD Из топки или подождать?
|
|
|
|
| постоянный участник
|
Пост N: 3654
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 18:52. Заголовок: Петр пишет Я честно ..
Петр пишет цитата: | Я честно не знаю, что там в minigui сломалось. В топку?! |
| К сожалению, в топке и уже давно консольные и wvt приложения Вот я и говорю, что со строковыми проще USE ... INDEX ON _FIELD->UID+_FILED->DATASTART TAG START INDEX ON _FIELD->UID+_FILED->DATAEND TAG END INDEX ON _FIELD->UIDNO TAG ID Запрос в GETBOX-ах cUID := ... dDT1 := ... dDT2 := ... SET SCOPE TO cUID+DtoS(dDT1), cUID+DtoS(dDt2) GO TOP
|
|
|
|
| постоянный участник
|
Пост N: 3655
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 19:00. Заголовок: Петр пишет Замените ..
Петр пишет цитата: | Замените FIELD по тексту на _FIELD |
| Хотел из совсем убрать, причем сразу, но не сделал ... и да, сработало, но осталось не заполнено время в DUE ...
|
|
|
|
| постоянный участник
|
Пост N: 3656
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 19:11. Заголовок: PS Показ в колонках ..
PS Показ в колонках решается через oCol:cPicture := "@R 9999-99-99 99:99:99"
|
|
|
|
| постоянный участник
|
Пост N: 1640
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 20:03. Заголовок: Петр пишет: Заменит..
Петр пишет: цитата: | Замените FIELD по тексту на _FIELD |
| Да, некрасиво получается FIELD->UID := "5981ddad-f421-47ea-bd2d-f442865b" + STRZERO(nI, 4) => _HMG_SYSDATA[404] := '->UID := "5981ddad-f421-47ea-bd2d-f442865b" + STRZERO(nI, 4)'
|
|
|
|
| постоянный участник
|
Пост N: 1641
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 20:18. Заголовок: Что-то мы отвлеклись..
Что-то мы отвлеклись от темы. 6. Значит что у нас осталось: FOR vs. FOR EACH, никогда не используйте File() для проверки доступности файла - короче мелочи. 7. Давайте вернемся к hb_Run().. 8. Научиться работать с xml пошло бы на пользу общему делу. 9. Не скажу. 10. Переход на libcurl - нужен или нет.
|
|
|
|
| постоянный участник
|
Пост N: 277
Зарегистрирован: 27.07.08
|
|
Отправлено: 27.03.21 20:28. Заголовок: Петр пишет: Переход..
Петр пишет: цитата: | Переход на libcurl - нужен или нет. |
| Нужен, но потом. Сейчас вот вопрос какой: curl -k --user USERNAME:PASSWORD -X PUT -H "Content-Type: text/calendar; charset=utf-8" -d "$a" "https://owncloud.jujens.eu/remote.php/caldav/calendars/jujens/omis/<mon-fichier.ics>" Обязательно надо, чтобы каждому событию создавали свой ics? Или можно все события в один ICS загнать?
|
|
|
|
| постоянный участник
|
Пост N: 1642
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.03.21 20:57. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Или можно все события в один ICS загнать |
| Если все события принадлежат одному календарю - можно и даже нужно. P.S. Оказывается не все сервера поддерживают такую ситуацию.
|
|
|
|
| постоянный участник
|
Пост N: 3657
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 21:10. Заголовок: Dr. Oldwarez пишетИл..
Dr. Oldwarez пишет цитата: | Или можно все события в один ICS загнать? |
| Вы можете все календари со всеми событиями загнать в одну базу и меть на поле календарь уникальный TAG, сделав SET ORDER на этот TAG, получите список календарей в тсб, выбрав, переключаете на др. TAG (<календарь>+<события>) и ставите scope на календарь, получите список событий календаря и т.д. Не ясно, что за календари с каким объемом данных на какой период отчетности, бесконечен во времени или сворачивается в архив. На эти вопросы себе ответьте в первую очередь
|
|
|
|
| постоянный участник
|
Пост N: 278
Зарегистрирован: 27.07.08
|
|
Отправлено: 27.03.21 22:22. Заголовок: SergKis пишет: Вы м..
SergKis пишет: цитата: | Вы можете все календари со всеми событиями загнать в одну базу и меть на поле календарь уникальный TAG, сделав SET ORDER на этот TAG, получите список календарей в тсб, выбрав, переключаете на др. TAG (<календарь>+<события>) и ставите scope на календарь, получите список событий календаря и т.д. Не ясно, что за календари с каким объемом данных на какой период отчетности, бесконечен во времени или сворачивается в архив. На эти вопросы себе ответьте в первую очередь |
| Очень простые календари вида BEGIN:VEVENT UID:20210401T073000Z-QWERTY-04357@abcdefg.com DTSTART:20210401T073000Z DTEND:20210401T161500Z SUMMARY:Visit to doctor DESCRIPTION:Vaccination against COVID-19, plague, cholera and Ebola LOCATION:Central hospital END:VEVENT
|
|
|
|
| постоянный участник
|
Пост N: 3658
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 22:40. Заголовок: Dr. Oldwarez пишет О..
Dr. Oldwarez пишет цитата: | Очень простые календари вида |
| Это событие календаря, 1 запись в базе (вроде, был еще параметр выполнение события дата-время, или ошибаюсь) календарей у вас 6 штук. Это личные календари событий или предприятия\организации. Объем календаря (в событиях-записях). И чего вы от них хотите ? Просто показ в табл. виде отчетов ? Цель ?
|
|
|
|
| постоянный участник
|
Пост N: 3659
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 22:49. Заголовок: PS Технические момен..
PS Технические моменты вы прошли, попробовали, на вас вывалили инф. Как бы дальше сами, создайте dbf[ы] и пробуйте, щупайте.
|
|
|
|
| постоянный участник
|
Пост N: 279
Зарегистрирован: 27.07.08
|
|
Отправлено: 27.03.21 23:05. Заголовок: SergKis пишет: Это ..
SergKis пишет: цитата: | Это событие календаря, 1 запись в базе (вроде, был еще параметр выполнение события дата-время, или ошибаюсь) календарей у вас 6 штук. Это личные календари событий или предприятия\организации. Объем календаря (в событиях-записях). И чего вы от них хотите ? Просто показ в табл. виде отчетов ? Цель ? |
| Да, просто занесения в DBF в целях синхронизации. 99% времени это работает в локальном режиме. А также обратно занесение полей из DBF в календарь. С последним некоторые проблемы. curl -k --user USERNAME:PASSWORD -X PUT -H "Content-Type: text/calendar; charset=utf-8" -d "$a" "https://owncloud.jujens.eu/remote.php/caldav/calendars/jujens/omis/<mon-fichier.ics>" То есть тут <mon-fichier.ics> - это не локальный сгенерированный файл, а элемент календаря в сети. Как в него занести данные из локальных полей, даже если они сгенерированы в ЛОКАЛЬНЫЙ ics файл? типа C:\MYCALPROG\TEMP\EXPORT.ICS Как его в календарь с помощью CURL забросить?
|
|
|
|
| постоянный участник
|
Пост N: 3660
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 23:07. Заголовок: PS2 Есть еще STATUS:..
PS2 Есть еще STATUS:... нашел несколько значений STATUS:CONFIRMED STATUS:CANCLED STATUS:TENTATIVE возможно надо учесть ?
|
|
|
|
| постоянный участник
|
Пост N: 280
Зарегистрирован: 27.07.08
|
|
Отправлено: 27.03.21 23:20. Заголовок: SergKis пишет: PS2 ..
SergKis пишет: цитата: | PS2 Есть еще STATUS:... нашел несколько значений STATUS:CONFIRMED STATUS:CANCLED STATUS:TENTATIVE возможно надо учесть ? |
| STATUS:CONFIRMED Но и без него можно обойтись Я уже сделал считывание из календаря в массив, который потом можно запихнуть в таблицу. Теперь моя последняя задача - запихивание данных из таблицы в календарь. После чего можно и отдохнуть.
|
|
|
|
| постоянный участник
|
Пост N: 3661
Зарегистрирован: 17.02.12
|
|
Отправлено: 27.03.21 23:47. Заголовок: Dr. Oldwarez пишет Т..
Dr. Oldwarez пишет цитата: | Теперь моя последняя задача - запихивание данных из таблицы в календарь. |
| В поиске попалось https://kb.kopano.io/display/WIKI/Importing+ICAL+.ics+files+into+Kopano тут https://curl.se/docs/manpage.html смотрим цитата: | -T, --upload-file <file> This transfers the specified local file to the remote URL. If there is no file part in the specified URL, curl will append the local file name. NOTE that you must use a trailing / on the last directory to really prove to Curl that there is no file name or curl will think that your last directory name is the remote file name to use. That will most likely cause the upload operation to fail. If this is used on an HTTP(S) server, the PUT command will be used. ... |
|
|
|
|
|
| постоянный участник
|
Пост N: 281
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.03.21 00:00. Заголовок: SergKis пишет: В по..
SergKis пишет: Спасибо. Завтра с утра попробую это
|
|
|
|
| постоянный участник
|
Пост N: 1643
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 00:51. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | curl -k --user USERNAME:PASSWORD -X PUT -H "Content-Type: text/calendar; charset=utf-8" -d "$a" "https://owncloud.jujens.eu/remote.php/caldav/calendars/jujens/omis/<mon-fichier.ics>" То есть тут <mon-fichier.ics> - это не локальный сгенерированный файл, а элемент календаря в сети. Как в него занести данные из локальных полей, даже если они сгенерированы в ЛОКАЛЬНЫЙ ics файл? типа C:\MYCALPROG\TEMP\EXPORT.ICS Как его в календарь с помощью CURL забросить? |
| Ну там же комментарии есть Q: In your post new event example, what is $a? A: Good question. It should contain the data you want to post, ie the content of you local ics file.
|
|
|
|
| постоянный участник
|
Пост N: 282
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.03.21 13:27. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: И сделал... curl -k --user USERNAME:PASSWORD -T C:\MINIGUI\PROGDIR\TEMPDIR\List.ics https://webmail.abcdef.com/rpc.php/calendars/aaaaa@abcdef.com/calendar~GhGVum1xWexaffEfhiVkNN7/ Спасибо. Завтра с утра попробую это И получил <?xml version="1.0" encoding="utf-8"?> <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"> <s:exception>Sabre\DAV\Exception\BadRequest</s:exception> <s:message>Every VEVENT in this object must have identical UIDs</s:message> <s:sabredav-version>1.8.12</s:sabredav-version> </d:error> Что это за identical UIDs?
|
|
|
|
| постоянный участник
|
Пост N: 1644
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 13:52. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Что это за identical UIDs? |
| Что-то типа этого BEGIN:VEVENT UID:19970901T130000Z-123402@example.com DTSTAMP:19970901T130000Z DTSTART:19970401T163000Z Если вы обновляете события, то как их сервер находит? Правильно, с помощью UIDs
|
|
|
|
| постоянный участник
|
Пост N: 283
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.03.21 14:07. Заголовок: Петр пишет: Петр п..
Петр пишет: [quote]` Петр пишет: цитата: | Что-то типа этого BEGIN:VEVENT UID:19970901T130000Z-123402@example.com DTSTAMP:19970901T130000Z DTSTART:19970401T163000Z Если вы обновляете события, то как их сервер находит? Правильно, с помощью UIDs |
| Знаю. Но я не хочу обновлять, хочу писать новые события. Тогда вообще лучше эти UIDы упразднить? Или как сделать, чтобы оно не искало события, а тупо писало их поверх существующих?
|
|
|
|
| постоянный участник
|
Пост N: 1645
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 14:17. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: И запрос какой-то подозрительный, ни -X, ни -T, ни -d, ни --config..
|
|
|
|
| постоянный участник
|
Пост N: 1646
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 14:22. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Знаю. Но я не хочу обновлять, хочу писать новые |
| По логике, вы не должны указывать UID, тогда сервер сгенерирует новый VEVENT и UID для него. цитата: | Тогда вообще лучше эти UIDы упразднить? Или как сделать, чтобы оно не искало события, а тупо писало их поверх существующих? |
| Это выше ваших сил. К счастью у разработчиков другое мнение.
|
|
|
|
| постоянный участник
|
Пост N: 284
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.03.21 14:35. Заголовок: Петр пишет: Dr. Ol..
Петр пишет: цитата: | Dr. Oldwarez пишет: цитата: Знаю. Но я не хочу обновлять, хочу писать новые По логике, вы не должны указывать UID, тогда сервер сгенерирует новый VEVENT и UID для него. цитата: Тогда вообще лучше эти UIDы упразднить? Или как сделать, чтобы оно не искало события, а тупо писало их поверх существующих? Это выше ваших сил. К счастью у разработчиков другое мнение. |
| Выкинул UIDы из ICS-файла и получил Every VEVENT component must have an UID
|
|
|
|
| постоянный участник
|
Пост N: 285
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.03.21 14:59. Заголовок: Петр пишет: И запро..
Петр пишет: цитата: | И запрос какой-то подозрительный, ни -X, ни -T, ни -d, ни --config.. |
| -Т есть curl -k --user USERNAME:PASSWORD -T C:\MINIGUI\MYPROG\TEMP\Terminliste.ics https://webmail.kleeblatt.com/rpc.php/calendars/USERNAME/calendar~GhGVum1xWexaffEfhiVkNN7/
|
|
|
|
| постоянный участник
|
Пост N: 1647
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 15:16. Заголовок: Значит начнем с нача..
Значит начнем с начала. Dr. Oldwarez пишет: цитата: | Но как реализовать подключение к облачному сервису в Harbour/Minigui? Возможно ли это вообще? |
| Возможно, но для этого нужно знать, что мы можем (и как) использовать из функционала Harbour и к чему нужно подключаться: какой сервер, протокол, версия, реализация некоторых моментов. С первым частично плохо. Как дела со вторым у топикстартера, для меня лично непонятно. Обратите внимание на посты №№257, 282 Dr. Oldwarez пишет: цитата: | <?xml version="1.0" encoding="utf-8"?> <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"> <s:exception>Sabre\DAV\Exception\BadRequest</s:exception> <s:message>Every VEVENT in this object must have identical UIDs</s:message> <s:sabredav-version>1.8.12</s:sabredav-version> </d:error> |
| Простой поиск быстро привод к Building a CalDAV client This document is a general howto on how to build a CalDAV client. The document is language-agnostic Совет: научились работать с curl, берите документацию и составляйте запросы. Есть вопросы как то или другое реализовать в Harbour - задавайте здесь.
|
|
|
|
| постоянный участник
|
Пост N: 286
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.03.21 15:51. Заголовок: Петр пишет: Возможн..
Петр пишет: цитата: | Возможно, но для этого нужно знать, что мы можем (и как) использовать из функционала Harbour и к чему нужно подключаться: какой сервер, протокол, версия, реализация некоторых моментов. С первым частично плохо. Как дела со вторым у топикстартера, для меня лично непонятно. |
| Ага, нет документации, не посмотрел, вот "частично плохо". Петр пишет: цитата: | Совет: научились работать с curl, берите документацию и составляйте запросы. Есть вопросы как то или другое реализовать в Harbour - задавайте здесь. |
| Так я уже подключал всё к CURL, считывал оттуда данные. И уже сохранил эти данные в DBF-формате. Осталось ТОЛЬКО ОДНО - забрасывание ics в календарь. И всё, прогу уже можно сдавать. Проблема, конкретно, не в программе, а в календаре. Установить его на генерацию UIDов. Он же принимал файлы без UIDов в ручном режиме
|
|
|
|
| постоянный участник
|
Пост N: 1648
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 16:12. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Установить его на генерацию UIDов. Он же принимал файлы без UIDов в ручном режиме |
| Без комментариев. Вам же результат нужен, а не.. Найдите online uuid generator например Сгенерируйте uuid, загрузите себе в базу и пользуйтесь.
|
|
|
|
| постоянный участник
|
Пост N: 287
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.03.21 16:49. Заголовок: Петр пишет: Без ком..
Петр пишет: цитата: | Без комментариев. Вам же результат нужен, а не.. Найдите online uuid generator например Сгенерируйте uuid, загрузите себе в базу и пользуйтесь. |
| В смысле, загрузить вот ЭТО 2f4f6320-8fcc-11eb-8dcd-0242ac130003 в регистр и присваивать ВСЕМ строкам? Или для каждой строки новый генерить, но тут нужна уже встроенная функция.
|
|
|
|
| постоянный участник
|
Пост N: 1649
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 17:04. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | В смысле, загрузить вот ЭТО |
| Это от сайта вам подарок. А ниже вы можете указать количество и нажать загрузить в файл, выбрав 1 или 4 версии генератора. Оффлайн можете подключить библиотеку hbwin и использовать win_UuidCreateString LOCAL nRPCStatus ? win_UuidCreateString( @nRPCStatus ) ? nRPCStatus
|
|
|
|
| постоянный участник
|
Пост N: 1650
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 17:51. Заголовок: Петр пишет: А ниже ..
Петр пишет: цитата: | А ниже вы можете указать количество и нажать загрузить в файл, выбрав 1 или 4 версии генератора. |
| А еще вы можете пользоваться API сайта и загрузить UUID с помощью CURL curl.exe -ouuid4.txt -k -X GET -H"text/plain; charset=utf-8" https://www.uuidgenerator.net/api/version4/500 или curl.exe -ouuid1.txt -k -X GET -H"text/plain; charset=utf-8" https://www.uuidgenerator.net/api/version1 PS. "text/plain; charset=utf-8" конечно же лучше заменить на "Content-Type: text/plain; charset=utf-8"
|
|
|
|
| постоянный участник
|
Пост N: 288
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.03.21 21:20. Заголовок: Петр пишет: Оффлайн..
Петр пишет: цитата: | Оффлайн можете подключить библиотеку hbwin и использовать win_UuidCreateString LOCAL nRPCStatus ? win_UuidCreateString( @nRPCStatus ) ? nRPCStatus |
| Подключил и сделал. То же самое <?xml version="1.0" encoding="utf-8"?> <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"> <s:exception>Sabre\DAV\Exception\BadRequest</s:exception> <s:message>Every VEVENT in this object must have identical UIDs</s:message> <s:sabredav-version>1.8.12</s:sabredav-version> </d:error> Но UIDы в файле выглядят по-другому BEGIN:VEVENT UID:89dbeac3-50de-4138-915a-1836802d0c9a DTSTAMP:20210328T211200Z DTSTART:20210331T090000Z DTEND:20210331T100000Z SUMMARY:abcd DESCRIPTION:qwerty LOCATION:Utopia END:VEVENT BEGIN:VEVENT UID:33892830-c61d-4279-91e8-3c69e9e13dd5 DTSTAMP:20210328T211200Z DTSTART:20210401T073000Z DTEND:20210401T161500Z SUMMARY:IT DONE DESCRIPTION:Blahblahblah LOCATION:Nowhere END:VEVENT
|
|
|
|
| постоянный участник
|
Пост N: 1651
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.03.21 22:36. Заголовок: Каждый VEVENT в этом..
Каждый VEVENT в этом объекте должен иметь идентичный UID. Соотносится с информацией по ссылке выше (пост №1647) Каждый объект должен содержать только 1 событие или задачу. Попробуйте указать для всех VEVENT одинаковый UID и посмотреть, что из этой затеи получится.
|
|
|
|
| постоянный участник
|
Пост N: 289
Зарегистрирован: 27.07.08
|
|
Отправлено: 29.03.21 08:49. Заголовок: Петр пишет: Каждый ..
Петр пишет: цитата: | Каждый объект должен содержать только 1 событие или задачу. Попробуйте указать для всех VEVENT одинаковый UID и посмотреть, что из этой затеи получится. |
| Получилось то, что второе событие импортировалось, а первое - нет. Вывод: надо импортировать поодиночке в цикле
|
|
|
|
| постоянный участник
|
Пост N: 290
Зарегистрирован: 27.07.08
|
|
Отправлено: 29.03.21 11:43. Заголовок: И даже это не срабат..
И даже это не срабатывает Просто ничего не выводит и не импортирует!!!
|
|
|
|
| постоянный участник
|
Пост N: 1652
Зарегистрирован: 09.10.06
|
|
Отправлено: 29.03.21 11:53. Заголовок: url -k -u USERNAME:P..
|
|
|
|
| постоянный участник
|
Пост N: 291
Зарегистрирован: 27.07.08
|
|
Отправлено: 29.03.21 13:19. Заголовок: Петр пишет: curl -k..
Петр пишет: И так делал, а всё не получается. Localname.ics можно брать любое или тоже UID? "PUT" - закавычивать или нет?
|
|
|
|
| постоянный участник
|
Пост N: 1653
Зарегистрирован: 09.10.06
|
|
Отправлено: 29.03.21 13:32. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | "PUT" - закавычивать или нет? |
| Нет Dr. Oldwarez пишет: цитата: | Localname.ics можно брать любое |
| Любое добавьте в командную строку -Dhead И покажите содержимое файла head здесь, и командную строку тоже без купюр. Ну конечно без личных данных
|
|
|
|
| постоянный участник
|
Пост N: 292
Зарегистрирован: 27.07.08
|
|
Отправлено: 29.03.21 14:12. Заголовок: Петр пишет: И покаж..
Петр пишет: цитата: | И покажите содержимое файла head здесь, и командную строку тоже купюр. Ну конечно без личных данных |
| curl -k -u USERNAME:PASSWORD -T C:\MINIGUI\MYPROG\TEMP\qwerty.ics -X PUT https://webmail.kleeblatt.com/rpc.php/calendars/USERNAME/calendar~GhGVum1xWexaffEfhiVkNN7/817474de-31f6-446d-a09b-d4976f554e5b.ics Где 817474de-31f6-446d-a09b-d4976f554e5b.ics - это имя сгенерированное функцией генератора UID qwerty.ics - локальный файл в одно событие А куда здесь ставить -Dhead?
|
|
|
|
| постоянный участник
|
Пост N: 1654
Зарегистрирован: 09.10.06
|
|
Отправлено: 29.03.21 15:53. Заголовок: curl -Dhead -k ....
curl -Dhead -k ..
|
|
|
|
| постоянный участник
|
Пост N: 293
Зарегистрирован: 27.07.08
|
|
Отправлено: 29.03.21 17:01. Заголовок: Петр пишет: curl -D..
Петр пишет: Да. И тот же результат curl -Dhead -k -u USERNAME:PASSWORD -T C:\MINIGUI\MYPROG\TEMP\localfile.ics -X PUT https://webmail.kleeblatt.com/rpc.php/calendars/USERNAME/calendar~GhGVum1xWexaffEfhiVkNN7/817474de-31f6-446d-a09b-d4976f554e5b.ics И заголовок HTTP/1.1 100 Continue HTTP/1.1 204 No Content Date: Mon, 29 Mar 2021 13:54:37 GMT Server: Apache X-Powered-By: PHP/7.3.27 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Vary: Accept-Encoding Set-Cookie: PHPSESSID=blunlmi2m5vrs8g6gdahahrrfn; path=/ Set-Cookie: horde_secret_key=blunlmi2m5vrs8g6gdahahrrfn; path=/; domain=webmail.kleeblatt.com; HttpOnly Set-Cookie: default_horde_view=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; domain=webmail.kleeblatt.com X-Powered-By: PleskLin Content-Type: text/html; charset=UTF-8
|
|
|
|
| постоянный участник
|
Пост N: 1655
Зарегистрирован: 09.10.06
|
|
Отправлено: 29.03.21 19:36. Заголовок: В общем-то результат..
В общем-то результат нормальный. HTTP/1.1 100 Continue HTTP/1.1 204 No Content Показывает когда файл уже сохранен на сервере и вы пытаетесь его сохранить снова. Зайдите в C:\MINIGUI\MYPROG\TEMP\localfile.ics, измените LOCATION, примените PUT, а потом GET к 817474de-31f6-446d-a09b-d4976f554e5b.ics P.S. 204 No Content
|
|
|
|
| постоянный участник
|
Пост N: 294
Зарегистрирован: 27.07.08
|
|
Отправлено: 30.03.21 07:45. Заголовок: Петр пишет: В общем..
Петр пишет: цитата: | В общем-то результат нормальный. HTTP/1.1 100 Continue HTTP/1.1 204 No Content Показывает когда файл уже сохранен на сервере и вы пытаетесь его сохранить снова. Зайдите в C:\MINIGUI\MYPROG\TEMP\localfile.ics, измените LOCATION, примените PUT, а потом GET к 817474de-31f6-446d-a09b-d4976f554e5b.ics P.S. |
| УРА!!! Заработало!
|
|
|
|
| постоянный участник
|
Пост N: 295
Зарегистрирован: 27.07.08
|
|
Отправлено: 28.04.21 15:55. Заголовок: Извините, оно не раб..
Извините, оно не работает. Не заносит данные из DBF в календарь. Может, с библиотекой попробовать? Притом, что ICSы генерятся BEGIN:VCALENDAR VERSION:2.0 PRODID:-//AaaaBbbbCccc BEGIN:VEVENT UID:c60a4464-2dec-4f83-8a9f-02d2463352e8 DTSTAMP:20210428T154800Z DTSTART:20210601T154700Z DTEND:20210601T161700Z SUMMARY:Тест DESCRIPTION:Просто тест LOCATION: Урюпинск END:VEVENT END:VCALENDAR curl -k -u '+cCALName+':'+cCALPWD+' -T '+cOutput+' -X PUT '+cCalName+IIF(RIGHT(cCalName,1)='/','','/')+cUID+'.ics где cOutput - это и есть вышеупомянутый ics файл
|
|
|
|
| постоянный участник
|
Пост N: 1660
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.04.21 23:30. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Притом, что ICSы генерятся |
| У Вас программа генерирует невалидные ics файлы iCalendar Validator Problem! Found 1 warning Warnings Line length should not be longer than 75 characters near line # 9 Reference: RFC 5545 3.1. Content Lines Problem! Found 1 error Errors Missing VCALENDAR object near line # 1 Reference: RFC 5545 3.4 iCalendar Object
|
|
|
|
| постоянный участник
|
Пост N: 1661
Зарегистрирован: 09.10.06
|
|
Отправлено: 28.04.21 23:35. Заголовок: И второе - Вы не ана..
И второе - Вы не анализируете ответ сервера (-Dhead и т.д.), а то бы сразу увидели что-то вроде HTTP/1.1 100 Continue HTTP/1.1 415 Unsupported Media Type
|
|
|
|
| постоянный участник
|
Пост N: 296
Зарегистрирован: 27.07.08
|
|
Отправлено: 29.04.21 18:59. Заголовок: Петр пишет: У Вас п..
Петр пишет: цитата: | У Вас программа генерирует невалидные ics файлы iCalendar Validator Problem! Found 1 warning Warnings Line length should not be longer than 75 characters near line # 9 Reference: RFC 5545 3.1. Content Lines Problem! Found 1 error Errors Missing VCALENDAR object near line # 1 Reference: RFC 5545 3.4 iCalendar Object |
| Уже исправил Вот теперь Results File Size: 13 lines, 323 bytes Number of events found: 1 Success! No errors found. Permalinks are available when validating by URL. You can use a permalink to send a link of the validation results page using e-mail or web posting. Show source data BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Qwwwwerty//UUUIIIOOOPP BEGIN:VEVENT UID:09a8e21b-fb27-49eb-9479-5b9c8ad1ba57 DTSTAMP:20210429T185200Z DTSTART:20210601T150000Z DTEND:20210601T190000Z SUMMARY:MYNAME: Birthday DESCRIPTION:My Birthday LOCATION:Pizzeria END:VEVENT END:VCALENDAR Но всё равно ничего в календарь не попадает. Скажите, пожалуйста, а как Dhead вывести тоже в отдельный файл отчёта, чтобы потом его проанализировать
|
|
|
|
| постоянный участник
|
Пост N: 1662
Зарегистрирован: 09.10.06
|
|
Отправлено: 29.04.21 20:34. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: Не Dhead, а -Dhead -D, --dump-header <filename> Write the received headers to <filename> Читайте файл с именем head (или назовите его так как Вам нужно) и анализируйте. цитата: | Но всё равно ничего в календарь не попадает |
| Что же у Вас заработало?
|
|
|
|
| постоянный участник
|
Пост N: 297
Зарегистрирован: 27.07.08
|
|
Отправлено: 03.05.21 07:36. Заголовок: Петр пишет: Не Dhea..
Петр пишет: цитата: | Не Dhead, а -Dhead -D, --dump-header <filename> Write the received headers to <filename> Читайте файл с именем head (или назовите его так как Вам нужно) и анализируйте. |
| И вот он, этот файл, который я назвал wtf.txt HTTP/1.1 100 Continue HTTP/1.1 401 Unauthorized Date: Mon, 03 May 2021 04:31:57 GMT Server: Apache X-Powered-By: PHP/7.3.27 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache WWW-Authenticate: Basic realm="Horde DAV Server" Vary: Accept-Encoding Set-Cookie: PHPSESSID=bub17ffsgkd7249csku3c3brkt; path=/ X-Powered-By: PleskLin Transfer-Encoding: chunked Content-Type: application/xml; charset=utf-8 Я так понял, это что-то с авторизацией. Но ведь логин и пароль при ручном вводе подходят! И почему что-то там истекло 19 ноября 1981 года? В чём же проблема?
|
|
|
|
| постоянный участник
|
Пост N: 1664
Зарегистрирован: 09.10.06
|
|
Отправлено: 03.05.21 10:18. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | И почему что-то там истекло 19 ноября 1981 года? В чём же проблема? |
| Какая там проблема .. цитата: | It's an attempt to disable caching. The date is the birthday of the developer Sascha Schumann who added the code. From session.c: Authors: Sascha Schumann <sascha@schumann.cx> Andrei Zmievski <andrei@php.net> // ... CACHE_LIMITER_FUNC(private) { ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT"); CACHE_LIMITER(private_no_expire)(TSRMLS_C); } |
| цитата: | Этот заголовок (ещё `Pragma: no-cache`) добавляется автоматически, когда запускается сессия (`session_start()`) для отключения кэша. Дата, на самом деле, не важна, главное чтобы она была из прошлого, чтобы кэш считался невалидным. |
| Curl кэширует запросы. Помните это.
|
|
|
|
| постоянный участник
|
Пост N: 1669
Зарегистрирован: 09.10.06
|
|
Отправлено: 03.05.21 11:51. Заголовок: Код робочей консоль..
Код робочей консольной программы для загрузки файлов календаря на сервер. Может кому-то будет интересно. Скрытый текст
цитата: | #include "hbmxml.ch" #include "ics.ch" #command ?C <message> => QOutClr( <message>, .T. ) #command ?! <message> => QOutClr( <message>, .F. ) #define DIR_UTILS ( hb_DirBase() + "utils" ) REQUEST HB_CODEPAGE_UTF8 MEMVAR mxml_error MEMVAR mxml_error_msg INIT PROCEDURE _OnInit() PUBLIC mxml_error PUBLIC mxml_error_msg FErase( hb_DirBase() + "_err.log" ) FErase( hb_DirBase() + "_header.log" ) FErase( hb_DirBase() + "_out.xml" ) // Проверка доступности cURL IF ! hb_FileExists( hb_DirSepAdd( DIR_UTILS ) + "curl.exe" ) ?! "#white+#Can't find #red+#curl.exe" ErrorLevel( 2 ) __Quit() ENDIF M->mxml_error := .F. M->mxml_error_msg := "" mxmlSetErrorCallback( @cb_error() ) RETURN /* */ PROCEDURE cb_error( cErrorMsg ) M->mxml_error_msg := cErrorMsg M->mxml_error := .T. RETURN /* */ FUNCTION cb_type( xmlNode ) LOCAL cType := mxmlElementGetAttr( xmlNode, "type" ) LOCAL nResult IF Empty( cType ) cType := mxmlGetElement( xmlNode ) ENDIF SWITCH Lower( cType ) CASE "s:exception" CASE "s:sabredav-version" nResult := MXML_TEXT EXIT CASE "s:message" nResult := MXML_OPAQUE EXIT OTHERWISE nResult := MXML_IGNORE EXIT ENDSWITCH RETURN nResult /* */ STATIC FUNCTION sf_GetEvent( aSource ) LOCAL nStart, nEnd, nLen, e1, e2 hb_default( @aSource, {} ) IF ! Empty( aSource ) nStart := nEnd := 0 FOR EACH e1 IN aSource IF e1[ ICS_PARAM ] = "BEGIN" FOR EACH e2 IN e1[ ICS_VALS ] IF hb_LeftEq( e2, "VEVENT" ) nStart := e1:__enumIndex() EXIT ENDIF NEXT ELSEIF e1[ ICS_PARAM ] = "END" FOR EACH e2 IN e1[ ICS_VALS ] IF hb_LeftEq( e2, "VEVENT" ) nEnd := e1:__enumIndex() EXIT ENDIF NEXT ENDIF IF nEnd > 0 EXIT ENDIF NEXT IF nStart != 0 .AND. nStart < nEnd nLen := nEnd - nStart + 1 RETURN ACopy( aSource, Array( nLen ), nStart, nLen ) ENDIF ENDIF RETURN {} /* */ STATIC FUNCTION sf_GetEventUID( aSource ) LOCAL nPos hb_default( @aSource, {} ) IF ! Empty( aSource ) nPos := AScan( aSource, {| e | e[ ICS_PARAM ] = "UID" } ) IF nPos > 0 RETURN aSource[ nPos ][ ICS_VALS ][ ICS_PARAM ] ENDIF ENDIF RETURN "" /* */ STATIC FUNCTION sf_GetError( cArg, cException, cMessage ) LOCAL xmlTree, xmlNode, xmlSubNode // Check arguments... IF ! HB_ISSTRING( cArg ) .OR. Empty( cArg ) RETURN .F. ENDIF xmlTree := iif( hb_LeftEq( cArg, "<" ), ; mxmlLoadString( NIL, cArg, @cb_type() ), mxmlLoadFile( NIL, cArg, @cb_type() ) ) IF M->mxml_error .OR. Empty( xmlTree ) RETURN .F. ENDIF xmlNode := mxmlFindElement( xmlTree, xmlTree, "d:error",,, MXML_DESCEND ) IF Empty( xmlNode ) mxmlDelete( xmlTree ) RETURN .F. ENDIF xmlSubNode := mxmlGetFirstChild( xmlNode ) DO WHILE ! Empty( xmlSubNode ) IF mxmlGetType( xmlSubNode ) == MXML_ELEMENT IF mxmlGetElement( xmlSubNode ) == "s:exception" cException := mxmlGetText( xmlSubNode ) ELSEIF mxmlGetElement( xmlSubNode ) == "s:message" cMessage := mxmlGetOpaque( xmlSubNode ) ENDIF ENDIF xmlSubNode := mxmlGetNextSibling( xmlSubNode ) ENDDO mxmlDelete( xmlTree ) RETURN .T. /* */ STATIC FUNCTION sf_GetHTTPStatusCode( cFile, cCode, cDesc ) LOCAL cStr := hb_MemoRead( cFile ) LOCAL aStr := hb_ATokens( cStr, hb_eol() ) LOCAL nAt := hb_RAScan( aStr, {| s | hb_LeftEq( s, 'HTTP' ) } ) IF nAt > 0 cStr := aStr[ nAt ] cCode := hb_tokenGet( cStr, 2, ' ' ) aStr := hb_ATokens( cStr, cCode ) cDesc := LTrim( aStr[ 2 ] ) RETURN .T. ENDIF RETURN .F. /* */ STATIC PROCEDURE Usage() OutStd( "Syntax: fput <file>" + hb_eol() + hb_eol() ) RETURN /* */ PROCEDURE Main( cFile ) LOCAL cStr LOCAL aEvent, w := 0, cUid LOCAL cOpt LOCAL cCmdLn := '%1$s\curl.exe -u "%2$s:%3$s" %4$s -T "%5$s" -X %6$s %7$s%8$s%9$s' LOCAL cUser := "b329767865754" LOCAL cPwd := "xk567vjh0t" LOCAL cCalDav := "https://dav.fruux.com/" LOCAL cHRef := "calendars/a3298166498/ae6b576a-981f-4697-8c00-ac043a96d075/" LOCAL cStdOut, cStdErr LOCAL cException := "", cMessage := "", cCode := "", cDescription := "" IF Empty( cFile ) Usage() ErrorLevel( 0 ) __Quit() ENDIF // Read iCalendar file cStr := hb_MemoRead( cFile ) // Get VEVENT aEvent := sf_GetEvent( IcsToArray2( cStr, @w ) ) IF w # 0 ?C "Warning:#white+# Missing newline at end of input" ENDIF // Get VEVENT UID cUid := sf_GetEventUID( aEvent ) IF Empty( cUid ) ?! "#white+#Do nothing for #red+#" + cFile ErrorLevel( 3 ) __Quit() ENDIF /* PUT /calendars/johndoe/home/somerandomstring.ics HTTP/1.1 Content-Type: text/calendar; charset=utf-8 BEGIN:VCALENDAR .... END:VCALENDAR */ cOpt := '--insecure --no-progress-meter ' cOpt += '--http1.1 ' cOpt += '--header "Content-Type: text/calendar; charset=utf-8" ' cOpt += '--dump-header _header.log ' cStr := RTrim( cUid ) + '.ics' cCmdLn := hb_StrFormat( cCmdLn, DIR_UTILS, cUser, cPwd, cOpt, cFile, "PUT", cCalDav, cHRef, cStr ) hb_processRun( cCmdLn, , @cStdOut, @cStdErr ) IF ! Empty( cStdErr ) hb_MemoWrit( hb_DirBase() + "_err.log", cStdErr ) ErrorLevel( 4 ) __Quit() ENDIF IF ! Empty( cStdOut ) hb_MemoWrit( hb_DirBase() + "_out.xml", cStdOut ) IF sf_GetHTTPStatusCode( '_header.log', @cCode, @cDescription ) ?C 'HTTP status code: #white+#' + cCode + '# (' + cDescription + ')' ENDIF IF sf_GetError( cStdOut, @cException, @cMessage ) ?! "#red+#" + cException + hb_eol() ?C "#white+#" + cMessage ErrorLevel( 5 ) __Quit() ENDIF IF M->mxml_error ?! "#red+#An error occured while parsing an XML document." + hb_eol() ?C "#white+#" + M->mxml_error_msg ErrorLevel( 6 ) __Quit() ENDIF ENDIF OutStd( "Done" + hb_eol() ) IF sf_GetHTTPStatusCode( '_header.log', @cCode, @cDescription ) ?C 'HTTP status code: #white+#' + cCode + '# (' + cDescription + ')' ENDIF RETURN |
|
| P.S. Нет предела совершенству - это я знаю
|
|
|
|
| постоянный участник
|
Пост N: 1670
Зарегистрирован: 09.10.06
|
|
Отправлено: 03.05.21 11:57. Заголовок: # fput.hbp -w3 #..
Файл сборки Скрытый текст
цитата: | # fput.hbp -w3 #-es2 #-mt -I../../include -inc -workdir=.hbmk -ofput -strip -instpath=.\ #Libs -lhbmxml -lmxml -lics -L../../lib #Link with harbour-32-x64.dll #-shared fput.prg colorize.prg |
|
|
|
|
|
|
| постоянный участник
|
Пост N: 1671
Зарегистрирован: 09.10.06
|
|
Отправлено: 03.05.21 12:01. Заголовок: colorize.prg #inc..
colorize.prg Скрытый текст
цитата: | #include "color.ch" PROCEDURE QOutClr( cMessage, lNewLine ) LOCAL cDefColor, cDefFGClr, cCurFGClr, cCurBKClr, cClrPair STATIC hColors := { ; "black" => "N", ; "blue" => "B", ; "green" => "G", ; "cyan" => "BG", ; "red" => "R", ; "magenta" => "RB", ; "brown" => "GR", ; "white" => "W", ; "gray" => "N+", ; "blue+" => "B+", ; // b - Bright "green+" => "G+", ; "cyan+" => "BG+",; "red+" => "R+", ; "magenta+" => "RB+",; "yellow" => "GR+",; "white+" => "W+" ; } LOCAL cStr hb_default( @cMessage, "" ) hb_default( @lNewLine, .T. ) hb_HCaseMatch( hColors, .F. ) IF .NOT. Empty( cMessage ) // Save a colors scheme cDefColor := SetColor() cClrPair := GetClrPair( cDefColor, CLR_STANDARD + 1 ) cDefFGClr := GetClrFore( cClrPair ) cCurBKClr := GetClrBack( cClrPair ) cCurFGClr := cDefFGClr FOR EACH cStr IN hb_ATokens( cMessage, '#' ) // If a string between #-Tags is equal to any predefined Color, // and is equal to the default Foreground Color: set current Foreground Color IF hb_HHasKey( hColors, cStr ) .AND. cCurFGClr == cDefFGClr cCurFGClr := hColors[ cStr ] ELSE SetColor( SetClrPair( cDefColor, CLR_STANDARD + 1, cCurFGClr + '/' + cCurBKClr ) ) QQOut( cStr ) // Reset current Foreground Color cCurFGClr := cDefFGClr ENDIF NEXT IF lNewLine ? e"\n" ENDIF // Restore a colors scheme SetColor( cDefColor ) ENDIF RETURN |
|
| ics.ch Скрытый текст
цитата: | #ifndef ICS_CH_ #define ICS_CH_ #define ICS_PARAM 1 #define ICS_PROPS 2 #define ICS_VALS 3 #endif /* ICS_CH_ */ |
|
|
|
|
|
|
| постоянный участник
|
Пост N: 298
Зарегистрирован: 27.07.08
|
|
Отправлено: 03.05.21 19:28. Заголовок: Огромное спасибо! Об..
Огромное спасибо! Обязательно попробую интегрировать в свою прогу! И с прошедшими праздниками!
|
|
|
|
| постоянный участник
|
Пост N: 1672
Зарегистрирован: 09.10.06
|
|
Отправлено: 03.05.21 20:42. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Огромное спасибо! Обязательно попробую интегрировать в свою прогу! И с прошедшими праздниками! |
| Был рад вам помочь. Если возникнут вопросы - обращайтесь. Спасибо!
|
|
|
|
| постоянный участник
|
Пост N: 299
Зарегистрирован: 27.07.08
|
|
Отправлено: 08.05.21 11:25. Заголовок: Петр пишет: #Libs ..
Петр пишет: цитата: | #Libs -lhbmxml -lmxml -lics -lhbwin |
| И сразу вопрос: где можно достать библиотеку ics.lib? У меня в директории C:\MINIGUI\HARBOUR\LIB есть hbmxml, mxml, hbwin. А вот ics.lib нет.
|
|
|
|
| постоянный участник
|
Пост N: 1674
Зарегистрирован: 09.10.06
|
|
Отправлено: 08.05.21 22:26. Заголовок: Dr. Oldwarez пишет: ..
|
|
|
|
| постоянный участник
|
Пост N: 1675
Зарегистрирован: 09.10.06
|
|
Отправлено: 08.05.21 22:38. Заголовок: IcsToArray2 обладает..
IcsToArray2 обладает тем же функционалом, написана на Harbour. Скрытый текст
цитата: | // This code is based on J Decker original code posted at // https://stackoverflow.com/questions/35003036/toolset-to-parse-icalendar-file-in-c // disclaimer : no support // code provided as a example of minimal things one can do. // format for lines is... // PARAMETER[;PARAM_PROPERTY..]:VALUE[,VALUE2..]\n #ifndef __DBG_PARTS__ #xtranslate hb_traceLog( [<x,...>] ) => #endif #define ICS_PARAMETER 1 #define ICS_PROPERTY 2 #define ICS_VALUE 3 FUNCTION IcsToArray2( cInput, i ) LOCAL nStart := 1 LOCAL nEnd := 1 LOCAL nState := ICS_PARAMETER LOCAL char, cParameter, cProperty, cValue LOCAL aIcs := {} LOCAL aProps := {} LOCAL aValues := {} LOCAL lInQuote := .F. hb_default( @cInput, "" ) IF hb_eol() $ cInput cInput := StrTran( cInput, hb_eol(), e"\n" ) ENDIF FOR EACH char IN cInput SWITCH nState CASE ICS_PARAMETER IF char == ":" .OR. char == ";" cParameter := SubStr( cInput, nStart, nEnd - nStart ) hb_traceLog( "PARAMETER:%s", cParameter ) IF char == ";" nState := ICS_PROPERTY ELSE nState := ICS_VALUE ENDIF nStart := nEnd + 1 ENDIF EXIT CASE ICS_PROPERTY IF char == '"' IF ! lInQuote lInQuote := .T. ELSE lInQuote := .F. EXIT ENDIF ENDIF IF lInQuote EXIT ENDIF IF char == ";" .OR. char == ":" cProperty := SubStr( cInput, nStart, nEnd - nStart ) hb_traceLog( "PROPERTY:%s", cProperty ) AAdd( aProps, cProperty ) IF char == ":" nState := ICS_VALUE ENDIF nStart := nEnd + 1 EXIT ENDIF EXIT CASE ICS_VALUE IF char == e"\n" .OR. char == "," cValue := SubStr( cInput, nStart, nEnd - nStart ) hb_traceLog( "VALUE:%s", cValue ) AAdd( aValues, cValue ) IF char == e"\n" AAdd( aIcs, { cParameter, AClone( aProps ), AClone( aValues ) } ) aProps := {} aValues := {} nState := ICS_PARAMETER ENDIF nStart := nEnd + 1 ENDIF EXIT ENDSWITCH nEnd++ NEXT IF nEnd != nStart i := 1 ENDIF RETURN aIcs |
|
|
|
|
|
|
| постоянный участник
|
Пост N: 1676
Зарегистрирован: 09.10.06
|
|
Отправлено: 08.05.21 22:47. Заголовок: Пример использования..
Пример использования Скрытый текст
цитата: | PROCEDURE Main( cFile ) LOCAL cStr := hb_MemoRead( cFile ) LOCAL aIcs, err := 0 aIcs := IcsToArray2( cStr, @err ) IF err == 0 ? hb_ValToExp( aIcs ), hb_eol() sp_Dump2( aIcs ) ENDIF RETURN STATIC PROCEDURE sp_Dump2( aSource ) LOCAL e1, e2 hb_default( @aSource, {} ) IF ! Empty( aSource ) FOR EACH e1 IN aSource ?? e1[ ICS_PARAM ] FOR EACH e2 IN e1[ ICS_PROPS ] ?? ";" + e2 NEXT FOR EACH e2 IN e1[ ICS_VALS ] IF e2:__enumIsFirst() ?? ":" + e2 ELSE ?? "," + e2 ENDIF NEXT ?? hb_eol() NEXT ENDIF RETURN |
|
| P.S. Код в посте №1669 исправил для использования IcsToArray2 Также добавлена функция извлечения кода возврата и его описания sf_GetHTTPStatusCode .
|
|
|
|
| постоянный участник
|
Пост N: 300
Зарегистрирован: 27.07.08
|
|
Отправлено: 09.05.21 12:49. Заголовок: Спасибо за функцию. ..
Спасибо за функцию. Только теперь вопрос: как передать имя файла в процедуру Import2Cal (бывшая Main), чтобы не выдавало такого вот сбоя. Error BASE/1081 Argument error: + Args: [1] = U [2] = C / У меня cFile:=cTempDIR+'\Test.ics', где cTempDIR - директория временных файлов, прописанная в INI PS: Поздравляю с днём Победы
|
|
|
|
| постоянный участник
|
Пост N: 1677
Зарегистрирован: 09.10.06
|
|
Отправлено: 09.05.21 13:30. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | PS: Поздравляю с днём Победы |
| Спасибо. И Вас и всех остальных форумчан с Праздником! цитата: | Только теперь вопрос: как передать имя файла в процедуру Import2Cal |
| Не совсем понял вопрос Import2Cal( cFile ). И зачем вам директория временных файлов. Error BASE/1081 Argument error: + Args: [1] = U [2] = C / cFile:=cTempDIR+'\Test.ics' TYPE( cTempDIR ) == "U" (Args: [1] = U) и складывать его с '\Test.ics' ([2] = C) нельзя Лучше так cFile:=hb_defaultValue(hb_DirSepAdd(cTempDIR), hb_DirTemp())+'Test.ics'
|
|
|
|
| постоянный участник
|
Пост N: 301
Зарегистрирован: 27.07.08
|
|
Отправлено: 09.05.21 14:03. Заголовок: Петр пишет: Import2..
Петр пишет: цитата: | Import2Cal( cFile ). И зачем вам директория временных файлов. |
| А куда ещё временные ics-ы девать?
|
|
|
|
| постоянный участник
|
Пост N: 1678
Зарегистрирован: 09.10.06
|
|
Отправлено: 09.05.21 14:18. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | А куда ещё временные ics-ы девать? |
| Ну вам виднее. Я обхожусь обычной субдиректорией в директории программы. И файлы там не временные, а копии файлов на сервере, как и рекомендуют разработчики.
|
|
|
|
| постоянный участник
|
Пост N: 302
Зарегистрирован: 27.07.08
|
|
Отправлено: 09.05.21 15:49. Заголовок: Error BASE 1081 уже ..
Error BASE 1081 уже убрал. Но теперь curl ругается на опцию --no-progress-meter curl: option --no-progress-meter: is unknown curl: try 'curl --help' for more information
|
|
|
|
| |
Пост N: 7341
Зарегистрирован: 17.05.05
|
|
Отправлено: 09.05.21 15:56. Заголовок: Dr. Oldwarez Может ..
Dr. Oldwarez Может CURL древний Fixed in 7.67.0 - November 6 2019 Changes: curl: added --no-progress-meter
|
|
|
|
| постоянный участник
|
Пост N: 303
Зарегистрирован: 27.07.08
|
|
Отправлено: 09.05.21 16:55. Заголовок: Dima пишет: Dr. Old..
Dima пишет: цитата: | Dr. Oldwarez Может CURL древний Fixed in 7.67.0 - November 6 2019 Changes: curl: added --no-progress-meter |
| Да, древний. И не обновляется, несмотря на прямую замену. Лучше давайте уберём эту опцию
|
|
|
|
| постоянный участник
|
Пост N: 304
Зарегистрирован: 27.07.08
|
|
Отправлено: 09.05.21 17:28. Заголовок: Петр пишет: IcsToAr..
Петр пишет: цитата: | IcsToArray2 обладает тем же функционалом, написана на Harbour. |
| Пока решил прочесать программу и обнаружил, что эта функция не работает. Выдаёт пустой массив
|
|
|
|
| постоянный участник
|
Пост N: 1679
Зарегистрирован: 09.10.06
|
|
Отправлено: 09.05.21 17:46. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: Да, если строка на входе не валидная. Можно и в ошибку времени исполнения свалиться, но так лучше. И в дальнейшем приводите самодостаточные примеры или хотя бы часть своего кода, чтобы был какой-то предмет для разговора.
|
|
|
|
| постоянный участник
|
Пост N: 305
Зарегистрирован: 27.07.08
|
|
Отправлено: 09.05.21 21:07. Заголовок: Бывший main FUNCTION..
Бывший main FUNCTION Import2Cal() LOCAL cStr LOCAL cCmdLn := 'curl.exe -u "%1$s:%2$s" %3$s -T "%4$s" -X %5$s %6$s%7$s' LOCAL cOpt:='',aICS LOCAL aEvent,w:=0, cUid LOCAL cFile:=hb_defaultValue(cTempLW,"")+'\Termin.ics' LOCAL cStdOut, cStdErr cStr:=hb_MemoRead( cFile ) aICS:=IcsToArray2(cStr,@w ) aEvent := sf_GetEvent( IcsToArray2(cStr,@w ) ) MsgInfo(STR(LEN(aICS))) cUid := sf_GetUID( aEvent ) cStr := RTrim( cUid ) + '.ics' cUid += ".ics" cOpt := '--insecure --no-progress-meter ' cOpt += '--http1.1 ' cOpt += '--header "Content-Type: text/calendar; charset=utf-8" ' cOpt += '--dump-header _header.log ' cCmdLn:=hb_StrFormat(cCmdLn, cCalLogin, cCalPwd, cOpt, cFile, "PUT", cCalName, cUid ) //MsgInfo(cCmdLn) hb_ProcessRun( cCmdLn,,@cStdOut,@cStdErr) IF ! Empty( cStdErr ) hb_MemoWrit( hb_DirBase() + "_err.log", cStdErr ) ENDIF IF ! Empty( cStdOut ) hb_MemoWrit( hb_DirBase() + "_out.xml", cStdOut ) ENDIF RETURN NIL STATIC FUNCTION sf_GetEvent(aSource) LOCAL nStart, nEnd, nLen, e1, e2 hb_default(@aSource, {}) IF .NOT. Empty( aSource ) nStart := nEnd := 0 FOR EACH e1 IN aSource DESCEND IF e1[ICS_PARAMETER] = "BEGIN" FOR EACH e2 IN e1[ICS_VALUE] DESCEND IF hb_LeftEq(e2, "VEVENT") nStart := e1:__enumIndex() EXIT ENDIF NEXT ELSEIF e1[ICS_PARAMETER] = "END" FOR EACH e2 IN e1[ICS_VALUE] DESCEND IF hb_LeftEq(e2, "VEVENT") nEnd := e1:__enumIndex() EXIT ENDIF NEXT ENDIF IF nEnd > 0 EXIT ENDIF NEXT IF nStart != 0 .AND. nStart > nEnd nLen := nStart - nEnd + 1 RETURN ACopy(aSource, Array(nLen), nEnd, nLen) ENDIF ENDIF RETURN {} Я проверил, что пустой массив aEvent выдаёт именно sf_getevent. aICS длиной в 12 элементов, как и положено ICS_PARAMETER ICS_VALUE - они не из "ICS.CH"? И где его взять?
|
|
|
|
| |
Пост N: 7342
Зарегистрирован: 17.05.05
|
|
Отправлено: 09.05.21 21:13. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | И не обновляется, несмотря на прямую замену |
| Так не бывает..........ну если корректно заменил конечно :)
|
|
|
|
| постоянный участник
|
Пост N: 1680
Зарегистрирован: 09.10.06
|
|
Отправлено: 09.05.21 21:22. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Я проверил, что пустой массив aEvent выдаёт именно sf_getevent. aICS длиной в 12 элементов, как и положено |
| У вас sf_getevent для использования с IcsToArray Для IcsToArray2 sf_GetEvent() код нужно модифицировать Читайте внимательно Код в посте №1669 исправил для использования IcsToArray2
|
|
|
|
| постоянный участник
|
Пост N: 1681
Зарегистрирован: 09.10.06
|
|
Отправлено: 09.05.21 21:29. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | ICS_PARAMETER ICS_VALUE - они не из "ICS.CH"? И где его взять? |
| ICS_PARAMETER см. мой пост №1675 если коротко цитата: | #include "ics.ch" #define ICS_PARAMETER ICS_PARAM #define ICS_PROPERTY ICS_PROPS #define ICS_VALUE ICS_VALS |
|
|
|
|
|
| постоянный участник
|
Пост N: 306
Зарегистрирован: 27.07.08
|
|
Отправлено: 10.05.21 07:35. Заголовок: Петр пишет: #inclu..
Петр пишет: Я имел в виду файл заголовка ics.ch. В директории заголовочных файлов у меня его нет.
|
|
|
|
| постоянный участник
|
Пост N: 1682
Зарегистрирован: 09.10.06
|
|
Отправлено: 10.05.21 08:19. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Я имел в виду файл заголовка ics.ch. |
| Пост №1671
|
|
|
|
| постоянный участник
|
Пост N: 307
Зарегистрирован: 27.07.08
|
|
Отправлено: 10.05.21 19:51. Заголовок: Петр пишет: У вас s..
Петр пишет: цитата: | У вас sf_getevent для использования с IcsToArray Для IcsToArray2 sf_GetEvent() код нужно модифицировать Читайте внимательно Код в посте №1669 исправил для использования IcsToArray2 |
| Спасибо! Всё исправил. И уже начало импортировать. Теперь только проблема отфильтровывания дубликатов.
|
|
|
|
| постоянный участник
|
Пост N: 308
Зарегистрирован: 27.07.08
|
|
Отправлено: 16.07.21 20:52. Заголовок: Часовые пояса и зимнее/летнее время
И снова здравствуйте. Всё уже вроде работает, но проблема теперь с часовыми поясами. При импорте из онлайн-календаря в локальную базу данных получается так, что все даты сходят на время по Гринвичу. А у заказчика UTC+1 зимой и UTC+2 летом. Как сделать, чтобы при импорте правильно подхватывало зимнее/летнее время? Какая есть функция для определения время летнее или зимнее? По ключу TZID и потом ниже выходит какая-то дикая абракадабра.
|
|
|
|
| постоянный участник
|
Пост N: 3788
Зарегистрирован: 17.02.12
|
|
Отправлено: 16.07.21 21:10. Заголовок: Dr. Oldwarez пишет К..
Dr. Oldwarez пишет цитата: | Какая есть функция для определения время летнее или зимнее? |
| Использую такие ф-ии Скрытый текст
*----------------------------------------------------------------------------* FUNCTION nUx2cDts( nUx, lDts ) // nUx := 1508186400 *----------------------------------------------------------------------------* LOCAL dDate, cDate, cTime DEFAULT lDts := .F. tDate := hb_datetime( 1970, 1, 1 ) + nUx / 86400 IF lDts ; RETURN tDate ENDIF cDate := DtoS( hb_TtoD( tDate ) ) cTime := hb_TtoC( tDate ) cTime := Subs( cTime, At(" ", cTime) + 1 ) cTime := StrTran( cTime, ":", "" ) cTime := StrTran( cTime, ".", "" ) RETURN ( cDate + cTime ) *----------------------------------------------------------------------------* FUNCTION Gmt2Utc( cDate, lTrans, nHour ) *----------------------------------------------------------------------------* LOCAL tDtm, tUtc, cTm1, cTm2 LOCAL dDat, dNew, cTim LOCAL nTime, cTime LOCAL lHour := .T. // "+" LOCAL lDate := Empty(cDate) STATIC s_nHour DEFAULT cDate := DtoS(Date())+StrTran(Time(), ":", "") IF ISLOGICAL(nHour) ; lHour := nHour ; nHour := Nil ELSEIF ISCHAR(nHour) ; lHour := "+" $ nHour ; nHour := Nil ENDIF dDat := StoD(left(cDate, 8)) dNew := dDat cTim := Transform(Val(subs(cDate, 9, 6)), "99:99:99") IF s_nHour == Nil .or. lDate cTm1 := cTm2 := "" tDtm := hb_DateTime() tUtc := hb_TSToUTC( tDtm ) HB_TTOD( tDtm, @cTm1, "hh:mm:ss" ) HB_TTOD( tUtc, @cTm2, "hh:mm:ss" ) s_nHour := Val(cTm1) - Val(cTm2) ENDIF DEFAULT nHour := iif( lHour, s_nHour, -(s_nHour) ) , lTrans := .T. nTime := Secs(cTim) + nHour*60*60 cTime := SecToTime(nTime + iif( nTime < 0, 24*60*60, 0 )) IF nHour < 0 ; dNew -= iif( Secs(cTime) > Secs(cTim ), 1, 0 ) ELSE ; dNew += iif( Secs(cTim ) > Secs(cTime), 1, 0 ) ENDIF cDate := DtoS( dNew ) + StrTran( cTime, ":", "" ) IF lTrans ; cDate := Transform( cDate, "@R 9999-99-99 99:99:99" ) ENDIF RETURN cDate
| Использование oCol := :GetColumn("R_DTM") ; oCol:nAlign := DT_CENTER oCol:cPicture := "@R 9999-99-99 99:99:99" oCol:nWidth := oCol:ToWidth(subs(oCol:cPicture, 2)) oCol:bDecode := {|cd| Gmt2Utc(cd, .F.) } oCol:cHeading := StrTran(ot:cDtms, "\", CRLF) ... по кнопке OK! для GETBOX-ов периода даты и периода времени :Event(10, {|ow,ky,cn| LOCAL o := Sys.Cargo, ot := Sys.Cargo:oBaseText LOCAL oObj := ow:Cargo:oObject, aTmp, cTmp, cDt1, cDt2, cFil, cObj LOCAL aObj := {}, cGm1 LOCAL aNam := {}, cGm2 LOCAL cNam := This.Events.Value LOCAL dDt1 := This.PeriodFrom.Value LOCAL dDt2 := This.PeriodTo.Value LOCAL cTm1 := This.TimesFrom.Value LOCAL cTm2 := This.TimesTo.Value ... cTm1 := left(trim(cTm1)+repl("0", 6), 6) cTm2 := left(trim(cTm2)+repl("0", 6), 6) cDt1 := hb_DtoC(dDt1, "YYYYMMDD")+cTm1 cDt2 := hb_DtoC(dDt2, "YYYYMMDD")+cTm2 cGm1 := Gmt2Utc(cDt1, .F., .F.) cGm2 := Gmt2Utc(cDt2, .F., .F.) ...
|
|
|
|
| постоянный участник
|
Пост N: 309
Зарегистрирован: 27.07.08
|
|
Отправлено: 17.07.21 09:30. Заголовок: SergKis пишет: *---..
SergKis пишет: цитата: | *----------------------------------------------------------------------------* FUNCTION nUx2cDts( nUx, lDts ) // nUx := 1508186400 *----------------------------------------------------------------------------* LOCAL dDate, cDate, cTime DEFAULT lDts := .F. tDate := hb_datetime( 1970, 1, 1 ) + nUx / 86400 IF lDts ; RETURN tDate ENDIF cDate := DtoS( hb_TtoD( tDate ) ) cTime := hb_TtoC( tDate ) cTime := Subs( cTime, At(" ", cTime) + 1 ) cTime := StrTran( cTime, ":", "" ) cTime := StrTran( cTime, ".", "" ) RETURN ( cDate + cTime ) |
| lDts - Date Shift, я так понимаю. nUx - это какое-то астрономическое число, но что оно означает? Тут идёт приплюсовка часа к времени, но как определить точно, это зимнее (от последнего воскресенья октября до последнего воскресенья марта) или летнее время?
|
|
|
|
| постоянный участник
|
Пост N: 3789
Зарегистрирован: 17.02.12
|
|
Отправлено: 17.07.21 12:42. Заголовок: Dr. Oldwarez пишет n..
Dr. Oldwarez пишет цитата: | nUx - это какое-то астрономическое число, но что оно означает? |
| см. http://clipper.borda.ru/?1-3-0-00000631-000-0-0-1618297675 возможно эта ф-я не нужна. цитата: | но как определить точно, это зимнее (от последнего воскресенья октября до последнего воскресенья марта) или летнее время? |
| ф-я Gmt2Utc(...) определяет разницу gmt и местного времени. Определяйте сами запуская Gmt2Utc(NIL) хоть каждый час разницу зимнего или летнего времени. В показанном варианте ф-ии дата timestamp (gmt) строковая без разделителей, т.к. именно такая хранится в базе dbf для упрощения работы с индексами (данные получены из FireBird ф-ей nUx2cDts( nUx )). За месяц ~2 500 000 записей, базы годовые.
|
|
|
|
| постоянный участник
|
Пост N: 311
Зарегистрирован: 27.07.08
|
|
Отправлено: 26.07.21 12:24. Заголовок: SergKis пишет: *--..
SergKis пишет: цитата: | *----------------------------------------------------------------------------* FUNCTION Gmt2Utc( cDate, lTrans, nHour ) *----------------------------------------------------------------------------* |
| Итак, попытаюсь расшифровать: cDate - входная дата и время по Гринвичу lTrans - указание формата вывода ГГГГ-ММ-ДД ЧЧ:ММ:СС 2021-07-26 12:30:00 Что здесь делает статический s_nhour? А параметр nHour - это заданный сдвиг относительно Гринвича?
|
|
|
|
| постоянный участник
|
Пост N: 3800
Зарегистрирован: 17.02.12
|
|
Отправлено: 26.07.21 12:56. Заголовок: hb_TSToUTC( ) e..
hb_TSToUTC( [<tLocalTime>] ) ➜ tUtcTime -> converts a local time tTIMESTAMP to UTC time. hb_DateTime() -> local time tTIMESTAMP cDate - Utc время из базы тип char, значение без миллисекунд, т.е. '20201203102045' s_nHour - разница в часах локального времени и Utc времени, т.е. для нас: 3 - часа для летнего, 2 - для зимнего времени вычисляем при входе в программу и можно переустановить s_nHour в каком то режиме (по таймеру, каждый час) используется дальше как константа для отображения данных базы в локальном времени (в TsBrowse) и после GETBOX запросов периода дат, времени (локальное время задается), приводим ко времени Utc для работы с базой (SET SCOPE ..., SET FILTER ... и т.д.) lTrans используется для TsBrowse отображения в колонках или Label, если не задаем Picture Пример Скрытый текст
@ y, x LABEL Period VALUE ot:cPer+":" WIDTH oDlu:W1 HEIGHT h FONT "FormNorm" BACKCOLOR aBClr x += This.Period.Width @ y, x LABEL PerFrom VALUE ot:cPers WIDTH oDlu:W1 HEIGHT h FONT "FormNorm" BACKCOLOR aBClr CENTERALIGN x += This.PerFrom.Width + 2 @ y, x GETBOX PeriodFrom OBJ oGet WIDTH oDlu:D3 HEIGHT h VALUE CtoD("") ; ACTION {|| _wPost(5, , This.Name) } IMAGE "view" PICTURE Nil ; BUTTONWIDTH h FONT "FormNorm" BACKCOLOR BClr ; ON INIT {|og| og:lOnGotFocusSelect := .T. } oGet:OnF5 := {|og| _wPost(5, , og:cControlName) } // VK_F5 x += This.PeriodFrom.Width + 2 @ y, x LABEL PerTo VALUE ot:cPerp WIDTH oDlu:W1 HEIGHT h FONT "FormNorm" BACKCOLOR aBClr CENTERALIGN x += This.PerTo.Width + 2 @ y, x GETBOX PeriodTo OBJ oGet WIDTH oDlu:D3 HEIGHT h VALUE CtoD("") ; ACTION {|| _wPost(6, , This.Name) } IMAGE "view" PICTURE Nil ; BUTTONWIDTH h FONT "FormNorm" BACKCOLOR BClr ; ON INIT {|og| og:lOnGotFocusSelect := .T. } oGet:OnF5 := {|og| _wPost(6, , og:cControlName) } // VK_F5 y := This.Period.Row + This.Period.Height + nGh x := This.Period.Col @ y, x LABEL Times VALUE ot:cTime+":" WIDTH oDlu:W1 HEIGHT h FONT "FormNorm" BACKCOLOR aBClr x += This.Times.Width @ y, x LABEL TimeFrom VALUE ot:cPers WIDTH oDlu:W1 HEIGHT h FONT "FormNorm" BACKCOLOR aBClr CENTERALIGN x += This.TimeFrom.Width + 2 @ y, x GETBOX TimesFrom OBJ oGet WIDTH oDlu:D3 HEIGHT h VALUE space(6) ; PICTURE "@R 99:99:99" VALID {|og,hw2| bValid(og, hw2) } ; BUTTONWIDTH h FONT "FormNorm" BACKCOLOR BClr ; ON INIT {|og| og:lOnGotFocusSelect := .T. } x += This.TimesFrom.Width + 2 @ y, x LABEL TimeTo VALUE ot:cPerp WIDTH oDlu:W1 HEIGHT h FONT "FormNorm" BACKCOLOR aBClr CENTERALIGN x += This.TimeTo.Width + 2 @ y, x GETBOX TimesTo OBJ oGet WIDTH oDlu:D3 HEIGHT h VALUE space(6) ; PICTURE "@R 99:99:99" VALID {|og,hw2| bValid(og, hw2) } ; BUTTONWIDTH h FONT "FormNorm" BACKCOLOR BClr ; ON INIT {|og| og:lOnGotFocusSelect := .T. } ... :Event(10, {|ow,ky,cn| // OK button LOCAL o := Sys.Cargo, ot := Sys.Cargo:oBaseText LOCAL oObj := ow:Cargo:oObject, aTmp, cTmp, cDt1, cDt2, cFil, cObj LOCAL aObj := {}, cGm1 LOCAL aNam := {}, cGm2 LOCAL cNam := This.Events.Value LOCAL dDt1 := This.PeriodFrom.Value LOCAL dDt2 := This.PeriodTo.Value LOCAL cTm1 := This.TimesFrom.Value LOCAL cTm2 := This.TimesTo.Value LOCAL oBuf := oKeyData() oBuf:cOwn := "" oBuf:cObj := "" oBuf:cPer := "" oBuf:cTim := "" oBuf:lRowId := This.RowID.Value FOR EACH aTmp IN oObj:GetAll() ; AAdd(aObj, aTmp[1]) NEXT IF Empty(aObj) cObj := This.ObjNum.Value IF Empty(cObj) MsgStop("Empty objects !", "ERROR") This.ObjNum.SetFocus DO EVENTS RETURN Nil ELSE aObj := { Tr0(cObj, 12) } ENDIF ENDIF DO EVENTS IF Empty(dDt1) MsgStop("Period: Date error or empty date from !", "ERROR") This.PeriodFrom.SetFocus DO EVENTS RETURN Nil ENDIF IF Empty(dDt2) MsgStop("Period: Date error or empty date to !", "ERROR") This.PeriodTo.SetFocus DO EVENTS RETURN Nil ENDIF IF dDt1 > dDt2 MsgStop("Period: Date from > Date to !", "ERROR") This.PeriodFrom.SetFocus DO EVENTS RETURN Nil ENDIF cTm1 := left(trim(cTm1)+repl("0", 6), 6) cTm2 := left(trim(cTm2)+repl("0", 6), 6) cDt1 := hb_DtoC(dDt1, "YYYYMMDD")+cTm1 cDt2 := hb_DtoC(dDt2, "YYYYMMDD")+cTm2 lEmpty := Empty(Val(cTm1)) .and. Empty(Val(cTm2)) IF lEmpty cGm1 := Gmt2Utc(cDt1 , .F., .F.) cDt2 := hb_DtoC(dDt2+1, "YYYYMMDD")+cTm2 cGm2 := Gmt2Utc(cDt2 , .F., .F.) ELSE cGm1 := Gmt2Utc(cDt1, .F., .F.) cGm2 := Gmt2Utc(cDt2, .F., .F.) ENDIF cNam := trim(cNam) IF !Empty(cNam) FOR EACH cTmp IN hb_ATokens(cNam, ";") IF !Empty(cTmp) ; AAdd( aNam, upper(alltrim(cTmp)) ) ENDIF NEXT ENDIF IF Len(aObj) > 1 ; aObj := ASort(aObj) ENDIF oBuf:aObj := aClone(aObj) oBuf:cOwn := "" oBuf:cObj := "" oBuf:cPer := hb_DtoC(dDt1, "DD.MM.YYYY")+"."+" - "+hb_DtoC(dDt2, "DD.MM.YYYY")+"." IF !Empty(Val(cTm1)) .and. !Empty(Val(cTm2)) oBuf:cTim := Transform(cTm1, "@R 99:99:99")+" - "+Transform(cTm2, "@R 99:99:99") ENDIF oMain:StatusBar:Say(ot:cWait, 1) ; DO EVENTS cFil := Select_God( cGm1, cGm2, aObj, aNam, lEmpty ) oMain:StatusBar:Say("", 1) ; DO EVENTS IF !Empty(cFil) .and. hb_FileExists(cFil+".dbf") wSelectEvent(cFil, oBuf) ENDIF RETURN Nil }) ...
|
|
|
|
|
| постоянный участник
|
Пост N: 312
Зарегистрирован: 27.07.08
|
|
Отправлено: 26.07.21 14:04. Заголовок: SergKis пишет: s_nH..
SergKis пишет: цитата: | s_nHour - разница в часах локального времени и Utc времени, т.е. для нас: 3 - часа для летнего, 2 - для зимнего времени вычисляем при входе в программу |
| А как именно его вычисляют? Или всё же прописывают в файле INI?
|
|
|
|
| постоянный участник
|
Пост N: 3801
Зарегистрирован: 17.02.12
|
|
Отправлено: 26.07.21 15:26. Заголовок: Dr. Oldwarez пишет к..
Dr. Oldwarez пишет цитата: | как именно его вычисляют? |
| В тексте ф-ии IF s_nHour == Nil .or. lDate cTm1 := cTm2 := "" tDtm := hb_DateTime() tUtc := hb_TSToUTC( tDtm ) HB_TTOD( tDtm, @cTm1, "hh:mm:ss" ) HB_TTOD( tUtc, @cTm2, "hh:mm:ss" ) s_nHour := Val(cTm1) - Val(cTm2) ENDIF
|
|
|
|
| постоянный участник
|
Пост N: 313
Зарегистрирован: 27.07.08
|
|
Отправлено: 20.10.21 13:26. Заголовок: Итак, у меня всё, вр..
Итак, у меня всё, вроде работает, но вот у шефа с той же прогой файл listall_ics.xml, который должен использоваться для считывания данных из онлайн-календаря выдаёт такую вот хрень. Я так понимаю, это шеф неправильно ввёл свои имя пользователя и пароль. <?xml version="1.0" encoding="utf-8"?> <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"> <s:exception>Sabre\DAV\Exception\NotAuthenticated</s:exception> <s:message>Username or password does not match</s:message> <s:sabredav-version>1.8.12</s:sabredav-version> </d:error>
|
|
|
|
| постоянный участник
|
Пост N: 1729
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.10.21 19:46. Заголовок: Dr. Oldwarez пишет: ..
Dr. Oldwarez пишет: цитата: | Я так понимаю, это шеф неправильно ввёл свои имя пользователя и пароль. |
| Да
|
|
|
|
| постоянный участник
|
Пост N: 314
Зарегистрирован: 27.07.08
|
|
Отправлено: 14.12.21 18:08. Заголовок: И снова здравствуйте..
И снова здравствуйте! Там у шефа был пароль с запретным символом, попросил заменить, потом в условии фильтра немного порылся. Вроде, работает, но только на стационарных компах. Если событие онлайн-календаря вводят с телефона - жутко коверкает даты и время, кроме конечной даты. Стартовая дата всегда - 27 октября 1996 год. Время коверкает в обеих случаях. В чём разница между событием, введённым с компа и таковым с мобилки? IF aCalStr[nBuf]="DTSTART" cDateTime:=SUBSTR(aCalStr[nBuf],AT(":",aCalStr[nBuf])+1) dStartDate:=STOD(LEFT(cDateTime,8)) cStartTime:=STRZERO(VAL(SUBSTR(cDateTime,10,2))+nTimeZone,2)+":"+SUBSTR(cDateTime,12,2) Тут, как видите, в качестве разделителя используется двоеточие. Возможно, в мобильниках какой-то другой символ, но как это влияет на календарь? Upd: с мобильника то же двоеточие, но даты искажаются до 1916, 1917 года. Upd2: в случае, если событие создано на андроидном мобильнике, но потом изменено и сохранено на компьютере - всё в порядке. Дата передаётся правильно, даже если меняют только текст.
|
|
|
Ответов - 174
, стр:
1
2
3
4
5
6
7
8
9
All
[только новые]
|
|