summaryrefslogtreecommitdiff
path: root/plugins/shotwell-publishing/FlickrPublishing.vala
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2023-06-28 21:35:52 +0200
committerJörg Frings-Fürst <debian@jff.email>2023-06-28 21:35:52 +0200
commitb86540b743f1a87a163ffb811c8fe22a01fefa38 (patch)
treeb47cb3bb83c2377234226fb3987ab3320a987dd9 /plugins/shotwell-publishing/FlickrPublishing.vala
parentac6e0b731b9f0b2efd392e3309a5c07e2a66adad (diff)
parente905d8e16eec152d19797937f13ba3cf4b8f8aca (diff)
Merge branch 'release/debian/0.32.1-1'debian/0.32.1-1
Diffstat (limited to 'plugins/shotwell-publishing/FlickrPublishing.vala')
-rw-r--r--plugins/shotwell-publishing/FlickrPublishing.vala246
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(