Merge lp:~verterok/account-polld/handle-account-created into lp:~ubuntu-push-hackers/account-polld/trunk

Proposed by Guillermo Gonzalez
Status: Rejected
Rejected by: Guillermo Gonzalez
Proposed branch: lp:~verterok/account-polld/handle-account-created
Merge into: lp:~ubuntu-push-hackers/account-polld/trunk
Diff against target: 423 lines (+174/-69)
6 files modified
accounts/account-watcher.c (+30/-1)
accounts/account-watcher.h (+6/-0)
accounts/accounts.c (+2/-1)
accounts/accounts.go (+36/-14)
cmd/account-polld/main.go (+74/-39)
po/account-polld.pot (+26/-14)
To merge this branch: bzr merge lp:~verterok/account-polld/handle-account-created
Reviewer Review Type Date Requested Status
Sergio Schvezov Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+230686@code.launchpad.net

Commit message

Send a notification when an account is created, which actions is to open the accounts settings page.

Description of the change

Send a notification when an account is created, which actions is to open the accounts settings page (this will be changed when we can open a specific account page)

To test this on the device you will need an updated push-helper, grab this: http://paste.ubuntu.com/8038589/ and save it as: /usr/lib/ubuntu-push-client/legacy-helpers/ubuntu-system-settings

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sergio Schvezov (sergiusens) wrote :

couple of inline comments added; I will test in a bit as well.

review: Needs Fixing
Revision history for this message
Guillermo Gonzalez (verterok) :
57. By Guillermo Gonzalez

add missing TRANSLATORS comments

58. By Guillermo Gonzalez

updated translations

Revision history for this message
Guillermo Gonzalez (verterok) :
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sergio Schvezov (sergiusens) wrote :

if I install this, I don't get updates anymore; only an account creation signal

59. By Guillermo Gonzalez

move mainloop setup into main

60. By Guillermo Gonzalez

merge with trunk

Revision history for this message
Guillermo Gonzalez (verterok) wrote :

inline comments regarding the mainloop change.

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
Sergio Schvezov (sergiusens) wrote :

[00:28:32] <sergiusens> I do get the message now, what I don't see working is the actual notifications
[00:28:45] <sergiusens> enabling or disabling the toggle does not trigger the poll loop

and two minor inline comments

review: Needs Fixing
Revision history for this message
Sergio Schvezov (sergiusens) wrote :

once more comment

review: Needs Fixing
61. By Guillermo Gonzalez

start the mainlopp in init()

62. By Guillermo Gonzalez

update notification body

Revision history for this message
Guillermo Gonzalez (verterok) wrote :

Thanks for the review.

Fixed & pushed the 3 issues, I'll test it once jenkins finishes with the build.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
63. By Guillermo Gonzalez

remove break from the accountCh case

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sergio Schvezov (sergiusens) wrote :

tested, works

review: Approve

Unmerged revisions

63. By Guillermo Gonzalez

remove break from the accountCh case

62. By Guillermo Gonzalez

update notification body

61. By Guillermo Gonzalez

start the mainlopp in init()

60. By Guillermo Gonzalez

merge with trunk

59. By Guillermo Gonzalez

move mainloop setup into main

58. By Guillermo Gonzalez

updated translations

57. By Guillermo Gonzalez

add missing TRANSLATORS comments

56. By Guillermo Gonzalez

fix the dbus path

55. By Guillermo Gonzalez

- improve the notification message
- update translations

54. By Guillermo Gonzalez

use the correct url for the accounts settings page

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'accounts/account-watcher.c'
2--- accounts/account-watcher.c 2014-07-24 05:46:03 +0000
3+++ accounts/account-watcher.c 2014-08-15 19:02:24 +0000
4@@ -22,7 +22,7 @@
5
6 #include "account-watcher.h"
7
8-/* #define DEBUG */
9+//#define DEBUG
10 #ifdef DEBUG
11 # define trace(...) fprintf(stderr, __VA_ARGS__)
12 #else
13@@ -37,9 +37,11 @@
14 GHashTable *services;
15
16 gulong enabled_event_signal_id;
17+ gulong created_event_signal_id;
18 gulong account_deleted_signal_id;
19
20 AccountEnabledCallback callback;
21+ AccountCreatedCallback created_callback;
22 void *user_data;
23 };
24
25@@ -231,6 +233,28 @@
26 g_object_unref(account);
27 }
28
29+static void account_watcher_created_event_cb(
30+ AgManager *manager, AgAccountId account_id, AccountWatcher *watcher) {
31+ trace("created-event for %u\n", account_id);
32+ AgAccount *account = ag_manager_get_account(manager, account_id);
33+ if (account == NULL) {
34+ /* There was a problem looking up the account */
35+ return;
36+ }
37+ /* Since our AgManager is restricted to a particular service type,
38+ * pick the first service for the account. */
39+ GList *services = ag_account_list_services(account);
40+ if (services != NULL) {
41+ AgService *service = services->data;
42+ const char *service_name = ag_service_get_name(service);
43+ watcher->created_callback(watcher,
44+ account_id,
45+ service_name);
46+ }
47+ ag_service_list_free(services);
48+ g_object_unref(account);
49+}
50+
51 static void account_watcher_account_deleted_cb(
52 AgManager *manager, AgAccountId account_id, AccountWatcher *watcher) {
53 trace("account-deleted for %u\n", account_id);
54@@ -246,6 +270,9 @@
55 watcher->enabled_event_signal_id = g_signal_connect(
56 watcher->manager, "enabled-event",
57 G_CALLBACK(account_watcher_enabled_event_cb), watcher);
58+ watcher->created_event_signal_id = g_signal_connect(
59+ watcher->manager, "account-created",
60+ G_CALLBACK(account_watcher_created_event_cb), watcher);
61 watcher->account_deleted_signal_id = g_signal_connect(
62 watcher->manager, "account-deleted",
63 G_CALLBACK(account_watcher_account_deleted_cb), watcher);
64@@ -264,6 +291,7 @@
65
66 AccountWatcher *account_watcher_new(const char *service_type,
67 AccountEnabledCallback callback,
68+ AccountCreatedCallback created_callback,
69 void *user_data) {
70 AccountWatcher *watcher = g_new0(AccountWatcher, 1);
71
72@@ -271,6 +299,7 @@
73 watcher->services = g_hash_table_new_full(
74 g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)account_info_free);
75 watcher->callback = callback;
76+ watcher->created_callback = created_callback;
77 watcher->user_data = user_data;
78
79 /* Make sure main setup occurs within the mainloop thread */
80
81=== modified file 'accounts/account-watcher.h'
82--- accounts/account-watcher.h 2014-07-24 05:06:56 +0000
83+++ accounts/account-watcher.h 2014-08-15 19:02:24 +0000
84@@ -32,10 +32,16 @@
85 const char *token_secret,
86 void *user_data);
87
88+typedef void (*AccountCreatedCallback)(AccountWatcher *watcher,
89+ unsigned int account_id,
90+ const char *service_name);
91+
92 AccountWatcher *account_watcher_new(const char *service_type,
93 AccountEnabledCallback callback,
94+ AccountCreatedCallback created_callback,
95 void *user_data);
96
97 void account_watcher_refresh(AccountWatcher *watcher, unsigned int account_id);
98
99+
100 #endif
101
102=== modified file 'accounts/accounts.c'
103--- accounts/accounts.c 2014-07-24 05:06:56 +0000
104+++ accounts/accounts.c 2014-08-15 19:02:24 +0000
105@@ -19,6 +19,7 @@
106 }
107
108 AccountWatcher *watcher = account_watcher_new(
109- service_type, (AccountEnabledCallback)authCallback, NULL);
110+ service_type, (AccountEnabledCallback)authCallback,
111+ (AccountCreatedCallback)accountCallback, NULL);
112 return watcher;
113 }
114
115=== modified file 'accounts/accounts.go'
116--- accounts/accounts.go 2014-07-25 20:09:20 +0000
117+++ accounts/accounts.go 2014-08-15 19:02:24 +0000
118@@ -33,8 +33,14 @@
119 )
120
121 type Watcher struct {
122- C <-chan AuthData
123- watcher *C.AccountWatcher
124+ C <-chan AuthData
125+ AccountCh <-chan AccountData
126+ watcher *C.AccountWatcher
127+}
128+
129+type AccountData struct {
130+ AccountId uint
131+ ServiceName string
132 }
133
134 type AuthData struct {
135@@ -50,18 +56,12 @@
136 }
137
138 var (
139- mainLoopOnce sync.Once
140- authChannels = make(map[*C.AccountWatcher]chan<- AuthData)
141- authChannelsLock sync.Mutex
142+ authChannels = make(map[*C.AccountWatcher]chan<- AuthData)
143+ authChannelsLock sync.Mutex
144+ accountChannels = make(map[*C.AccountWatcher]chan<- AccountData)
145+ accountChannelsLock sync.Mutex
146 )
147
148-func startMainLoop() {
149- mainLoopOnce.Do(func() {
150- mainLoop := C.g_main_loop_new(nil, C.gboolean(1))
151- go C.g_main_loop_run(mainLoop)
152- })
153-}
154-
155 // NewWatcher creates a new account watcher for the given service names
156 func NewWatcher(serviceType string) *Watcher {
157 w := new(Watcher)
158@@ -74,8 +74,12 @@
159 authChannelsLock.Lock()
160 authChannels[w.watcher] = ch
161 authChannelsLock.Unlock()
162-
163- startMainLoop()
164+ // account stuff
165+ accountCh := make(chan AccountData)
166+ w.AccountCh = accountCh
167+ accountChannelsLock.Lock()
168+ accountChannels[w.watcher] = accountCh
169+ accountChannelsLock.Unlock()
170
171 return w
172 }
173@@ -121,3 +125,21 @@
174 }
175 ch <- data
176 }
177+
178+//export accountCallback
179+func accountCallback(watcher unsafe.Pointer, accountId C.uint, serviceName *C.char) {
180+ // Ideally the first argument would be of type
181+ // *C.AccountWatcher, but that fails with Go 1.2.
182+ accountChannelsLock.Lock()
183+ ch := accountChannels[(*C.AccountWatcher)(watcher)]
184+ accountChannelsLock.Unlock()
185+ if ch == nil {
186+ // Log the error
187+ return
188+ }
189+
190+ var data AccountData
191+ data.AccountId = uint(accountId)
192+ data.ServiceName = C.GoString(serviceName)
193+ ch <- data
194+}
195
196=== modified file 'cmd/account-polld/main.go'
197--- cmd/account-polld/main.go 2014-08-08 20:11:14 +0000
198+++ cmd/account-polld/main.go 2014-08-15 19:02:24 +0000
199@@ -17,10 +17,17 @@
200
201 package main
202
203+/*
204+#cgo pkg-config: glib-2.0
205+#include <glib.h>
206+*/
207+import "C"
208 import (
209 "encoding/json"
210 "fmt"
211 "strings"
212+ "sync"
213+ "time"
214
215 "log"
216
217@@ -52,7 +59,11 @@
218 POSTAL_OBJECT_PATH_PART = "/com/ubuntu/Postal/"
219 )
220
221+var mainLoopOnce sync.Once
222+var mainLoop *C.GMainLoop
223+
224 func init() {
225+ startGlibMainLoop()
226 }
227
228 func main() {
229@@ -76,40 +87,61 @@
230 <-done
231 }
232
233+func startGlibMainLoop() {
234+ mainLoopOnce.Do(func() {
235+ mainLoop = C.g_main_loop_new(nil, C.gboolean(1))
236+ go C.g_main_loop_run(mainLoop)
237+ })
238+}
239+
240 func monitorAccounts(postWatch chan *PostWatch) {
241 watcher := accounts.NewWatcher(SERVICETYPE_POLL)
242 mgr := make(map[uint]*AccountManager)
243 L:
244- for data := range watcher.C {
245- if account, ok := mgr[data.AccountId]; ok {
246- if data.Enabled {
247- log.Println("New account data for existing account with id", data.AccountId)
248- account.updateAuthData(data)
249- } else {
250- account.Delete()
251- delete(mgr, data.AccountId)
252- }
253- } else if data.Enabled {
254- var plugin plugins.Plugin
255- switch data.ServiceName {
256- case SERVICENAME_GMAIL:
257- log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
258- plugin = gmail.New(data.AccountId)
259- case SERVICENAME_FACEBOOK:
260- // This is just stubbed until the plugin exists.
261- log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
262- plugin = facebook.New(data.AccountId)
263- case SERVICENAME_TWITTER:
264- // This is just stubbed until the plugin exists.
265- log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
266- plugin = twitter.New()
267- default:
268- log.Println("Unhandled account with id", data.AccountId, "for", data.ServiceName)
269- continue L
270- }
271- mgr[data.AccountId] = NewAccountManager(watcher, postWatch, plugin)
272- mgr[data.AccountId].updateAuthData(data)
273- go mgr[data.AccountId].Loop()
274+ for {
275+ select {
276+ case data := <-watcher.C:
277+ if account, ok := mgr[data.AccountId]; ok {
278+ if data.Enabled {
279+ log.Println("New account data for existing account with id", data.AccountId)
280+ account.updateAuthData(data)
281+ } else {
282+ account.Delete()
283+ delete(mgr, data.AccountId)
284+ }
285+ } else if data.Enabled {
286+ var plugin plugins.Plugin
287+ switch data.ServiceName {
288+ case SERVICENAME_GMAIL:
289+ log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
290+ plugin = gmail.New(data.AccountId)
291+ case SERVICENAME_FACEBOOK:
292+ // This is just stubbed until the plugin exists.
293+ log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
294+ plugin = facebook.New(data.AccountId)
295+ case SERVICENAME_TWITTER:
296+ // This is just stubbed until the plugin exists.
297+ log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
298+ plugin = twitter.New()
299+ default:
300+ log.Println("Unhandled account with id", data.AccountId, "for", data.ServiceName)
301+ break L
302+ }
303+ mgr[data.AccountId] = NewAccountManager(watcher, postWatch, plugin)
304+ mgr[data.AccountId].updateAuthData(data)
305+ go mgr[data.AccountId].Loop()
306+ }
307+ case data := <-watcher.AccountCh:
308+ log.Println("New Account:", data.AccountId, "for", data.ServiceName)
309+ // TRANSLATORS: This is the summary of the notification triggered after creating a new account
310+ summary := gettext.Gettext("New account created")
311+ // TRANSLATORS: This is the body of the notification triggered after creating a new account
312+ body := gettext.Gettext("To enable notifications for this account, toggle Notifications from the account setting")
313+ epoch := time.Now().Unix()
314+ action := "settings://personal/online-accounts"
315+ pushMsg := *plugins.NewStandardPushMessage(summary, body, action, "", epoch)
316+ msgs := []plugins.PushMessage{pushMsg}
317+ postWatch <- &PostWatch{messages: msgs, appId: "_ubuntu-system-settings"}
318 }
319 }
320 }
321@@ -140,18 +172,21 @@
322 // e.g.; if the APP_ID is com.ubuntu.music", the returned object path
323 // would be "/com/ubuntu/PushNotifications/com_2eubuntu_2eubuntu_2emusic
324 func pushObjectPath(id plugins.ApplicationId) dbus.ObjectPath {
325+ pkg := POSTAL_OBJECT_PATH_PART
326 idParts := strings.Split(string(id), "_")
327 if len(idParts) < 2 {
328 panic(fmt.Sprintf("APP_ID '%s' is not valid", id))
329- }
330-
331- pkg := POSTAL_OBJECT_PATH_PART
332- for _, c := range idParts[0] {
333- switch c {
334- case '+', '.', '-', ':', '~', '_':
335- pkg += fmt.Sprintf("_%x", string(c))
336- default:
337- pkg += string(c)
338+ } else if strings.HasPrefix(string(id), "_") {
339+ // it's a legacy app!
340+ pkg += "_"
341+ } else {
342+ for _, c := range idParts[0] {
343+ switch c {
344+ case '+', '.', '-', ':', '~', '_':
345+ pkg += fmt.Sprintf("_%x", string(c))
346+ default:
347+ pkg += string(c)
348+ }
349 }
350 }
351 return dbus.ObjectPath(pkg)
352
353=== modified file 'po/account-polld.pot'
354--- po/account-polld.pot 2014-08-11 18:35:28 +0000
355+++ po/account-polld.pot 2014-08-15 19:02:24 +0000
356@@ -8,7 +8,7 @@
357 msgstr ""
358 "Project-Id-Version: account-polld\n"
359 "Report-Msgid-Bugs-To: \n"
360-"POT-Creation-Date: 2014-08-11 15:35-0300\n"
361+"POT-Creation-Date: 2014-08-15 11:06-0300\n"
362 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
363 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
364 "Language-Team: LANGUAGE <LL@li.org>\n"
365@@ -17,6 +17,31 @@
366 "Content-Type: text/plain; charset=CHARSET\n"
367 "Content-Transfer-Encoding: 8bit\n"
368
369+#. TRANSLATORS: This is the summary of the notification triggered after creating a new account
370+#: cmd/account-polld/main.go:137
371+msgid "New account created"
372+msgstr ""
373+
374+#. TRANSLATORS: This is the body of the notification triggered after creating a new account
375+#: cmd/account-polld/main.go:139
376+msgid ""
377+"To enable notifications for this account, toggle Notifications from the "
378+"account setting"
379+msgstr ""
380+
381+#. TRANSLATORS: This represents a notification summary about more facebook notifications
382+#: plugins/facebook/facebook.go:170
383+msgid "Multiple more notifications"
384+msgstr ""
385+
386+#. TRANSLATORS: This represents a notification body with the comma separated facebook usernames
387+#. TRANSLATORS: This represents a notification body with the comma separated twitter usernames
388+#: plugins/facebook/facebook.go:172 plugins/twitter/twitter.go:130
389+#: plugins/twitter/twitter.go:187
390+#, c-format
391+msgid "From %s"
392+msgstr ""
393+
394 #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username.
395 #: plugins/twitter/twitter.go:113 plugins/twitter/twitter.go:170
396 #, c-format
397@@ -28,14 +53,6 @@
398 msgid "Multiple more mentions"
399 msgstr ""
400
401-#. TRANSLATORS: This represents a notification body with the comma separated twitter usernames
402-#. TRANSLATORS: This represents a notification body with the comma separated facebook usernames
403-#: plugins/twitter/twitter.go:130 plugins/twitter/twitter.go:187
404-#: plugins/facebook/facebook.go:172
405-#, c-format
406-msgid "From %s"
407-msgstr ""
408-
409 #. TRANSLATORS: This represents a notification summary about more twitter direct messages available
410 #: plugins/twitter/twitter.go:185
411 msgid "Multiple direct messages available"
412@@ -72,11 +89,6 @@
413 msgid "You have an approximate of %d additional unread messages"
414 msgstr ""
415
416-#. TRANSLATORS: This represents a notification summary about more facebook notifications
417-#: plugins/facebook/facebook.go:170
418-msgid "Multiple more notifications"
419-msgstr ""
420-
421 #: data/account-polld.desktop.tr.h:1
422 msgid "Notifications"
423 msgstr ""

Subscribers

People subscribed via source and target branches