2014/12/07

Just a Note: GCALDaemon 1.0 alpha 17 for Google Calendar API V3

Google 公告於 2014/11/17 停止支援 Calendar API v2,請使用 API v3。
As announced by Google, Google Calendar API v2 is a subject to the Deprecation Policy and was shut down on November 17, 2014. Please use APIv3 instead.

所以便試著將 GCALDaemon 提升至 API v3。
So I try to upgrade Google Calendar API to v3 for GCALDaemon.

我只有針對 Google Calendar 和 Rainlendar 同步處理的部分,修改了兩個功能:
1. config-editor 中的檔案同步設定。
2. sync-now (手動同步)
I only modified two function for synchronizing calendar events between Google Calendar & Rainlendar.
1. config-editor for File synchronizer.
2. sync-now (manually sync)

修改後的程式可以在 github 取得。
The modified source can be download from github.

在 API v3 中,有兩項比較顯著的變更:
1. 授權方式:必須使用 OAuth 2.0,而不支援其他的授權方式。
2. Google 日曆的 private URL:無法透過 API 取得 private URL 了。
For API v3, there are two significant changes:
1. authorize method: Application must use OAuth 2.0 to authorize requests. No other authorization protocols are supported.
2. calendar private URL: We can't fetch calendar private URL from API anymore.

所以在開始使用新版 GCALDaemon 前,需要進行以下步驟。
So we have to follow steps below to use new GCALDaemon.

1. 從 My Google Drive 下載 GCALDaemon 並解壓縮。
1. Download GCALDaemon from My Google Drive and unzip.

2. 啟用 Google Calendar API。
2. Enable Google Calendar API.
(1) 開啟 Google Develop Console 並新增專案。
(1) Go to Google Develop Console and create a project.

(2) 啟用 Calendar API。
(2) Enable Calendar API.

(3) 新增 Client ID。
(3) Create Client ID.




(4) 下載 JSON,並更名為 client_secrets.json。
(4) Download JSON and rename to client_secrets.json.

(5) 將 client_secrets.json 放到 GCALDaemon/etc 目錄中。
(5) Put client_secrets.json into GCALDaemon/etc folder.

3. 執行 bin/config-editor-new.bat (或  bin/config-editor-new.sh),點選 "File synchronizer"。直接點選 "+New" 新增欲同步的日曆,不需要做 Account 的新增。
3. Execute bin/config-editor-new.bat (or bin/config-editor-new.sh) and click "File synchronizer", Just click "+New" to add Calendar you want to sync. Don't need to add Google Accounts.

4. 點選 "Refresh" 取得 Google Calendar 清單,此時會開啟瀏覽器,並要求授予管理日曆的權限。同意後,便可在下拉選單中看到你的日曆清單。
4. Click "Refresh" to fetch Google Calendar list from your default logged-in Google Account. There will show authorizing page in browser and you should click accept. Then you can get calendar list into combo box.



5. 選擇要同步的日曆,並指定對應的 iCal 檔案路徑。
5. Select the Calendar you want to sync and specify the iCal file location. Click OK.

6. 取得並複製該日曆的 ICAL 私人網址,只要保留 /calendar/ical/xxxxxxx/private-yyyyyyyy/basic.ics 的部分。
6. Open browser to get Google Calendar private URL. Copy the private address of ICAL and only keep the URL like /calendar/ical/xxxxxxx/private-yyyyyyyy/basic.ics

7. 回到 Config Editor 並修改步驟 5 新增的日曆,修改 Google Calendar 欄位,輸入步驟 6 取得的 URL。
7. Back to Config Editor and edit the calendar created on step 5. Change the Google Calender field to /calendar/ical/xxxxxxx/private-yyyyyyyy/basic.ics from step 6.


8. 儲存並離開 Config Edit。
8. Save and Exit config-editor.

9. 執行 bin/sync-now-new.bat (或 bin/sync-now-new.sh ) 進行同步。
9. Now you can execute bin/sync-now-new.bat (or bin/sync-now-new.sh ) to synchronize Google Calendar and the iCal file for Rainlendar.

59 則留言:

  1. 測試成功,但請問同步是不是變成一定要執行 bin/sync-now-new.bat

    回覆刪除
  2. 是的,因為我原本就沒有掛上 GCALDaemon 的 service,而是透過 Windows 排程每 5 或 10 分鐘同步一次,
    所以我只有大致確認 bin/sync-now-new.bat 的功能是正常的。

    回覆刪除
  3. 回覆
    1. I also get this.

      DEBUG | New event XXXX found in the local calendar.
      DEBUG | Connection refused, reconnecting...
      DEBUG | Connecting to Google...
      DEBUG | Connection refused, reconnecting...
      DEBUG | Connecting to Google...

      刪除
    2. It seems that the private ICAL URL of Google Calendar is wrong.

      The private ICAL URL from Google Calendar is like https://www.google.com/calendar/ical/xxxxxxx/private-yyyyyyyy/basic.ics, but we only need partial of it. (without 'https://www.google.com')

      So in step 5, we need to change Google Calender field to /calendar/ical/xxxxxxx/private-yyyyyyyy/basic.ics

      刪除
    3. Hello,
      I am getting a new error now. A null pointer exception. See Below:

      DEBUG | Calendar loaded successfully (203 bytes).
      DEBUG | Starting Google Calendar synchronizer...
      FATAL | Fatal service error!
      java.lang.NullPointerException
      at org.gcaldaemon.core.ICalUtilities.getNewEvents(ICalUtilities.java:267)
      at org.gcaldaemon.core.Synchronizer.syncronizeNow(Synchronizer.java:218)
      at org.gcaldaemon.core.Configurator.synchronizeNow(Configurator.java:1070)
      at org.gcaldaemon.core.file.OfflineFileListener.run(OfflineFileListener.java:61)
      INFO | Synchronization finished.
      E:\Software\GCALDaemon\bin>

      Any ideas? Thanks in advance

      刪除
    4. I check the exception and I'm pretty sure that you run on old version.
      Because there is no chance to threw exception at ICalUtilities.java line 267 in new version.

      There should be a new .bat/.sh named sync-now-new.bat/sync-now-new.sh and maybe you use the old one.

      刪除
    5. Hello, I use the new one but i will try downloading it again.

      刪除
    6. Please download new gcal-daemon.jar (https://drive.google.com/file/d/0B0o-LAlImy2kRThTWHRiZFZCZUE/view?usp=sharing) and replace it in GCALDaemon/lib folder.
      Or re-download full zip from my article.

      I don't try to re-produce the case and just prevent the NullPointerException.

      刪除
  4. 請問我執行到步驟三的時候,產生 unable to verify account (null)!
    是怎麼回事??

    回覆刪除
    回覆
    1. 不好意思,看到你的提問才發現我步驟的編號都亂掉了,已經重新編號。

      不太確定你真正出錯的是哪一步,如果是按下 Refresh 發生錯誤,那比較有可能的原因就是 client_secrets.json 有問題(檔名不對、或是放的位置不對),或者請重新檢視步驟 2. 啟用 Google Calendar API 的每一小步有沒有哪裡遺漏了。

      另外請確認執行的是 config-editor-new.bat,才會使用新的 calendar api。

      刪除
    2. 是我的錯!!我的檔案忘記改名字了,謝謝你,測試OK!!

      刪除
    3. 不過,我也發現一個問題,就是我在建立ical檔案位置時,他在gcal-daemon.cfg檔案中,路徑是改在file.ical.path2
      這會導致同步時他還是在搜尋file.ical.path的路徑,而導致ics檔案無法建立,實際如下,我得自己修正才能使用之!!

      # Full path of the local iCalendar file (don't include backslash characters!)
      file.ical.path=/google1.ics

      # URL (without hostname) of the Google Calendar's private ical file
      file.private.ical.url=

      # Full path of the local iCalendar file (don't include backslash characters!)
      file.ical.path2=D\:/\u5783\u573e\u5340/\u884c\u4e8b\u66c6/GCALDaemon_1.0_alpha17/GCALDaemon/google.ics

      刪除
    4. 你新增了一筆資料後,就可以把軟體原本預設的那筆資料刪掉了。

      刪除
  5. 非常感謝您!! 之前就已經有用 GCALDaemon 在同步 google calendar ,後來突然不能使用才找到您這篇,
    測試兩次後終於成功了!!大大感謝!

    回覆刪除
  6. Hi, I'm trying to sync again with google and found your GCALDaemon's fork, thanks for it!


    However I'm having some issues, maybe you can give me a light?


    INFO | Mail terminal disabled.
    DEBUG | File loaded successfully (502804 bytes).
    Exception in thread "File listener" java.lang.NoClassDefFoundError: com/google/api/client/json/JsonFactory
    at org.gcaldaemon.core.GCalUtilities.loadCalendar(GCalUtilities.java:196)
    at org.gcaldaemon.core.Configurator.synchronizeNow(Configurator.java:1016)
    at org.gcaldaemon.core.file.OfflineFileListener.run(OfflineFileListener.java:61)
    Caused by: java.lang.ClassNotFoundException: com.google.api.client.json.JsonFactory
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 3 more

    I'm using OSX

    Thanks!

    回覆刪除
    回覆
    1. It seems like you use the original .sh file.
      There are some dependency libraries changed for Google Calendar API V3. So we have to modify the batch/shell script to include new libraries and to exclude old dependencies.

      I'll try it on OSX later after work. If it works, I'll reply here.

      刪除
    2. I put two shell script config-editor-new.sh & sync-now-new.sh in my google drive.
      https://drive.google.com/open?id=0B0o-LAlImy2kYlRsZTZJZ2JXN1U&authuser=0

      Please download, unzip the file and put the two .sh files into GCALDaemon/bin folder.
      Then you can use the new shell script to config and sync ical file.

      刪除
  7. Hi Lancelot,

    Thanks for your great work.

    I just launched sync-now-new.sh ibut everything stopped after the following:

    INFO | GCALDaemon V1.0 alpha 17 starting...
    INFO | RSS/ATOM feed converter disabled.
    INFO | Local time zone is Central European Time.
    INFO | Start listening file /home/me/personalCalendar.ics...
    INFO | File listener started successfully.
    INFO | Offline file synchronization enabled.

    Do you know by any chance how I can fix this?

    回覆刪除
    回覆
    1. There should be some other information show after "INFO | Offline file synchronization enabled."
      Whether it success or not, it will show "INFO | Synchronization finished." at the end.

      If there are no additional logs/exceptions, I think I couldn't figure out what happened.

      刪除
    2. No there's nothing else. It's as if it's getting stuck.
      What can I do to make this more verbose?

      刪除
    3. You can follow steps below to enable the DEBUG mode to get more information. But I'm not sure if it's useful.
      1. Open GCALDeamon/conf/logger-config.cfg in text editor like vi.
      2. Find the line start with "log4j.rootLogger"
      3. Edit the line from "log4j.rootLogger=INFO, file, console" to "log4j.rootLogger=DEBUG, file, console"
      4. Run sync-now-new.sh again then there should be more DEBUG logs in console and bin/log/gcal-daemon.log.

      The DEBUG logs will contain the private URL of your ICAL and all calendar events.
      So if you want attach logs here, please remove the sensitive data first.

      刪除
    4. Just found something weird

      The 4th line says:

      INFO | Start listening file /home/myself/personalCalendar.ics...

      I thought that would mean my local file personalCalendar.ics would be uploaded to my google account. Is that right?

      So what I just tried is I deleted my local file and launched sync-now-new.sh. Surprisingly enough this shell recreated my personalCalendar.ics. How's that possible?

      刪除
    5. If there is an existing personalCalendar.ics, GCALDeamon should sync Google Calendar and the file.
      In your case, maybe there is something wrong when GCALDeamon parsing the existing personalCalendar.ics.

      刪除
    6. So what I did is erase all my calendars on my google account in order not to have any interference. Then I completely went through the GCALDaemon procedure again.

      But I end up having the same problem. I really don't understand where this comes from.

      Here is what I get in my log:

      INFO | GCALDaemon V1.0 alpha 17 starting...
      INFO | RSS/ATOM feed converter disabled.
      INFO | Local time zone is Central European Time.
      INFO | Start listening file /home/myself/google.ics...
      INFO | File listener started successfully.
      INFO | Offline file synchronization enabled.
      DEBUG | >> "GET /calendar/ical/myself%40gmail.com/private-35c0eea54230500eedbf3c03eca7600f/basic.ics HTTP/1.1[\r][\n]"
      DEBUG | >> "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; hu; rv:1.8.0.8) Gecko/20061025 Thunderbird/1.5.0.8[\r][\n]"
      DEBUG | >> "Host: www.google.com[\r][\n]"
      DEBUG | >> "[\r][\n]"
      DEBUG | << "HTTP/1.1 200 OK[\r][\n]"
      DEBUG | << "Expires: Fri, 01 Jan 1990 00:00:00 GMT[\r][\n]"
      DEBUG | << "Date: Sun, 15 Mar 2015 12:47:56 GMT[\r][\n]"
      DEBUG | << "Content-Type: text/calendar; charset=UTF-8[\r][\n]"
      DEBUG | << "Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]"
      DEBUG | << "Pragma: no-cache[\r][\n]"
      DEBUG | << "X-Content-Type-Options: nosniff[\r][\n]"
      DEBUG | << "X-Frame-Options: SAMEORIGIN[\r][\n]"
      DEBUG | << "X-XSS-Protection: 1; mode=block[\r][\n]"
      DEBUG | << "Server: GSE[\r][\n]"
      DEBUG | << "Alternate-Protocol: 443:quic,p=0.5[\r][\n]"
      DEBUG | << "Accept-Ranges: none[\r][\n]"
      DEBUG | << "Vary: Accept-Encoding[\r][\n]"
      DEBUG | << "Transfer-Encoding: chunked[\r][\n]"
      DEBUG | << "2"
      DEBUG | << "a"
      DEBUG | << "3"
      DEBUG | << "[\r]"
      DEBUG | << "[\n]"
      DEBUG | << "BEGIN:VCALENDAR[\r][\n]"
      DEBUG | << "PRODID:-//Google Inc//Google Calendar 70.9054//EN[\r][\n]"
      DEBUG | << "VERSION:2.0[\r][\n]"
      DEBUG | << "CALSCALE:GREGORIAN[\r][\n]"
      DEBUG | << "METHOD:PUBLISH[\r][\n]"
      DEBUG | << "X-WR-CALNAME:myself[\r][\n]"
      DEBUG | << "X-WR-TIMEZONE:Europe/Paris[\r][\n]"
      DEBUG | << "BEGIN:VTIMEZONE[\r][\n]"
      DEBUG | << "TZID:CET[\r][\n]"
      DEBUG | << "X-LIC-LOCATION:CET[\r][\n]"
      DEBUG | << "BEGIN:DAYLIGHT[\r][\n]"
      DEBUG | << "TZOFFSETFROM:+0100[\r][\n]"
      DEBUG | << "TZOFFSETTO:+0200[\r][\n]"
      DEBUG | << "TZNAME:CEST[\r][\n]"
      DEBUG | << "DTSTART:19700329T020000[\r][\n]"
      DEBUG | << "RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU[\r][\n]"
      DEBUG | << "END:DAYLIGHT[\r][\n]"
      DEBUG | << "BEGIN:STANDARD[\r][\n]"
      DEBUG | << "TZOFFSETFROM:+0200[\r][\n]"
      DEBUG | << "TZOFFSETTO:+0100[\r][\n]"
      DEBUG | << "TZNAME:CET[\r][\n]"
      DEBUG | << "DTSTART:19701025T030000[\r][\n]"
      DEBUG | << "RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU[\r][\n]"
      DEBUG | << "END:STANDARD[\r][\n]"
      DEBUG | << "END:VTIMEZONE[\r][\n]"
      DEBUG | << "BEGIN:VEVENT[\r][\n]"
      DEBUG | << "DTSTART:20141020T070000Z[\r][\n]"
      DEBUG | << "DTEND:20141020T143000Z[\r][\n]"
      DEBUG | << "DTSTAMP:20150315T124756Z[\r][\n]"
      DEBUG | << "UID:TS1-76df5a38-3b6f-4e38-937d-cc4639802c9c[\r][\n]"
      DEBUG | << "CREATED:20150312T"

      Any help would be greatly welcome.

      刪除
    7. Let me confirm the situation first.
      If there is no file in folder, gcaldaemon will pull the data from google calendar, but if there is already a file, gcaldaemon will stuck.
      Is it right?

      刪除
    8. I erased every thing and did it all over again from scratch.

      Here is the first part of the message i get:

      INFO | Configurator | GCALDaemon V1.0 alpha 17 starting...
      INFO | Configurator | RSS/ATOM feed converter disabled.
      INFO | Configurator | Local time zone is Central European Time.
      INFO | OnlineFileListener | Start listening file /home/myself/personalCalendar.ics...
      INFO | OnlineFileListener | File listener started successfully.
      INFO | OnlineFileListener | Offline file synchronization enabled.
      DEBUG | CalendarParserImpl | [-3]
      DEBUG | CalendarParserImpl | [BEGIN]
      DEBUG | CalendarParserImpl | [58]
      DEBUG | CalendarParserImpl | [-3]
      DEBUG | CalendarParserImpl | [VCALENDAR]
      DEBUG | CalendarParserImpl | [10]
      DEBUG | CalendarParserImpl | [-3]
      DEBUG | CalendarParserImpl | Property [VERSION]
      DEBUG | CalendarParserImpl | Aborting absorbing extra whitespace [Error at line 3: Expected [10], read [-3]]
      DEBUG | CalendarParserImpl | Property [X-WR-CALNAME]
      DEBUG | CalendarParserImpl | Aborting absorbing extra whitespace [Error at line 4: Expected [10], read [-3]]
      DEBUG | CalendarParserImpl | Property [PRODID]
      DEBUG | CalendarParserImpl | Aborting absorbing extra whitespace [Error at line 5: Expected [10], read [-3]]
      DEBUG | CalendarParserImpl | Property [X-WR-TIMEZONE]
      DEBUG | CalendarParserImpl | Aborting absorbing extra whitespace [Error at line 6: Expected [10], read [-3]]
      DEBUG | CalendarParserImpl | Property [X-WR-CALDESC]
      DEBUG | CalendarParserImpl | Aborting absorbing extra whitespace [Error at line 7: Expected [10], read [-3]]
      DEBUG | CalendarParserImpl | Property [CALSCALE]
      DEBUG | CalendarParserImpl | Aborting absorbing extra whitespace [Error at line 8: Expected [10], read [-3]]

      刪除
    9. the end of the message is

      (...)

      DEBUG | header | >> "GET /calendar/ical/myself%40gmail.com/private-735396cb8bf070ad05948f88647f9214/basic.ics HTTP/1.1[\r][\n]"
      DEBUG | header | >> "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; hu; rv:1.8.0.8) Gecko/20061025 Thunderbird/1.5.0.8[\r][\n]"
      DEBUG | header | >> "Host: www.google.com[\r][\n]"
      DEBUG | header | >> "[\r][\n]"
      DEBUG | header | << "HTTP/1.1 200 OK[\r][\n]"
      DEBUG | header | << "Expires: Fri, 01 Jan 1990 00:00:00 GMT[\r][\n]"
      DEBUG | header | << "Date: Mon, 16 Mar 2015 21:19:32 GMT[\r][\n]"
      DEBUG | header | << "Content-Type: text/calendar; charset=UTF-8[\r][\n]"
      DEBUG | header | << "Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]"
      DEBUG | header | << "Pragma: no-cache[\r][\n]"
      DEBUG | header | << "X-Content-Type-Options: nosniff[\r][\n]"
      DEBUG | header | << "X-Frame-Options: SAMEORIGIN[\r][\n]"
      DEBUG | header | << "X-XSS-Protection: 1; mode=block[\r][\n]"
      DEBUG | header | << "Server: GSE[\r][\n]"
      DEBUG | header | << "Alternate-Protocol: 443:quic,p=0.5[\r][\n]"
      DEBUG | header | << "Accept-Ranges: none[\r][\n]"
      DEBUG | header | << "Vary: Accept-Encoding[\r][\n]"
      DEBUG | header | << "Transfer-Encoding: chunked[\r][\n]"
      DEBUG | content | << "b"
      DEBUG | content | << "f"
      DEBUG | content | << "[\r]"
      DEBUG | content | << "[\n]"
      DEBUG | content | << "BEGIN:VCALENDAR[\r][\n]"
      DEBUG | content | << "PRODID:-//Google Inc//Google Calendar 70.9054//EN[\r][\n]"
      DEBUG | content | << "VERSION:2.0[\r][\n]"
      DEBUG | content | << "CALSCALE:GREGORIAN[\r][\n]"
      DEBUG | content | << "METHOD:PUBLISH[\r][\n]"
      DEBUG | content | << "X-WR-CALNAME:myself[\r][\n]"
      DEBUG | content | << "X-WR-TIMEZONE:Europe/Paris[\r][\n]"
      DEBUG | content | << "END:VCALENDAR[\r][\n]"
      DEBUG | content | << "[\r]"
      DEBUG | content | << "[\n]"
      DEBUG | content | << "0"
      DEBUG | content | << "[\r]"
      DEBUG | content | << "[\n]"
      DEBUG | content | << "[\r]"
      DEBUG | content | << "[\n]"

      (...)

      FATAL | OnlineFileListener | Fatal service error!
      [1 ] java.lang.NullPointerException
      [2 ] at org.gcaldaemon.core.ICalUtilities.getNewEvents(ICalUtilities.java:267)
      [3 ] at org.gcaldaemon.core.Synchronizer.syncronizeNow(Synchronizer.java:218)
      [4 ] at org.gcaldaemon.core.Configurator.synchronizeNow(Configurator.java:1070)
      [5 ] at org.gcaldaemon.core.file.OfflineFileListener.run(OfflineFileListener.java:61)
      INFO | OnlineFileListener | Synchronization finished.

      刪除
    10. Please download new gcal-daemon.jar (https://drive.google.com/file/d/0B0o-LAlImy2kRThTWHRiZFZCZUE/view?usp=sharing) and replace it in GCALDaemon/lib folder.
      Or re-download full zip from my article.

      I don't try to re-produce the case and just prevent the NullPointerException.

      刪除
    11. A big Thank You. I did it all over again and this time it worked!
      Thanks

      刪除
    12. You're welcome. The information you provided is also a great help.

      刪除
    13. My calendar holds a little more than 500 events. I've got two annoying problems:

      1. Uploading my local .ics file to google calendar using sync-now-new.sh is pretty slow. It takes about one hour every time. Am I doing something wrong or is this about the right amount of time given the number of events in my calendar?

      2. I end up having my appointments twice in my google calendar.

      --

      刪除
    14. The log trace works quickly until it says:

      -------------------------------------------------------------------------------------------------
      DEBUG | Property [DTSTAMP]
      DEBUG | Clearing timezone [null]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10112: Expected [10], read [-3]]
      DEBUG | Property [UID]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10113: Expected [10], read [-3]]
      DEBUG | Property [DTSTART]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10114: Expected [10], read [-3]]
      DEBUG | Property [DTEND]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10115: Expected [10], read [-3]]
      DEBUG | Property [SUMMARY]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10116: Expected [10], read [-3]]
      DEBUG | Property [DESCRIPTION]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10117: Expected [10], read [-3]]
      DEBUG | Property [CATEGORIES]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10118: Expected [10], read [-3]]
      DEBUG | [58]
      DEBUG | [-3]
      DEBUG | [10]
      DEBUG | [-3]
      DEBUG | Property [ACTION]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10120: Expected [10], read [-3]]
      DEBUG | Property [DESCRIPTION]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10121: Expected [10], read [-3]]
      DEBUG | Property [TRIGGER]
      DEBUG | Clearing timezone [null]
      DEBUG | Redundant [P] token ignored.
      DEBUG | Redundant [T] token ignored.
      DEBUG | Clearing timezone [null]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10122: Expected [10], read [-3]]
      DEBUG | [58]
      DEBUG | [-3]
      DEBUG | [VALARM]
      DEBUG | [10]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10123: Expected [10], read [-3]]
      DEBUG | [58]
      DEBUG | [-3]
      DEBUG | [VEVENT]
      DEBUG | [10]
      DEBUG | Aborting absorbing extra whitespace [Error at line 10124: Expected [10], read [-3]]
      DEBUG | [58]
      DEBUG | [-3]
      DEBUG | [VCALENDAR]
      DEBUG | [-3]
      DEBUG | [BEGIN]
      DEBUG | [58]
      DEBUG | [-3]
      DEBUG | [VCALENDAR]
      DEBUG | [10]
      DEBUG | [-3]
      DEBUG | Property [PRODID]
      DEBUG | Aborting absorbing extra whitespace [Error at line 3: Expected [10], read [-3]]
      DEBUG | Property [VERSION]
      DEBUG | Aborting absorbing extra whitespace [Error at line 4: Expected [10], read [-3]]
      DEBUG | Property [CALSCALE]
      DEBUG | Aborting absorbing extra whitespace [Error at line 5: Expected [10], read [-3]]
      DEBUG | Property [METHOD]
      DEBUG | Aborting absorbing extra whitespace [Error at line 6: Expected [10], read [-3]]
      DEBUG | Property [X-WR-CALNAME]
      DEBUG | Aborting absorbing extra whitespace [Error at line 7: Expected [10], read [-3]]
      DEBUG | Property [X-WR-TIMEZONE]
      DEBUG | Aborting absorbing extra whitespace [Error at line 8: Expected [10], read [-3]]
      DEBUG | [58]
      DEBUG | [-3]
      DEBUG | [VCALENDAR]
      ----------------------------------------------------------------------------------------

      And then the script seems to be waiting. For one hour, no log is produced.

      After about an hour, then the ics file is being uploaded. One can see the progress bar animating.

      Then the log trace starts again:

      -------------------------------------------------------------------------------------------------------
      WARN | GCalUtilitiesV3 | Unable to insert event ([10/24] Reunion hebd...)!
      com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
      {
      "code" : 400,
      "errors" : [ {
      "domain" : "global",
      "message" : "Missing time zone definition for start time.",
      "reason" : "required"
      } ],
      "message" : "Missing time zone definition for start time."
      }
      -----------------------------------------------------------------------------------------------

      This warning message repeats about 10 times. This seems to correspond to recurrent events in my calendar.

      刪除
    15. Then I get the final log trace:

      -----------------------------------------------------------------------------
      DEBUG | header | >> "GET /calendar/ical/myself%40gmail.com/private-35c0eea54230500eedbf3c03eca7600f/basic.ics HTTP/1.1[\r][\n]"
      DEBUG | header | >> "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; hu; rv:1.8.0.8) Gecko/20061025 Thunderbird/1.5.0.8[\r][\n]"
      DEBUG | header | >> "Host: www.google.com[\r][\n]"
      DEBUG | header | >> "[\r][\n]"
      DEBUG | header | << "HTTP/1.1 200 OK[\r][\n]"
      DEBUG | header | << "Expires: Fri, 01 Jan 1990 00:00:00 GMT[\r][\n]"
      DEBUG | header | << "Date: Sat, 02 May 2015 12:54:22 GMT[\r][\n]"
      DEBUG | header | << "Content-Type: text/calendar; charset=UTF-8[\r][\n]"
      DEBUG | header | << "Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]"
      DEBUG | header | << "Pragma: no-cache[\r][\n]"
      DEBUG | header | << "X-Content-Type-Options: nosniff[\r][\n]"
      DEBUG | header | << "X-Frame-Options: SAMEORIGIN[\r][\n]"
      DEBUG | header | << "X-XSS-Protection: 1; mode=block[\r][\n]"
      DEBUG | header | << "Server: GSE[\r][\n]"
      DEBUG | header | << "Alternate-Protocol: 443:quic,p=1[\r][\n]"
      DEBUG | header | << "Accept-Ranges: none[\r][\n]"
      DEBUG | header | << "Vary: Accept-Encoding[\r][\n]"
      DEBUG | header | << "Transfer-Encoding: chunked[\r][\n]"
      DEBUG | content | << "1"
      DEBUG | content | << "a"
      DEBUG | content | << "8"
      DEBUG | content | << "0"
      DEBUG | content | << "[\r]"
      DEBUG | content | << "[\n]"
      DEBUG | content | << "BEGIN:VCALENDAR[\r][\n]"
      DEBUG | content | << "PRODID:-//Google Inc//Google Calendar 70.9054//EN[\r][\n]"
      DEBUG | content | << "VERSION:2.0[\r][\n]"
      DEBUG | content | << "CALSCALE:GREGORIAN[\r][\n]"
      DEBUG | content | << "METHOD:PUBLISH[\r][\n]"
      DEBUG | content | << "X-WR-CALNAME:myself-work[\r][\n]"
      DEBUG | content | << "X-WR-TIMEZONE:Europe/Paris[\r][\n]"
      DEBUG | content | << "BEGIN:VEVENT[\r][\n]"
      DEBUG | content | << "DTSTART:20150514T180000Z[\r][\n]"
      DEBUG | content | << "DTEND:20150514T190000Z[\r][\n]"
      DEBUG | content | << "DTSTAMP:20150502T125422Z[\r][\n]"
      DEBUG | content | << "UID:nogmt9ol5onb9bh5ljkd1eg88o@google.com[\r][\n]"
      DEBUG | content | << "CREATED:20150502T125419Z[\r][\n]"
      DEBUG | content | << "DESCRIPTION:<2015-05-14 Thu 20:00>[0xe2][0x80][0x93]<2015-05-14 Thu 21:00>[\r][\n]"
      DEBUG | content | << "LAST-MODIFIED:20150502T125419Z[\r][\n]"

      (...)

      DEBUG | content | << "END:VEVENT[\r][\n]"
      DEBUG | content | << "END:VCALENDAR[\r][\n]"
      DEBUG | content | << "[\r]"
      DEBUG | content | << "[\n]"
      DEBUG | content | << "0"
      DEBUG | content | << "[\r]"
      DEBUG | content | << "[\n]"
      DEBUG | content | << "[\r]"
      DEBUG | content | << "[\n]"

      INFO | OnlineFileListener | Synchronization finished.
      ---------------------------------------------------------------------------------------------------------

      Please help me improve the process which takes more than one hour.

      刪除
    16. Thank you for your feedback. Sorry that I have been busy with work recently.
      I'll try to figure out this problem on my own time.

      刪除
    17. Ok. Thank You.

      Looking forward to your help

      刪除
  8. 你好,這篇很有幫助,已同步成功。

    想請教一個問題,從第一個連結 github 下載的 GCALDaemon-master 和 從第二個連結下載的 GCALDaemon 有何不同?

    回覆刪除
    回覆
    1. github 放的是原始程式碼,Google Drive 則是編譯好的執行碼。

      刪除
    2. 我剛剛才發現原始 source 也包含 binary,一併更新至 github 了。

      刪除
  9. 你好,感謝你的分享,我執行bin/sync-now-new.bat 後出現,warning setPermissionsToOwnerOnly, warning> unable to change permissions for everybody, unable to change permissions for owner,這問題改怎麼解決呢

    回覆刪除
    回覆
    1. 目前查到的原因:
      google api 會寫一個 StoredCredential 檔案到 C:\Users\你的使用者名稱\.store\calendar_sample\ 目錄下,應該是這個檔案的權限問題。

      解決方式可能要試一下幾種方式(擇一):
      1. 使用管理者權限執行 sync-now-new.bat 或是使用一般權限執行 sync-now-new.bat。(因為不確定權限不一致的原因,所以兩種方式要試試看)
      2. 刪掉 StoredCredential,然後重新從步驟 3 開始做起,因為 StoredCredential 被刪除,所以會再要求一次授權。

      刪除
    2. 版大您好我找不到GCALDaemon/etc路徑,無法將client_secrets.json 放到 GCALDaemon/etc 目錄中。

      刪除
    3. 上次更新誤植了連結,請重新下載。下載後是 zip 檔,解壓縮後便可看到 etc 目錄。

      刪除
    4. 你好,第一個方法我之前有試過了,一樣出現這樣的問題。第二個方法剛剛嘗試過了一次後,一樣出現同樣的問題。另外StoredCredential 檔案在我電腦上它是存到 GCALDaemon/bin/store/ 裡的,我不知道跟這有沒有關係,因為用的是公司電腦。
      這是執行bin/sync-now-new.bat 後出現的警告 https://www.dropbox.com/s/or0mr3ajw458tye/IMAG0630.jpg?dl=0

      刪除
    5. 我的 StoredCredential 檔案也是在 GCALDaemon/bin/store/ 裡,跟存放路徑沒有甚麼關係。
      以訊息來看是指 C:\GCALDaemon\bin\store 這個目錄的權限有問題,如果把 store 目錄整個刪除再試試看呢?

      刪除
    6. 把 store 目錄整個刪除後再試,一樣出現這樣的訊息。把每個使用者使用 StoredCredential 檔案的權限設定最高權限後,一樣還是出現這樣的問題。

      刪除
    7. 這只是 warning,不影響同步的處理。
      看起來是 Google API 試圖去變更目錄權限。

      刪除
  10. 作者已經移除這則留言。

    回覆刪除
  11. Thank you for your patch. After configuring things as described in your post, I launch standalone-start.bat and see a WARN "Incompatible Gmail interface - unable to download contacts!" in the logs. Is that expected? Should this now work with GMail address books as described at http://gcaldaemon.sourceforge.net/usage4.html?

    回覆刪除
    回覆
    1. I think that is expected. I only modified the config-editor (file synchronizer) & sync-now for Google Calendar.

      刪除
  12. Hello,
    I just upgraded from GCALDaemon_1.0_alpha17 to GCALDaemon_1.0_alpha18 but still get the error

    Jun 16, 2015 4:04:21 PM com.google.api.client.util.store.FileDataStoreFactory se
    tPermissionsToOwnerOnly
    WARNING: unable to change permissions for everybody: C:\Program Files (x86)\Wind
    ows Calendar\GCALDaemon\bin\store
    Jun 16, 2015 4:04:21 PM com.google.api.client.util.store.FileDataStoreFactory se
    tPermissionsToOwnerOnly
    WARNING: unable to change permissions for owner: C:\Program Files (x86)\Windows
    Calendar\GCALDaemon\bin\store

    I already set the permissions for this folder C:\Program Files (x86)\Windows
    Calendar\GCALDaemon\bin\store to Full Access for everyone but that does not help. I still get this error.

    回覆刪除
  13. 您好,
    我刚刚从GCALDaemon_1.0_alpha17升级到GCALDaemon_1.0_alpha18,但仍然得到错误

    2015年6月16日下午4时04分21秒com.google.api.client.util.store.FileDataStoreFactory SE
    tPermissionsToOwnerOnly
    警告:无法改变大家的权限:C:\ Program Files文件(x86)的\风
    OWS日历\ GCALDaemon\ BIN\店
    2015年6月16日下午4时04分21秒com.google.api.client.util.store.FileDataStoreFactory SE
    tPermissionsToOwnerOnly
    警告:无法更改权限的所有者:C:\ Program Files文件(x86)的\ Windows下
    日历\ GCALDaemon\ BIN\店

    我已经设置权限此文件夹C:\ Program Files文件(x86)的\ Windows下
    日历\ GCALDaemon\ BIN\店为大家完全访问,但是这并没有帮助。我仍然得到这个错误。

    回覆刪除
  14. Hi

    I have been getting this error. Did google change something with authorization?

    [1 ] com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
    {
    "error" : "invalid_grant"
    }

    I tried to recreate the token a few times. Any Ideas? I am using the new v18.

    Thanks

    回覆刪除
    回覆
    1. I did a complete reinstall and deleted my google projects. Then I created a new google project and token.

      The program is working again.

      刪除
  15. Hi! thanks for taking the time to modify this. I'm having this issue right now:

    .
    DEBUG | Calendar loaded successfully (198 bytes).
    DEBUG | Starting Google Calendar synchronizer...
    DEBUG | Connecting to Google...
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google...
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google...
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google...
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google...
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google...
    DEBUG | Unable to load event (040000008200E00074C5B7101A82E00800000000B95B1C6052059DCC2E90C63035D606BF41000A02DB0633709AD514944E747207CF8F6821)!
    com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
    {
    "code" : 404,
    "errors" : [ {
    "domain" : "global",
    "message" : "Not Found",
    "reason" : "notFound"
    } ],
    "message" : "Not Found"
    }
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1049)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
    at org.gcaldaemon.core.GCalUtilitiesV3.getGoogleEntryByUID(GCalUtilitiesV3.java:1507)
    at org.gcaldaemon.core.GCalUtilitiesV3.getGoogleEntry(GCalUtilitiesV3.java:1482)
    at org.gcaldaemon.core.GCalUtilitiesV3.findEvent(GCalUtilitiesV3.java:618)
    at org.gcaldaemon.core.GCalUtilities.findEvent(GCalUtilities.java:325)
    at org.gcaldaemon.core.Synchronizer.syncronizeNow(Synchronizer.java:238)
    at org.gcaldaemon.core.Configurator.synchronizeNow(Configurator.java:1070)
    at org.gcaldaemon.core.file.OfflineFileListener.run(OfflineFileListener.java:61)
    DEBUG | New event (donde esta la gente ...) found in the local calendar.
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google...
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google...
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google...
    DEBUG | Connection refused, reconnecting...
    DEBUG | Connecting to Google..

    回覆刪除