~mardy/account-polld/dekko-gmail

« back to all changes in this revision

Viewing changes to plugins/gcalendar/gcalendar.go

  • Committer: CI Train Bot
  • Author(s): Renato Araujo Oliveira Filho
  • Date: 2016-04-21 23:33:48 UTC
  • mfrom: (157.2.16 account-polld)
  • Revision ID: ci-train-bot@canonical.com-20160421233348-qu4f1eln0r771269
Create gcalendar plugin.
Approved by: Jonas G. Drange, PS Jenkins bot

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright 2016 Canonical Ltd.
 
3
 
 
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.
 
7
 
 
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.
 
12
 
 
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/>.
 
15
*/
 
16
 
 
17
package gcalendar
 
18
 
 
19
import (
 
20
        "encoding/json"
 
21
        "log"
 
22
        "net/http"
 
23
        "net/url"
 
24
        "os"
 
25
 
 
26
        "launchpad.net/account-polld/accounts"
 
27
        "launchpad.net/account-polld/plugins"
 
28
)
 
29
 
 
30
const (
 
31
        APP_ID     = "com.ubuntu.calendar_calendar"
 
32
        pluginName = "gcalendar"
 
33
)
 
34
 
 
35
var baseUrl, _ = url.Parse("https://www.googleapis.com/calendar/v3/calendars/primary/")
 
36
 
 
37
type GCalendarPlugin struct {
 
38
        accountId uint
 
39
}
 
40
 
 
41
func New(accountId uint) *GCalendarPlugin {
 
42
        return &GCalendarPlugin{accountId: accountId}
 
43
}
 
44
 
 
45
func (p *GCalendarPlugin) ApplicationId() plugins.ApplicationId {
 
46
        return plugins.ApplicationId(APP_ID)
 
47
}
 
48
 
 
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
 
53
        }
 
54
 
 
55
        syncMonitor := NewSyncMonitor()
 
56
        if syncMonitor == nil {
 
57
                log.Print("Sync monitor not available yet.")
 
58
                return nil, nil
 
59
        }
 
60
 
 
61
        lastSyncDate, err := syncMonitor.LastSyncDate(p.accountId, "calendar")
 
62
        if err != nil {
 
63
                log.Print("calendar plugin ", p.accountId, ": cannot load previous sync date: ", err, ". Try next time.")
 
64
                return nil, nil
 
65
        } else {
 
66
                log.Print("calendar plugin ", p.accountId, ": last sync date: ", lastSyncDate)
 
67
        }
 
68
 
 
69
        resp, err := p.requestChanges(authData.AccessToken, lastSyncDate)
 
70
        if err != nil {
 
71
                return nil, err
 
72
        }
 
73
 
 
74
        messages, err := p.parseChangesResponse(resp)
 
75
        if err != nil {
 
76
                return nil, err
 
77
        }
 
78
 
 
79
        if len(messages) > 0 {
 
80
                // Update last sync date
 
81
                log.Print("Request calendar sync")
 
82
                err = syncMonitor.SyncAccount(p.accountId, "calendar")
 
83
                if err != nil {
 
84
                        log.Print("Fail to start calendar sync ", p.accountId, " error: ", err)
 
85
                }
 
86
        } else {
 
87
                log.Print("Found no calendar updates for account: ", p.accountId)
 
88
        }
 
89
 
 
90
        return nil, nil
 
91
}
 
92
 
 
93
func (p *GCalendarPlugin) parseChangesResponse(resp *http.Response) ([]event, error) {
 
94
        defer resp.Body.Close()
 
95
        decoder := json.NewDecoder(resp.Body)
 
96
 
 
97
        if resp.StatusCode != http.StatusOK {
 
98
                var errResp errorResp
 
99
                if err := decoder.Decode(&errResp); err != nil {
 
100
                        return nil, err
 
101
                }
 
102
                if errResp.Err.Code == 401 {
 
103
                        return nil, plugins.ErrTokenExpired
 
104
                }
 
105
                return nil, nil
 
106
        }
 
107
 
 
108
        var events eventList
 
109
        if err := decoder.Decode(&events); err != nil {
 
110
                return nil, err
 
111
        }
 
112
 
 
113
        for _, ev := range events.Events {
 
114
                log.Print("Found event: ", ev.Etag, ev.Summary)
 
115
        }
 
116
 
 
117
        return events.Events, nil
 
118
}
 
119
 
 
120
func (p *GCalendarPlugin) requestChanges(accessToken string, lastSyncDate string) (*http.Response, error) {
 
121
        u, err := baseUrl.Parse("events")
 
122
        if err != nil {
 
123
                return nil, err
 
124
        }
 
125
 
 
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)
 
134
        }
 
135
        u.RawQuery = query.Encode()
 
136
 
 
137
        req, err := http.NewRequest("GET", u.String(), nil)
 
138
        if err != nil {
 
139
                return nil, err
 
140
        }
 
141
        req.Header.Set("Authorization", "Bearer "+accessToken)
 
142
 
 
143
        return http.DefaultClient.Do(req)
 
144
}