~ubuntu-branches/ubuntu/quantal/shotwell/quantal

« back to all changes in this revision

Viewing changes to plugins/shotwell-publishing/FlickrPublishing.vala

  • Committer: Package Import Robot
  • Author(s): Ken VanDine, Alberto Mardegan
  • Date: 2012-09-24 11:10:48 UTC
  • Revision ID: package-import@ubuntu.com-20120924111048-dic3zkytvn0iaz36
Tags: 0.13.0-0ubuntu2
[ Alberto Mardegan ]
* debian/patches/06_uoa.patch (LP: #1046461)
  - Support multiple accounts per service
  - Attempt automatic login
  - Remove logout buttons

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 
9
9
extern string hmac_sha1(string key, string message);
10
10
 
11
 
public class FlickrService : Object, Spit.Pluggable, Spit.Publishing.Service {
 
11
public class FlickrService : UOAPublishingService, Spit.Pluggable, Spit.Publishing.Service {
12
12
    private const string ICON_FILENAME = "flickr.png";
13
13
 
14
14
    private static Gdk.Pixbuf[] icon_pixbuf_set = null;
15
15
    
16
16
    public FlickrService(GLib.File resource_directory) {
 
17
        base("flickr");
17
18
        if (icon_pixbuf_set == null)
18
19
            icon_pixbuf_set = Resources.load_icon_set(resource_directory.get_child(ICON_FILENAME));
19
20
    }
20
21
 
21
 
    public int get_pluggable_interface(int min_host_interface, int max_host_interface) {
22
 
        return Spit.negotiate_interfaces(min_host_interface, max_host_interface,
23
 
            Spit.Publishing.CURRENT_INTERFACE);
24
 
    }
25
 
    
26
 
    public unowned string get_id() {
 
22
    public override unowned string get_id() {
27
23
        return "org.yorba.shotwell.publishing.flickr";
28
24
    }
29
25
    
30
 
    public unowned string get_pluggable_name() {
 
26
    public override unowned string get_pluggable_name() {
31
27
        return "Flickr";
32
28
    }
33
29
    
34
 
    public void get_info(ref Spit.PluggableInfo info) {
 
30
    public override void get_info(ref Spit.PluggableInfo info) {
35
31
        info.authors = "Lucas Beeler";
36
32
        info.copyright = _("Copyright 2009-2012 Yorba Foundation");
37
33
        info.translators = Resources.TRANSLATORS;
43
39
        info.icons = icon_pixbuf_set;
44
40
    }
45
41
 
46
 
    public void activation(bool enabled) {
47
 
    }
48
 
 
49
 
    public Spit.Publishing.Publisher create_publisher(Spit.Publishing.PluginHost host) {
50
 
        return new Publishing.Flickr.FlickrPublisher(this, host);
 
42
    public override Spit.Publishing.Publisher create_publisher(string? account_name, Spit.Publishing.PluginHost host) {
 
43
        SharingAccount account = find_account(account_name);
 
44
        return new Publishing.Flickr.FlickrPublisher(this, account, host);
51
45
    }
52
46
    
53
 
    public Spit.Publishing.Publisher.MediaType get_supported_media() {
 
47
    public override Spit.Publishing.Publisher.MediaType get_supported_media() {
54
48
        return (Spit.Publishing.Publisher.MediaType.PHOTO |
55
49
            Spit.Publishing.Publisher.MediaType.VIDEO);
56
50
    }
57
 
 
58
 
    public bool is_enabled() {
59
 
        SharingAccounts accounts = new SharingAccounts();
60
 
        return accounts.get_account_for_provider("flickr") != null;
61
 
    }
62
51
}
63
52
 
64
53
namespace Publishing.Flickr {
112
101
    private bool was_started = false;
113
102
    private Session session = null;
114
103
    private PublishingOptionsPane publishing_options_pane = null;
115
 
    private Signon.AuthSession auth_session = null;
 
104
    private UOAPublisherAuthenticator authenticator = null;
116
105
   
117
106
    private PublishingParameters parameters = null;
118
107
 
119
108
    public FlickrPublisher(Spit.Publishing.Service service,
 
109
        SharingAccount account,
120
110
        Spit.Publishing.PluginHost host) {
121
111
        debug("FlickrPublisher instantiated.");
122
112
        this.service = service;
123
113
        this.host = host;
124
114
        this.session = new Session();
 
115
        authenticator = new UOAPublisherAuthenticator(account, host,
 
116
                                                      SERVICE_WELCOME_MESSAGE);
125
117
        this.parameters = new PublishingParameters();
126
118
        
127
119
        session.authenticated.connect(on_session_authenticated);
 
120
        HashTable<string,Value?> data =
 
121
            authenticator.get_authentication_data();
 
122
        session.set_api_credentials(data.lookup("ConsumerKey").get_string(),
 
123
                                    data.lookup("ConsumerSecret").get_string());
 
124
        authenticator.authenticated.connect(on_authenticator_authenticated);
128
125
    }
129
126
    
130
127
    ~FlickrPublisher() {
131
128
        session.authenticated.disconnect(on_session_authenticated);
132
129
    }
133
130
    
134
 
    private void invalidate_persistent_session() {
135
 
        set_persistent_access_phase_token("");
136
 
        set_persistent_access_phase_token_secret("");
137
 
        set_persistent_access_phase_username("");
138
 
    }
139
 
    
140
 
    private bool is_persistent_session_valid() {
141
 
        return (get_persistent_access_phase_username() != null &&
142
 
                get_persistent_access_phase_token() != null &&
143
 
                get_persistent_access_phase_token_secret() != null);
144
 
    }
145
 
    
146
 
    private string? get_persistent_access_phase_username() {
147
 
        return host.get_config_string("access_phase_username", null);
148
 
    }
149
 
    
150
 
    private void set_persistent_access_phase_username(string username) {
151
 
        host.set_config_string("access_phase_username", username);
152
 
    }
153
 
 
154
 
    private string? get_persistent_access_phase_token() {
155
 
        return host.get_config_string("access_phase_token", null);
156
 
    }
157
 
 
158
 
    private void set_persistent_access_phase_token(string token) {
159
 
        host.set_config_string("access_phase_token", token);
160
 
    }
161
 
 
162
 
    private string? get_persistent_access_phase_token_secret() {
163
 
        return host.get_config_string("access_phase_token_secret", null);
164
 
    }
165
 
 
166
 
    private void set_persistent_access_phase_token_secret(string secret) {
167
 
        host.set_config_string("access_phase_token_secret", secret);
168
 
    }
169
 
 
170
131
    private bool get_persistent_strip_metadata() {
171
132
        return host.get_config_bool("strip_metadata", false);
172
133
    }
175
136
        host.set_config_bool("strip_metadata", strip_metadata);
176
137
    }    
177
138
 
178
 
    private void on_welcome_pane_login_clicked() {
179
 
        if (!running)
180
 
            return;
181
 
 
182
 
        debug("EVENT: user clicked 'Login' button in the welcome pane");
183
 
        
184
 
        HashTable<string,Value?> data = null;
185
 
        string mechanism = null;
186
 
        SharingAccounts accounts = new SharingAccounts();
187
 
 
188
 
        SharingAccount? account = accounts.get_account_for_provider("flickr");
189
 
        if (account != null) {
190
 
            try {
191
 
                auth_session = account.create_auth_session();
192
 
                data = account.get_session_parameters(out mechanism);
193
 
                debug("Got account data");
194
 
            } catch (GLib.Error e) {
195
 
                warning("EVENT: couldn't create session for account: %s",
196
 
                        e.message);
197
 
            }
198
 
        }
199
 
 
200
 
        if (data == null) {
201
 
            warning ("No account authentication data");
202
 
            host.post_error(new Spit.Publishing.PublishingError.SERVICE_ERROR(
203
 
                "Error while accessing the account"));
204
 
            return;
205
 
        }
206
 
 
207
 
        session.set_api_credentials(data.lookup("ConsumerKey").get_string(),
208
 
                                    data.lookup("ConsumerSecret").get_string());
209
 
 
210
 
        var windowId = host.get_dialog_xid();
211
 
        if (windowId != 0) {
212
 
            data.insert("WindowId", (uint)windowId);
213
 
        }
214
 
 
215
 
        auth_session.process(data, mechanism, on_processed);
216
 
        host.set_service_locked(false);
217
 
    }
218
 
 
219
 
    public void on_processed(Signon.AuthSession self, owned HashTable<string,Value?> session_data, GLib.Error error){
220
 
        /* TODO: handle errors */
221
 
 
 
139
    public void on_authenticator_authenticated(owned HashTable<string,Value?> session_data) {
222
140
        host.set_service_locked(true);
223
141
        host.install_account_fetch_wait_pane();
224
142
 
237
155
        
238
156
        parameters.username = session.get_username();
239
157
        
240
 
        set_persistent_access_phase_token(session.get_access_phase_token());
241
 
        set_persistent_access_phase_token_secret(session.get_access_phase_token_secret());
242
 
        set_persistent_access_phase_username(session.get_username());
243
 
        
244
158
        do_fetch_account_info();
245
159
    }
246
160
 
277
191
 
278
192
    private void on_publishing_options_pane_publish(bool strip_metadata) {
279
193
        publishing_options_pane.publish.disconnect(on_publishing_options_pane_publish);
280
 
        publishing_options_pane.logout.disconnect(on_publishing_options_pane_logout);
281
194
        
282
195
        if (!is_running())
283
196
            return;
286
199
        do_publish(strip_metadata);
287
200
    }
288
201
 
289
 
    private void on_publishing_options_pane_logout() {
290
 
        publishing_options_pane.publish.disconnect(on_publishing_options_pane_publish);
291
 
        publishing_options_pane.logout.disconnect(on_publishing_options_pane_logout);
292
 
 
293
 
        if (!is_running())
294
 
            return;
295
 
 
296
 
        debug("EVENT: user clicked the 'Logout' button in the publishing options pane");
297
 
 
298
 
        do_logout();
299
 
    }
300
 
 
301
202
    private void on_upload_status_updated(int file_number, double completed_fraction) {
302
203
        if (!is_running())
303
204
            return;
335
236
        host.post_error(err);
336
237
    }
337
238
 
338
 
    private void do_show_login_welcome_pane() {
339
 
        debug("ACTION: installing login welcome pane");
340
 
 
341
 
        host.set_service_locked(false);
342
 
        host.install_welcome_pane(SERVICE_WELCOME_MESSAGE, on_welcome_pane_login_clicked);
343
 
    }
344
 
    
345
239
    private void do_fetch_account_info() {
346
240
        debug("ACTION: running network transaction to fetch account information");
347
241
 
407
301
        debug("ACTION: logging user out, deauthenticating session, and erasing stored credentials");
408
302
 
409
303
        session.deauthenticate();
410
 
        invalidate_persistent_session();
411
304
 
412
305
        running = false;
413
306
 
438
331
        publishing_options_pane = new PublishingOptionsPane(this, parameters,
439
332
            host.get_publishable_media_type(), builder, get_persistent_strip_metadata());
440
333
        publishing_options_pane.publish.connect(on_publishing_options_pane_publish);
441
 
        publishing_options_pane.logout.connect(on_publishing_options_pane_logout);
442
334
        host.install_dialog_pane(publishing_options_pane);
443
335
    }
444
336
    
513
405
        running = true;
514
406
        was_started = true;
515
407
        
516
 
        if (is_persistent_session_valid()) {
517
 
            debug("attempt start: a persistent session is available; using it");
518
 
 
519
 
            session.authenticate_from_persistent_credentials(get_persistent_access_phase_token(),
520
 
                get_persistent_access_phase_token_secret(), get_persistent_access_phase_username());
521
 
        } else {
522
 
            debug("attempt start: no persistent session available; showing login welcome pane");
523
 
 
524
 
            do_show_login_welcome_pane();
525
 
        }
 
408
        authenticator.authenticate();
526
409
    }
527
410
    
528
411
    public void start() {
782
665
            username != null);
783
666
    }
784
667
 
785
 
    public void authenticate_from_persistent_credentials(string token, string secret,
786
 
        string username) {
787
 
        this.access_phase_token = token;
788
 
        this.access_phase_token_secret = secret;
789
 
        this.username = username;
790
 
        
791
 
        authenticated();
792
 
    }
793
 
    
794
668
    public void deauthenticate() {
795
669
        access_phase_token = null;
796
670
        access_phase_token_secret = null;
894
768
        return access_phase_token;
895
769
    }
896
770
    
897
 
    public string get_access_phase_token_secret() {
898
 
        assert(access_phase_token_secret != null);
899
 
        return access_phase_token_secret;
900
 
    }
901
 
    
902
771
    public string get_username() {
903
772
        assert(is_authenticated());
904
773
        return username;
931
800
    private Gtk.Label visibility_label = null;
932
801
    private Gtk.Label upload_info_label = null;
933
802
    private Gtk.Label size_label = null;
934
 
    private Gtk.Button logout_button = null;
935
803
    private Gtk.Button publish_button = null;
936
804
    private Gtk.ComboBoxText visibility_combo = null;
937
805
    private Gtk.ComboBoxText size_combo = null;
943
811
    private Spit.Publishing.Publisher.MediaType media_type;
944
812
 
945
813
    public signal void publish(bool strip_metadata);
946
 
    public signal void logout();
947
814
 
948
815
    public PublishingOptionsPane(FlickrPublisher publisher, PublishingParameters parameters,
949
816
        Spit.Publishing.Publisher.MediaType media_type, Gtk.Builder builder, bool strip_metadata) {
955
822
        pane_widget = (Gtk.Box) this.builder.get_object("flickr_pane");
956
823
        visibility_label = (Gtk.Label) this.builder.get_object("visibility_label");
957
824
        upload_info_label = (Gtk.Label) this.builder.get_object("upload_info_label");
958
 
        logout_button = (Gtk.Button) this.builder.get_object("logout_button");
959
825
        publish_button = (Gtk.Button) this.builder.get_object("publish_button");
960
826
        visibility_combo = (Gtk.ComboBoxText) this.builder.get_object("visibility_combo");
961
827
        size_combo = (Gtk.ComboBoxText) this.builder.get_object("size_combo");
1002
868
        
1003
869
        strip_metadata_check.set_active(strip_metadata);
1004
870
 
1005
 
        logout_button.clicked.connect(on_logout_clicked);
1006
871
        publish_button.clicked.connect(on_publish_clicked);
1007
872
    }
1008
873
 
1009
 
    private void on_logout_clicked() {
1010
 
        logout();
1011
 
    }
1012
 
 
1013
874
    private void on_publish_clicked() {
1014
875
        parameters.visibility_specification =
1015
876
            visibilities[visibility_combo.get_active()].specification;
1076
937
        publish(strip_metadata_check.get_active());
1077
938
    }
1078
939
    
1079
 
    protected void notify_logout() {
1080
 
        logout();
1081
 
    }
1082
 
 
1083
940
    public Gtk.Widget get_widget() {
1084
941
        return pane_widget;
1085
942
    }
1090
947
    
1091
948
    public void on_pane_installed() {        
1092
949
        publish.connect(notify_publish);
1093
 
        logout.connect(notify_logout);
1094
950
    }
1095
951
    
1096
952
    public void on_pane_uninstalled() {
1097
953
        publish.disconnect(notify_publish);
1098
 
        logout.disconnect(notify_logout);
1099
954
    }
1100
955
}
1101
956