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
=== modified file 'accounts/account-watcher.c'
--- accounts/account-watcher.c 2014-07-24 05:46:03 +0000
+++ accounts/account-watcher.c 2014-08-15 19:02:24 +0000
@@ -22,7 +22,7 @@
2222
23#include "account-watcher.h"23#include "account-watcher.h"
2424
25/* #define DEBUG */25//#define DEBUG
26#ifdef DEBUG26#ifdef DEBUG
27# define trace(...) fprintf(stderr, __VA_ARGS__)27# define trace(...) fprintf(stderr, __VA_ARGS__)
28#else28#else
@@ -37,9 +37,11 @@
37 GHashTable *services;37 GHashTable *services;
3838
39 gulong enabled_event_signal_id;39 gulong enabled_event_signal_id;
40 gulong created_event_signal_id;
40 gulong account_deleted_signal_id;41 gulong account_deleted_signal_id;
4142
42 AccountEnabledCallback callback;43 AccountEnabledCallback callback;
44 AccountCreatedCallback created_callback;
43 void *user_data;45 void *user_data;
44};46};
4547
@@ -231,6 +233,28 @@
231 g_object_unref(account);233 g_object_unref(account);
232}234}
233235
236static void account_watcher_created_event_cb(
237 AgManager *manager, AgAccountId account_id, AccountWatcher *watcher) {
238 trace("created-event for %u\n", account_id);
239 AgAccount *account = ag_manager_get_account(manager, account_id);
240 if (account == NULL) {
241 /* There was a problem looking up the account */
242 return;
243 }
244 /* Since our AgManager is restricted to a particular service type,
245 * pick the first service for the account. */
246 GList *services = ag_account_list_services(account);
247 if (services != NULL) {
248 AgService *service = services->data;
249 const char *service_name = ag_service_get_name(service);
250 watcher->created_callback(watcher,
251 account_id,
252 service_name);
253 }
254 ag_service_list_free(services);
255 g_object_unref(account);
256}
257
234static void account_watcher_account_deleted_cb(258static void account_watcher_account_deleted_cb(
235 AgManager *manager, AgAccountId account_id, AccountWatcher *watcher) {259 AgManager *manager, AgAccountId account_id, AccountWatcher *watcher) {
236 trace("account-deleted for %u\n", account_id);260 trace("account-deleted for %u\n", account_id);
@@ -246,6 +270,9 @@
246 watcher->enabled_event_signal_id = g_signal_connect(270 watcher->enabled_event_signal_id = g_signal_connect(
247 watcher->manager, "enabled-event",271 watcher->manager, "enabled-event",
248 G_CALLBACK(account_watcher_enabled_event_cb), watcher);272 G_CALLBACK(account_watcher_enabled_event_cb), watcher);
273 watcher->created_event_signal_id = g_signal_connect(
274 watcher->manager, "account-created",
275 G_CALLBACK(account_watcher_created_event_cb), watcher);
249 watcher->account_deleted_signal_id = g_signal_connect(276 watcher->account_deleted_signal_id = g_signal_connect(
250 watcher->manager, "account-deleted",277 watcher->manager, "account-deleted",
251 G_CALLBACK(account_watcher_account_deleted_cb), watcher);278 G_CALLBACK(account_watcher_account_deleted_cb), watcher);
@@ -264,6 +291,7 @@
264291
265AccountWatcher *account_watcher_new(const char *service_type,292AccountWatcher *account_watcher_new(const char *service_type,
266 AccountEnabledCallback callback,293 AccountEnabledCallback callback,
294 AccountCreatedCallback created_callback,
267 void *user_data) {295 void *user_data) {
268 AccountWatcher *watcher = g_new0(AccountWatcher, 1);296 AccountWatcher *watcher = g_new0(AccountWatcher, 1);
269297
@@ -271,6 +299,7 @@
271 watcher->services = g_hash_table_new_full(299 watcher->services = g_hash_table_new_full(
272 g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)account_info_free);300 g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)account_info_free);
273 watcher->callback = callback;301 watcher->callback = callback;
302 watcher->created_callback = created_callback;
274 watcher->user_data = user_data;303 watcher->user_data = user_data;
275304
276 /* Make sure main setup occurs within the mainloop thread */305 /* Make sure main setup occurs within the mainloop thread */
277306
=== modified file 'accounts/account-watcher.h'
--- accounts/account-watcher.h 2014-07-24 05:06:56 +0000
+++ accounts/account-watcher.h 2014-08-15 19:02:24 +0000
@@ -32,10 +32,16 @@
32 const char *token_secret,32 const char *token_secret,
33 void *user_data);33 void *user_data);
3434
35typedef void (*AccountCreatedCallback)(AccountWatcher *watcher,
36 unsigned int account_id,
37 const char *service_name);
38
35AccountWatcher *account_watcher_new(const char *service_type,39AccountWatcher *account_watcher_new(const char *service_type,
36 AccountEnabledCallback callback,40 AccountEnabledCallback callback,
41 AccountCreatedCallback created_callback,
37 void *user_data);42 void *user_data);
3843
39void account_watcher_refresh(AccountWatcher *watcher, unsigned int account_id);44void account_watcher_refresh(AccountWatcher *watcher, unsigned int account_id);
4045
46
41#endif47#endif
4248
=== modified file 'accounts/accounts.c'
--- accounts/accounts.c 2014-07-24 05:06:56 +0000
+++ accounts/accounts.c 2014-08-15 19:02:24 +0000
@@ -19,6 +19,7 @@
19 }19 }
2020
21 AccountWatcher *watcher = account_watcher_new(21 AccountWatcher *watcher = account_watcher_new(
22 service_type, (AccountEnabledCallback)authCallback, NULL);22 service_type, (AccountEnabledCallback)authCallback,
23 (AccountCreatedCallback)accountCallback, NULL);
23 return watcher;24 return watcher;
24}25}
2526
=== modified file 'accounts/accounts.go'
--- accounts/accounts.go 2014-07-25 20:09:20 +0000
+++ accounts/accounts.go 2014-08-15 19:02:24 +0000
@@ -33,8 +33,14 @@
33)33)
3434
35type Watcher struct {35type Watcher struct {
36 C <-chan AuthData36 C <-chan AuthData
37 watcher *C.AccountWatcher37 AccountCh <-chan AccountData
38 watcher *C.AccountWatcher
39}
40
41type AccountData struct {
42 AccountId uint
43 ServiceName string
38}44}
3945
40type AuthData struct {46type AuthData struct {
@@ -50,18 +56,12 @@
50}56}
5157
52var (58var (
53 mainLoopOnce sync.Once59 authChannels = make(map[*C.AccountWatcher]chan<- AuthData)
54 authChannels = make(map[*C.AccountWatcher]chan<- AuthData)60 authChannelsLock sync.Mutex
55 authChannelsLock sync.Mutex61 accountChannels = make(map[*C.AccountWatcher]chan<- AccountData)
62 accountChannelsLock sync.Mutex
56)63)
5764
58func startMainLoop() {
59 mainLoopOnce.Do(func() {
60 mainLoop := C.g_main_loop_new(nil, C.gboolean(1))
61 go C.g_main_loop_run(mainLoop)
62 })
63}
64
65// NewWatcher creates a new account watcher for the given service names65// NewWatcher creates a new account watcher for the given service names
66func NewWatcher(serviceType string) *Watcher {66func NewWatcher(serviceType string) *Watcher {
67 w := new(Watcher)67 w := new(Watcher)
@@ -74,8 +74,12 @@
74 authChannelsLock.Lock()74 authChannelsLock.Lock()
75 authChannels[w.watcher] = ch75 authChannels[w.watcher] = ch
76 authChannelsLock.Unlock()76 authChannelsLock.Unlock()
7777 // account stuff
78 startMainLoop()78 accountCh := make(chan AccountData)
79 w.AccountCh = accountCh
80 accountChannelsLock.Lock()
81 accountChannels[w.watcher] = accountCh
82 accountChannelsLock.Unlock()
7983
80 return w84 return w
81}85}
@@ -121,3 +125,21 @@
121 }125 }
122 ch <- data126 ch <- data
123}127}
128
129//export accountCallback
130func accountCallback(watcher unsafe.Pointer, accountId C.uint, serviceName *C.char) {
131 // Ideally the first argument would be of type
132 // *C.AccountWatcher, but that fails with Go 1.2.
133 accountChannelsLock.Lock()
134 ch := accountChannels[(*C.AccountWatcher)(watcher)]
135 accountChannelsLock.Unlock()
136 if ch == nil {
137 // Log the error
138 return
139 }
140
141 var data AccountData
142 data.AccountId = uint(accountId)
143 data.ServiceName = C.GoString(serviceName)
144 ch <- data
145}
124146
=== modified file 'cmd/account-polld/main.go'
--- cmd/account-polld/main.go 2014-08-08 20:11:14 +0000
+++ cmd/account-polld/main.go 2014-08-15 19:02:24 +0000
@@ -17,10 +17,17 @@
1717
18package main18package main
1919
20/*
21#cgo pkg-config: glib-2.0
22#include <glib.h>
23*/
24import "C"
20import (25import (
21 "encoding/json"26 "encoding/json"
22 "fmt"27 "fmt"
23 "strings"28 "strings"
29 "sync"
30 "time"
2431
25 "log"32 "log"
2633
@@ -52,7 +59,11 @@
52 POSTAL_OBJECT_PATH_PART = "/com/ubuntu/Postal/"59 POSTAL_OBJECT_PATH_PART = "/com/ubuntu/Postal/"
53)60)
5461
62var mainLoopOnce sync.Once
63var mainLoop *C.GMainLoop
64
55func init() {65func init() {
66 startGlibMainLoop()
56}67}
5768
58func main() {69func main() {
@@ -76,40 +87,61 @@
76 <-done87 <-done
77}88}
7889
90func startGlibMainLoop() {
91 mainLoopOnce.Do(func() {
92 mainLoop = C.g_main_loop_new(nil, C.gboolean(1))
93 go C.g_main_loop_run(mainLoop)
94 })
95}
96
79func monitorAccounts(postWatch chan *PostWatch) {97func monitorAccounts(postWatch chan *PostWatch) {
80 watcher := accounts.NewWatcher(SERVICETYPE_POLL)98 watcher := accounts.NewWatcher(SERVICETYPE_POLL)
81 mgr := make(map[uint]*AccountManager)99 mgr := make(map[uint]*AccountManager)
82L:100L:
83 for data := range watcher.C {101 for {
84 if account, ok := mgr[data.AccountId]; ok {102 select {
85 if data.Enabled {103 case data := <-watcher.C:
86 log.Println("New account data for existing account with id", data.AccountId)104 if account, ok := mgr[data.AccountId]; ok {
87 account.updateAuthData(data)105 if data.Enabled {
88 } else {106 log.Println("New account data for existing account with id", data.AccountId)
89 account.Delete()107 account.updateAuthData(data)
90 delete(mgr, data.AccountId)108 } else {
91 }109 account.Delete()
92 } else if data.Enabled {110 delete(mgr, data.AccountId)
93 var plugin plugins.Plugin111 }
94 switch data.ServiceName {112 } else if data.Enabled {
95 case SERVICENAME_GMAIL:113 var plugin plugins.Plugin
96 log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)114 switch data.ServiceName {
97 plugin = gmail.New(data.AccountId)115 case SERVICENAME_GMAIL:
98 case SERVICENAME_FACEBOOK:116 log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
99 // This is just stubbed until the plugin exists.117 plugin = gmail.New(data.AccountId)
100 log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)118 case SERVICENAME_FACEBOOK:
101 plugin = facebook.New(data.AccountId)119 // This is just stubbed until the plugin exists.
102 case SERVICENAME_TWITTER:120 log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
103 // This is just stubbed until the plugin exists.121 plugin = facebook.New(data.AccountId)
104 log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)122 case SERVICENAME_TWITTER:
105 plugin = twitter.New()123 // This is just stubbed until the plugin exists.
106 default:124 log.Println("Creating account with id", data.AccountId, "for", data.ServiceName)
107 log.Println("Unhandled account with id", data.AccountId, "for", data.ServiceName)125 plugin = twitter.New()
108 continue L126 default:
109 }127 log.Println("Unhandled account with id", data.AccountId, "for", data.ServiceName)
110 mgr[data.AccountId] = NewAccountManager(watcher, postWatch, plugin)128 break L
111 mgr[data.AccountId].updateAuthData(data)129 }
112 go mgr[data.AccountId].Loop()130 mgr[data.AccountId] = NewAccountManager(watcher, postWatch, plugin)
131 mgr[data.AccountId].updateAuthData(data)
132 go mgr[data.AccountId].Loop()
133 }
134 case data := <-watcher.AccountCh:
135 log.Println("New Account:", data.AccountId, "for", data.ServiceName)
136 // TRANSLATORS: This is the summary of the notification triggered after creating a new account
137 summary := gettext.Gettext("New account created")
138 // TRANSLATORS: This is the body of the notification triggered after creating a new account
139 body := gettext.Gettext("To enable notifications for this account, toggle Notifications from the account setting")
140 epoch := time.Now().Unix()
141 action := "settings://personal/online-accounts"
142 pushMsg := *plugins.NewStandardPushMessage(summary, body, action, "", epoch)
143 msgs := []plugins.PushMessage{pushMsg}
144 postWatch <- &PostWatch{messages: msgs, appId: "_ubuntu-system-settings"}
113 }145 }
114 }146 }
115}147}
@@ -140,18 +172,21 @@
140// e.g.; if the APP_ID is com.ubuntu.music", the returned object path172// e.g.; if the APP_ID is com.ubuntu.music", the returned object path
141// would be "/com/ubuntu/PushNotifications/com_2eubuntu_2eubuntu_2emusic173// would be "/com/ubuntu/PushNotifications/com_2eubuntu_2eubuntu_2emusic
142func pushObjectPath(id plugins.ApplicationId) dbus.ObjectPath {174func pushObjectPath(id plugins.ApplicationId) dbus.ObjectPath {
175 pkg := POSTAL_OBJECT_PATH_PART
143 idParts := strings.Split(string(id), "_")176 idParts := strings.Split(string(id), "_")
144 if len(idParts) < 2 {177 if len(idParts) < 2 {
145 panic(fmt.Sprintf("APP_ID '%s' is not valid", id))178 panic(fmt.Sprintf("APP_ID '%s' is not valid", id))
146 }179 } else if strings.HasPrefix(string(id), "_") {
147180 // it's a legacy app!
148 pkg := POSTAL_OBJECT_PATH_PART181 pkg += "_"
149 for _, c := range idParts[0] {182 } else {
150 switch c {183 for _, c := range idParts[0] {
151 case '+', '.', '-', ':', '~', '_':184 switch c {
152 pkg += fmt.Sprintf("_%x", string(c))185 case '+', '.', '-', ':', '~', '_':
153 default:186 pkg += fmt.Sprintf("_%x", string(c))
154 pkg += string(c)187 default:
188 pkg += string(c)
189 }
155 }190 }
156 }191 }
157 return dbus.ObjectPath(pkg)192 return dbus.ObjectPath(pkg)
158193
=== modified file 'po/account-polld.pot'
--- po/account-polld.pot 2014-08-11 18:35:28 +0000
+++ po/account-polld.pot 2014-08-15 19:02:24 +0000
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: account-polld\n"9"Project-Id-Version: account-polld\n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2014-08-11 15:35-0300\n"11"POT-Creation-Date: 2014-08-15 11:06-0300\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,6 +17,31 @@
17"Content-Type: text/plain; charset=CHARSET\n"17"Content-Type: text/plain; charset=CHARSET\n"
18"Content-Transfer-Encoding: 8bit\n"18"Content-Transfer-Encoding: 8bit\n"
1919
20#. TRANSLATORS: This is the summary of the notification triggered after creating a new account
21#: cmd/account-polld/main.go:137
22msgid "New account created"
23msgstr ""
24
25#. TRANSLATORS: This is the body of the notification triggered after creating a new account
26#: cmd/account-polld/main.go:139
27msgid ""
28"To enable notifications for this account, toggle Notifications from the "
29"account setting"
30msgstr ""
31
32#. TRANSLATORS: This represents a notification summary about more facebook notifications
33#: plugins/facebook/facebook.go:170
34msgid "Multiple more notifications"
35msgstr ""
36
37#. TRANSLATORS: This represents a notification body with the comma separated facebook usernames
38#. TRANSLATORS: This represents a notification body with the comma separated twitter usernames
39#: plugins/facebook/facebook.go:172 plugins/twitter/twitter.go:130
40#: plugins/twitter/twitter.go:187
41#, c-format
42msgid "From %s"
43msgstr ""
44
20#. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username.45#. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username.
21#: plugins/twitter/twitter.go:113 plugins/twitter/twitter.go:17046#: plugins/twitter/twitter.go:113 plugins/twitter/twitter.go:170
22#, c-format47#, c-format
@@ -28,14 +53,6 @@
28msgid "Multiple more mentions"53msgid "Multiple more mentions"
29msgstr ""54msgstr ""
3055
31#. TRANSLATORS: This represents a notification body with the comma separated twitter usernames
32#. TRANSLATORS: This represents a notification body with the comma separated facebook usernames
33#: plugins/twitter/twitter.go:130 plugins/twitter/twitter.go:187
34#: plugins/facebook/facebook.go:172
35#, c-format
36msgid "From %s"
37msgstr ""
38
39#. TRANSLATORS: This represents a notification summary about more twitter direct messages available56#. TRANSLATORS: This represents a notification summary about more twitter direct messages available
40#: plugins/twitter/twitter.go:18557#: plugins/twitter/twitter.go:185
41msgid "Multiple direct messages available"58msgid "Multiple direct messages available"
@@ -72,11 +89,6 @@
72msgid "You have an approximate of %d additional unread messages"89msgid "You have an approximate of %d additional unread messages"
73msgstr ""90msgstr ""
7491
75#. TRANSLATORS: This represents a notification summary about more facebook notifications
76#: plugins/facebook/facebook.go:170
77msgid "Multiple more notifications"
78msgstr ""
79
80#: data/account-polld.desktop.tr.h:192#: data/account-polld.desktop.tr.h:1
81msgid "Notifications"93msgid "Notifications"
82msgstr ""94msgstr ""

Subscribers

People subscribed via source and target branches