diff options
Diffstat (limited to 'plugins/shotwell-publishing-extras')
-rw-r--r-- | plugins/shotwell-publishing-extras/GalleryConnector.vala | 2035 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/RajcePublishing.vala | 1554 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/YandexPublishing.vala | 642 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/gallery3.png | bin | 802 -> 0 bytes | |||
-rw-r--r-- | plugins/shotwell-publishing-extras/gallery3_authentication_pane.ui | 216 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/gallery3_publishing_options_pane.ui | 238 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/meson.build | 21 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/org.gnome.Shotwell.Publishing.Extras.gresource.xml | 12 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/rajce.png | bin | 1650 -> 0 bytes | |||
-rw-r--r-- | plugins/shotwell-publishing-extras/rajce_authentication_pane.ui | 142 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/rajce_publishing_options_pane.ui | 246 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/shotwell-publishing-extras.vala | 51 | ||||
-rw-r--r-- | plugins/shotwell-publishing-extras/yandex_publish_model.ui | 182 |
13 files changed, 0 insertions, 5339 deletions
diff --git a/plugins/shotwell-publishing-extras/GalleryConnector.vala b/plugins/shotwell-publishing-extras/GalleryConnector.vala deleted file mode 100644 index 9932862..0000000 --- a/plugins/shotwell-publishing-extras/GalleryConnector.vala +++ /dev/null @@ -1,2035 +0,0 @@ -/* Copyright 2012-2013 Joe Sapp nixphoeni@gentoo.org - * - * This software is licensed under the GNU LGPL (version 2.1 or later). - * See the COPYING file in this distribution. - */ - - -const string G3_VERSION = "0.1"; - -const string G3_LICENSE = """ -The Gallery3Publishing module is free software; you can redistribute it -and/or modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either version 2.1 -of the License, or (at your option) any later version. - -The Gallery3Publishing module is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with The Gallery3Publishing module; if not, write to the Free -Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -02110-1301 USA -"""; - -const string WEBSITE_URL = - "https://github.com/sappjw/shotwell-gallery3"; - -// This module's Spit.Module -private class ShotwellPublishingGallery3 : Object, Spit.Module { - private Spit.Pluggable[] pluggables = new Spit.Pluggable[0]; - - public ShotwellPublishingGallery3(GLib.File module_file) { - GLib.File resource_directory = module_file.get_parent(); - - pluggables += new Gallery3Service(resource_directory); - } - - public unowned string get_module_name() { - return _("Gallery3 publishing module"); - } - - public unowned string get_version() { - return G3_VERSION; - } - - public unowned string get_id() { - return "org.yorba.shotwell.sharing.gallery3"; - } - - public unowned Spit.Pluggable[]? get_pluggables() { - return pluggables; - } -} - -// The Pluggable -public class Gallery3Service : Object, Spit.Pluggable, - Spit.Publishing.Service { - private const string ICON_FILENAME = "gallery3.png"; - - private static Gdk.Pixbuf[] icon_pixbuf_set = null; - - public Gallery3Service(GLib.File resource_directory) { - if (icon_pixbuf_set == null) - icon_pixbuf_set = Resources.load_from_resource - (Resources.RESOURCE_PATH + "/" + ICON_FILENAME); - } - - public int get_pluggable_interface(int min_host_interface, - int max_host_interface) { - return Spit.negotiate_interfaces(min_host_interface, - max_host_interface, - Spit.Publishing.CURRENT_INTERFACE); - } - - public unowned string get_id() { - return "publishing-gallery3"; - } - - public unowned string get_pluggable_name() { - return "Gallery3"; - } - - public void get_info(ref Spit.PluggableInfo info) { - info.authors = "Joe Sapp"; - info.copyright = "2012-2013 Joe Sapp"; - info.translators = Resources.TRANSLATORS; - info.version = G3_VERSION; - info.website_url = WEBSITE_URL; - info.is_license_wordwrapped = false; - info.license = G3_LICENSE; - info.icons = icon_pixbuf_set; - } - - public void activation(bool enabled) { - } - - public Spit.Publishing.Publisher create_publisher( - Spit.Publishing.PluginHost host) { - return new Publishing.Gallery3.GalleryPublisher(this, host); - } - - public Spit.Publishing.Publisher.MediaType get_supported_media() { - return (Spit.Publishing.Publisher.MediaType.PHOTO | - Spit.Publishing.Publisher.MediaType.VIDEO); - } -} - - -namespace Publishing.Gallery3 { -private const string SERVICE_NAME = "Gallery3"; -private const string SERVICE_WELCOME_MESSAGE = - _("You are not currently logged into your Gallery.\n\nYou must have already signed up for a Gallery3 account to complete the login process."); -private const string DEFAULT_ALBUM_DIR = _("Shotwell"); -private const string DEFAULT_ALBUM_TITLE = - _("Shotwell default directory"); -private const string REST_PATH = "/index.php/rest"; - -private class Album { - - // Properties - public string name { get; private set; default = ""; } - public string title { get; private set; default = ""; } - public string summary { get; private set; default = ""; } - public string parentname { get; private set; default = ""; } - public string url { get; private set; default = ""; } - public string path { get; private set; default = ""; } - public bool editable { get; private set; default = false; } - - // Each element is a collection - public Album(Json.Object collection) { - - unowned Json.Object entity = - collection.get_object_member("entity"); - - title = entity.get_string_member("title"); - name = entity.get_string_member("name"); - parentname = entity.get_string_member("parent"); - url = collection.get_string_member("url"); - editable = entity.get_boolean_member("can_edit"); - - // Get the path from the last two elements of the URL. - // This should always be "/item/#" where "#" is a number. - path = strip_session_url(url); - - } - -} - -private class BaseGalleryTransaction : - Publishing.RESTSupport.Transaction { - - protected Json.Parser parser; - - // BaseGalleryTransaction constructor - public BaseGalleryTransaction(Session session, string endpoint_url, - string item_path = "", - Publishing.RESTSupport.HttpMethod method = - Publishing.RESTSupport.HttpMethod.POST) { - - // TODO: eventually we can remove this - if ((item_path != "") && (item_path[0] != '/')) { - warning("Bad item path, this is a bug!"); - error(item_path); - } - - base.with_endpoint_url(session, - endpoint_url + REST_PATH + item_path, - method); - - this.parser = new Json.Parser(); - - } - - protected unowned Json.Node get_root_node() - throws Spit.Publishing.PublishingError { - - string json_object; - unowned Json.Node root_node; - - json_object = get_response(); - - if ((null == json_object) || (0 == json_object.length)) - throw new Spit.Publishing.PublishingError.MALFORMED_RESPONSE( - "No response data from %s", get_endpoint_url()); - - try { - this.parser.load_from_data(json_object); - } - catch (GLib.Error e) { - // If this didn't work, reset the "executed" state - warning("ERROR: didn't load JSON data"); - set_is_executed(false); - throw new Spit.Publishing.PublishingError.PROTOCOL_ERROR(e.message); - } - - root_node = this.parser.get_root(); - if (root_node.is_null()) - throw new Spit.Publishing.PublishingError.MALFORMED_RESPONSE( - "Root node is null, doesn't appear to be JSON data"); - - return root_node; - - } - -} - -private class KeyFetchTransaction : BaseGalleryTransaction { - - private string key = ""; - - // KeyFetchTransaction constructor - // - // url: Base gallery URL - public KeyFetchTransaction(Session session, string url, - string username, string password) { - base(session, url); - add_argument("user", username); - add_argument("password", password); - } - - public string get_key() { - - if (key != "") - return key; - - key = get_response(); - - // The returned data isn't actually a JSON object... - if (null == key || "" == key || 0 == key.length) { - warning("No response data from \"%s\"", get_endpoint_url()); - return ""; - } - - // Eliminate quotes surrounding key - key = key[1:-1]; - - return key; - } - -} - -private class GalleryRequestTransaction : BaseGalleryTransaction { - - // GalleryRequestTransaction constructor - // - // item: Item URL component - public GalleryRequestTransaction(Session session, string item, - Publishing.RESTSupport.HttpMethod method = - Publishing.RESTSupport.HttpMethod.GET) { - - if (!session.is_authenticated()) { - error("Not authenticated"); - } - else { - base(session, session.url, item, method); - add_header("X-Gallery-Request-Key", session.key); - add_header("X-Gallery-Request-Method", "GET"); - } - - } - -} - -private class GetAlbumURLsTransaction : GalleryRequestTransaction { - - public GetAlbumURLsTransaction(Session session) { - - base(session, "/item/1"); - add_argument("type", "album"); - add_argument("scope", "all"); - - } - - public string [] get_album_urls() { - - unowned Json.Node root_node; - unowned Json.Array all_members; - - try { - root_node = get_root_node(); - } - catch (Spit.Publishing.PublishingError e) { - error("Could not get root node"); - } - - all_members = - root_node.get_object().get_array_member("members"); - - string [] member_urls = null; - - for (uint i = 0; i <= all_members.get_length() - 1; i++) - member_urls += all_members.get_string_element(i); - - return member_urls; - - } - -} - -private class GetAlbumsTransaction : GalleryRequestTransaction { - - // Properties - // Original list of album URLs - public string [] album_urls { get; private set; default = null; } - // How many URLs have been sent? - public uint urls_sent { get; private set; default = 0; } - // Are there (possibly) more URLs to send? - public bool more_urls { get; private set; default = false; } - - public GetAlbumsTransaction(Session session, string [] _album_urls, - uint start = 0) { - - base(session, "/items"); - add_argument("scope", "all"); - - // Save original list of URLs - album_urls = _album_urls; - - // Wrap each URL in double quotes and separate by a comma, but - // we should try to keep the length of the URL under 255 - // characters. We need to do this to avoid problems with URLs - // that are too long on some web servers (and, really, if there - // are alot of albums, this can get large quickly). - // The Gallery3 API should probably allow this in a POST - // transaction... - string url_list = "["; - string [] my_album_urls = null; - string? endpoint_url = session.get_endpoint_url(); - int url_length = (null != endpoint_url) ? - endpoint_url.length : 0; - url_length += 18; // for: ?scope=all&urls=[] - - // We have to allow at least one URL at a time - if (start <= album_urls.length - 1) { - - urls_sent = start; - do { - my_album_urls += "\"" + album_urls[urls_sent] + "\""; - // Add 3 for: "", - url_length += album_urls[urls_sent].length + 3; - urls_sent++; - } while ((urls_sent <= album_urls.length - 1) && - (url_length + - album_urls[urls_sent].length + 3 <= 255)); - url_list += string.joinv(",", my_album_urls); - - more_urls = (urls_sent <= (album_urls.length - 1)); - - } - url_list += "]"; - - add_argument("urls", url_list); - - } - - public Album [] get_albums() - throws Spit.Publishing.PublishingError { - - Album [] albums = null; - Album tmp_album; - unowned Json.Node root_node = get_root_node(); - unowned Json.Array members = root_node.get_array(); - - // Only add editable items - for (uint i = 0; i <= members.get_length() - 1; i++) { - tmp_album = new Album(members.get_object_element(i)); - - if (tmp_album.editable) - albums += tmp_album; - else - warning(@"Album \"$(tmp_album.title)\" is not editable"); - } - - return albums; - } - -} - -// Class to create or get a tag URL. -// Tag URLs are placed in the "item_tags" object and relate an item and -// its tags. -private class GalleryGetTagTransaction : BaseGalleryTransaction { - - public GalleryGetTagTransaction(Session session, string tag_name) { - - if (!session.is_authenticated()) { - error("Not authenticated"); - } - else { - Json.Generator entity = new Json.Generator(); - Json.Node root_node = new Json.Node(Json.NodeType.OBJECT); - Json.Object obj = new Json.Object(); - - base(session, session.url, - "/tags", - Publishing.RESTSupport.HttpMethod.POST); - add_header("X-Gallery-Request-Key", session.key); - add_header("X-Gallery-Request-Method", "POST"); - - obj.set_string_member("name", tag_name); - root_node.set_object(obj); - entity.set_root(root_node); - - size_t entity_length; - string entity_value = entity.to_data(out entity_length); - - debug("created entity: %s", entity_value); - - add_argument("entity", entity_value); - } - - } - - public string tag_url() { - - unowned Json.Node root_node; - string url; - - try { - root_node = get_root_node(); - } - catch (Spit.Publishing.PublishingError e) { - error("Could not get root node"); - } - - url = - root_node.get_object().get_string_member("url"); - - return url; - - } - -} - -// Get the item_tags URL for a given item -private class GalleryGetItemTagsURLsTransaction : - GalleryRequestTransaction { - - private string item_tags_path = ""; - - public GalleryGetItemTagsURLsTransaction(Session session, - string item_url) { - - base(session, item_url); - - } - - public string get_item_tags_path() { - - unowned Json.Node root_node; - unowned Json.Object relationships, tags; - - if ("" == item_tags_path) { - - try { - root_node = get_root_node(); - } - catch (Spit.Publishing.PublishingError e) { - error("Could not get root node"); - } - - relationships = - root_node.get_object().get_object_member("relationships"); - tags = relationships.get_object_member("tags"); - - item_tags_path = tags.get_string_member("url"); - - // Remove the session URL from the beginning of this URL - item_tags_path = strip_session_url(item_tags_path); - - } - - return item_tags_path; - - } - -} - -// Set a tag relationship with an item -private class GallerySetTagRelationshipTransaction : - BaseGalleryTransaction { - - public GallerySetTagRelationshipTransaction(Session session, - string item_tags_path, string tag_url, string item_url) { - - if (!session.is_authenticated()) { - error("Not authenticated"); - } - else { - Json.Generator entity = new Json.Generator(); - Json.Node root_node = new Json.Node(Json.NodeType.OBJECT); - Json.Object obj = new Json.Object(); - - base(session, session.url, - item_tags_path, - Publishing.RESTSupport.HttpMethod.POST); - add_header("X-Gallery-Request-Key", session.key); - add_header("X-Gallery-Request-Method", "POST"); - - obj.set_string_member("tag", tag_url); - obj.set_string_member("item", item_url); - root_node.set_object(obj); - entity.set_root(root_node); - - size_t entity_length; - string entity_value = entity.to_data(out entity_length); - - debug("created entity: %s", entity_value); - - add_argument("entity", entity_value); - } - - } - -} - -private class GalleryAlbumCreateTransaction : BaseGalleryTransaction { - - // Properties - public PublishingParameters parameters { get; private set; } - // Private variables - private string? session_url; - - // GalleryAlbumCreateTransaction constructor - // - // parameters: New album parameters - public GalleryAlbumCreateTransaction(Session session, - PublishingParameters parameters) { - - if (!session.is_authenticated()) { - error("Not authenticated"); - } - else { - Json.Generator entity = new Json.Generator(); - Json.Node root_node = new Json.Node(Json.NodeType.OBJECT); - Json.Object obj = new Json.Object(); - - base(session, session.url, "/item/1", - Publishing.RESTSupport.HttpMethod.POST); - add_header("X-Gallery-Request-Key", session.key); - add_header("X-Gallery-Request-Method", "POST"); - - this.session_url = session.url; - this.parameters = parameters; - - obj.set_string_member("name", parameters.album_name); - obj.set_string_member("type", "album"); - obj.set_string_member("title", parameters.album_title); - root_node.set_object(obj); - entity.set_root(root_node); - - string entity_value = entity.to_data(null); - - debug("created entity: %s", entity_value); - - add_argument("entity", entity_value); - } - - } - - public string get_new_album_path() { - - unowned Json.Node root_node; - string new_path; - - try { - root_node = get_root_node(); - } - catch (Spit.Publishing.PublishingError e) { - error("Could not get root node"); - } - - new_path = - root_node.get_object().get_string_member("url"); - new_path = strip_session_url(new_path); - - return new_path; - - } - -} - -private class GalleryUploadTransaction : - Publishing.RESTSupport.UploadTransaction { - - private Session session; - private Json.Generator generator; - private PublishingParameters parameters; - private string item_url; - private string item_path; - private string item_tags_path; - - public GalleryUploadTransaction(Session session, - PublishingParameters parameters, - Spit.Publishing.Publishable publishable) { - - // TODO: eventually we can remove this - if (parameters.album_path[0] != '/') { - warning("Bad upload item path, this is a bug!"); - error(parameters.album_path); - } - - base.with_endpoint_url(session, publishable, - session.url + REST_PATH + parameters.album_path); - - this.parameters = parameters; - this.session = session; - - add_header("X-Gallery-Request-Key", session.key); - add_header("X-Gallery-Request-Method", "POST"); - - GLib.HashTable<string, string> disposition_table = - new GLib.HashTable<string, string>(GLib.str_hash, - GLib.str_equal); - string? title = publishable.get_publishing_name(); - string filename = publishable.get_param_string( - Spit.Publishing.Publishable.PARAM_STRING_BASENAME); - if (title == null || title == "") - //TODO: remove extension? - title = filename; - - disposition_table.insert("filename", @"$(filename)"); - disposition_table.insert("name", "file"); - - set_binary_disposition_table(disposition_table); - - // Do the JSON stuff - generator = new Json.Generator(); - string desc = publishable.get_param_string( - Spit.Publishing.Publishable.PARAM_STRING_COMMENT); - string type = (publishable.get_media_type() == - Spit.Publishing.Publisher.MediaType.VIDEO) ? - "movie" : "photo"; - - Json.Node root_node = new Json.Node(Json.NodeType.OBJECT); - Json.Object obj = new Json.Object(); - obj.set_string_member("name", filename); - obj.set_string_member("type", type); - obj.set_string_member("title", title); - obj.set_string_member("description", desc); - - root_node.set_object(obj); - generator.set_root(root_node); - - add_argument("entity", generator.to_data(null)); - } - - private string get_new_item_url() { - - string json_object; - string new_url; - unowned Json.Node root_node; - Json.Parser parser = new Json.Parser(); - - json_object = get_response(); - - if ((null == json_object) || (0 == json_object.length)) { - warning("No response data from %s", get_endpoint_url()); - return ""; - } - - debug("json_object: %s", json_object); - - try { - parser.load_from_data(json_object); - } - catch (GLib.Error e) { - // If this didn't work, reset the "executed" state - // TODO: can we recover from this? - warning("ERROR: didn't load JSON data"); - set_is_executed(false); - error(e.message); - } - - root_node = parser.get_root(); - if (root_node.is_null()) { - warning("Root node is null, doesn't appear to be JSON data"); - return ""; - } - - new_url = - root_node.get_object().get_string_member("url"); - - return new_url; - - } - - private void do_set_tag_relationship(string tag_url) - throws Spit.Publishing.PublishingError { - GallerySetTagRelationshipTransaction tag_txn = - new GallerySetTagRelationshipTransaction( - (Session) get_parent_session(), item_tags_path, - tag_url, item_url); - - tag_txn.execute(); - - debug("Response from setting tag relationship: %s", - tag_txn.get_response()); - } - - private string get_new_item_tags_path() { - GalleryGetItemTagsURLsTransaction tag_urls_txn = - new GalleryGetItemTagsURLsTransaction( - (Session) get_parent_session(), item_path); - - try { - tag_urls_txn.execute(); - } catch (Spit.Publishing.PublishingError err) { - debug("Problem getting the item_tags URL: %s", - err.message); - return ""; - } - - return tag_urls_txn.get_item_tags_path(); - } - - private string get_tag_url(string tag) { - - GalleryGetTagTransaction tag_txn = - new GalleryGetTagTransaction( - (Session) get_parent_session(), tag); - - try { - tag_txn.execute(); - } catch (Spit.Publishing.PublishingError err) { - debug("Problem getting the tags URL: %s", - err.message); - return ""; - } - - return tag_txn.tag_url(); - - } - - private void on_upload_completed() - throws Spit.Publishing.PublishingError { - - debug("EVENT: upload completed"); - - if (!parameters.strip_metadata) { - - string[] keywords; - - debug("EVENT: evaluating tags"); - - keywords = base.publishable.get_publishing_keywords(); - - // If this publishable has no tags, continue - if (null == keywords) { - debug("No tags"); - return; - } - - // Get URLs from the file we just finished uploading - item_url = get_new_item_url(); - item_path = strip_session_url(item_url); - item_tags_path = get_new_item_tags_path(); - debug("new item path is %s", item_path); - debug("item_tags path is %s", item_tags_path); - - // Verify these aren't empty - if (("" == item_path) || ("" == item_tags_path)) { - throw new - Spit.Publishing.PublishingError.COMMUNICATION_FAILED( - "Could not obtain URL of uploaded item or its " + - "\"item_tags\" relationship URL"); - } - - // Do the tagging here - foreach (string tag in keywords) { - debug(@"Found tag: $(tag)"); - string new_tag_url = get_tag_url(tag); - - try { - do_set_tag_relationship(new_tag_url); - } catch (Spit.Publishing.PublishingError err) { - debug("Problem setting the relationship between tag " + - "and item: %s", err.message); - throw err; - } - } - - } - - } - - public override void execute() - throws Spit.Publishing.PublishingError { - base.execute(); - - // Run tagging operations here - on_upload_completed(); - } - -} - - -public class GalleryPublisher : Spit.Publishing.Publisher, GLib.Object { - private const string BAD_FILE_MSG = _("\n\nThe file “%s” may not be supported by or may be too large for this instance of Gallery3."); - private const string BAD_MOVIE_MSG = _("\nNote that Gallery3 only supports the video types that Flowplayer does."); - - private weak Spit.Publishing.PluginHost host = null; - private Spit.Publishing.ProgressCallback progress_reporter = null; - private weak Spit.Publishing.Service service = null; - private Session session = null; - private bool running = false; - private Album[] albums = null; - private string key = null; - - private PublishingOptionsPane publishing_options_pane = null; - - public GalleryPublisher(Spit.Publishing.Service service, - Spit.Publishing.PluginHost host) { - this.service = service; - this.host = host; - this.session = new Session(); - } - - public bool is_running() { - return running; - } - - public Spit.Publishing.Service get_service() { - return service; - } - - public void start() { - if (is_running()) - return; - - if (host == null) - error("GalleryPublisher: start( ): can't start; this " + - "publisher is not restartable."); - - debug("GalleryPublisher: starting interaction."); - - running = true; - - key = get_api_key(); - - if ((null == key) || ("" == key)) - do_show_service_welcome_pane(); - else { - string url = get_gallery_url(); - string username = get_gallery_username(); - - if ((null == username) || (null == key) || (null == url)) - do_show_service_welcome_pane(); - else { - debug("ACTION: attempting network login for user " + - "'%s' at URL '%s' from saved credentials.", - username, url); - - host.install_account_fetch_wait_pane(); - - session.authenticate(url, username, key); - - // Initiate an album transaction - do_fetch_album_urls(); - } - } - } - - public void stop() { - debug("GalleryPublisher: stop( ) invoked."); - - running = false; - } - - // Config getters/setters - // API key - internal string? get_api_key() { - return host.get_config_string("api-key", null); - } - - internal void set_api_key(string key) { - host.set_config_string("api-key", key); - } - - // URL - internal string? get_gallery_url() { - return host.get_config_string("url", null); - } - - internal void set_gallery_url(string url) { - host.set_config_string("url", url); - } - - // Username - internal string? get_gallery_username() { - return host.get_config_string("username", null); - } - - internal void set_gallery_username(string username) { - host.set_config_string("username", username); - } - - internal bool? get_persistent_strip_metadata() { - return host.get_config_bool("strip-metadata", false); - } - - internal void set_persistent_strip_metadata(bool strip_metadata) { - host.set_config_bool("strip-metadata", strip_metadata); - } - - internal int? get_scaling_constraint_id() { - return host.get_config_int("scaling-constraint-id", 0); - } - - internal void set_scaling_constraint_id(int constraint) { - host.set_config_int("scaling-constraint-id", constraint); - } - - internal int? get_scaling_pixels() { - return host.get_config_int("scaling-pixels", 1024); - } - - internal void set_scaling_pixels(int pixels) { - host.set_config_int("scaling-pixels", pixels); - } - - // Pane installation functions - private void do_show_service_welcome_pane() { - debug("ACTION: showing service welcome pane."); - - host.install_welcome_pane(SERVICE_WELCOME_MESSAGE, - on_service_welcome_login); - } - - private void do_show_credentials_pane(CredentialsPane.Mode mode) { - debug("ACTION: showing credentials capture pane in %s mode.", - mode.to_string()); - - session.deauthenticate(); - - CredentialsPane creds_pane = - new CredentialsPane(host, mode, get_gallery_url(), - get_gallery_username(), get_api_key()); - creds_pane.go_back.connect(on_credentials_go_back); - creds_pane.login.connect(on_credentials_login); - - host.install_dialog_pane(creds_pane); - } - - private void do_network_login(string url, string username, - string password) { - debug("ACTION: attempting network login for user '%s' at URL " + - "'%s'.", username, url); - - host.install_login_wait_pane(); - - KeyFetchTransaction fetch_trans = - new KeyFetchTransaction(session, url, username, password); - fetch_trans.network_error.connect(on_key_fetch_error); - fetch_trans.completed.connect(on_key_fetch_complete); - - try { - fetch_trans.execute(); - } catch (Spit.Publishing.PublishingError err) { - debug("Caught an error attempting to login"); - // 403 errors may be recoverable, so don't post the error to - // our host immediately; instead, try to recover from it - on_key_fetch_error(fetch_trans, err); - } - } - - private void do_fetch_album_urls() { - - host.install_account_fetch_wait_pane(); - - GetAlbumURLsTransaction album_trans = - new GetAlbumURLsTransaction(session); - album_trans.network_error.connect(on_album_urls_fetch_error); - album_trans.completed.connect(on_album_urls_fetch_complete); - - try { - album_trans.execute(); - } catch (Spit.Publishing.PublishingError err) { - debug("Caught an error attempting to fetch albums"); - // 403 errors may be recoverable, so don't post the error to - // our host immediately; instead, try to recover from it - on_album_urls_fetch_error(album_trans, err); - } - - } - - private void do_fetch_albums(string [] album_urls, uint start = 0) { - - GetAlbumsTransaction album_trans = - new GetAlbumsTransaction(session, album_urls, start); - album_trans.network_error.connect(on_album_fetch_error); - album_trans.completed.connect(on_album_fetch_complete); - - try { - album_trans.execute(); - } catch (Spit.Publishing.PublishingError err) { - // 403 errors may be recoverable, so don't post the error to - // our host immediately; instead, try to recover from it - on_album_fetch_error(album_trans, err); - } - - } - - private void do_show_publishing_options_pane(string url, - string username) { - - debug("ACTION: showing publishing options pane"); - - Gtk.Builder builder = new Gtk.Builder(); - - try { - builder.add_from_resource(Resources.RESOURCE_PATH + - "/gallery3_publishing_options_pane.ui"); - } - catch (Error e) { - warning("Could not parse UI file! Error: %s.", e.message); - host.post_error( - new Spit.Publishing.PublishingError.LOCAL_FILE_ERROR( - _("A file required for publishing is unavailable. Publishing to %s can’t continue.") - .printf(SERVICE_NAME) - ) - ); - return; - } - - publishing_options_pane = - new PublishingOptionsPane(host, url, username, albums, - builder, get_persistent_strip_metadata(), - get_scaling_constraint_id(), get_scaling_pixels()); - publishing_options_pane.publish.connect( - on_publishing_options_pane_publish); - publishing_options_pane.logout.connect( - on_publishing_options_pane_logout); - host.install_dialog_pane(publishing_options_pane); - - } - - private void do_create_album(PublishingParameters parameters) { - - debug("ACTION: creating album"); - - GalleryAlbumCreateTransaction album_trans = - new GalleryAlbumCreateTransaction(session, parameters); - album_trans.network_error.connect(on_album_create_error); - album_trans.completed.connect(on_album_create_complete); - - try { - album_trans.execute(); - } catch (Spit.Publishing.PublishingError err) { - // 403 errors may be recoverable, so don't post the error to - // our host immediately; instead, try to recover from it - on_album_create_error(album_trans, err); - } - - } - - private void do_publish(PublishingParameters parameters) { - - debug("ACTION: publishing items"); - - set_persistent_strip_metadata(parameters.strip_metadata); - set_scaling_constraint_id( - (parameters.photo_major_axis_size <= 0) ? 0 : 1); - set_scaling_pixels(parameters.photo_major_axis_size); - host.set_service_locked(true); - progress_reporter = - host.serialize_publishables(parameters.photo_major_axis_size, - parameters.strip_metadata); - - // Serialization is a long and potentially cancellable - // operation, so before we use the publishables, make sure that - // the publishing interaction is still running. If it isn't, the - // publishing environment may be partially torn down so do a - // short-circuit return. - if (!is_running()) - return; - - Uploader uploader = - new Uploader(session, host.get_publishables(), - parameters); - uploader.upload_complete.connect(on_publish_complete); - uploader.upload_error.connect(on_publish_error); - uploader.upload(on_upload_status_updated); - - } - - private void do_show_success_pane() { - debug("ACTION: showing success pane."); - - host.set_service_locked(false); - host.install_success_pane(); - } - - // Callbacks - private void on_service_welcome_login() { - if (!is_running()) - return; - - debug("EVENT: user clicked 'Login' in welcome pane."); - - do_show_credentials_pane(CredentialsPane.Mode.INTRO); - } - - private void on_credentials_login(string url, string username, - string password) { - if (!is_running()) - return; - - debug("EVENT: user '%s' clicked 'Login' in credentials pane.", - username); - - set_gallery_url(url); - set_gallery_username(username); - do_network_login(url, username, password); - } - - private void on_credentials_go_back() { - if (!is_running()) - return; - - debug("EVENT: user is attempting to go back."); - - do_show_service_welcome_pane(); - } - - private void on_key_fetch_error( - Publishing.RESTSupport.Transaction bad_txn, - Spit.Publishing.PublishingError err) { - bad_txn.completed.disconnect(on_key_fetch_complete); - bad_txn.network_error.disconnect(on_key_fetch_error); - - if (!is_running()) - return; - - // ignore these events if the session is already auth'd - if (session.is_authenticated()) - return; - - debug("EVENT: network transaction to fetch key for login " + - "failed; response = '%s'.", - bad_txn.get_response()); - - // HTTP error 403 is invalid authentication -- if we get this - // error during key fetch then we can just show the login screen - // again with a retry message; if we get any error other than - // 403 though, we can't recover from it, so just post the error - // to the user - if (bad_txn.get_status_code() == 403) { - // TODO: can we give more detail on the problem? - do_show_credentials_pane(CredentialsPane.Mode.FAILED_RETRY); - } - else if (bad_txn.get_status_code() == 400) { - // This might not be a Gallery URL - // TODO: can we give more detail on the problem? - do_show_credentials_pane(CredentialsPane.Mode.NOT_GALLERY_URL); - } - else { - host.post_error(err); - } - } - - private void on_key_fetch_complete( - Publishing.RESTSupport.Transaction txn) { - txn.completed.disconnect(on_key_fetch_complete); - txn.network_error.disconnect(on_key_fetch_error); - - if (!is_running()) - return; - - // ignore these events if the session is already auth'd - if (session.is_authenticated()) - return; - - key = (txn as KeyFetchTransaction).get_key(); - - if (key == null) error("key doesn\'t exist"); - else { - string url = get_gallery_url(); - string username = get_gallery_username(); - - debug("EVENT: network transaction to fetch key completed " + - "successfully."); - - set_api_key(key); - session.authenticate(url, username, key); - - // Initiate an album transaction - do_fetch_album_urls(); - } - } - - private void on_album_urls_fetch_error( - Publishing.RESTSupport.Transaction bad_txn, - Spit.Publishing.PublishingError err) { - bad_txn.completed.disconnect(on_album_urls_fetch_complete); - bad_txn.network_error.disconnect(on_album_urls_fetch_error); - - if (!is_running()) - return; - - // ignore these events if the session is not auth'd - if (!session.is_authenticated()) - return; - - debug("EVENT: network transaction to fetch album URLs " + - "failed; response = \'%s\'.", - bad_txn.get_response()); - - // HTTP error 403 is invalid authentication -- if we get this - // error during key fetch then we can just show the login screen - // again with a retry message; if we get any error other than - // 403 though, we can't recover from it, so just post the error - // to the user - if (bad_txn.get_status_code() == 403) { - // TODO: can we give more detail on the problem? - do_show_credentials_pane(CredentialsPane.Mode.FAILED_RETRY); - } - else if (bad_txn.get_status_code() == 400) { - // This might not be a Gallery URL - // TODO: can we give more detail on the problem? - do_show_credentials_pane(CredentialsPane.Mode.NOT_GALLERY_URL); - } - else { - host.post_error(err); - } - } - - private void on_album_urls_fetch_complete( - Publishing.RESTSupport.Transaction txn) { - txn.completed.disconnect(on_album_urls_fetch_complete); - txn.network_error.disconnect(on_album_urls_fetch_error); - - if (!is_running()) - return; - - // ignore these events if the session is not auth'd - if (!session.is_authenticated()) - return; - - debug("EVENT: retrieving all album URLs."); - - string [] album_urls = - (txn as GetAlbumURLsTransaction).get_album_urls(); - - if (null == album_urls) { - - string url = session.url; - string username = session.username; - - do_show_publishing_options_pane(url, username); - - } - else - do_fetch_albums(album_urls); - } - - private void on_album_fetch_error( - Publishing.RESTSupport.Transaction bad_txn, - Spit.Publishing.PublishingError err) { - bad_txn.completed.disconnect(on_album_fetch_complete); - bad_txn.network_error.disconnect(on_album_fetch_error); - - if (!is_running()) - return; - - // ignore these events if the session is not auth'd - if (!session.is_authenticated()) - return; - - debug("EVENT: network transaction to fetch albums " + - "failed; response = \'%s\'.", - bad_txn.get_response()); - - // HTTP error 403 is invalid authentication -- if we get this - // error during key fetch then we can just show the login screen - // again with a retry message; if we get any error other than - // 403 though, we can't recover from it, so just post the error - // to the user - if (bad_txn.get_status_code() == 403) { - // TODO: can we give more detail on the problem? - do_show_credentials_pane(CredentialsPane.Mode.FAILED_RETRY); - } - else if (bad_txn.get_status_code() == 400) { - // This might not be a Gallery URL - // TODO: can we give more detail on the problem? - do_show_credentials_pane(CredentialsPane.Mode.NOT_GALLERY_URL); - } - else { - host.post_error(err); - } - } - - private void on_album_fetch_complete( - Publishing.RESTSupport.Transaction txn) { - txn.completed.disconnect(on_album_fetch_complete); - txn.network_error.disconnect(on_album_fetch_error); - - Album[] new_albums = null; - - if (!is_running()) - return; - - // ignore these events if the session is not auth'd - if (!session.is_authenticated()) - return; - - debug("EVENT: user is attempting to populate the album list."); - - try { - new_albums = - (txn as GetAlbumsTransaction).get_albums(); - } catch (Spit.Publishing.PublishingError err) { - on_album_fetch_error(txn, err); - } - - // Append new albums to existing - for (int i = 0; i <= new_albums.length - 1; i++) - albums += new_albums[i]; - - if ((txn as GetAlbumsTransaction).more_urls) { - - do_fetch_albums((txn as GetAlbumsTransaction).album_urls, - (txn as GetAlbumsTransaction).urls_sent); - - } - else { - - string url = session.url; - string username = session.username; - - do_show_publishing_options_pane(url, username); - - } - } - - private void on_album_create_error( - Publishing.RESTSupport.Transaction bad_txn, - Spit.Publishing.PublishingError err) { - bad_txn.completed.disconnect(on_album_create_complete); - bad_txn.network_error.disconnect(on_album_create_error); - - if (!is_running()) - return; - - // ignore these events if the session is not auth'd - if (!session.is_authenticated()) - return; - - debug("EVENT: network transaction to create an album " + - "failed; response = \'%s\'.", - bad_txn.get_response()); - - // HTTP error 403 is invalid authentication -- if we get this - // error during key fetch then we can just show the login screen - // again with a retry message; if we get any error other than - // 403 though, we can't recover from it, so just post the error - // to the user - if (bad_txn.get_status_code() == 403) { - // TODO: can we give more detail on the problem? - do_show_credentials_pane(CredentialsPane.Mode.FAILED_RETRY); - } - else if (bad_txn.get_status_code() == 400) { - // This might not be a Gallery URL - // TODO: can we give more detail on the problem? - do_show_credentials_pane(CredentialsPane.Mode.NOT_GALLERY_URL); - } - else { - host.post_error(err); - } - } - - private void on_album_create_complete( - Publishing.RESTSupport.Transaction txn) { - txn.completed.disconnect(on_album_create_complete); - txn.network_error.disconnect(on_album_create_error); - - if (!is_running()) - return; - - // ignore these events if the session is not auth'd - if (!session.is_authenticated()) - return; - - PublishingParameters new_params = - (txn as GalleryAlbumCreateTransaction).parameters; - new_params.album_path = - (txn as GalleryAlbumCreateTransaction).get_new_album_path(); - - debug("EVENT: user has created an album at \"%s\".", - new_params.album_path); - - do_publish(new_params); - } - - private void on_publish_error( - Publishing.RESTSupport.BatchUploader _uploader, - Spit.Publishing.PublishingError err) { - if (!is_running()) - return; - - Uploader uploader = _uploader as Uploader; - GLib.Error g3_err = err.copy(); - - debug("EVENT: uploader reports upload error = '%s' " + - "for file '%s' (code %d)", err.message, - uploader.current_publishable_name, uploader.status_code); - - uploader.upload_complete.disconnect(on_publish_complete); - uploader.upload_error.disconnect(on_publish_error); - - // Is this a 400 error? Then it may be a bad file. - if (uploader.status_code == 400) { - g3_err.message += - BAD_FILE_MSG.printf(uploader.current_publishable_name); - // Add an additional message if this appears to be a video - // file. - if (uploader.current_publishable_type == - Spit.Publishing.Publisher.MediaType.VIDEO) - g3_err.message += BAD_MOVIE_MSG; - } - host.post_error(g3_err); - } - - private void on_upload_status_updated(int file_number, - double completed_fraction) { - - if (!is_running()) - return; - - debug("EVENT: uploader reports upload %.2f percent complete.", - 100.0 * completed_fraction); - - assert(progress_reporter != null); - - progress_reporter(file_number, completed_fraction); - - } - - private void on_publish_complete( - Publishing.RESTSupport.BatchUploader uploader, - int num_published) { - uploader.upload_complete.disconnect(on_publish_complete); - uploader.upload_error.disconnect(on_publish_error); - - if (!is_running()) - return; - - // ignore these events if the session is not auth'd - if (!session.is_authenticated()) - return; - - debug("EVENT: publishing complete; %d items published", - num_published); - - do_show_success_pane(); - - } - - private void on_publishing_options_pane_logout() { - publishing_options_pane.publish.disconnect( - on_publishing_options_pane_publish); - publishing_options_pane.logout.disconnect( - on_publishing_options_pane_logout); - - if (!is_running()) - return; - - debug("EVENT: user is attempting to log out."); - - session.deauthenticate(); - do_show_service_welcome_pane(); - } - - private void on_publishing_options_pane_publish(PublishingParameters parameters) { - publishing_options_pane.publish.disconnect( - on_publishing_options_pane_publish); - publishing_options_pane.logout.disconnect( - on_publishing_options_pane_logout); - - if (!is_running()) - return; - - debug("EVENT: user is attempting to publish something."); - - if (parameters.is_to_new_album()) { - debug("EVENT: must create new album \"%s\" first.", - parameters.album_name); - do_create_album(parameters); - } - else { - do_publish(parameters); - } - } - -} - -internal class PublishingOptionsPane : Spit.Publishing.DialogPane, GLib.Object { - private const string DEFAULT_ALBUM_NAME = ""; - private const string LAST_ALBUM_CONFIG_KEY = "last-album"; - - private Gtk.Builder builder = null; - - private Gtk.Grid pane_widget = null; - private Gtk.Label title_label = null; - private Gtk.RadioButton use_existing_radio = null; - private Gtk.ComboBoxText existing_albums_combo = null; - private Gtk.RadioButton create_new_radio = null; - private Gtk.Entry new_album_entry = null; - private Gtk.ComboBoxText scaling_combo = null; - private Gtk.Entry pixels = null; - private Gtk.CheckButton strip_metadata_check = null; - private Gtk.Button publish_button = null; - private Gtk.Button logout_button = null; - - private Album[] albums; - private weak Spit.Publishing.PluginHost host; - - public signal void publish(PublishingParameters parameters); - public signal void logout(); - - public PublishingOptionsPane(Spit.Publishing.PluginHost host, - string url, string username, Album[] albums, - Gtk.Builder builder, bool strip_metadata, - int scaling_id, int scaling_pixels) { - this.albums = albums; - this.host = host; - - this.builder = builder; - assert(null != builder); - assert(builder.get_objects().length() > 0); - - // pull in all widgets from builder - pane_widget = builder.get_object("pane_widget") as Gtk.Grid; - title_label = builder.get_object("title_label") as Gtk.Label; - use_existing_radio = builder.get_object("publish_to_existing_radio") as Gtk.RadioButton; - existing_albums_combo = builder.get_object("existing_albums_combo") as Gtk.ComboBoxText; - scaling_combo = builder.get_object("scaling_constraint_combo") as Gtk.ComboBoxText; - pixels = builder.get_object("major_axis_pixels") as Gtk.Entry; - create_new_radio = builder.get_object("publish_new_radio") as Gtk.RadioButton; - new_album_entry = builder.get_object("new_album_name") as Gtk.Entry; - strip_metadata_check = this.builder.get_object("strip_metadata_check") as Gtk.CheckButton; - publish_button = builder.get_object("publish_button") as Gtk.Button; - logout_button = builder.get_object("logout_button") as Gtk.Button; - - // populate any widgets whose contents are - // programmatically-generated - title_label.set_label( - _("Publishing to %s as %s.").printf(url, username)); - strip_metadata_check.set_active(strip_metadata); - scaling_combo.set_active(scaling_id); - pixels.set_text(@"$(scaling_pixels)"); - - // connect all signals - use_existing_radio.clicked.connect(on_use_existing_radio_clicked); - create_new_radio.clicked.connect(on_create_new_radio_clicked); - new_album_entry.changed.connect(on_new_album_entry_changed); - scaling_combo.changed.connect(on_scaling_constraint_changed); - pixels.changed.connect(on_pixels_changed); - logout_button.clicked.connect(on_logout_clicked); - publish_button.clicked.connect(on_publish_clicked); - } - - private void on_publish_clicked() { - string album_name; - int photo_major_axis_size = - (scaling_combo.get_active() == 1) ? - int.parse(pixels.get_text()) : -1; - PublishingParameters param; - - if (create_new_radio.get_active()) { - album_name = new_album_entry.get_text(); - host.set_config_string(LAST_ALBUM_CONFIG_KEY, album_name); - param = - new PublishingParameters.to_new_album(album_name); - debug("Trying to publish to \"%s\"", album_name); - } else { - album_name = - albums[existing_albums_combo.get_active()].title; - host.set_config_string(LAST_ALBUM_CONFIG_KEY, album_name); - string album_path = - albums[existing_albums_combo.get_active()].path; - param = - new PublishingParameters.to_existing_album(album_path); - } - - param.photo_major_axis_size = photo_major_axis_size; - param.strip_metadata = strip_metadata_check.get_active(); - - publish(param); - } - - private void on_use_existing_radio_clicked() { - existing_albums_combo.set_sensitive(true); - new_album_entry.set_sensitive(false); - existing_albums_combo.grab_focus(); - update_publish_button_sensitivity(); - } - - private void on_create_new_radio_clicked() { - new_album_entry.set_sensitive(true); - existing_albums_combo.set_sensitive(false); - new_album_entry.grab_focus(); - update_publish_button_sensitivity(); - } - - private void on_logout_clicked() { - logout(); - } - - private void update_publish_button_sensitivity() { - string album_name = new_album_entry.get_text(); - publish_button.set_sensitive(!(album_name.strip() == "" && - create_new_radio.get_active())); - } - - private void on_new_album_entry_changed() { - update_publish_button_sensitivity(); - } - - private void update_pixel_entry_sensitivity() { - pixels.set_sensitive(scaling_combo.get_active() == 1); - } - - private void on_scaling_constraint_changed() { - update_pixel_entry_sensitivity(); - } - - private void on_pixels_changed() { - string orig_text = pixels.get_text(); - char last_char = orig_text[orig_text.length - 1]; - - if (orig_text.length > 0) { - if (!last_char.isdigit()) - pixels.set_text(orig_text.substring(0, - orig_text.length - 1)); - } - } - - public void installed() { - int default_album_id = -1; - string last_album = - host.get_config_string(LAST_ALBUM_CONFIG_KEY, ""); - for (int i = 0; i <= albums.length - 1; i++) { - existing_albums_combo.append_text(albums[i].title); - if ((albums[i].title == last_album) || - ((DEFAULT_ALBUM_NAME == albums[i].title) && - (-1 == default_album_id))) - default_album_id = i; - } - - if (albums.length == 0) { - existing_albums_combo.set_sensitive(false); - use_existing_radio.set_sensitive(false); - create_new_radio.set_active(true); - new_album_entry.grab_focus(); - new_album_entry.set_text(DEFAULT_ALBUM_NAME); - } else { - if (default_album_id >= 0) { - use_existing_radio.set_active(true); - existing_albums_combo.set_active(default_album_id); - new_album_entry.set_sensitive(false); - } else { - create_new_radio.set_active(true); - existing_albums_combo.set_active(0); - new_album_entry.set_text(DEFAULT_ALBUM_NAME); - new_album_entry.grab_focus(); - } - } - update_publish_button_sensitivity(); - update_pixel_entry_sensitivity(); - } - - public Gtk.Widget get_widget() { - return pane_widget; - } - - public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() { - return Spit.Publishing.DialogPane.GeometryOptions.NONE; - } - - public void on_pane_installed() { - installed(); - } - - public void on_pane_uninstalled() { - } -} - -internal class PublishingParameters { - - // Private variables for properties - private string _album_title = ""; - - // Properties - public string album_title { - get { - assert(is_to_new_album()); - return _album_title; - } - private set { _album_title = value; } - } - public string album_name { get; private set; default = ""; } - public string album_path { get; set; default = ""; } - public string entity_title { get; private set; default = ""; } - public int photo_major_axis_size { get; set; default = -1; } - public bool strip_metadata { get; set; default = false; } - - private PublishingParameters() { - } - - public PublishingParameters.to_new_album(string album_title) { - this.album_name = album_title.delimit(" ", '-'); - //this.album_name = this.album_name.delimit("\"\'", ''); - this.album_title = album_title; - } - - public PublishingParameters.to_existing_album(string album_path) { - this.album_path = album_path; - } - - public bool is_to_new_album() { - return (album_name != ""); - } -} - -internal class CredentialsPane : Spit.Publishing.DialogPane, GLib.Object { - public enum Mode { - INTRO, - FAILED_RETRY, - NOT_GALLERY_URL; - - public string to_string() { - switch (this) { - case Mode.INTRO: - return "INTRO"; - - case Mode.FAILED_RETRY: - return "FAILED_RETRY"; - - case Mode.NOT_GALLERY_URL: - return "NOT_GALLERY_URL"; - - default: - error("unrecognized CredentialsPane.Mode enumeration value"); - } - } - } - - private CredentialsGrid frame = null; - private Gtk.Widget grid_widget = null; - - public signal void go_back(); - public signal void login(string url, string uname, string password, - string key); - - public CredentialsPane(Spit.Publishing.PluginHost host, - Mode mode = Mode.INTRO, - string? url = null, string? username = null, - string? key = null) { - - Gtk.Builder builder = new Gtk.Builder(); - - try { - builder.add_from_resource (Resources.RESOURCE_PATH + - "/gallery3_authentication_pane.ui"); - } - catch (Error e) { - warning("Could not parse UI file! Error: %s.", e.message); - host.post_error( - new Spit.Publishing.PublishingError.LOCAL_FILE_ERROR( - _("A file required for publishing is unavailable. Publishing to %s can’t continue.") - .printf(SERVICE_NAME) - ) - ); - - return; - } - - frame = new CredentialsGrid(host, mode, url, username, key, builder); - grid_widget = frame.pane_widget as Gtk.Widget; - } - - protected void notify_go_back() { - go_back(); - } - - protected void notify_login(string url, string uname, - string password, string key) { - login(url, uname, password, key); - } - - public Gtk.Widget get_widget() { - assert(null != grid_widget); - return grid_widget; - } - - public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() { - return Spit.Publishing.DialogPane.GeometryOptions.NONE; - } - - public void on_pane_installed() { - frame.go_back.connect(notify_go_back); - frame.login.connect(notify_login); - - frame.installed(); - } - - public void on_pane_uninstalled() { - frame.go_back.disconnect(notify_go_back); - frame.login.disconnect(notify_login); - } -} - -internal class CredentialsGrid : GLib.Object { - private const string INTRO_MESSAGE = _("Enter the URL for your Gallery3 site and the username and password (or API key) for your Gallery3 account."); - private const string FAILED_RETRY_MESSAGE = _("The username and password or API key were incorrect. To try again, re-enter your username and password below."); - private const string NOT_GALLERY_URL_MESSAGE = _("The URL entered does not appear to be the main directory of a Gallery3 instance. Please make sure you typed it correctly and it does not have any trailing components (e.g., index.php)."); - - public Gtk.Grid pane_widget { get; private set; default = null; } - - private weak Spit.Publishing.PluginHost host = null; - private Gtk.Builder builder = null; - private Gtk.Label intro_message_label = null; - private Gtk.Entry url_entry = null; - private Gtk.Entry username_entry = null; - private Gtk.Entry password_entry = null; - private Gtk.Entry key_entry = null; - private Gtk.Button login_button = null; - private Gtk.Button go_back_button = null; - private string? url = null; - private string? username = null; - private string? key = null; - - public signal void go_back(); - public signal void login(string url, string username, - string password, string key); - - public CredentialsGrid(Spit.Publishing.PluginHost host, - CredentialsPane.Mode mode = CredentialsPane.Mode.INTRO, - string? url = null, string? username = null, - string? key = null, - Gtk.Builder builder) { - this.host = host; - this.url = url; - this.key = key; - this.username = username; - - this.builder = builder; - assert(builder != null); - assert(builder.get_objects().length() > 0); - - // pull in all widgets from builder - pane_widget = builder.get_object("gallery3_auth_pane_widget") as Gtk.Grid; - intro_message_label = builder.get_object("intro_message_label") as Gtk.Label; - url_entry = builder.get_object("url_entry") as Gtk.Entry; - username_entry = builder.get_object("username_entry") as Gtk.Entry; - key_entry = builder.get_object("key_entry") as Gtk.Entry; - password_entry = builder.get_object("password_entry") as Gtk.Entry; - go_back_button = builder.get_object("go_back_button") as Gtk.Button; - login_button = builder.get_object("login_button") as Gtk.Button; - - // Intro message - switch (mode) { - case CredentialsPane.Mode.INTRO: - intro_message_label.set_markup(INTRO_MESSAGE); - break; - - case CredentialsPane.Mode.FAILED_RETRY: - intro_message_label.set_markup("<b>%s</b>\n\n%s".printf(_( - "Unrecognized User"), FAILED_RETRY_MESSAGE)); - break; - - case CredentialsPane.Mode.NOT_GALLERY_URL: - intro_message_label.set_markup("<b>%s</b>\n\n%s".printf( - _(SERVICE_NAME + " Site Not Found"), - NOT_GALLERY_URL_MESSAGE)); - break; - - default: - error("Invalid CredentialsPane mode"); - } - - // Gallery URL - if (url != null) { - url_entry.set_text(url); - username_entry.grab_focus(); - } - url_entry.changed.connect(on_url_or_username_changed); - // User name - if (username != null) { - username_entry.set_text(username); - password_entry.grab_focus(); - } - username_entry.changed.connect(on_url_or_username_changed); - - // Key - if (key != null) { - key_entry.set_text(key); - key_entry.grab_focus(); - } - key_entry.changed.connect(on_url_or_username_changed); - - // Buttons - go_back_button.clicked.connect(on_go_back_button_clicked); - login_button.clicked.connect(on_login_button_clicked); - login_button.set_sensitive((url != null) && (username != null)); - } - - private void on_login_button_clicked() { - login(url_entry.get_text(), username_entry.get_text(), - password_entry.get_text(), key_entry.get_text()); - } - - private void on_go_back_button_clicked() { - go_back(); - } - - private void on_url_or_username_changed() { - login_button.set_sensitive( - ((url_entry.get_text() != "") && - (username_entry.get_text() != "")) || - (key_entry.get_text() != "")); - } - - public void installed() { - host.set_service_locked(false); - - // TODO: following line necessary? - host.set_dialog_default_widget(login_button); - } -} - -internal class Session : Publishing.RESTSupport.Session { - - // Properties - public string? url { get; private set; default = null; } - public string? username { get; private set; default = null; } - public string? key { get; private set; default = null; } - - public Session() { - } - - public override bool is_authenticated() { - return (null != key); - } - - public void authenticate(string gallery_url, string username, string key) { - this.url = gallery_url; - this.username = username; - this.key = key; - - notify_authenticated(); - } - - public void deauthenticate() { - url = null; - username = null; - key = null; - } - -} - -internal class Uploader : Publishing.RESTSupport.BatchUploader { - - private PublishingParameters parameters; - private string _current_publishable_name; - private Spit.Publishing.Publisher.MediaType _current_media_type; - private Publishing.RESTSupport.Transaction? _current_transaction; - - /* Properties */ - public string current_publishable_name { - get { - return _current_publishable_name; - } - } - public uint status_code { - get { - return _current_transaction.get_status_code(); - } - } - public Spit.Publishing.Publisher.MediaType - current_publishable_type { - get { - return _current_media_type; - } - } - - public Uploader(Session session, - Spit.Publishing.Publishable[] publishables, - PublishingParameters parameters) { - - base(session, publishables); - - this.parameters = parameters; - - } - - protected override Publishing.RESTSupport.Transaction - create_transaction(Spit.Publishing.Publishable publishable) { - - Spit.Publishing.Publishable p = get_current_publishable(); - _current_publishable_name = - p.get_param_string(Spit.Publishing.Publishable.PARAM_STRING_BASENAME); - _current_media_type = p.get_media_type(); - - _current_transaction = - new GalleryUploadTransaction((Session) get_session(), - parameters, p); - return _current_transaction; - - } - -} - -private string strip_session_url(string url) { - - // Remove the session URL from the beginning of this URL - debug("Searching for \"%s\" in \"%s\"", - REST_PATH, url); - int item_loc = - url.last_index_of(REST_PATH); - - if (-1 == item_loc) - error("Did not find \"%s\" in the base of the new item " + - "URL \"%s\"", REST_PATH, url); - - return url.substring(item_loc + REST_PATH.length); - -} - -} - -// vi:ts=4:sw=4:et diff --git a/plugins/shotwell-publishing-extras/RajcePublishing.vala b/plugins/shotwell-publishing-extras/RajcePublishing.vala deleted file mode 100644 index a088274..0000000 --- a/plugins/shotwell-publishing-extras/RajcePublishing.vala +++ /dev/null @@ -1,1554 +0,0 @@ -/* Copyright 2014 rajce.net - * - * This software is licensed under the GNU Lesser General Public License - * (version 2.1 or later). See the COPYING file in this distribution. - */ - -public class RajceService : Object, Spit.Pluggable, Spit.Publishing.Service -{ - private const string ICON_FILENAME = "rajce.png"; - - private static Gdk.Pixbuf[] icon_pixbuf_set = null; - - public RajceService(GLib.File resource_directory) - { - if (icon_pixbuf_set == null) - icon_pixbuf_set = - Resources.load_from_resource(Resources.RESOURCE_PATH + "/" + - ICON_FILENAME); - } - - public int get_pluggable_interface(int min_host_interface, int max_host_interface) - { - return Spit.negotiate_interfaces(min_host_interface, max_host_interface, - Spit.Publishing.CURRENT_INTERFACE); - } - - public unowned string get_id() - { - return "org.yorba.shotwell.publishing.rajce"; - } - - public unowned string get_pluggable_name() - { - return "Rajce"; - } - - public void get_info(ref Spit.PluggableInfo info) - { - info.authors = "rajce.net developers"; - info.copyright = _("Copyright © 2013 rajce.net"); - 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; - } - - public Spit.Publishing.Publisher create_publisher(Spit.Publishing.PluginHost host) - { - return new Publishing.Rajce.RajcePublisher(this, host); - } - - public Spit.Publishing.Publisher.MediaType get_supported_media() - { - return( Spit.Publishing.Publisher.MediaType.PHOTO /*| Spit.Publishing.Publisher.MediaType.VIDEO*/ ); - } - - public void activation(bool enabled) {} -} - -namespace Publishing.Rajce -{ - -public class RajcePublisher : Spit.Publishing.Publisher, GLib.Object -{ - private Spit.Publishing.PluginHost host = null; - private Spit.Publishing.ProgressCallback progress_reporter = null; - private Spit.Publishing.Service service = null; - private bool running = false; - private Session session; -// private string username = ""; -// private string token = ""; -// private int last_photo_size = -1; -// private bool hide_album = false; -// private bool show_album = true; -// private bool remember = false; -// private bool strip_metadata = false; - private Album[] albums = null; - private PublishingParameters parameters = null; - private Spit.Publishing.Publisher.MediaType media_type = Spit.Publishing.Publisher.MediaType.NONE; - - public RajcePublisher(Spit.Publishing.Service service, Spit.Publishing.PluginHost host) - { - debug("RajcePublisher created."); - this.service = service; - this.host = host; - this.session = new Session(); - - foreach(Spit.Publishing.Publishable p in host.get_publishables()) - media_type |= p.get_media_type(); - } - - private string get_rajce_url() - { - return "http://www.rajce.idnes.cz/liveAPI/index.php"; - } - - // Publisher interface implementation - - public Spit.Publishing.Service get_service() { return service; } - public Spit.Publishing.PluginHost get_host() { return host; } - public bool is_running() { return running; } - - public void start() - { - if (is_running()) - return; - - debug("RajcePublisher: start"); - running = true; - - if (session.is_authenticated()) - { - debug("RajcePublisher: session is authenticated."); - do_fetch_albums(); - } - else - { - debug("RajcePublisher: session is not authenticated."); - string? persistent_username = get_username(); - string? persistent_token = get_token(); - bool? persistent_remember = get_remember(); - if (persistent_username != null && persistent_token != null) - do_network_login(persistent_username, persistent_token, persistent_remember ); - else - do_show_authentication_pane(); - } - } - - public void stop() - { - debug("RajcePublisher: stop"); - running = false; - } - - // persistent data - - public string? get_url() { return get_rajce_url(); } - public string? get_username() { return host.get_config_string("username", null); } - private void set_username(string username) { host.set_config_string("username", username); } - public string? get_token() { return host.get_config_string("token", null); } - private void set_token(string? token) { host.set_config_string("token", token); } -// public int get_last_photo_size() { return host.get_config_int("last-photo-size", -1); } -// private void set_last_photo_size(int last_photo_size) { host.set_config_int("last-photo-size", last_photo_size); } - public bool get_remember() { return host.get_config_bool("remember", false); } - private void set_remember(bool remember) { host.set_config_bool("remember", remember); } - public bool get_hide_album() { return host.get_config_bool("hide-album", false); } - public void set_hide_album(bool hide_album) { host.set_config_bool("hide-album", hide_album); } - public bool get_show_album() { return host.get_config_bool("show-album", true); } - public void set_show_album(bool show_album) { host.set_config_bool("show-album", show_album); } -// public bool get_strip_metadata() { return host.get_config_bool("strip-metadata", false); } -// private void set_strip_metadata(bool strip_metadata) { host.set_config_bool("strip-metadata", strip_metadata); } - - // Actions and events - - /** - * Action that shows the authentication pane. - */ - private void do_show_authentication_pane(AuthenticationPane.Mode mode = AuthenticationPane.Mode.INTRO) - { - debug("ACTION: installing authentication pane"); - - host.set_service_locked(false); - AuthenticationPane authentication_pane = new AuthenticationPane(this, mode); - authentication_pane.login.connect(on_authentication_pane_login_clicked); - host.install_dialog_pane(authentication_pane, Spit.Publishing.PluginHost.ButtonMode.CLOSE); - host.set_dialog_default_widget(authentication_pane.get_default_widget()); - } - - /** - * Event triggered when the login button in the authentication panel is clicked. - */ - private void on_authentication_pane_login_clicked( string username, string token, bool remember ) - { - debug("EVENT: on_authentication_pane_login_clicked"); - if (!running) - return; - do_network_login(username, token, remember); - } - - /** - * Action to perform a network login to a Rajce service. - */ - private void do_network_login(string username, string token, bool remember) - { - debug("ACTION: logging in"); - host.set_service_locked(true); - host.install_login_wait_pane(); - set_remember( remember ); - set_username( username ); - set_token( remember ? token : null ); - SessionLoginTransaction login_trans = new SessionLoginTransaction(session, get_url(), username, token); - login_trans.network_error.connect(on_login_network_error); - login_trans.completed.connect(on_login_network_complete); - try - { - login_trans.execute(); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: do_network_login"); - do_show_error(err); - } - } - - /** - * Event triggered when the network login action is complete and successful. - */ - private void on_login_network_complete(Publishing.RESTSupport.Transaction txn) - { - debug("EVENT: on_login_network_complete"); - txn.completed.disconnect(on_login_network_complete); - txn.network_error.disconnect(on_login_network_error); - - try - { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string( txn.get_response(), Transaction.validate_xml); - Xml.Node* response = doc.get_root_node(); - Xml.Node* sessionToken = doc.get_named_child( response, "sessionToken" ); - Xml.Node* maxWidth = doc.get_named_child( response, "maxWidth" ); - Xml.Node* maxHeight = doc.get_named_child( response, "maxHeight" ); - Xml.Node* quality = doc.get_named_child( response, "quality" ); - Xml.Node* nick = doc.get_named_child( response, "nick" ); - int maxW = int.parse( maxWidth->get_content() ); - int maxH = int.parse( maxHeight->get_content() ); - if( maxW > maxH ) - { - maxH = maxW; - } - session.authenticate( sessionToken->get_content(), nick->get_content(), 0, maxH, int.parse( quality->get_content() ) ); - } - catch (Spit.Publishing.PublishingError err) - { - int code_int = int.parse(err.message); - if (code_int == 999) - { - debug("ERROR: on_login_network_complete, code 999"); - do_show_authentication_pane(AuthenticationPane.Mode.FAILED_RETRY_USER); - } - else - { - debug("ERROR: on_login_network_complete"); - do_show_error(err); - } - return; - } - do_fetch_albums(); - } - - /** - * Event triggered when a network login action fails due to a network error. - */ - private void on_login_network_error( Publishing.RESTSupport.Transaction bad_txn, Spit.Publishing.PublishingError err ) - { - debug("EVENT: on_login_network_error"); - bad_txn.completed.disconnect(on_login_network_complete); - bad_txn.network_error.disconnect(on_login_network_error); - do_show_authentication_pane(AuthenticationPane.Mode.FAILED_RETRY_USER); - } - - /** - * Action that fetches all user albums from the Rajce. - */ - private void do_fetch_albums() - { - debug("ACTION: fetching albums"); - host.set_service_locked(true); - host.install_account_fetch_wait_pane(); - - GetAlbumsTransaction get_albums_trans = new GetAlbumsTransaction(session, get_url() ); - get_albums_trans.network_error.connect(on_albums_fetch_error); - get_albums_trans.completed.connect(on_albums_fetch_complete); - - try - { - get_albums_trans.execute(); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: do_fetch_albums"); - do_show_error(err); - } - } - - /** - * Event triggered when the fetch albums action completes successfully. - */ - private void on_albums_fetch_complete(Publishing.RESTSupport.Transaction txn) - { - debug("EVENT: on_albums_fetch_complete"); - txn.completed.disconnect(on_albums_fetch_complete); - txn.network_error.disconnect(on_albums_fetch_error); - debug("RajcePlugin: list of albums: %s", txn.get_response()); - if (albums != null) - { - albums = null; - } - Gee.ArrayList<Album> list = new Gee.ArrayList<Album>(); - try - { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string( txn.get_response(), Transaction.validate_xml); - Xml.Node* response = doc.get_root_node(); - Xml.Node* sessionToken = doc.get_named_child( response, "sessionToken" ); - Xml.Node* nodealbums = doc.get_named_child( response, "albums" ); - for( Xml.Node* album = nodealbums->children; album != null; album = album->next ) - { - int id = int.parse( album->get_prop("id") ); - string albumName = doc.get_named_child( album, "albumName" )->get_content(); - string url = doc.get_named_child( album, "url" )->get_content(); - string thumbUrl = doc.get_named_child( album, "thumbUrl" )->get_content(); - string createDate = doc.get_named_child( album, "createDate" )->get_content(); - string updateDate = doc.get_named_child( album, "updateDate" )->get_content(); - bool hidden = ( int.parse( doc.get_named_child( album, "hidden" )->get_content() ) > 0 ? true : false ); - bool secure = ( int.parse( doc.get_named_child( album, "secure" )->get_content() ) > 0 ? true : false ); - int photoCount = int.parse( doc.get_named_child( album, "photoCount" )->get_content() ); - list.insert( 0, new Album( id, albumName, url, thumbUrl, createDate, updateDate, hidden, secure, photoCount ) ); - } - list.sort( Album.compare_albums ); - albums = list.to_array(); - session.set_usertoken( sessionToken->get_content() ); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: on_albums_fetch_complete"); - do_show_error(err); - return; - } - do_show_publishing_options_pane(); - } - - /** - * Event triggered when the fetch albums transaction fails due to a network error. - */ - private void on_albums_fetch_error( Publishing.RESTSupport.Transaction bad_txn, Spit.Publishing.PublishingError err ) - { - debug("EVENT: on_albums_fetch_error"); - bad_txn.completed.disconnect(on_albums_fetch_complete); - bad_txn.network_error.disconnect(on_albums_fetch_error); - on_network_error(bad_txn, err); - } - - /** - * Action that shows the publishing options pane. - */ - private void do_show_publishing_options_pane() - { - debug("ACTION: installing publishing options pane"); - host.set_service_locked(false); - PublishingOptionsPane opts_pane = new PublishingOptionsPane( this, session.get_username(), albums ); - opts_pane.logout.connect(on_publishing_options_pane_logout_clicked); - opts_pane.publish.connect(on_publishing_options_pane_publish_clicked); - host.install_dialog_pane(opts_pane, Spit.Publishing.PluginHost.ButtonMode.CLOSE); - host.set_dialog_default_widget(opts_pane.get_default_widget()); - } - - /** - * Event triggered when the user clicks logout in the publishing options pane. - */ - private void on_publishing_options_pane_logout_clicked() - { - debug("EVENT: on_publishing_options_pane_logout_clicked"); - session.deauthenticate(); - do_show_authentication_pane( AuthenticationPane.Mode.INTRO ); - } - - /** - * Event triggered when the user clicks publish in the publishing options pane. - * - * @param parameters the publishing parameters - */ - private void on_publishing_options_pane_publish_clicked( PublishingParameters parameters ) - { - debug("EVENT: on_publishing_options_pane_publish_clicked"); - this.parameters = parameters; - do_begin_upload(); - } - - /** - * Begin upload action: open existing album or create a new one - */ - private void do_begin_upload() - { - host.set_service_locked(true); - if( parameters.album_id == 0 ) - { - // new album - debug("ACTION: closing album"); - CreateAlbumTransaction create_album_trans = new CreateAlbumTransaction(session, get_url(), parameters.album_name, this.parameters.album_hidden ); - create_album_trans.network_error.connect(on_create_album_error); - create_album_trans.completed.connect(on_create_album_complete); - try - { - create_album_trans.execute(); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: create album"); - do_show_error(err); - } - } - else - { - // existing album - debug("ACTION: opening album"); - OpenAlbumTransaction open_album_trans = new OpenAlbumTransaction(session, get_url(), parameters.album_id ); - open_album_trans.network_error.connect(on_open_album_error); - open_album_trans.completed.connect(on_open_album_complete); - try - { - open_album_trans.execute(); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: open album"); - do_show_error(err); - } - } - } - - /** - * Event triggered when the create album completes successfully. - */ - private void on_create_album_complete( Publishing.RESTSupport.Transaction txn) - { - debug("EVENT: on_create_album_complete"); - txn.completed.disconnect(on_create_album_complete); - txn.network_error.disconnect(on_create_album_error); - debug("RajcePlugin: create album: %s", txn.get_response()); - try - { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string( txn.get_response(), Transaction.validate_xml); - Xml.Node* response = doc.get_root_node(); - string sessionToken = doc.get_named_child( response, "sessionToken" )->get_content(); - string albumToken = doc.get_named_child( response, "albumToken" )->get_content(); - parameters.album_id = int.parse( doc.get_named_child( response, "albumID" )->get_content() ); - session.set_usertoken( sessionToken ); - session.set_albumtoken( albumToken ); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: on_create_album_complete"); - do_show_error(err); - return; - } - do_upload_photos(); - } - - /** - * Event triggered when the create album transaction fails due to a network error. - */ - private void on_create_album_error( Publishing.RESTSupport.Transaction bad_txn, Spit.Publishing.PublishingError err ) - { - debug("EVENT: on_create_album_error"); - bad_txn.completed.disconnect(on_create_album_complete); - bad_txn.network_error.disconnect(on_create_album_error); - on_network_error(bad_txn, err); - } - - /** - * Event triggered when the open album completes successfully. - */ - private void on_open_album_complete(Publishing.RESTSupport.Transaction txn) - { - debug("EVENT: on_open_album_complete"); - txn.completed.disconnect(on_open_album_complete); - txn.network_error.disconnect(on_open_album_error); - debug("RajcePlugin: open album: %s", txn.get_response()); - try - { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string( txn.get_response(), Transaction.validate_xml); - Xml.Node* response = doc.get_root_node(); - string sessionToken = doc.get_named_child( response, "sessionToken" )->get_content(); - string albumToken = doc.get_named_child( response, "albumToken" )->get_content(); - session.set_usertoken( sessionToken ); - session.set_albumtoken( albumToken ); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: on_open_album_complete"); - do_show_error(err); - return; - } - do_upload_photos(); - } - - /** - * Event triggered when the open album transaction fails due to a network error. - */ - private void on_open_album_error( Publishing.RESTSupport.Transaction bad_txn, Spit.Publishing.PublishingError err ) - { - debug("EVENT: on_open_album_error"); - bad_txn.completed.disconnect(on_open_album_complete); - bad_txn.network_error.disconnect(on_open_album_error); - on_network_error(bad_txn, err); - } - - /** - * Upload photos: the key part of the plugin - */ - private void do_upload_photos() - { - debug("ACTION: uploading photos"); - progress_reporter = host.serialize_publishables( session.get_maxsize() ); - Spit.Publishing.Publishable[] publishables = host.get_publishables(); - - Uploader uploader = new Uploader( session, get_url(), publishables, parameters ); - uploader.upload_complete.connect( on_upload_photos_complete ); - uploader.upload_error.connect( on_upload_photos_error ); - uploader.upload( on_upload_photos_status_updated ); - } - - /** - * Event triggered when the batch uploader reports that at least one of the - * network transactions encapsulating uploads has completed successfully - */ - private void on_upload_photos_complete(Publishing.RESTSupport.BatchUploader uploader, int num_published) - { - debug("EVENT: on_upload_photos_complete"); - uploader.upload_complete.disconnect(on_upload_photos_complete); - uploader.upload_error.disconnect(on_upload_photos_error); - - // TODO: should a message be displayed to the user if num_published is zero? - do_end_upload(); - } - - /** - * Event triggered when the batch uploader reports that at least one of the - * network transactions encapsulating uploads has caused a network error - */ - private void on_upload_photos_error( Publishing.RESTSupport.BatchUploader uploader, Spit.Publishing.PublishingError err) - { - debug("EVENT: on_upload_photos_error"); - uploader.upload_complete.disconnect(on_upload_photos_complete); - uploader.upload_error.disconnect(on_upload_photos_error); - do_show_error(err); - } - - /** - * Event triggered when upload progresses and the status needs to be updated. - */ - private void on_upload_photos_status_updated(int file_number, double completed_fraction) - { - if( is_running() ) - { - debug("EVENT: uploader reports upload %.2f percent complete.", 100.0 * completed_fraction); - assert(progress_reporter != null); - progress_reporter(file_number, completed_fraction); - } - } - - private void do_end_upload() - { - if( get_show_album() ) - { - do_get_album_url(); - } - else - { - do_close_album(); - } - } - - /** - * End upload action: get album url - */ - private void do_get_album_url() - { - debug("ACTION: getting album URL"); - host.set_service_locked(true); - GetAlbumUrlTransaction get_album_url_trans = new GetAlbumUrlTransaction(session, get_url() ); - get_album_url_trans.network_error.connect(on_get_album_url_error); - get_album_url_trans.completed.connect(on_get_album_url_complete); - try - { - get_album_url_trans.execute(); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: close album"); - do_show_error(err); - } - } - - /** - * Event triggered when the get album url completes successfully. - */ - private void on_get_album_url_complete(Publishing.RESTSupport.Transaction txn) - { - debug("EVENT: on_get_album_url_complete"); - txn.completed.disconnect(on_get_album_url_complete); - txn.network_error.disconnect(on_get_album_url_error); - debug("RajcePlugin: get album url: %s", txn.get_response()); - try - { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string( txn.get_response(), Transaction.validate_xml); - Xml.Node* response = doc.get_root_node(); - string sessionToken = doc.get_named_child( response, "sessionToken" )->get_content(); - string url = doc.get_named_child( response, "url" )->get_content(); - session.set_usertoken( sessionToken ); - session.set_albumticket( url ); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: on_get_album_url_complete"); - // ignore this error -// do_show_error(err); -// return; - } - do_close_album(); - } - - /** - * Event triggered when the get album url transaction fails due to a network error. - */ - private void on_get_album_url_error( Publishing.RESTSupport.Transaction bad_txn, Spit.Publishing.PublishingError err ) - { - debug("EVENT: on_get_album_url_error"); - bad_txn.completed.disconnect(on_get_album_url_complete); - bad_txn.network_error.disconnect(on_get_album_url_error); - // ignore this error -// on_network_error(bad_txn, err); - do_close_album(); - } - - - /** - * End upload action: close album - */ - private void do_close_album() - { - debug("ACTION: closing album"); - host.set_service_locked(true); - CloseAlbumTransaction close_album_trans = new CloseAlbumTransaction(session, get_url() ); - close_album_trans.network_error.connect(on_close_album_error); - close_album_trans.completed.connect(on_close_album_complete); - try - { - close_album_trans.execute(); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: close album"); - do_show_error(err); - } - } - - /** - * Event triggered when the close album completes successfully. - */ - private void on_close_album_complete(Publishing.RESTSupport.Transaction txn) - { - debug("EVENT: on_close_album_complete"); - txn.completed.disconnect(on_close_album_complete); - txn.network_error.disconnect(on_close_album_error); - debug("RajcePlugin: close album: %s", txn.get_response()); - try - { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string( txn.get_response(), Transaction.validate_xml); - Xml.Node* response = doc.get_root_node(); - string sessionToken = doc.get_named_child( response, "sessionToken" )->get_content(); - session.set_usertoken( sessionToken ); - session.set_albumtoken( null ); - } - catch (Spit.Publishing.PublishingError err) - { - debug("ERROR: on_close_album_complete"); - do_show_error(err); - return; - } - do_show_success_pane(); - } - - /** - * Event triggered when the close album transaction fails due to a network error. - */ - private void on_close_album_error( Publishing.RESTSupport.Transaction bad_txn, Spit.Publishing.PublishingError err ) - { - debug("EVENT: on_close_album_error"); - bad_txn.completed.disconnect(on_close_album_complete); - bad_txn.network_error.disconnect(on_close_album_error); - // ignore this error -// on_network_error(bad_txn, err); - do_show_success_pane(); - } - - - /** - * Action to display the success pane in the publishing dialog. - */ - private void do_show_success_pane() - { - debug("ACTION: installing success pane"); - if( get_show_album() && session.get_albumticket() != null ) - { - try - { - GLib.Process.spawn_command_line_async( "xdg-open " + session.get_albumticket() ); - } - catch( GLib.SpawnError e ) - { - } - } - host.set_service_locked(false); - host.install_success_pane(); - } - - /** - * Helper event to handle network errors. - */ - private void on_network_error( Publishing.RESTSupport.Transaction bad_txn, Spit.Publishing.PublishingError err ) - { - debug("EVENT: on_network_error"); - do_show_error(err); - } - - /** - * Action to display an error to the user. - */ - private void do_show_error(Spit.Publishing.PublishingError e) - { - debug("ACTION: do_show_error"); - string error_type = "UNKNOWN"; - if (e is Spit.Publishing.PublishingError.NO_ANSWER) - { - do_show_authentication_pane(AuthenticationPane.Mode.FAILED_RETRY_USER); - return; - } else if(e is Spit.Publishing.PublishingError.COMMUNICATION_FAILED) { - error_type = "COMMUNICATION_FAILED"; - } else if(e is Spit.Publishing.PublishingError.PROTOCOL_ERROR) { - error_type = "PROTOCOL_ERROR"; - } else if(e is Spit.Publishing.PublishingError.SERVICE_ERROR) { - error_type = "SERVICE_ERROR"; - } else if(e is Spit.Publishing.PublishingError.MALFORMED_RESPONSE) { - error_type = "MALFORMED_RESPONSE"; - } else if(e is Spit.Publishing.PublishingError.LOCAL_FILE_ERROR) { - error_type = "LOCAL_FILE_ERROR"; - } else if(e is Spit.Publishing.PublishingError.EXPIRED_SESSION) { - error_type = "EXPIRED_SESSION"; - } - - debug("Unhandled error: type=%s; message='%s'".printf(error_type, e.message)); - do_show_error_message(_("An error message occurred when publishing to Rajce. Please try again.")); - } - - /** - * Action to display an error message to the user. - */ - private void do_show_error_message(string message) - { - debug("ACTION: do_show_error_message"); - host.install_static_message_pane(message, Spit.Publishing.PluginHost.ButtonMode.CLOSE); - } - -} - -// Rajce Album -internal class Album -{ - public int id; - public string albumName; - public string url; - public string thumbUrl; - public string createDate; - public string updateDate; - public bool hidden; - public bool secure; - public int photoCount; - - public Album( int id, string albumName, string url, string thumbUrl, string createDate, string updateDate, bool hidden, bool secure, int photoCount ) - { - this.id = id; - this.albumName = albumName; - this.url = url; - this.thumbUrl = thumbUrl; - this.createDate = createDate; - this.updateDate = updateDate; - this.hidden = hidden; - this.secure = secure; - this.photoCount = photoCount; - } - public static int compare_albums(Album? a, Album? b) - { - if( a == null && b == null ) - { - return 0; - } - else if( a == null && b != null ) - { - return 1; - } - else if( a != null && b == null ) - { - return -1; - } - return( b.updateDate.ascii_casecmp( a.updateDate ) ); - } -} - -// Uploader -internal class Uploader : Publishing.RESTSupport.BatchUploader -{ - private PublishingParameters parameters; - private string url; - - public Uploader(Session session, string url, Spit.Publishing.Publishable[] publishables, PublishingParameters parameters) - { - base(session, publishables); - this.parameters = parameters; - this.url = url; - } - - protected override Publishing.RESTSupport.Transaction create_transaction( Spit.Publishing.Publishable publishable ) - { - return new AddPhotoTransaction((Session) get_session(), url, parameters, publishable); - } -} - -// UI elements - -/** - * The authentication pane used when asking service URL, user name and password - * from the user. - */ -internal class AuthenticationPane : Spit.Publishing.DialogPane, Object -{ - public enum Mode - { - INTRO, - FAILED_RETRY_USER - } - private static string INTRO_MESSAGE = _("Enter email and password associated with your Rajce account."); - private static string FAILED_RETRY_USER_MESSAGE = _("Invalid email and/or password. Please try again"); - - private Gtk.Box pane_widget = null; - private Gtk.Builder builder; - private Gtk.Entry username_entry; - private Gtk.Entry password_entry; - private Gtk.CheckButton remember_checkbutton; - private Gtk.Button login_button; - private bool crypt = true; - - public signal void login( string user, string token, bool remember ); - - public AuthenticationPane( RajcePublisher publisher, Mode mode = Mode.INTRO ) - { - this.pane_widget = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); - try - { - builder = new Gtk.Builder(); - builder.add_from_resource (Resources.RESOURCE_PATH + - "/rajce_authentication_pane.ui"); - builder.connect_signals(null); - var content = builder.get_object ("content") as Gtk.Box; - Gtk.Label message_label = builder.get_object("message_label") as Gtk.Label; - switch (mode) - { - case Mode.INTRO: - message_label.set_text(INTRO_MESSAGE); - break; - - case Mode.FAILED_RETRY_USER: - message_label.set_markup("<b>%s</b>\n\n%s".printf(_( - "Invalid User Email or Password"), FAILED_RETRY_USER_MESSAGE)); - break; - } - username_entry = builder.get_object ("username_entry") as Gtk.Entry; - string? persistent_username = publisher.get_username(); - if (persistent_username != null) - { - username_entry.set_text(persistent_username); - } - password_entry = builder.get_object ("password_entry") as Gtk.Entry; - string? persistent_token = publisher.get_token(); - if (persistent_token != null) - { - password_entry.set_text(persistent_token); - this.crypt = false; - } - else - { - this.crypt = true; - } - remember_checkbutton = builder.get_object ("remember_checkbutton") as Gtk.CheckButton; - remember_checkbutton.set_active(publisher.get_remember()); - login_button = builder.get_object("login_button") as Gtk.Button; - - Gtk.Label label2 = builder.get_object("label2") as Gtk.Label; - Gtk.Label label3 = builder.get_object("label3") as Gtk.Label; - - label2.set_label(_("_Email address") ); - label3.set_label(_("_Password") ); - remember_checkbutton.set_label(_("_Remember") ); - login_button.set_label(_("Log in") ); - - username_entry.changed.connect(on_user_changed); - password_entry.changed.connect(on_password_changed); - login_button.clicked.connect(on_login_button_clicked); - content.parent.remove (content); - pane_widget.add (content); - publisher.get_host().set_dialog_default_widget(login_button); - } - catch (Error e) - { - warning("Could not load UI: %s", e.message); - } - } - - public Gtk.Widget get_default_widget() - { - return login_button; - } - - private void on_login_button_clicked() - { - string token = password_entry.get_text(); - if( this.crypt ) - { - token = GLib.Checksum.compute_for_string( GLib.ChecksumType.MD5, token ); - } - login(username_entry.get_text(), token, remember_checkbutton.get_active()); - } - - private void on_user_changed() - { - update_login_button_sensitivity(); - } - - private void on_password_changed() - { - this.crypt = true; - update_login_button_sensitivity(); - } - - private void update_login_button_sensitivity() - { - login_button.set_sensitive(username_entry.text_length > 0 && - password_entry.text_length > 0); - } - - public Gtk.Widget get_widget() - { - return pane_widget; - } - - public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() - { - return Spit.Publishing.DialogPane.GeometryOptions.NONE; - } - - public void on_pane_installed() - { - username_entry.grab_focus(); - password_entry.set_activates_default(true); - login_button.can_default = true; - update_login_button_sensitivity(); - } - public void on_pane_uninstalled() {} - -} - -internal class PublishingOptionsPane : Spit.Publishing.DialogPane, GLib.Object -{ - RajcePublisher publisher; - private Album[] albums; - private string username; - - private Gtk.Builder builder = null; - private Gtk.Box pane_widget = null; - private Gtk.Label login_identity_label = null; - private Gtk.Label publish_to_label = null; - private Gtk.RadioButton use_existing_radio = null; - private Gtk.ComboBoxText existing_albums_combo = null; - private Gtk.RadioButton create_new_radio = null; - private Gtk.Entry new_album_entry = null; - private Gtk.CheckButton hide_check = null; - private Gtk.CheckButton show_check = null; - private Gtk.Button publish_button = null; - private Gtk.Button logout_button = null; - - public signal void publish( PublishingParameters parameters ); - public signal void logout(); - - public PublishingOptionsPane( RajcePublisher publisher, string username, Album[] albums ) - { - this.username = username; - this.albums = albums; - this.publisher = publisher; - this.pane_widget = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); - - try - { - this.builder = new Gtk.Builder(); - builder.add_from_resource (Resources.RESOURCE_PATH + "/rajce_publishing_options_pane.ui"); - builder.connect_signals(null); - - pane_widget = (Gtk.Box) builder.get_object("rajce_pane_widget"); - login_identity_label = (Gtk.Label) builder.get_object("login_identity_label"); - publish_to_label = (Gtk.Label) builder.get_object("publish_to_label"); - use_existing_radio = (Gtk.RadioButton) builder.get_object("use_existing_radio"); - existing_albums_combo = (Gtk.ComboBoxText) builder.get_object("existing_albums_combo"); - create_new_radio = (Gtk.RadioButton) builder.get_object("create_new_radio"); - new_album_entry = (Gtk.Entry) builder.get_object("new_album_entry"); - hide_check = (Gtk.CheckButton) builder.get_object("hide_check"); - hide_check.set_label(_("_Hide album") ); - show_check = (Gtk.CheckButton) builder.get_object("show_check"); - publish_button = (Gtk.Button) builder.get_object("publish_button"); - logout_button = (Gtk.Button) builder.get_object("logout_button"); - - hide_check.set_active( publisher.get_hide_album() ); - show_check.set_active( publisher.get_show_album() ); - login_identity_label.set_label(_("You are logged into Rajce as %s.").printf(username)); - publish_to_label.set_label(_("Photos will appear in:")); - use_existing_radio.set_label(_("An _existing album:") ); - create_new_radio.set_label(_("A _new album named:") ); - show_check.set_label(_("Open target _album in browser") ); - publish_button.set_label(_("_Publish") ); - logout_button.set_label(_("_Logout") ); - - use_existing_radio.clicked.connect(on_use_existing_radio_clicked); - create_new_radio.clicked.connect(on_create_new_radio_clicked); - new_album_entry.changed.connect(on_new_album_entry_changed); - logout_button.clicked.connect(on_logout_clicked); - publish_button.clicked.connect(on_publish_clicked); - } - catch (Error e) - { - warning("Could not load UI: %s", e.message); - } - - } - - private void on_publish_clicked() - { - bool show_album = show_check.get_active(); - publisher.set_show_album( show_album ); - if (create_new_radio.get_active()) - { - string album_name = new_album_entry.get_text(); - bool hide_album = hide_check.get_active(); - publisher.set_hide_album( hide_album ); - publish( new PublishingParameters.to_new_album( album_name, hide_album ) ); - } - else - { - int id = albums[existing_albums_combo.get_active()].id; - string album_name = albums[existing_albums_combo.get_active()].albumName; - publish( new PublishingParameters.to_existing_album( album_name, id ) ); - } - } - - private void on_use_existing_radio_clicked() - { - existing_albums_combo.set_sensitive(true); - new_album_entry.set_sensitive(false); - existing_albums_combo.grab_focus(); - update_publish_button_sensitivity(); - hide_check.set_sensitive(false); - } - - private void on_create_new_radio_clicked() - { - new_album_entry.set_sensitive(true); - existing_albums_combo.set_sensitive(false); - new_album_entry.grab_focus(); - update_publish_button_sensitivity(); - hide_check.set_sensitive(true); - } - - private void on_logout_clicked() - { - logout(); - } - private void update_publish_button_sensitivity() - { - string album_name = new_album_entry.get_text(); - publish_button.set_sensitive( album_name.strip() != "" || !create_new_radio.get_active()); - } - private void on_new_album_entry_changed() - { - update_publish_button_sensitivity(); - } - public void installed() - { - for (int i = 0; i < albums.length; i++) - { - // TODO: sort albums according to their updateDate property - existing_albums_combo.append_text( albums[i].albumName ); - } - if (albums.length == 0) - { - existing_albums_combo.set_sensitive(false); - use_existing_radio.set_sensitive(false); - } - else - { - existing_albums_combo.set_active(0); - existing_albums_combo.set_sensitive(true); - use_existing_radio.set_sensitive(true); - } - create_new_radio.set_active(true); - on_create_new_radio_clicked(); - } - - protected void notify_publish(PublishingParameters parameters) - { - publish( parameters ); - } - - protected void notify_logout() - { - logout(); - } - - public Gtk.Widget get_default_widget() - { - return logout_button; - } - public Gtk.Widget get_widget() - { - return pane_widget; - } - - public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() - { - return Spit.Publishing.DialogPane.GeometryOptions.NONE; - } - - public void on_pane_installed() - { - installed(); - publish.connect(notify_publish); - logout.connect(notify_logout); - } - - public void on_pane_uninstalled() - { - publish.disconnect(notify_publish); - logout.disconnect(notify_logout); - } -} - -internal class PublishingParameters -{ - public string? album_name; - public bool? album_hidden; - public int? album_id; - - private PublishingParameters() - { - } - public PublishingParameters.to_new_album( string album_name, bool album_hidden ) - { - this.album_name = album_name; - this.album_hidden = album_hidden; - this.album_id = 0; - } - public PublishingParameters.to_existing_album( string album_name, int album_id ) - { - this.album_name = album_name; - this.album_hidden = null; - this.album_id = album_id; - } -} - -// REST support classes -/** - * Session class that keeps track of the credentials - */ -internal class Session : Publishing.RESTSupport.Session { - private string? usertoken = null; - private string? albumtoken = null; - private string? albumticket = null; - private string? username = null; - private int? userid = null; - private int? maxsize = null; - private int? quality = null; - - public Session() - { - base(""); - } - - public override bool is_authenticated() - { - return (userid != null && usertoken != null && username != null); - } - - public void authenticate(string token, string name, int id, int maxsize, int quality ) - { - this.usertoken = token; - this.username = name; - this.userid = id; - this.maxsize = maxsize; - this.quality = quality; - } - - public void deauthenticate() - { - usertoken = null; - albumtoken = null; - albumticket = null; - username = null; - userid = null; - maxsize = null; - quality = null; - } - - public void set_usertoken( string? usertoken ){ this.usertoken = usertoken; } - public void set_albumtoken( string? albumtoken ){ this.albumtoken = albumtoken; } - public void set_albumticket( string? albumticket ){ this.albumticket = albumticket; } - - public string get_usertoken() { return usertoken; } - public string get_albumtoken() { return albumtoken; } - public string get_albumticket() { return albumticket; } - public string get_username() { return username; } -// public int get_userid() { return userid; } - public int get_maxsize() { return maxsize; } -// public int get_quality() { return quality; } -} - -internal class ArgItem -{ - public string? key; - public string? val; - public ArgItem[] children; - - public ArgItem( string? k, string? v ) - { - key = k; - val = v; - children = new ArgItem[0]; - } - public void AddChild( ArgItem child ) - { - children += child; - } - public void AddChildren( ArgItem[] newchildren ) - { - foreach( ArgItem child in newchildren ) - { - AddChild( child ); - } - } - ~ArgItem() - { - foreach( ArgItem child in children ) - { - child = null; - } - } -} - -/// <summary> -/// implementation of Rajce Live API -/// </summary> -internal class LiveApiRequest -{ - private ArgItem[] _params; - private string _cmd; - public LiveApiRequest( string cmd ) - { - _params = new ArgItem[0]; - _cmd = cmd; - } - /// <summary> - /// add string parameter - /// </summary> - public void AddParam( string name, string val ) - { - _params += new ArgItem( name, val ); - } - /// <summary> - /// add boolean parameter - /// </summary> - public void AddParamBool( string name, bool val ) - { - AddParam( name, val ? "1" : "0" ); - } - /// <summary> - /// add integer parameter - /// </summary> - public void AddParamInt( string name, int val ) - { - AddParam( name, val.to_string() ); - } -/* /// <summary> - /// add double parameter - /// </summary> - public void AddParamDouble( string name, double val ) - { - AddParam( name, val.to_string() ); - } -*/ /// <summary> - /// add compound parameter - /// </summary> - public void AddParamNode( string name, ArgItem[] val ) - { - ArgItem newItem = new ArgItem( name, null ); - newItem.AddChildren( val ); - _params += newItem; - } - /// <summary> - /// create XML fragment containing all parameters - /// </summary> - public string Params2XmlString( bool urlencode = true ) - { - Xml.Doc* doc = new Xml.Doc( "1.0" ); - Xml.Node* root = new Xml.Node( null, "request" ); - doc->set_root_element( root ); - root->new_text_child( null, "command", _cmd ); - Xml.Node* par = root->new_text_child( null, "parameters", "" ); - foreach( ArgItem arg in _params ) - { - WriteParam( par, arg ); - } - string xmlstr; - doc->dump_memory_enc( out xmlstr ); - delete doc; - if( urlencode ) - { - return Soup.URI.encode( xmlstr, "&;" ); - } - return xmlstr; - } - /// <summary> - /// write single or compound (recursively) parameter into XML - /// </summary> - private static void WriteParam( Xml.Node* node, ArgItem arg ) - { - if( arg.children.length == 0 ) - { - node->new_text_child( null, arg.key, arg.val ); - } - else - { - Xml.Node* subnode = node->new_text_child( null, arg.key, "" ); - foreach( ArgItem child in arg.children ) - { - WriteParam( subnode, child ); - } - } - } -} - - -/** - * Generic REST transaction class. - * - * This class implements the generic logic for all REST transactions used - * by the Rajce publishing plugin. - */ -internal class Transaction : Publishing.RESTSupport.Transaction -{ - public Transaction(Session session) - { - base(session); - } - - public static string? validate_xml(Publishing.RESTSupport.XmlDocument doc) - { - Xml.Node* root = doc.get_root_node(); - if( root == null ) - { - return "No XML returned from server"; - } - string name = root->name; - - // treat malformed root as an error condition - if( name == null || name != "response" ) - { - return "No response from Rajce in XML"; - } - Xml.Node* errcode; - Xml.Node* result; - try - { - errcode = doc.get_named_child(root, "errorCode"); - result = doc.get_named_child(root, "result"); - } - catch (Spit.Publishing.PublishingError err) - { - return null; - } - return "999 Rajce Error [%d]: %s".printf( int.parse( errcode->get_content() ), result->get_content() ); - } -} - -/** - * Transaction used to implement the network login interaction. - */ -internal class SessionLoginTransaction : Transaction -{ - public SessionLoginTransaction(Session session, string url, string username, string token) - { - debug("SessionLoginTransaction: URL: %s", url); - base.with_endpoint_url(session, url); - LiveApiRequest req = new LiveApiRequest( "login" ); - req.AddParam( "clientID", "RajceShotwellPlugin" ); - req.AddParam( "currentVersion", "1.1.1.1" ); - req.AddParam( "login", username ); - req.AddParam( "password", token ); - string xml = req.Params2XmlString(); - add_argument("data", xml); - } -} - -/** - * Transaction used to implement the get albums interaction. - */ -internal class GetAlbumsTransaction : Transaction -{ - public GetAlbumsTransaction(Session session, string url) - { - base.with_endpoint_url(session, url); - LiveApiRequest req = new LiveApiRequest( "getAlbumList" ); - req.AddParam( "token", session.get_usertoken() ); - ArgItem[] columns = new ArgItem[0]; - columns += new ArgItem( "column", "viewCount" ); - columns += new ArgItem( "column", "isFavourite" ); - columns += new ArgItem( "column", "descriptionHtml" ); - columns += new ArgItem( "column", "coverPhotoID" ); - columns += new ArgItem( "column", "localPath" ); - req.AddParamNode( "columns", columns ); - string xml = req.Params2XmlString(); - add_argument("data", xml ); - } -} - -/** - * Transaction used to implement the create album interaction. - */ -internal class CreateAlbumTransaction : Transaction -{ - public CreateAlbumTransaction( Session session, string url, string albumName, bool hidden ) - { - base.with_endpoint_url(session, url); - LiveApiRequest req = new LiveApiRequest( "createAlbum" ); - req.AddParam( "token", session.get_usertoken() ); - req.AddParam( "albumName", albumName ); - req.AddParam( "albumDescription", "" ); - req.AddParamBool( "albumVisible", !hidden ); - string xml = req.Params2XmlString(); - add_argument("data", xml); - } -} - -/** - * Transaction used to implement the open album interaction. - */ -internal class OpenAlbumTransaction : Transaction -{ - public OpenAlbumTransaction( Session session, string url, int albumID ) - { - base.with_endpoint_url(session, url); - LiveApiRequest req = new LiveApiRequest( "openAlbum" ); - req.AddParam( "token", session.get_usertoken() ); - req.AddParamInt( "albumID", albumID ); - string xml = req.Params2XmlString(); - add_argument("data", xml); - } -} - -/** - * Transaction used to implement the close album interaction. - */ -internal class GetAlbumUrlTransaction : Transaction -{ - public GetAlbumUrlTransaction( Session session, string url ) - { - base.with_endpoint_url(session, url); - LiveApiRequest req = new LiveApiRequest( "getAlbumUrl" ); - req.AddParam( "token", session.get_usertoken() ); - req.AddParam( "albumToken", session.get_albumtoken() ); - string xml = req.Params2XmlString(); - add_argument("data", xml); - } -} - -/** - * Transaction used to implement the close album interaction. - */ -internal class CloseAlbumTransaction : Transaction -{ - public CloseAlbumTransaction( Session session, string url ) - { - base.with_endpoint_url(session, url); - LiveApiRequest req = new LiveApiRequest( "closeAlbum" ); - req.AddParam( "token", session.get_usertoken() ); - req.AddParam( "albumToken", session.get_albumtoken() ); - string xml = req.Params2XmlString(); - add_argument("data", xml); - } -} - -/** - * Transaction used to implement the get categories interaction. - */ -internal class GetCategoriesTransaction : Transaction -{ - public GetCategoriesTransaction( Session session, string url ) - { - base.with_endpoint_url(session, url); - LiveApiRequest req = new LiveApiRequest( "getCategories" ); - req.AddParam( "token", session.get_usertoken() ); - string xml = req.Params2XmlString(); - add_argument("data", xml); - } -} - -/** - * Transaction used to implement the upload photo. - */ -private class AddPhotoTransaction : Publishing.RESTSupport.UploadTransaction -{ - private PublishingParameters parameters = null; - - public AddPhotoTransaction(Session session, string url, PublishingParameters parameters, Spit.Publishing.Publishable publishable) - { - base.with_endpoint_url( session, publishable, url ); - this.parameters = parameters; - - debug("RajcePlugin: Uploading photo %s to%s album %s", publishable.get_serialized_file().get_basename(), ( parameters.album_id > 0 ? "" : " new" ), parameters.album_name ); - - string basename = publishable.get_param_string( Spit.Publishing.Publishable.PARAM_STRING_BASENAME ); - string comment = publishable.get_param_string( Spit.Publishing.Publishable.PARAM_STRING_COMMENT ); - string pubname = publishable.get_publishing_name(); - - int width = session.get_maxsize(); - int height = session.get_maxsize(); - - LiveApiRequest req = new LiveApiRequest( "addPhoto" ); - req.AddParam( "token", session.get_usertoken() ); - req.AddParamInt( "width", width ); - req.AddParamInt( "height", height ); - req.AddParam( "albumToken", session.get_albumtoken() ); - req.AddParam( "photoName", pubname ); - req.AddParam( "fullFileName", basename ); - req.AddParam( "description", ( comment != null ? comment : "" ) ); - string xml = req.Params2XmlString( false ); - add_argument( "data", xml ); - - GLib.HashTable<string, string> disposition_table = new GLib.HashTable<string, string>(GLib.str_hash, GLib.str_equal); - disposition_table.insert("name", "photo"); - disposition_table.insert("filename", Soup.URI.encode( basename, null ) ); - set_binary_disposition_table( disposition_table ); - } - -} - - -} - diff --git a/plugins/shotwell-publishing-extras/YandexPublishing.vala b/plugins/shotwell-publishing-extras/YandexPublishing.vala deleted file mode 100644 index 04b28d2..0000000 --- a/plugins/shotwell-publishing-extras/YandexPublishing.vala +++ /dev/null @@ -1,642 +0,0 @@ -/* Copyright 2010+ Evgeniy Polyakov <zbr@ioremap.net> - * - * This software is licensed under the GNU LGPL (version 2.1 or later). - * See the COPYING file in this distribution. - */ - -public class YandexService : Object, Spit.Pluggable, Spit.Publishing.Service { - public int get_pluggable_interface(int min_host_interface, int max_host_interface) { - return Spit.negotiate_interfaces(min_host_interface, max_host_interface, Spit.Publishing.CURRENT_INTERFACE); - } - - public unowned string get_id() { - return "org.yorba.shotwell.publishing.yandex-fotki"; - } - - public unowned string get_pluggable_name() { - return "Yandex.Fotki"; - } - - public void get_info(ref Spit.PluggableInfo info) { - info.authors = "Evgeniy Polyakov <zbr@ioremap.net>"; - info.copyright = _("Copyright 2010+ Evgeniy Polyakov <zbr@ioremap.net>"); - info.translators = Resources.TRANSLATORS; - info.version = _VERSION; - info.website_name = _("Visit the Yandex.Fotki web site"); - info.website_url = "https://fotki.yandex.ru/"; - info.is_license_wordwrapped = false; - info.license = Resources.LICENSE; - } - - public Spit.Publishing.Publisher create_publisher(Spit.Publishing.PluginHost host) { - return new Publishing.Yandex.YandexPublisher(this, host); - } - - public Spit.Publishing.Publisher.MediaType get_supported_media() { - return (Spit.Publishing.Publisher.MediaType.PHOTO); - } - - public void activation(bool enabled) { - } -} - -namespace Publishing.Yandex { - -internal const string SERVICE_NAME = "Yandex.Fotki"; - -private const string client_id = "52be4756dee3438792c831a75d7cd360"; - -internal class Transaction: Publishing.RESTSupport.Transaction { - public Transaction.with_url(Session session, string url, Publishing.RESTSupport.HttpMethod method = Publishing.RESTSupport.HttpMethod.GET) { - base.with_endpoint_url(session, url, method); - add_headers(); - } - - private void add_headers() { - if (((Session) get_parent_session()).is_authenticated()) { - add_header("Authorization", "OAuth %s".printf(((Session) get_parent_session()).get_auth_token())); - add_header("Connection", "close"); - } - } - - public Transaction(Session session, Publishing.RESTSupport.HttpMethod method = Publishing.RESTSupport.HttpMethod.GET) { - base(session, method); - add_headers(); - } - - public void add_data(string type, string data) { - set_custom_payload(data, type); - } -} - -internal class Session : Publishing.RESTSupport.Session { - private string? auth_token = null; - - public Session() { - } - - public override bool is_authenticated() { - return (auth_token != null); - } - - public void deauthenticate() { - auth_token = null; - } - - public void set_auth_token(string token) { - this.auth_token = token; - } - - public string? get_auth_token() { - return auth_token; - } -} - -internal class WebAuthPane : Shotwell.Plugins.Common.WebAuthenticationPane { - private Regex re; - - public signal void login_succeeded(string success_url); - public signal void login_failed(); - - public WebAuthPane(string login_url) { - Object (login_uri : login_url, - preferred_geometry : - Spit.Publishing.DialogPane.GeometryOptions.RESIZABLE); - } - - public override void constructed () { - try { - this.re = new Regex("(.*)#access_token=([a-zA-Z0-9]*)&"); - } catch (RegexError e) { - assert_not_reached (); - } - - this.get_view ().decide_policy.connect (on_decide_policy); - } - - public override void on_page_load () { } - - private bool on_decide_policy (WebKit.PolicyDecision decision, - WebKit.PolicyDecisionType type) { - switch (type) { - case WebKit.PolicyDecisionType.NAVIGATION_ACTION: - WebKit.NavigationPolicyDecision n_decision = (WebKit.NavigationPolicyDecision) decision; - WebKit.NavigationAction action = n_decision.navigation_action; - string uri = action.get_request().uri; - debug("Navigating to '%s'", uri); - - MatchInfo info = null; - - if (re.match(uri, 0, out info)) { - string access_token = info.fetch_all()[2]; - - debug("Load completed: %s", access_token); - this.set_cursor (Gdk.CursorType.LEFT_PTR); - if (access_token != null) { - login_succeeded(access_token); - decision.ignore(); - break; - } else - login_failed(); - } - decision.use(); - break; - case WebKit.PolicyDecisionType.RESPONSE: - decision.use(); - break; - default: - return false; - } - return true; - } -} - -internal class PublishOptions { - public bool disable_comments = false; - public bool hide_original = false; - public string access_type; - - public string destination_album = null; - public string destination_album_url = null; -} - -internal class PublishingOptionsPane: Spit.Publishing.DialogPane, GLib.Object { - private Gtk.Box box; - private Gtk.Builder builder; - private Gtk.Button logout_button; - private Gtk.Button publish_button; - private Gtk.ComboBoxText album_list; - - private weak PublishOptions options; - - public signal void publish(); - public signal void logout(); - - public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() { - return Spit.Publishing.DialogPane.GeometryOptions.NONE; - } - public void on_pane_installed() { - } - public void on_pane_uninstalled() { - } - public Gtk.Widget get_widget() { - return box; - } - - public PublishingOptionsPane(PublishOptions options, Gee.HashMap<string, string> list, - Spit.Publishing.PluginHost host) { - this.options = options; - - box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); - - try { - builder = new Gtk.Builder(); - builder.add_from_resource (Resources.RESOURCE_PATH + "/yandex_publish_model.ui"); - - builder.connect_signals(null); - var content = builder.get_object ("content") as Gtk.Widget; - - album_list = builder.get_object ("album_list") as Gtk.ComboBoxText; - foreach (string key in list.keys) - album_list.append_text(key); - - album_list.set_active(0); - - publish_button = builder.get_object("publish_button") as Gtk.Button; - logout_button = builder.get_object("logout_button") as Gtk.Button; - - publish_button.clicked.connect(on_publish_clicked); - logout_button.clicked.connect(on_logout_clicked); - - content.parent.remove (content); - box.pack_start (content, true, true, 0); - } catch (Error e) { - warning("Could not load UI: %s", e.message); - } - } - - private void on_logout_clicked() { - logout(); - } - - private void on_publish_clicked() { - options.destination_album = album_list.get_active_text(); - - Gtk.CheckButton tmp = builder.get_object("hide_original_check") as Gtk.CheckButton; - options.hide_original = tmp.active; - - tmp = builder.get_object("disable_comments_check") as Gtk.CheckButton; - options.disable_comments = tmp.active; - - Gtk.ComboBoxText access_type = builder.get_object("access_type_list") as Gtk.ComboBoxText; - options.access_type = access_type.get_active_text(); - - publish(); - } -} - -private class Uploader: Publishing.RESTSupport.BatchUploader { - private weak PublishOptions options; - - public Uploader(Session session, PublishOptions options, Spit.Publishing.Publishable[] photos) { - base(session, photos); - - this.options = options; - } - - protected override Publishing.RESTSupport.Transaction create_transaction(Spit.Publishing.Publishable publishable) { - debug("create transaction"); - return new UploadTransaction(((Session) get_session()), options, get_current_publishable()); - } -} - -private class UploadTransaction: Transaction { - public UploadTransaction(Session session, PublishOptions options, Spit.Publishing.Publishable photo) { - base.with_url(session, options.destination_album_url, Publishing.RESTSupport.HttpMethod.POST); - - set_custom_payload("qwe", "image/jpeg", 1); - - debug("Uploading '%s' -> %s : %s", photo.get_publishing_name(), options.destination_album, options.destination_album_url); - - Soup.Multipart message_parts = new Soup.Multipart("multipart/form-data"); - message_parts.append_form_string("title", photo.get_publishing_name()); - message_parts.append_form_string("hide_original", options.hide_original.to_string()); - message_parts.append_form_string("disable_comments", options.disable_comments.to_string()); - message_parts.append_form_string("access", options.access_type.down()); - - string photo_data; - size_t data_length; - - try { - FileUtils.get_contents(photo.get_serialized_file().get_path(), out photo_data, out data_length); - } catch (GLib.FileError e) { - critical("Failed to read data file '%s': %s", photo.get_serialized_file().get_path(), e.message); - } - - int image_part_num = message_parts.get_length(); - - Soup.Buffer bindable_data = new Soup.Buffer(Soup.MemoryUse.COPY, photo_data.data[0:data_length]); - message_parts.append_form_file("", photo.get_serialized_file().get_path(), "image/jpeg", bindable_data); - - unowned Soup.MessageHeaders image_part_header; - unowned Soup.Buffer image_part_body; - message_parts.get_part(image_part_num, out image_part_header, out image_part_body); - - GLib.HashTable<string, string> result = new GLib.HashTable<string, string>(GLib.str_hash, GLib.str_equal); - result.insert("name", "image"); - result.insert("filename", "unused"); - - image_part_header.set_content_disposition("form-data", result); - - Soup.Message outbound_message = Soup.Form.request_new_from_multipart(get_endpoint_url(), message_parts); - outbound_message.request_headers.append("Authorization", ("OAuth %s").printf(session.get_auth_token())); - outbound_message.request_headers.append("Connection", "close"); - set_message(outbound_message); - } -} - -public class YandexPublisher : Spit.Publishing.Publisher, GLib.Object { - private weak Spit.Publishing.PluginHost host = null; - private Spit.Publishing.ProgressCallback progress_reporter = null; - private weak Spit.Publishing.Service service = null; - - private string service_url = null; - - private Gee.HashMap<string, string> album_list = null; - private PublishOptions options; - - private bool running = false; - - private WebAuthPane web_auth_pane = null; - - private Session session; - - public YandexPublisher(Spit.Publishing.Service service, Spit.Publishing.PluginHost host) { - this.service = service; - this.host = host; - this.session = new Session(); - this.album_list = new Gee.HashMap<string, string>(); - this.options = new PublishOptions(); - } - - internal string? get_persistent_auth_token() { - return host.get_config_string("auth_token", null); - } - - internal void set_persistent_auth_token(string auth_token) { - host.set_config_string("auth_token", auth_token); - } - - internal void invalidate_persistent_session() { - host.unset_config_key("auth_token"); - } - - internal bool is_persistent_session_available() { - return (get_persistent_auth_token() != null); - } - - public bool is_running() { - return running; - } - - public Spit.Publishing.Service get_service() { - return service; - } - - private new string? check_response(Publishing.RESTSupport.XmlDocument doc) { - return null; - } - - private void parse_album_entry(Xml.Node *e) throws Spit.Publishing.PublishingError { - string title = null; - string link = null; - - for (Xml.Node* c = e->children ; c != null; c = c->next) { - if (c->name == "title") - title = c->get_content(); - - if ((c->name == "link") && (c->get_prop("rel") == "photos")) - link = c->get_prop("href"); - - if (title != null && link != null) { - debug("Added album: '%s', link: %s", title, link); - album_list.set(title, link); - title = null; - link = null; - break; - } - } - } - - public void parse_album_creation(string data) throws Spit.Publishing.PublishingError { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string(data, check_response); - Xml.Node *root = doc.get_root_node(); - - parse_album_entry(root); - } - - public void parse_album_list(string data) throws Spit.Publishing.PublishingError { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string(data, check_response); - Xml.Node *root = doc.get_root_node(); - - for (Xml.Node *e = root->children ; e != null; e = e->next) { - if (e->name != "entry") - continue; - - parse_album_entry(e); - } - } - - private void album_creation_error(Publishing.RESTSupport.Transaction t, Spit.Publishing.PublishingError err) { - t.completed.disconnect(album_creation_complete); - t.network_error.disconnect(album_creation_error); - - warning("Album creation error: %s", err.message); - } - - private void album_creation_complete(Publishing.RESTSupport.Transaction t) { - t.completed.disconnect(album_creation_complete); - t.network_error.disconnect(album_creation_error); - - try { - parse_album_creation(t.get_response()); - } catch (Spit.Publishing.PublishingError err) { - host.post_error(err); - return; - } - - if (album_list.get(options.destination_album) != null) - start_upload(); - else - host.post_error(new Spit.Publishing.PublishingError.PROTOCOL_ERROR("Server did not create album")); - } - - private void create_destination_album() { - string album = options.destination_album; - string data = "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:f=\"yandex:fotki\"><title>%s</title></entry>".printf(album); - - Transaction t = new Transaction.with_url(session, service_url, Publishing.RESTSupport.HttpMethod.POST); - - t.add_data("application/atom+xml; charset=utf-8; type=entry", data); - - t.completed.connect(album_creation_complete); - t.network_error.connect(album_creation_error); - - try { - t.execute(); - } catch (Spit.Publishing.PublishingError err) { - host.post_error(err); - } - } - - private void on_upload_complete(Publishing.RESTSupport.BatchUploader uploader, int num_published) { - uploader.upload_complete.disconnect(on_upload_complete); - uploader.upload_error.disconnect(on_upload_error); - - if (num_published == 0) - host.post_error(new Spit.Publishing.PublishingError.LOCAL_FILE_ERROR("")); - - host.set_service_locked(false); - - host.install_success_pane(); - } - - private void on_upload_error(Publishing.RESTSupport.BatchUploader uploader, Spit.Publishing.PublishingError err) { - uploader.upload_complete.disconnect(on_upload_complete); - uploader.upload_error.disconnect(on_upload_error); - - warning("Photo upload error: %s", err.message); - } - - private void on_upload_status_updated(int file_number, double completed_fraction) { - debug("EVENT: uploader reports upload %.2f percent complete.", 100.0 * completed_fraction); - - assert(progress_reporter != null); - - progress_reporter(file_number, completed_fraction); - } - - private void start_upload() { - host.set_service_locked(true); - - progress_reporter = host.serialize_publishables(0); - - options.destination_album_url = album_list.get(options.destination_album); - Spit.Publishing.Publishable[] publishables = host.get_publishables(); - Uploader uploader = new Uploader(session, options, publishables); - - uploader.upload_complete.connect(on_upload_complete); - uploader.upload_error.connect(on_upload_error); - uploader.upload(on_upload_status_updated); - } - - private void on_logout() { - if (!is_running()) - return; - - session.deauthenticate(); - invalidate_persistent_session(); - - running = false; - - start(); - } - - private void on_publish() { - debug("Going to publish to '%s' : %s", options.destination_album, album_list.get(options.destination_album)); - if (album_list.get(options.destination_album) == null) - create_destination_album(); - else - start_upload(); - } - - public void service_get_album_list_error(Publishing.RESTSupport.Transaction t, Spit.Publishing.PublishingError err) { - t.completed.disconnect(service_get_album_list_complete); - t.network_error.disconnect(service_get_album_list_error); - - invalidate_persistent_session(); - warning("Failed to get album list: %s", err.message); - } - - public void service_get_album_list_complete(Publishing.RESTSupport.Transaction t) { - t.completed.disconnect(service_get_album_list_complete); - t.network_error.disconnect(service_get_album_list_error); - - debug("service_get_album_list_complete: %s", t.get_response()); - try { - parse_album_list(t.get_response()); - } catch (Spit.Publishing.PublishingError err) { - host.post_error(err); - } - - PublishingOptionsPane publishing_options_pane = new PublishingOptionsPane(options, album_list, - host); - - publishing_options_pane.publish.connect(on_publish); - publishing_options_pane.logout.connect(on_logout); - host.install_dialog_pane(publishing_options_pane); - } - - public void service_get_album_list(string url) { - service_url = url; - - Transaction t = new Transaction.with_url(session, url); - t.completed.connect(service_get_album_list_complete); - t.network_error.connect(service_get_album_list_error); - - try { - t.execute(); - } catch (Spit.Publishing.PublishingError err) { - host.post_error(err); - } - } - - public void fetch_account_error(Publishing.RESTSupport.Transaction t, Spit.Publishing.PublishingError err) { - t.completed.disconnect(fetch_account_complete); - t.network_error.disconnect(fetch_account_error); - - warning("Failed to fetch account info: %s", err.message); - } - - public void fetch_account_complete(Publishing.RESTSupport.Transaction t) { - t.completed.disconnect(fetch_account_complete); - t.network_error.disconnect(fetch_account_error); - - debug("account info: %s", t.get_response()); - try { - Publishing.RESTSupport.XmlDocument doc = Publishing.RESTSupport.XmlDocument.parse_string(t.get_response(), check_response); - Xml.Node* root = doc.get_root_node(); - - for (Xml.Node* work = root->children ; work != null; work = work->next) { - if (work->name != "workspace") - continue; - for (Xml.Node* c = work->children ; c != null; c = c->next) { - if (c->name != "collection") - continue; - - if (c->get_prop("id") == "album-list") { - string url = c->get_prop("href"); - - set_persistent_auth_token(session.get_auth_token()); - service_get_album_list(url); - break; - } - } - } - } catch (Spit.Publishing.PublishingError err) { - host.post_error(err); - } - } - - public void fetch_account_information(string auth_token) { - session.set_auth_token(auth_token); - - Transaction t = new Transaction.with_url(session, "https://api-fotki.yandex.ru/api/me/"); - t.completed.connect(fetch_account_complete); - t.network_error.connect(fetch_account_error); - - try { - t.execute(); - } catch (Spit.Publishing.PublishingError err) { - host.post_error(err); - } - } - - private void web_auth_login_succeeded(string access_token) { - debug("login succeeded with token %s", access_token); - - host.set_service_locked(true); - host.install_account_fetch_wait_pane(); - - fetch_account_information(access_token); - } - - private void web_auth_login_failed() { - debug("login failed"); - } - - private void start_web_auth() { - host.set_service_locked(false); - - web_auth_pane = new WebAuthPane(("https://oauth.yandex.ru/authorize?client_id=%s&response_type=token").printf(client_id)); - web_auth_pane.login_succeeded.connect(web_auth_login_succeeded); - web_auth_pane.login_failed.connect(web_auth_login_failed); - - host.install_dialog_pane(web_auth_pane, Spit.Publishing.PluginHost.ButtonMode.CANCEL); - } - - private void show_welcome_page() { - host.install_welcome_pane(_("You are not currently logged into Yandex.Fotki."), - start_web_auth); - } - - public void start() { - if (is_running()) - return; - - if (host == null) - error("YandexPublisher: start( ): can't start; this publisher is not restartable."); - - debug("YandexPublisher: starting interaction."); - - running = true; - - if (is_persistent_session_available()) { - session.set_auth_token(get_persistent_auth_token()); - - fetch_account_information(get_persistent_auth_token()); - } else { - show_welcome_page(); - } - } - - public void stop() { - debug("YandexPublisher: stop( ) invoked."); - - host = null; - running = false; - } -} - -} - diff --git a/plugins/shotwell-publishing-extras/gallery3.png b/plugins/shotwell-publishing-extras/gallery3.png Binary files differdeleted file mode 100644 index 9e3c5cc..0000000 --- a/plugins/shotwell-publishing-extras/gallery3.png +++ /dev/null diff --git a/plugins/shotwell-publishing-extras/gallery3_authentication_pane.ui b/plugins/shotwell-publishing-extras/gallery3_authentication_pane.ui deleted file mode 100644 index 3317805..0000000 --- a/plugins/shotwell-publishing-extras/gallery3_authentication_pane.ui +++ /dev/null @@ -1,216 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> -<interface> - <requires lib="gtk+" version="3.14"/> - <object class="GtkGrid" id="gallery3_auth_pane_widget"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkLabel" id="intro_message_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="ypad">15</property> - <property name="label">Intro message replaced at runtime</property> - <property name="use_markup">True</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - <property name="width">5</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="url_entry_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_bottom">30</property> - <property name="label" translatable="yes">_Gallery3 URL:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">url_entry</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="url_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="margin_bottom">30</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - <property name="width">4</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="username_entry_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">_User name:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">username_entry</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="password_entry_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">_Password:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">password_entry</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">3</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="username_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">3</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="password_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="visibility">False</property> - <property name="invisible_char">●</property> - <property name="activates_default">True</property> - </object> - <packing> - <property name="left_attach">3</property> - <property name="top_attach">3</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="buttons_grid"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_top">30</property> - <child> - <object class="GtkButton" id="go_back_button"> - <property name="label" translatable="yes">Go _Back</property> - <property name="width_request">102</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="halign">center</property> - <property name="valign">center</property> - <property name="hexpand">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="login_button"> - <property name="label" translatable="yes">_Log in</property> - <property name="width_request">102</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="is_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">True</property> - <property name="halign">center</property> - <property name="valign">center</property> - <property name="hexpand">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">6</property> - <property name="width">5</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="key_entry_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">API _Key:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">key_entry</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">5</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="key_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <property name="activates_default">True</property> - <property name="width_chars">33</property> - </object> - <packing> - <property name="left_attach">3</property> - <property name="top_attach">5</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="or_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">or</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">4</property> - <property name="width">5</property> - </packing> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - </object> -</interface> diff --git a/plugins/shotwell-publishing-extras/gallery3_publishing_options_pane.ui b/plugins/shotwell-publishing-extras/gallery3_publishing_options_pane.ui deleted file mode 100644 index f27fd2d..0000000 --- a/plugins/shotwell-publishing-extras/gallery3_publishing_options_pane.ui +++ /dev/null @@ -1,238 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> -<interface domain="shotwell"> - <requires lib="gtk+" version="3.14"/> - <object class="GtkGrid" id="pane_widget"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkLabel" id="title_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="margin_top">16</property> - <property name="margin_bottom">16</property> - <property name="label">'Publishing to $url as $username' (populated in application code)</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - <property name="width">2</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="options_grid"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_bottom">16</property> - <property name="hexpand">True</property> - <property name="row_spacing">8</property> - <property name="column_spacing">32</property> - <property name="column_homogeneous">True</property> - <child> - <object class="GtkRadioButton" id="publish_to_existing_radio"> - <property name="label" translatable="yes">An _existing album</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">publish_new_radio</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkComboBoxText" id="existing_albums_combo"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="publish_new_radio"> - <property name="label" translatable="yes">A _new album</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="new_album_name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="strip_metadata_check"> - <property name="label" translatable="yes">_Remove location, tag and camera-identifying data before uploading</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="valign">center</property> - <property name="margin_top">16</property> - <property name="hexpand">True</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">5</property> - <property name="width">2</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="major_axis_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="label" translatable="yes">Scaling constraint:</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="pixels_grid"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="column_spacing">5</property> - <child> - <object class="GtkLabel" id="pixels_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">pixels</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="major_axis_pixels"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="invisible_char">●</property> - <property name="truncate_multiline">True</property> - <property name="caps_lock_warning">False</property> - <property name="input_purpose">number</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">4</property> - </packing> - </child> - <child> - <object class="GtkComboBoxText" id="scaling_constraint_combo"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <items> - <item translatable="yes">Original size</item> - <item translatable="yes">Longest edge</item> - </items> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">3</property> - </packing> - </child> - <child> - <object class="GtkSeparator" id="album_separator"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_left">5</property> - <property name="margin_right">5</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - <property name="width">2</property> - </packing> - </child> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - <property name="width">2</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="buttons_grid"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_left">112</property> - <property name="margin_right">112</property> - <property name="margin_top">48</property> - <property name="margin_bottom">24</property> - <property name="hexpand">True</property> - <property name="column_spacing">128</property> - <property name="column_homogeneous">True</property> - <child> - <object class="GtkButton" id="logout_button"> - <property name="label" translatable="yes">_Logout</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="publish_button"> - <property name="label" translatable="yes">_Publish</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="is_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - <property name="width">2</property> - </packing> - </child> - </object> -</interface> diff --git a/plugins/shotwell-publishing-extras/meson.build b/plugins/shotwell-publishing-extras/meson.build deleted file mode 100644 index 34f3e12..0000000 --- a/plugins/shotwell-publishing-extras/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -shotwell_publishing_extra_sources = [ - 'GalleryConnector.vala', - 'RajcePublishing.vala', - 'shotwell-publishing-extras.vala', - 'YandexPublishing.vala' - ] - -shotwell_publishing_extra_resources = gnome.compile_resources('publishing-extra-resource', - 'org.gnome.Shotwell.Publishing.Extras.gresource.xml') - -shared_module('shotwell-publishing-extras', - shotwell_publishing_extra_sources + shotwell_publishing_extra_resources, - dependencies : [gee, gtk, xml, soup, gdk_pixbuf, sw_plugin, - sw_plugin_common_dep, json_glib, webkit], - vala_args : [ - '--gresources', 'org.gnome.Shotwell.Publishing.Extras.gresource.xml' - ], - c_args : ['-DPLUGIN_RESOURCE_PATH="/org/gnome/Shotwell/Publishing/Extras"', - '-DGCR_API_SUBJECT_TO_CHANGE'], - install: true, - install_dir : shotwell_plugin_dir) diff --git a/plugins/shotwell-publishing-extras/org.gnome.Shotwell.Publishing.Extras.gresource.xml b/plugins/shotwell-publishing-extras/org.gnome.Shotwell.Publishing.Extras.gresource.xml deleted file mode 100644 index 5916f82..0000000 --- a/plugins/shotwell-publishing-extras/org.gnome.Shotwell.Publishing.Extras.gresource.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<gresources> - <gresource prefix="/org/gnome/Shotwell/Publishing/Extras"> - <file>gallery3.png</file> - <file>rajce.png</file> - <file>gallery3_authentication_pane.ui</file> - <file>gallery3_publishing_options_pane.ui</file> - <file>rajce_authentication_pane.ui</file> - <file>rajce_publishing_options_pane.ui</file> - <file>yandex_publish_model.ui</file> - </gresource> -</gresources> diff --git a/plugins/shotwell-publishing-extras/rajce.png b/plugins/shotwell-publishing-extras/rajce.png Binary files differdeleted file mode 100644 index 8ab0995..0000000 --- a/plugins/shotwell-publishing-extras/rajce.png +++ /dev/null diff --git a/plugins/shotwell-publishing-extras/rajce_authentication_pane.ui b/plugins/shotwell-publishing-extras/rajce_authentication_pane.ui deleted file mode 100644 index 2ef9f3d..0000000 --- a/plugins/shotwell-publishing-extras/rajce_authentication_pane.ui +++ /dev/null @@ -1,142 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> -<interface domain="shotwell"> - <requires lib="gtk+" version="3.14"/> - <object class="GtkWindow" id="authentication_pane"> - <property name="can_focus">False</property> - <child> - <object class="GtkBox" id="content"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_left">30</property> - <property name="margin_right">30</property> - <property name="orientation">vertical</property> - <property name="spacing">8</property> - <child> - <object class="GtkLabel" id="message_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="label">label</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="field_table"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="row_spacing">2</property> - <property name="column_spacing">8</property> - <child> - <object class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="label" translatable="yes">_Email address</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">username_entry</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="username_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="password_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="vexpand">False</property> - <property name="visibility">False</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="label" translatable="yes">_Password</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">password_entry</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="remember_checkbutton"> - <property name="label" translatable="yes">_Remember</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkButtonBox" id="hbuttonbox1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkButton" id="login_button"> - <property name="label" translatable="yes">Log in</property> - <property name="use_action_appearance">False</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">3</property> - </packing> - </child> - </object> - </child> - </object> -</interface> diff --git a/plugins/shotwell-publishing-extras/rajce_publishing_options_pane.ui b/plugins/shotwell-publishing-extras/rajce_publishing_options_pane.ui deleted file mode 100644 index 28011f1..0000000 --- a/plugins/shotwell-publishing-extras/rajce_publishing_options_pane.ui +++ /dev/null @@ -1,246 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> -<interface domain="shotwell"> - <requires lib="gtk+" version="3.14"/> - <object class="GtkBox" id="rajce_pane_widget"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">1</property> - <child> - <placeholder/> - </child> - <child> - <object class="GtkBox" id="user_area_box"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">center</property> - <property name="margin_left">36</property> - <property name="margin_right">36</property> - <property name="margin_top">24</property> - <property name="margin_bottom">24</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="login_identity_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="valign">center</property> - <property name="label">you are logged in rajce as $name</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="padding">4</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="logout_button"> - <property name="label" translatable="yes">_Logout</property> - <property name="width_request">64</property> - <property name="height_request">24</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="valign">center</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkBox" id="album_gallery_layout_box"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_left">16</property> - <property name="margin_right">16</property> - <property name="orientation">vertical</property> - <child> - <placeholder/> - </child> - <child> - <object class="GtkGrid" id="album_choice_area_grid"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_left">1</property> - <property name="row_spacing">8</property> - <child> - <object class="GtkComboBoxText" id="existing_albums_combo"> - <property name="width_request">320</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="new_album_entry"> - <property name="width_request">320</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">•</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="use_existing_radio"> - <property name="label" translatable="yes">An _existing album:</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="margin_left">4</property> - <property name="margin_right">4</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - <property name="group">create_new_radio</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="create_new_radio"> - <property name="label" translatable="yes">A _new album named:</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="margin_left">4</property> - <property name="margin_right">4</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="hide_check"> - <property name="label" translatable="yes">_Hide album</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">3</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="show_check"> - <property name="label" translatable="yes">Open target _album in browser</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">4</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="publish_to_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="margin_top">4</property> - <property name="margin_bottom">8</property> - <property name="label">$mediatype will appear in</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - <property name="width">2</property> - </packing> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="padding">4</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> - <child> - <placeholder/> - </child> - <child> - <object class="GtkBox" id="button_area_box"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_left">196</property> - <property name="margin_right">196</property> - <property name="margin_top">24</property> - <property name="margin_bottom">24</property> - <property name="spacing">128</property> - <property name="homogeneous">True</property> - <child> - <object class="GtkButton" id="publish_button"> - <property name="label" translatable="yes">_Publish</property> - <property name="width_request">96</property> - <property name="height_request">30</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="halign">center</property> - <property name="valign">center</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">4</property> - </packing> - </child> - </object> -</interface> diff --git a/plugins/shotwell-publishing-extras/shotwell-publishing-extras.vala b/plugins/shotwell-publishing-extras/shotwell-publishing-extras.vala deleted file mode 100644 index fb622fa..0000000 --- a/plugins/shotwell-publishing-extras/shotwell-publishing-extras.vala +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2016 Software Freedom Conservancy Inc. - * - * This software is licensed under the GNU Lesser General Public License - * (version 2.1 or later). See the COPYING file in this distribution. - */ - -extern const string _VERSION; - -private class ShotwellPublishingExtraServices : Object, Spit.Module { - private Spit.Pluggable[] pluggables = new Spit.Pluggable[0]; - - public ShotwellPublishingExtraServices(GLib.File module_file) { -#if HAVE_YANDEX - pluggables += new YandexService(); -#endif - -#if HAVE_RAJCE - pluggables += new RajceService(module_file.get_parent()); -#endif - -#if HAVE_GALLERY3 - pluggables += new Gallery3Service(module_file.get_parent()); -#endif - } - - public unowned string get_module_name() { - return _("Shotwell Extra Publishing Services"); - } - - public unowned string get_version() { - return _VERSION; - } - - public unowned string get_id() { - return "org.yorba.shotwell.publishing.extras"; - } - - public unowned Spit.Pluggable[]? get_pluggables() { - return pluggables; - } -} - -// This entry point is required for all SPIT modules. -public Spit.Module? spit_entry_point(Spit.EntryPointParams *params) { - params->module_spit_interface = Spit.negotiate_interfaces(params->host_min_spit_interface, - params->host_max_spit_interface, Spit.CURRENT_INTERFACE); - - return (params->module_spit_interface != Spit.UNSUPPORTED_INTERFACE) - ? new ShotwellPublishingExtraServices(params->module_file) : null; -} - diff --git a/plugins/shotwell-publishing-extras/yandex_publish_model.ui b/plugins/shotwell-publishing-extras/yandex_publish_model.ui deleted file mode 100644 index e1cc54d..0000000 --- a/plugins/shotwell-publishing-extras/yandex_publish_model.ui +++ /dev/null @@ -1,182 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> -<interface> - <requires lib="gtk+" version="3.14"/> - <object class="GtkListStore" id="liststore1"> - <columns> - <!-- column-name text --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">Public</col> - </row> - <row> - <col id="0" translatable="yes">Friends</col> - </row> - <row> - <col id="0" translatable="yes">Private</col> - </row> - </data> - </object> - <object class="GtkListStore" id="liststore2"> - <columns> - <!-- column-name gchararray1 --> - <column type="gchararray"/> - </columns> - </object> - <object class="GtkWindow" id="publish_options_window"> - <property name="can_focus">False</property> - <child> - <object class="GtkBox" id="content"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">center</property> - <property name="valign">center</property> - <property name="margin_left">30</property> - <property name="margin_right">30</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkGrid" id="table1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">_Albums (or write new):</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">album_list</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkComboBoxText" id="access_type_list"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="active">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkComboBoxText" id="album_list"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="active">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="margin_left">6</property> - <property name="margin_right">6</property> - <property name="label" translatable="yes">Access _type:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">access_type_list</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <placeholder/> - </child> - <child> - <object class="GtkCheckButton" id="disable_comments_check"> - <property name="label" translatable="yes">Disable _comments</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="padding">2</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="hide_original_check"> - <property name="label" translatable="yes">_Forbid downloading original photo</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkButtonBox" id="hbuttonbox1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">2</property> - <property name="layout_style">spread</property> - <child> - <object class="GtkButton" id="logout_button"> - <property name="label" translatable="yes">_Logout</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="publish_button"> - <property name="label" translatable="yes">_Publish</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="padding">12</property> - <property name="position">4</property> - </packing> - </child> - </object> - </child> - </object> -</interface> |