diff options
Diffstat (limited to 'plugins/shotwell-publishing/FlickrPublishing.vala')
-rw-r--r-- | plugins/shotwell-publishing/FlickrPublishing.vala | 246 |
1 files changed, 107 insertions, 139 deletions
diff --git a/plugins/shotwell-publishing/FlickrPublishing.vala b/plugins/shotwell-publishing/FlickrPublishing.vala index 5a80284..8c7e9a1 100644 --- a/plugins/shotwell-publishing/FlickrPublishing.vala +++ b/plugins/shotwell-publishing/FlickrPublishing.vala @@ -5,15 +5,8 @@ */ public class FlickrService : Object, Spit.Pluggable, Spit.Publishing.Service { - private const string ICON_FILENAME = "flickr.png"; - private static Gdk.Pixbuf[] icon_pixbuf_set = null; - - public FlickrService(GLib.File resource_directory) { - if (icon_pixbuf_set == null) - icon_pixbuf_set = Resources.load_from_resource - (Resources.RESOURCE_PATH + "/" + ICON_FILENAME); - } + public FlickrService() {} public int get_pluggable_interface(int min_host_interface, int max_host_interface) { return Spit.negotiate_interfaces(min_host_interface, max_host_interface, @@ -21,23 +14,19 @@ public class FlickrService : Object, Spit.Pluggable, Spit.Publishing.Service { } public unowned string get_id() { - return "org.yorba.shotwell.publishing.flickr"; + return "org.gnome.shotwell.publishing.flickr"; } public unowned string get_pluggable_name() { return "Flickr"; } - public void get_info(ref Spit.PluggableInfo info) { + public Spit.PluggableInfo get_info() { + var info = new Spit.PluggableInfo(); info.authors = "Lucas Beeler"; info.copyright = _("Copyright 2016 Software Freedom Conservancy Inc."); - info.translators = Resources.TRANSLATORS; - info.version = _VERSION; - info.website_name = Resources.WEBSITE_NAME; - info.website_url = Resources.WEBSITE_URL; - info.is_license_wordwrapped = false; - info.license = Resources.LICENSE; - info.icons = icon_pixbuf_set; + + return info; } public void activation(bool enabled) { @@ -80,10 +69,12 @@ internal class VisibilitySpecification { // not a struct because we want reference semantics internal class PublishingParameters { public UserKind user_kind; - public int64 quota_free_bytes; + public int64 max_images_count; + public uint64 uploaded_images_count; public int photo_major_axis_size; public string username; public VisibilitySpecification visibility_specification; + public bool strip_metadata; public PublishingParameters() { } @@ -154,30 +145,7 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object { parameters.username = session.get_username(); - do_fetch_account_info(); - } - - private void on_account_fetch_txn_completed(Publishing.RESTSupport.Transaction txn) { - txn.completed.disconnect(on_account_fetch_txn_completed); - txn.network_error.disconnect(on_account_fetch_txn_error); - - if (!is_running()) - return; - - debug("EVENT: account fetch transaction response received over the network"); - do_parse_account_info_from_xml(txn.get_response()); - } - - private void on_account_fetch_txn_error(Publishing.RESTSupport.Transaction txn, - Spit.Publishing.PublishingError err) { - txn.completed.disconnect(on_account_fetch_txn_completed); - txn.network_error.disconnect(on_account_fetch_txn_error); - - if (!is_running()) - return; - - debug("EVENT: account fetch transaction caused a network error"); - host.post_error(err); + do_fetch_account_info.begin(); } private void on_account_info_available() { @@ -196,7 +164,7 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object { return; debug("EVENT: user clicked the 'Publish' button in the publishing options pane"); - do_publish(strip_metadata); + do_publish.begin(strip_metadata); } private void on_publishing_options_pane_logout() { @@ -222,45 +190,19 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object { progress_reporter(file_number, completed_fraction); } - private void on_upload_complete(Publishing.RESTSupport.BatchUploader uploader, - int num_published) { - if (!is_running()) - return; - - debug("EVENT: uploader reports upload complete; %d items published.", num_published); - - uploader.upload_complete.disconnect(on_upload_complete); - uploader.upload_error.disconnect(on_upload_error); - - do_show_success_pane(); - } - - private void on_upload_error(Publishing.RESTSupport.BatchUploader uploader, - Spit.Publishing.PublishingError err) { - if (!is_running()) - return; - - debug("EVENT: uploader reports upload error = '%s'.", err.message); - - uploader.upload_complete.disconnect(on_upload_complete); - uploader.upload_error.disconnect(on_upload_error); - - host.post_error(err); - } - - private void do_fetch_account_info() { + private async void do_fetch_account_info() { debug("ACTION: running network transaction to fetch account information"); host.set_service_locked(true); host.install_account_fetch_wait_pane(); AccountInfoFetchTransaction txn = new AccountInfoFetchTransaction(session); - txn.completed.connect(on_account_fetch_txn_completed); - txn.network_error.connect(on_account_fetch_txn_error); - try { - txn.execute(); - } catch (Spit.Publishing.PublishingError err) { + yield txn.execute_async(); + debug("EVENT: account fetch transaction response received over the network"); + do_parse_account_info_from_xml(txn.get_response()); + } catch (Error err) { + debug("EVENT: account fetch transaction caused a network error"); host.post_error(err); } } @@ -275,9 +217,8 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object { string is_pro_str = response_doc.get_property_value(user_node, "ispro"); - Xml.Node* bandwidth_node = response_doc.get_named_child(user_node, "bandwidth"); - - string remaining_kb_str = response_doc.get_property_value(bandwidth_node, "remainingkb"); + string max_images_str = response_doc.get_property_value(user_node, "upload_limit"); + string uploaded_images_str = response_doc.get_property_value(user_node, "upload_count"); UserKind user_kind; if (is_pro_str == "0") @@ -287,10 +228,9 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object { else throw new Spit.Publishing.PublishingError.MALFORMED_RESPONSE( "Unable to determine if user has free or pro account"); - - var quota_bytes_left = int64.parse(remaining_kb_str) * 1024; - parameters.quota_free_bytes = quota_bytes_left; + parameters.max_images_count = int64.parse(max_images_str); + parameters.uploaded_images_count = int64.parse(uploaded_images_str); parameters.user_kind = user_kind; } catch (Spit.Publishing.PublishingError err) { @@ -353,7 +293,7 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object { return a.get_exposure_date_time().compare(b.get_exposure_date_time()); } - private void do_publish(bool strip_metadata) { + private async void do_publish(bool strip_metadata) { set_persistent_strip_metadata(strip_metadata); debug("ACTION: uploading media items to remote server."); @@ -377,9 +317,14 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object { sorted_list.sort(flickr_date_time_compare_func); Uploader uploader = new Uploader(session, sorted_list.to_array(), parameters, strip_metadata); - uploader.upload_complete.connect(on_upload_complete); - uploader.upload_error.connect(on_upload_error); - uploader.upload(on_upload_status_updated); + try { + var num_published = yield uploader.upload_async(on_upload_status_updated); + debug("EVENT: uploader reports upload complete; %d items published.", num_published); + do_show_success_pane(); + } catch (Error err) { + debug("EVENT: uploader reports upload error = '%s'.", err.message); + host.post_error(err); + } } private void do_show_success_pane() { @@ -506,7 +451,7 @@ private class UploadTransaction : Publishing.RESTSupport.OAuth1.UploadTransactio public UploadTransaction(Publishing.RESTSupport.OAuth1.Session session, PublishingParameters parameters, Spit.Publishing.Publishable publishable) { - base(session, publishable, "https://api.flickr.com/services/upload"); + base(session, publishable, "https://up.flickr.com/services/upload"); this.parameters = parameters; @@ -514,6 +459,18 @@ private class UploadTransaction : Publishing.RESTSupport.OAuth1.UploadTransactio add_argument("is_friend", ("%d".printf(parameters.visibility_specification.friends_level))); add_argument("is_family", ("%d".printf(parameters.visibility_specification.family_level))); + if (!parameters.strip_metadata) { + var title = publishable.get_param_string(Spit.Publishing.Publishable.PARAM_STRING_TITLE); + if (title != null && title != "") { + add_argument("title", title); + } + + var comment = publishable.get_param_string(Spit.Publishing.Publishable.PARAM_STRING_COMMENT); + if (comment != null && comment != "") { + add_argument("description", comment); + } + } + GLib.HashTable<string, string> disposition_table = new GLib.HashTable<string, string>(GLib.str_hash, GLib.str_equal); string? filename = publishable.get_publishing_name(); @@ -522,7 +479,7 @@ private class UploadTransaction : Publishing.RESTSupport.OAuth1.UploadTransactio /// TODO: This may need to be revisited to send the title separately; please see /// http://www.flickr.com/services/api/upload.api.html for more details. - disposition_table.insert("filename", Soup.URI.encode( + disposition_table.insert("filename", GLib.Uri.escape_string( publishable.get_param_string(Spit.Publishing.Publishable.PARAM_STRING_BASENAME), null)); disposition_table.insert("name", "photo"); @@ -530,9 +487,9 @@ private class UploadTransaction : Publishing.RESTSupport.OAuth1.UploadTransactio set_binary_disposition_table(disposition_table); } - public override void execute() throws Spit.Publishing.PublishingError { + public override async void execute_async() throws Spit.Publishing.PublishingError { this.authorize(); - base.execute(); + yield base.execute_async(); } } @@ -606,19 +563,19 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, GLib.Object { string upload_label_text = _("You are logged into Flickr as %s.\n\n").printf(parameters.username); if (parameters.user_kind == UserKind.FREE) { - upload_label_text += _("Your free Flickr account limits how much data you can upload per month.\nThis month you have %s remaining in your upload quota.").printf(GLib.format_size(parameters.quota_free_bytes, FormatSizeFlags.LONG_FORMAT | FormatSizeFlags.IEC_UNITS)); + upload_label_text += _("Your free Flickr account limits how many photos you can upload to the service.\nYou have uploaded %llu out of your %lld file limit.").printf(parameters.uploaded_images_count, parameters.max_images_count); } else { - upload_label_text += _("Your Flickr Pro account entitles you to unlimited uploads."); + upload_label_text += ngettext("Your Flickr Pro account entitles you to unlimited uploads. You have currently uploaded a file", "Your Flickr Pro account entitles you to unlimited uploads. You have currently uploaded %d files", (int) parameters.uploaded_images_count).printf((int) parameters.uploaded_images_count); } upload_info_label.set_label(upload_label_text); - string visibility_label_text = _("Photos _visible to:"); + string visibility_label_text = _("Photos _visible to"); if ((media_type == Spit.Publishing.Publisher.MediaType.VIDEO)) { - visibility_label_text = _("Videos _visible to:"); + visibility_label_text = _("Videos _visible to"); } else if ((media_type == (Spit.Publishing.Publisher.MediaType.PHOTO | Spit.Publishing.Publisher.MediaType.VIDEO))) { - visibility_label_text = _("Photos and videos _visible to:"); + visibility_label_text = _("Photos and videos _visible to"); } visibility_label.set_label(visibility_label_text); @@ -646,6 +603,7 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, GLib.Object { } private void on_publish_clicked() { + parameters.strip_metadata = strip_metadata_check.get_active(); parameters.visibility_specification = visibilities[visibility_combo.get_active()].specification; @@ -765,52 +723,62 @@ internal class Uploader : Publishing.RESTSupport.BatchUploader { if (!publishable_metadata.has_iptc()) return; - if (publishable_metadata.has_tag("Iptc.Application2.Caption")) - publishable_metadata.set_tag_string("Iptc.Application2.Caption", - Publishing.RESTSupport.asciify_string(publishable_metadata.get_tag_string( - "Iptc.Application2.Caption"))); - - if (publishable_metadata.has_tag("Iptc.Application2.Headline")) - publishable_metadata.set_tag_string("Iptc.Application2.Headline", - Publishing.RESTSupport.asciify_string(publishable_metadata.get_tag_string( - "Iptc.Application2.Headline"))); - - if (publishable_metadata.has_tag("Iptc.Application2.Keywords")) { - Gee.Set<string> keyword_set = new Gee.HashSet<string>(); - string[] iptc_keywords = publishable_metadata.get_tag_multiple("Iptc.Application2.Keywords"); - if (iptc_keywords != null) - foreach (string keyword in iptc_keywords) - keyword_set.add(keyword); - - string[] xmp_keywords = publishable_metadata.get_tag_multiple("Xmp.dc.subject"); - if (xmp_keywords != null) - foreach (string keyword in xmp_keywords) - keyword_set.add(keyword); - - string[] all_keywords = keyword_set.to_array(); - // append a null pointer to the end of all_keywords -- this is a necessary workaround - // for http://trac.yorba.org/ticket/3264. See also http://trac.yorba.org/ticket/3257, - // which describes the user-visible behavior seen in the Flickr Connector as a result - // of the former bug. - all_keywords += null; - - string[] no_keywords = new string[1]; - // append a null pointer to the end of no_keywords -- this is a necessary workaround - // for http://trac.yorba.org/ticket/3264. See also http://trac.yorba.org/ticket/3257, - // which describes the user-visible behavior seen in the Flickr Connector as a result - // of the former bug. - no_keywords[0] = null; - - publishable_metadata.set_tag_multiple("Xmp.dc.subject", all_keywords); - publishable_metadata.set_tag_multiple("Iptc.Application2.Keywords", no_keywords); - - try { - publishable_metadata.save_file(publishable.get_serialized_file().get_path()); - } catch (GLib.Error err) { - warning("couldn't write metadata to file '%s' for upload preprocessing.", - publishable.get_serialized_file().get_path()); + try { + if (publishable_metadata.try_has_tag("Iptc.Application2.Caption")) + publishable_metadata.try_set_tag_string("Iptc.Application2.Caption", + Publishing.RESTSupport.asciify_string(publishable_metadata.try_get_tag_string( + "Iptc.Application2.Caption"))); + } catch (Error err) {} + + try { + if (publishable_metadata.try_has_tag("Iptc.Application2.Headline")) + publishable_metadata.try_set_tag_string("Iptc.Application2.Headline", + Publishing.RESTSupport.asciify_string(publishable_metadata.try_get_tag_string( + "Iptc.Application2.Headline"))); + } catch (Error error) {} + + try { + if (publishable_metadata.try_has_tag("Iptc.Application2.Keywords")) { + Gee.Set<string> keyword_set = new Gee.HashSet<string>(); + string[] iptc_keywords = publishable_metadata.try_get_tag_multiple("Iptc.Application2.Keywords"); + if (iptc_keywords != null) + foreach (string keyword in iptc_keywords) + keyword_set.add(keyword); + + string[] xmp_keywords = publishable_metadata.try_get_tag_multiple("Xmp.dc.subject"); + if (xmp_keywords != null) + foreach (string keyword in xmp_keywords) + keyword_set.add(keyword); + + string[] all_keywords = keyword_set.to_array(); + // append a null pointer to the end of all_keywords -- this is a necessary workaround + // https://bugzilla.gnome.org/show_bug.cgi?id=712479. See also + // https://bugzilla.gnome.org/show_bug.cgi?id=717438 which describes the user-visible + // behavior seen in the Flickr Connector as a result of the former bug. + all_keywords += null; + + string[] no_keywords = new string[1]; + // append a null pointer to the end of no_keywords -- this is a necessary workaround + // for similar reasons as above. + no_keywords[0] = null; + + try { + publishable_metadata.try_set_tag_multiple("Xmp.dc.subject", all_keywords); + } catch (Error error) { + } + try { + publishable_metadata.try_set_tag_multiple("Iptc.Application2.Keywords", no_keywords); + } catch (Error error) { + } + + try { + publishable_metadata.save_file(publishable.get_serialized_file().get_path()); + } catch (GLib.Error err) { + warning("couldn't write metadata to file '%s' for upload preprocessing.", + publishable.get_serialized_file().get_path()); + } } - } + } catch (Error error) {} } protected override Publishing.RESTSupport.Transaction create_transaction( |