Merge lp:~jonas-drange/account-polld/gmail-missing-notifications into lp:~ubuntu-push-hackers/account-polld/trunk

Proposed by Jonas G. Drange
Status: Merged
Approved by: Jonas G. Drange
Approved revision: 159
Merged at revision: 149
Proposed branch: lp:~jonas-drange/account-polld/gmail-missing-notifications
Merge into: lp:~ubuntu-push-hackers/account-polld/trunk
Diff against target: 175 lines (+58/-54)
2 files modified
cmd/account-polld/main.go (+15/-42)
plugins/gmail/gmail.go (+43/-12)
To merge this branch: bzr merge lp:~jonas-drange/account-polld/gmail-missing-notifications
Reviewer Review Type Date Requested Status
John Lenton (community) Approve
Bill Filler (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+280711@code.launchpad.net

Commit message

- Force parsing of email address even if it violates RFC 5322.
- Encode icon file paths since unity-notifications require it.
- Summarize notification bubbles when > 10 in a batch, but never summarize in the indicator.

To post a comment you must log in.
Revision history for this message
John Lenton (chipaca) wrote :

Given the level of insanity of this codepath, this does not seem worse than what we have :-)

+1

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Bill Filler (bfiller) wrote :

tested, works well!

review: Approve
Revision history for this message
John Lenton (chipaca) wrote :

My 'approve' stands.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'cmd/account-polld/main.go'
--- cmd/account-polld/main.go 2015-11-03 13:40:45 +0000
+++ cmd/account-polld/main.go 2015-12-21 11:51:14 +0000
@@ -44,8 +44,8 @@
44const (44const (
45 SERVICETYPE_WEBAPPS = "webapps"45 SERVICETYPE_WEBAPPS = "webapps"
4646
47 SERVICENAME_GMAIL = "com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail"47 SERVICENAME_GMAIL = "com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail"
48 SERVICENAME_TWITTER = "com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter"48 SERVICENAME_TWITTER = "com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter"
49)49)
5050
51const (51const (
@@ -169,50 +169,23 @@
169func postOffice(bus *dbus.Connection, postWatch chan *PostWatch) {169func postOffice(bus *dbus.Connection, postWatch chan *PostWatch) {
170 for post := range postWatch {170 for post := range postWatch {
171 obj := bus.Object(POSTAL_SERVICE, pushObjectPath(post.appId))171 obj := bus.Object(POSTAL_SERVICE, pushObjectPath(post.appId))
172 pers, err := obj.Call(POSTAL_INTERFACE, "ListPersistent", post.appId)
173 if err != nil {
174 log.Println("Could not list previous messages:", err)
175 continue
176 }
177 var tags []string
178 tagmap := make(map[string]int)
179 if err := pers.Args(&tags); err != nil {
180 log.Println("Could not get tags:", err)
181 continue
182 }
183 log.Printf("Previous messages: %#v\n", tags)
184 for _, tag := range tags {
185 tagmap[tag]++
186 }
187172
188 for _, batch := range post.batches {173 for _, batch := range post.batches {
189 // add individual notifications upto the batch limit174
190 // (minus currently presented notifications). If175 notifs := batch.Messages
191 // overflowed and no overflow present, present that.176 overflowing := len(notifs) > batch.Limit
192 var notifs []*plugins.PushMessage177
193 add := batch.Limit - tagmap[batch.Tag]
194 if add > 0 {
195 // there are less notifications presented than
196 // the limit; we can show some
197 if len(batch.Messages) < add {
198 notifs = batch.Messages
199 } else {
200 notifs = batch.Messages[:add]
201 }
202 }
203 for _, n := range notifs {178 for _, n := range notifs {
204 n.Notification.Tag = batch.Tag179 // We're overflowing, so no popups.
180 // See LP: #1527171
181 if overflowing {
182 n.Notification.Card.Popup = false
183 }
205 }184 }
206 ofTag := batch.Tag + "-overflow"185
207 if len(notifs) < len(batch.Messages) {186 if overflowing {
208 // overflow187 n := batch.OverflowHandler(notifs)
209 n := batch.OverflowHandler(batch.Messages[len(notifs):])188 n.Notification.Card.Persist = false
210 n.Notification.Tag = ofTag
211 if tagmap[ofTag] != 0 {
212 // sneakily, don't replace the overflow card,
213 // but do play the sound & etc
214 n.Notification.Card = nil
215 }
216 notifs = append(notifs, n)189 notifs = append(notifs, n)
217 }190 }
218191
219192
=== modified file 'plugins/gmail/gmail.go'
--- plugins/gmail/gmail.go 2015-03-27 11:40:37 +0000
+++ plugins/gmail/gmail.go 2015-12-21 11:51:14 +0000
@@ -23,7 +23,9 @@
23 "net/mail"23 "net/mail"
24 "net/url"24 "net/url"
25 "os"25 "os"
26 "regexp"
26 "sort"27 "sort"
28 "strings"
27 "time"29 "time"
2830
29 "log"31 "log"
@@ -37,8 +39,10 @@
37const (39const (
38 APP_ID = "com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail"40 APP_ID = "com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail"
39 gmailDispatchUrl = "https://mail.google.com/mail/mu/mp/#cv/priority/^smartlabel_%s/%s"41 gmailDispatchUrl = "https://mail.google.com/mail/mu/mp/#cv/priority/^smartlabel_%s/%s"
40 // this means 3 individual messages + 1 bundled notification.42 // If there's more than 10 emails in one batch, we don't show 10 notification
41 individualNotificationsLimit = 243 // bubbles, but instead show one summary. We always show all notifications in the
44 // indicator.
45 individualNotificationsLimit = 10
42 pluginName = "gmail"46 pluginName = "gmail"
43)47)
4448
@@ -52,6 +56,9 @@
52// trackDelta defines how old messages can be before removed from tracking56// trackDelta defines how old messages can be before removed from tracking
53var trackDelta = time.Duration(time.Hour * 24 * 7)57var trackDelta = time.Duration(time.Hour * 24 * 7)
5458
59// regexp for identifying non-ascii characters
60var nonAsciiChars, _ = regexp.Compile("[^\x00-\x7F]")
61
55type GmailPlugin struct {62type GmailPlugin struct {
56 // reportedIds holds the messages that have already been notified. This63 // reportedIds holds the messages that have already been notified. This
57 // approach is taken against timestamps as it avoids needing to call64 // approach is taken against timestamps as it avoids needing to call
@@ -154,12 +161,34 @@
154 from := hdr[hdrFROM]161 from := hdr[hdrFROM]
155 var avatarPath string162 var avatarPath string
156163
157 if emailAddress, err := mail.ParseAddress(hdr[hdrFROM]); err == nil {164 emailAddress, err := mail.ParseAddress(from)
158 if emailAddress.Name != "" {165 if err != nil {
159 from = emailAddress.Name166 // If the email address contains non-ascii characters, we get an
160 avatarPath = qtcontact.GetAvatar(emailAddress.Address)167 // error so we're going to try again, this time mangling the name
161 }168 // by removing all non-ascii characters. We only care about the email
162 }169 // address here anyway.
170 // XXX: We can't check the error message due to [1]: the error
171 // message is different in go < 1.3 and > 1.5.
172 // [1] https://github.com/golang/go/issues/12492
173 mangledAddr := nonAsciiChars.ReplaceAllString(from, "")
174 mangledEmail, _ := mail.ParseAddress(mangledAddr)
175 if err != nil {
176 emailAddress = mangledEmail
177 }
178 } else {
179 from = emailAddress.Name
180 }
181
182 if emailAddress != nil {
183 avatarPath = qtcontact.GetAvatar(emailAddress.Address)
184 // If icon path starts with a path separator, assume local file path,
185 // encode it and prepend file scheme defined in RFC 1738.
186 if strings.HasPrefix(avatarPath, string(os.PathSeparator)) {
187 avatarPath = url.QueryEscape(avatarPath)
188 avatarPath = "file://" + avatarPath
189 }
190 }
191
163 msgStamp := hdr.getTimestamp()192 msgStamp := hdr.getTimestamp()
164193
165 if _, ok := pushMsgMap[msg.ThreadId]; ok {194 if _, ok := pushMsgMap[msg.ThreadId]; ok {
@@ -186,12 +215,14 @@
186215
187}216}
188func (p *GmailPlugin) handleOverflow(pushMsg []*plugins.PushMessage) *plugins.PushMessage {217func (p *GmailPlugin) handleOverflow(pushMsg []*plugins.PushMessage) *plugins.PushMessage {
189 // TRANSLATORS: This represents a notification summary about more unread emails
190 summary := gettext.Gettext("More unread emails available")
191 // TODO it would probably be better to grab the estimate that google returns in the message list.218 // TODO it would probably be better to grab the estimate that google returns in the message list.
192 approxUnreadMessages := len(pushMsg)219 approxUnreadMessages := len(pushMsg)
193 // TRANSLATORS: the first %d refers to approximate additional email message count220
194 body := fmt.Sprintf(gettext.Gettext("You have about %d more unread messages"), approxUnreadMessages)221 // TRANSLATORS: the %d refers to the number of new email messages.
222 summary := fmt.Sprintf(gettext.Gettext("You have %d new messages"), approxUnreadMessages)
223
224 body := ""
225
195 // fmt with label personal and no threadId226 // fmt with label personal and no threadId
196 action := fmt.Sprintf(gmailDispatchUrl, "personal")227 action := fmt.Sprintf(gmailDispatchUrl, "personal")
197 epoch := time.Now().Unix()228 epoch := time.Now().Unix()

Subscribers

People subscribed via source and target branches