2
Copyright 2016 Canonical Ltd.
4
This program is free software: you can redistribute it and/or modify it
5
under the terms of the GNU General Public License version 3, as published
6
by the Free Software Foundation.
8
This program is distributed in the hope that it will be useful, but
9
WITHOUT ANY WARRANTY; without even the implied warranties of
10
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11
PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along
14
with this program. If not, see <http://www.gnu.org/licenses/>.
26
"launchpad.net/account-polld/accounts"
27
"launchpad.net/account-polld/plugins"
31
APP_ID = "com.ubuntu.calendar_calendar"
32
pluginName = "gcalendar"
35
var baseUrl, _ = url.Parse("https://www.googleapis.com/calendar/v3/calendars/primary/")
37
type GCalendarPlugin struct {
41
func New(accountId uint) *GCalendarPlugin {
42
return &GCalendarPlugin{accountId: accountId}
45
func (p *GCalendarPlugin) ApplicationId() plugins.ApplicationId {
46
return plugins.ApplicationId(APP_ID)
49
func (p *GCalendarPlugin) Poll(authData *accounts.AuthData) ([]*plugins.PushMessageBatch, error) {
50
// This envvar check is to ease testing.
51
if token := os.Getenv("ACCOUNT_POLLD_TOKEN_GCALENDAR"); token != "" {
52
authData.AccessToken = token
55
syncMonitor := NewSyncMonitor()
56
if syncMonitor == nil {
57
log.Print("Sync monitor not available yet.")
61
lastSyncDate, err := syncMonitor.LastSyncDate(p.accountId, "calendar")
63
log.Print("calendar plugin ", p.accountId, ": cannot load previous sync date: ", err, ". Try next time.")
66
log.Print("calendar plugin ", p.accountId, ": last sync date: ", lastSyncDate)
69
resp, err := p.requestChanges(authData.AccessToken, lastSyncDate)
74
messages, err := p.parseChangesResponse(resp)
79
if len(messages) > 0 {
80
// Update last sync date
81
log.Print("Request calendar sync")
82
err = syncMonitor.SyncAccount(p.accountId, "calendar")
84
log.Print("Fail to start calendar sync ", p.accountId, " error: ", err)
87
log.Print("Found no calendar updates for account: ", p.accountId)
93
func (p *GCalendarPlugin) parseChangesResponse(resp *http.Response) ([]event, error) {
94
defer resp.Body.Close()
95
decoder := json.NewDecoder(resp.Body)
97
if resp.StatusCode != http.StatusOK {
99
if err := decoder.Decode(&errResp); err != nil {
102
if errResp.Err.Code == 401 {
103
return nil, plugins.ErrTokenExpired
109
if err := decoder.Decode(&events); err != nil {
113
for _, ev := range events.Events {
114
log.Print("Found event: ", ev.Etag, ev.Summary)
117
return events.Events, nil
120
func (p *GCalendarPlugin) requestChanges(accessToken string, lastSyncDate string) (*http.Response, error) {
121
u, err := baseUrl.Parse("events")
126
//GET https://www.googleapis.com/calendar/v3/calendars/primary/events?showDeleted=true&singleEvents=true&updatedMin=2016-04-06T10%3A00%3A00.00Z&fields=description%2Citems(description%2Cetag%2Csummary)&key={YOUR_API_KEY}
127
query := baseUrl.Query()
128
query.Add("showDeleted", "true")
129
query.Add("singleEvents", "true")
130
query.Add("fields", "description,items(summary,etag)")
131
query.Add("maxResults", "1")
132
if len(lastSyncDate) > 0 {
133
query.Add("updatedMin", lastSyncDate)
135
u.RawQuery = query.Encode()
137
req, err := http.NewRequest("GET", u.String(), nil)
141
req.Header.Set("Authorization", "Bearer "+accessToken)
143
return http.DefaultClient.Do(req)