[seahorse/wip/nielsdg/gkr-the-big-cleanup] gkr: Split off ItemInfo



commit c277528859433db8a2ee1c6575d17a178201b4bd
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Wed Jan 15 07:48:23 2020 +0100

    gkr: Split off ItemInfo
    
    Convert the `DisplayInfo` struct to a proper class and use subclasses
    for the specific types of entries.

 gkr/gkr-item-info.vala | 323 +++++++++++++++++++++++
 gkr/gkr-item.vala      | 680 ++++++++++++++++---------------------------------
 gkr/meson.build        |   1 +
 po/POTFILES.in         |   1 +
 po/POTFILES.skip       |   1 +
 5 files changed, 539 insertions(+), 467 deletions(-)
---
diff --git a/gkr/gkr-item-info.vala b/gkr/gkr-item-info.vala
new file mode 100644
index 00000000..efaedd2c
--- /dev/null
+++ b/gkr/gkr-item-info.vala
@@ -0,0 +1,323 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2006 Stefan Walter
+ * Copyright (C) 2011 Collabora Ltd.
+ * Copyright (C) 2020 Niels De Graef
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Seahorse.Gkr {
+
+/**
+ * The generic base class that holds extra info for a {@link Gkr.Item}.
+ */
+public class ItemInfo : GLib.Object {
+
+    public string label { get; protected set; default = ""; }
+
+    public string description { get; protected set; default = _("Password or Secret"); }
+
+    public string details { get; protected set; default = ""; }
+
+    public GLib.Icon? icon { get; protected set; }
+
+    public ItemInfo(string? label, string? description = null) {
+        GLib.Object(label: label);
+
+        if (label != null)
+            this.label = label;
+
+        if (description != null)
+            this.description = description;
+    }
+
+    public void query_installed_apps(string item_type) {
+        DesktopAppInfo? app_info = new DesktopAppInfo("%s.desktop".printf(item_type));
+        if (app_info == null)
+            return;
+
+        this.icon = app_info.get_icon();
+    }
+
+    // Hlper methods to get attributes
+    protected unowned string? get_attribute_string(HashTable<string, string>? attrs,
+                                                   string name) {
+        if (attrs == null)
+            return null;
+        return attrs.lookup(name);
+    }
+
+    protected int get_attribute_int(HashTable<string, string>? attrs,
+                                    string name) {
+        if (attrs == null)
+            return 0;
+
+        var value = attrs.lookup(name);
+        if (value != null)
+            return int.parse(value);
+
+        return 0;
+    }
+}
+
+/**
+ * Used for NetworkManager connections, with xdg:schema
+ * "org.freedesktop.NetworkManager.Connection"
+ */
+public class NmConnectionInfo : ItemInfo {
+
+    public NmConnectionInfo(string label, HashTable<string, string>? attrs) {
+        GLib.Object(label: label,
+                    description: _("Network connection secret"));
+
+        unowned string? setting_name = get_attribute_string(attrs,
+                                                            "setting-name");
+
+        if (setting_name == "802-11-wireless-security") {
+            this.icon = new ThemedIcon("network-wireless-symbolic");
+            this.description = _("Wi-Fi password");
+        }
+    }
+}
+
+/**
+ * Used for entries in gnome-keyring with xdg:schema
+ * "org.gnome.keyring.NetworkPassword"
+ */
+public class GkrNetworkPassInfo : ItemInfo {
+
+    public GkrNetworkPassInfo(string label, HashTable<string, string>? attrs) {
+        GLib.Object(label: label,
+                    description: _("Network password"));
+
+        unowned string? server = get_attribute_string(attrs, "server");
+        unowned string? protocol = get_attribute_string(attrs, "protocol");
+        unowned string? object = get_attribute_string(attrs, "object");
+        unowned string? user = get_attribute_string(attrs, "user");
+        var port = get_attribute_int (attrs, "port");
+
+        if (protocol == null)
+            return;
+
+        /* If it's customized by the application or user then display that */
+        if (!is_custom_network_label (server, user, object, port, label))
+            this.label = calc_network_label (attrs, true);
+        else
+            this.label = label;
+
+        unowned string symbol = "@";
+        if (user == null) {
+            user = "";
+            symbol = "";
+        }
+
+        if (object == null)
+            object = "";
+
+        if (server != null && protocol != null) {
+            this.details = GLib.Markup.printf_escaped("%s://%s%s%s/%s",
+                                                      protocol, user, symbol,
+                                                      server, object);
+        }
+    }
+
+    /* For network passwords gnome-keyring generates in a funky looking display
+     * name that's generated from login credentials. We simulate that generating
+     * here and return FALSE if it matches. This allows us to display user
+     * customized display names and ignore the generated ones. */
+    private bool is_custom_network_label(string? server,
+                                         string? user,
+                                         string? object,
+                                         int port,
+                                         string? label) {
+
+        if (server == null)
+            return true;
+
+        var generated = new GLib.StringBuilder("");
+        if (user != null)
+            generated.append_printf("%s@", user);
+        generated.append(server);
+        if (port != 0)
+            generated.append_printf(":%d", port);
+        if (object != null)
+            generated.append_printf ("/%s", object);
+
+        return (generated.str == label);
+    }
+
+    private string? calc_network_label(HashTable<string, string>? attrs,
+                                       bool always) {
+        /* HTTP usually has a the realm as the "object" display that */
+        if (is_network_item (attrs, "http") && attrs != null) {
+            unowned string? val = get_attribute_string(attrs, "object");
+            if (val != null && val != "")
+                return val;
+
+            /* Display the server name as a last resort */
+            if (always) {
+                val = get_attribute_string(attrs, "server");
+                if (val != null && val != "")
+                    return val;
+            }
+        }
+
+        return null;
+    }
+
+    private bool is_network_item(HashTable<string, string>? attrs,
+                                 string match) {
+        unowned string? protocol = get_attribute_string(attrs, "protocol");
+        return protocol != null && protocol.ascii_casecmp(match) == 0;
+    }
+}
+
+/** Used for GNOME Web (epiphany) passwordss */
+public class EpiphanyPassInfo : ItemInfo {
+
+    public EpiphanyPassInfo(string label, HashTable<string, string>? attrs) {
+        GLib.Object(label: label,
+                    description: _("GNOME Web password"));
+
+        // Set the Epiphany icon
+        query_installed_apps("org.gnome.Epiphany");
+
+        unowned string? uri = get_attribute_string(attrs, "uri");
+        if (uri != null)
+            this.label = uri;
+
+        unowned string? username = get_attribute_string(attrs, "username");
+        if (username != null)
+            this.details = Markup.escape_text(username);
+    }
+}
+
+/** Used for passwords saved in Chrome/Chromium */
+public class ChromePassInfo : ItemInfo {
+
+    public ChromePassInfo(string label, HashTable<string, string>? attrs) {
+        GLib.Object(label: label,
+                    description: _("Google Chrome password"));
+
+
+        unowned string? origin = get_attribute_string(attrs, "origin_url");
+        /* A brain dead url, parse */
+        if (label != null && label == origin) {
+            try {
+                var regex = new GLib.Regex("[a-z]+://([^/]+)/", GLib.RegexCompileFlags.CASELESS, 0);
+                GLib.MatchInfo match;
+                if (regex.match(label, GLib.RegexMatchFlags.ANCHORED, out match)) {
+                    if (match.matches())
+                        this.label = match.fetch(1);
+                }
+            } catch (GLib.RegexError err) {
+                GLib.critical("%s", err.message);
+                return;
+            }
+
+        }
+
+        if (this.label == "")
+            this.label = label;
+        if (origin != null)
+            this.details = GLib.Markup.escape_text(origin);
+        else
+            this.details = "";
+    }
+}
+
+/** Used for Empathy */
+public class EmpathyInfo : ItemInfo {
+
+    public EmpathyInfo(string label, HashTable<string, string>? attrs) {
+        GLib.Object(label: label,
+                    description: _("Instant messaging password"));
+
+        unowned string? account = get_attribute_string(attrs, "account-id");
+
+        /* Translators: This should be the same as the string in empathy */
+        unowned string prefix = _("IM account password for ");
+
+        if (label != null && label.has_prefix(prefix)) {
+            var len = prefix.length;
+            var pos = label.index_of_char ('(', (int)len);
+            if (pos != -1)
+                this.label = label.slice(len, pos);
+
+            try {
+                var regex = new GLib.Regex("^.+/.+/(.+)$", GLib.RegexCompileFlags.CASELESS, 0);
+                GLib.MatchInfo match;
+                if (regex.match(account, GLib.RegexMatchFlags.ANCHORED, out match)) {
+                    if (match.matches())
+                        this.details = TelepathyInfo.decode_id(match.fetch(1));
+                }
+            } catch (GLib.RegexError err) {
+                GLib.critical("%s", err.message);
+                return;
+            }
+        }
+
+        if (this.label == "")
+            this.label = label;
+        if (this.details == null)
+            this.details = GLib.Markup.escape_text (account);
+    }
+}
+
+/** Used for Telepathy */
+public class TelepathyInfo : ItemInfo {
+
+    public TelepathyInfo(string label, HashTable<string, string>? attrs) {
+        GLib.Object(label: label,
+                    description: _("Telepathy password"));
+
+        unowned string? account = get_attribute_string (attrs, "account");
+        if (account != null && label != null && label.index_of(account) != -1) {
+            try {
+                var regex = new GLib.Regex("^.+/.+/(.+)$", GLib.RegexCompileFlags.CASELESS, 0);
+                GLib.MatchInfo match;
+                if (regex.match(account, GLib.RegexMatchFlags.ANCHORED, out match)) {
+                    if (match.matches()) {
+                        var identifier = match.fetch(1);
+                        this.label = decode_id(identifier);
+                    }
+                }
+            } catch (GLib.RegexError err) {
+                GLib.critical("%s", err.message);
+                return;
+            }
+        }
+
+        if (this.label == "")
+            this.label = label;
+        if (account != null)
+            this.details = GLib.Markup.escape_text(account);
+    }
+
+    public static string? decode_id(string account) {
+        account.replace("_", "%");
+        return GLib.Uri.unescape_string(account);
+    }
+}
+
+/** Used for GNOME Online Accounts */
+public class GoaInfo : ItemInfo {
+
+    public GoaInfo(string label, HashTable<string, string>? attrs) {
+        GLib.Object(label: label,
+                    description: _("GNOME Online Accounts password"));
+    }
+}
+}
diff --git a/gkr/gkr-item.vala b/gkr/gkr-item.vala
index e5f0c2b4..8542a954 100644
--- a/gkr/gkr-item.vala
+++ b/gkr/gkr-item.vala
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2006 Stefan Walter
  * Copyright (C) 2011 Collabora Ltd.
+ * Copyright (C) 2020 Niels De Graef
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,91 +18,71 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-namespace Seahorse {
-namespace Gkr {
+namespace Seahorse.Gkr {
 
 public enum Use {
-       OTHER,
-       NETWORK,
-       WEB,
-       PGP,
-       SSH,
+    OTHER,
+    NETWORK,
+    WEB,
+    PGP,
+    SSH,
 }
 
-private struct DisplayInfo {
-       string? item_type;
-       string? label;
-       string? details;
-       string? description;
-    GLib.Icon? icon;
+/**
+ * The Seahorse-specific class for entries in a libsecret keyring.
+ *
+ * Since libsecret creates the object for us, we can't really add stuff using a
+ * constructor, so to add specific info for certain categories of items, we
+ * stuff everything into the {@link ItemInfo} field.
+ */
+public class Item : Secret.Item, Deletable, Viewable {
 
-    public void query_installed_apps(string item_type) {
-        DesktopAppInfo? app_info = new DesktopAppInfo("%s.desktop".printf(item_type));
-        if (app_info == null)
-            return;
+    public string description {
+        owned get {
+            ensure_item_info();
+            return this._info.description;
+        }
+    }
 
-        this.icon = app_info.get_icon();
+    public Use use {
+        get {
+            var schema_name = get_attribute("xdg:schema");
+            if (schema_name != null && schema_name == NETWORK_PASSWORD)
+                return Use.NETWORK;
+            return Use.OTHER;
+        }
     }
-}
 
-[CCode (has_target = false)]
-private delegate void DisplayCustom(string label,
-                                    GLib.HashTable<string, string> item_attrs,
-                                    ref DisplayInfo info);
+    public bool has_secret {
+        get { return _item_secret != null; }
+    }
 
-private struct DisplayEntry {
-       string item_type;
-       string description;
-       DisplayCustom? custom_func;
-}
+    public Keyring place {
+        owned get { return (Keyring)_place.get(); }
+        set { _place.set(value); }
+    }
 
-public class Item : Secret.Item, Deletable, Viewable {
-       public string description {
-               owned get {
-                       ensure_display_info ();
-                       return this._info.description;
-               }
-       }
-
-       public Use use {
-               get {
-                       var schema_name = get_attribute("xdg:schema");
-                       if (schema_name != null && schema_name == NETWORK_PASSWORD)
-                               return Use.NETWORK;
-                       return Use.OTHER;
-               }
-       }
-
-       public bool has_secret {
-               get { return _item_secret != null; }
-       }
-
-       public Keyring place {
-               owned get { return (Keyring)_place.get(); }
-               set { _place.set(value); }
-       }
-
-       public Flags object_flags {
-               get { return Flags.DELETABLE | Flags.PERSONAL; }
-       }
+    public Flags object_flags {
+        get { return Flags.DELETABLE | Flags.PERSONAL; }
+    }
 
     public GLib.Icon icon {
         owned get {
-            ensure_display_info();
+            ensure_item_info();
             return this._info.icon ?? new GLib.ThemedIcon (ICON_PASSWORD);
         }
     }
 
-       public new string label {
-               owned get {
-                       ensure_display_info ();
-                       return this._info.label;
-               }
-       }
+    public new string label {
+        owned get {
+            ensure_item_info ();
+            return this._info.label;
+        }
+    }
 
     public string markup {
         owned get {
-            ensure_display_info ();
+            ensure_item_info ();
             var result = new StringBuilder("");
             result.append(Markup.escape_text(this._info.label));
             if (this._info.details != null && this._info.details != "") {
@@ -113,132 +94,145 @@ public class Item : Secret.Item, Deletable, Viewable {
         }
     }
 
-       public Usage usage {
-               get { return Usage.CREDENTIALS; }
-       }
-
-       public Gtk.ActionGroup? actions {
-               get { return null; }
-       }
-
-       public bool deletable {
-               get { return true; }
-       }
-
-       private Secret.Value? _item_secret = null;
-       private DisplayInfo? _info = null;
-       private GLib.WeakRef _place;
-       private GLib.Cancellable? _req_secret = null;
-
-       construct {
-               g_properties_changed.connect((changed_properties, invalidated_properties) => {
-                       this._info = null;
-                       freeze_notify();
-                       notify_property("has-secret");
-                       notify_property("use");
-                       notify_property("label");
-                       notify_property("icon");
-                       notify_property("markup");
-                       notify_property("description");
-                       notify_property("object-flags");
-                       thaw_notify();
-               });
-       }
-
-       public override void dispose() {
-               if (this._req_secret != null)
-                       this._req_secret.cancel();
-               this._req_secret = null;
-               base.dispose();
-       }
-
-       public Deleter create_deleter() {
-               return new ItemDeleter(this);
-       }
-
-       public Gtk.Window? create_viewer(Gtk.Window? parent) {
-               return new ItemProperties(this, parent);
-       }
-
-    private void ensure_display_info() {
+    public Usage usage {
+        get { return Usage.CREDENTIALS; }
+    }
+
+    public bool deletable {
+        get { return true; }
+    }
+
+    private Secret.Value? _item_secret = null;
+    private ItemInfo? _info = null;
+    private GLib.WeakRef _place;
+    private GLib.Cancellable? _req_secret = null;
+
+    construct {
+        g_properties_changed.connect((changed_properties, invalidated_properties) => {
+            this._info = null;
+            freeze_notify();
+            notify_property("has-secret");
+            notify_property("use");
+            notify_property("label");
+            notify_property("icon");
+            notify_property("markup");
+            notify_property("description");
+            notify_property("object-flags");
+            thaw_notify();
+        });
+    }
+
+    public override void dispose() {
+        if (this._req_secret != null)
+            this._req_secret.cancel();
+        this._req_secret = null;
+        base.dispose();
+    }
+
+    public Deleter create_deleter() {
+        return new ItemDeleter(this);
+    }
+
+    public Gtk.Window? create_viewer(Gtk.Window? parent) {
+        return new ItemProperties(this, parent);
+    }
+
+    private void ensure_item_info() {
         if (this._info != null)
             return;
 
-        this._info = DisplayInfo();
-
+        unowned string? item_type = null;
         var attrs = this.attributes;
-        var item_type = get_attribute_string (attrs, "xdg:schema");
-        item_type = map_item_type_to_specific (item_type, attrs);
+        if (attrs != null)
+            item_type = attrs.lookup("xdg:schema");
+        item_type = map_item_type_to_specific(item_type, attrs);
         assert (item_type != null);
-        this._info.item_type = item_type;
 
         var label = base.get_label();
-        bool found_custom = false;
-        foreach (var entry in DISPLAY_ENTRIES) {
-            if (entry.item_type == item_type) {
-                found_custom = true;
-                if (entry.custom_func != null)
-                    entry.custom_func(label, attrs, ref this._info);
-                if (this._info.description == null)
-                    this._info.description = _(entry.description);
+
+        this._info = item_type_to_item_info(item_type, label, attrs);
+
+        // If we look at the schema, we might be able to deduce the app (icon)
+        if (this._info.icon == null)
+            this._info.query_installed_apps(item_type);
+    }
+
+    private ItemInfo item_type_to_item_info(string item_type, string? label, HashTable<string, string>? 
attrs) {
+        switch (item_type) {
+            case GENERIC_SECRET:
+                return new ItemInfo(label);
+            case KEYRING_NOTE:
+                return new ItemInfo(label, _("Stored note"));
+            case CHAINED_KEYRING:
+                return new ItemInfo(label, _("Keyring password"));
+            case ENCRYPTION_KEY:
+                return new ItemInfo(label, _("Encryption key password"));
+            case PK_STORAGE:
+                return new ItemInfo(label, _("Key storage password"));
+            case NETWORK_MANAGER_SECRET:
+                return new ItemInfo(label, _("Network Manager secret"));
+            case NETWORK_PASSWORD:
+                return new GkrNetworkPassInfo(label, attrs);
+            case EPIPHANY_PASSWORD:
+                return new EpiphanyPassInfo(label, attrs);
+            case CHROME_PASSWORD:
+                return new ChromePassInfo(label, attrs);
+            case GOA_PASSWORD:
+                return new GoaInfo(label, attrs);
+            case TELEPATHY_PASSWORD:
+                return new TelepathyInfo(label, attrs);
+            case EMPATHY_PASSWORD:
+                return new EmpathyInfo(label, attrs);
+            case NETWORK_MANAGER_CONNECTION:
+                return new NmConnectionInfo(label, attrs);
+            default:
                 break;
-            }
         }
 
-        // If we look at the schema, we might be able to deduce the app
-        if (!found_custom)
-            this._info.query_installed_apps (item_type);
+        return new ItemInfo(label);
+    }
+
+    private void load_item_secret() {
+        if (this._req_secret == null) {
+            this._req_secret = new GLib.Cancellable();
+            load_secret.begin(this._req_secret, (obj, res) => {
+                try {
+                    this._req_secret = null;
+                    load_secret.end(res);
+                    this._item_secret = base.get_secret();
+                    notify_property("has-secret");
+                } catch (GLib.Error err) {
+                    GLib.warning("Couldn't retrieve secret: %s", err.message);
+                }
+            });
+        }
+    }
 
-        if (this._info.label == null)
-            this._info.label = label;
-        if (this._info.label == null)
-            this._info.label = "";
-        if (this._info.details == null)
-            this._info.details = "";
+    public new void refresh() {
+        base.refresh();
+        if (this._item_secret != null)
+            load_item_secret();
     }
 
-       private void load_item_secret() {
-               if (this._req_secret == null) {
-                       this._req_secret = new GLib.Cancellable();
-                       load_secret.begin(this._req_secret, (obj, res) => {
-                               try {
-                                       this._req_secret = null;
-                                       load_secret.end(res);
-                                       this._item_secret = base.get_secret();
-                                       notify_property("has-secret");
-                               } catch (GLib.Error err) {
-                                       GLib.warning("Couldn't retrieve secret: %s", err.message);
-                               }
-                       });
-               }
-       }
-
-
-       public new void refresh() {
-               base.refresh();
-               if (this._item_secret != null)
-                       load_item_secret ();
-       }
-
-       public new Secret.Value? get_secret() {
-               if (this._item_secret == null)
-                       load_item_secret ();
-               return this._item_secret;
-       }
-
-       public string? get_attribute(string name) {
-               if (this.attributes == null)
-                       return null;
-               return this.attributes.lookup(name);
-       }
-
-       public new async bool set_secret(Secret.Value value,
-                                        GLib.Cancellable? cancellable) throws GLib.Error {
-               yield base.set_secret(value, cancellable);
-               _item_secret = value;
-               notify_property("has-secret");
-               return true;
-       }
+    public new Secret.Value? get_secret() {
+        if (this._item_secret == null)
+            load_item_secret();
+        return this._item_secret;
+    }
+
+    public string? get_attribute(string name) {
+        if (this.attributes == null)
+            return null;
+        return this.attributes.lookup(name);
+    }
+
+    public new async bool set_secret(Secret.Value value,
+                                     GLib.Cancellable? cancellable) throws GLib.Error {
+        yield base.set_secret(value, cancellable);
+        _item_secret = value;
+        notify_property("has-secret");
+        return true;
+    }
 }
 
 private const string GENERIC_SECRET = "org.freedesktop.Secret.Generic";
@@ -255,253 +249,6 @@ private const string EMPATHY_PASSWORD = "org.freedesktop.Empathy";
 private const string NETWORK_MANAGER_SECRET = "org.freedesktop.NetworkManager";
 private const string NETWORK_MANAGER_CONNECTION = "org.freedesktop.NetworkManager.Connection";
 
-private string? get_attribute_string(GLib.HashTable<string, string>? attrs,
-                                     string name) {
-       if (attrs == null)
-               return null;
-       return attrs.lookup(name);
-}
-
-private int get_attribute_int(GLib.HashTable<string, string>? attrs,
-                              string name)
-{
-       if (attrs == null)
-               return 0;
-
-       var value = attrs.lookup(name);
-       if (value != null)
-               return int.parse(value);
-
-       return 0;
-}
-
-private bool is_network_item(GLib.HashTable<string, string>? attrs,
-                             string match)
-{
-       var protocol = get_attribute_string (attrs, "protocol");
-       return protocol != null && protocol.ascii_casecmp(match) == 0;
-}
-
-private bool is_custom_network_label(string? server,
-                                     string? user,
-                                     string? object,
-                                     int port,
-                                     string? display)
-{
-       /*
-        * For network passwords gnome-keyring generates in a funky looking display
-        * name that's generated from login credentials. We simulate that generating
-        * here and return FALSE if it matches. This allows us to display user
-        * customized display names and ignore the generated ones.
-        */
-
-       if (server == null)
-               return true;
-
-       var generated = new GLib.StringBuilder("");
-       if (user != null)
-               generated.append_printf("%s@", user);
-       generated.append(server);
-       if (port != 0)
-               generated.append_printf(":%d", port);
-       if (object != null)
-               generated.append_printf ("/%s", object);
-
-       return (generated.str == display);
-}
-
-private string? calc_network_label(GLib.HashTable<string, string>? attrs,
-                                   bool always)
-{
-       /* HTTP usually has a the realm as the "object" display that */
-       if (is_network_item (attrs, "http") && attrs != null) {
-               var val = get_attribute_string (attrs, "object");
-               if (val != null && val != "")
-                       return val;
-
-               /* Display the server name as a last resort */
-               if (always) {
-                       val = get_attribute_string (attrs, "server");
-                       if (val != null && val != "")
-                               return val;
-               }
-       }
-
-       return null;
-}
-
-private void network_custom(string? display,
-                            GLib.HashTable<string, string>? attrs,
-                            ref DisplayInfo info)
-{
-       var server = get_attribute_string (attrs, "server");
-       var protocol = get_attribute_string (attrs, "protocol");
-       var object = get_attribute_string (attrs, "object");
-       var user = get_attribute_string (attrs, "user");
-       var port = get_attribute_int (attrs, "port");
-
-       if (protocol == null)
-               return;
-
-       /* If it's customized by the application or user then display that */
-       if (!is_custom_network_label (server, user, object, port, display))
-               info.label = calc_network_label (attrs, true);
-       if (info.label == null)
-               info.label = display;
-
-       string symbol = "@";
-       if (user == null) {
-               user = "";
-               symbol = "";
-       }
-
-       if (object == null)
-               object = "";
-
-       if (server != null && protocol != null) {
-               info.details = GLib.Markup.printf_escaped("%s://%s%s%s/%s",
-                                                         protocol, user, symbol,
-                                                         server, object);
-       }
-}
-
-private void epiphany_custom(string? display,
-                             HashTable<string, string>? attrs,
-                             ref DisplayInfo info) {
-    /* Set the Epiphany icon */
-    info.query_installed_apps("org.gnome.Epiphany");
-
-    var uri = get_attribute_string(attrs, "uri");
-    if (uri != null)
-        info.label = uri;
-
-    var username = get_attribute_string(attrs, "username");
-    if (username != null)
-        info.details = Markup.escape_text(username);
-}
-
-private void chrome_custom(string? display,
-                           GLib.HashTable<string, string>? attrs,
-                           ref DisplayInfo info)
-{
-       var origin = get_attribute_string (attrs, "origin_url");
-
-       /* A brain dead url, parse */
-       if (display != null && display == origin) {
-               try {
-                       var regex = new GLib.Regex("[a-z]+://([^/]+)/", GLib.RegexCompileFlags.CASELESS, 0);
-                       GLib.MatchInfo match;
-                       if (regex.match(display, GLib.RegexMatchFlags.ANCHORED, out match)) {
-                               if (match.matches())
-                                       info.label = match.fetch(1);
-                       }
-               } catch (GLib.RegexError err) {
-                       GLib.critical("%s", err.message);
-                       return;
-               }
-
-       }
-
-       if (info.label == null)
-               info.label = display;
-       if (origin != null)
-               info.details = GLib.Markup.escape_text(origin);
-       else
-               info.details = "";
-}
-
-private string? decode_telepathy_id(string account) {
-       account.replace("_", "%");
-       return GLib.Uri.unescape_string(account);
-}
-
-private void empathy_custom(string? display,
-                            GLib.HashTable<string, string>? attrs,
-                            ref DisplayInfo info)
-{
-       var account = get_attribute_string(attrs, "account-id");
-
-       /* Translators: This should be the same as the string in empathy */
-       var prefix = _("IM account password for ");
-
-       if (display != null && display.has_prefix(prefix)) {
-               var len = prefix.length;
-               var pos = display.index_of_char ('(', (int)len);
-               if (pos != -1)
-                       info.label = display.slice(len, pos);
-
-               try {
-                       var regex = new GLib.Regex("^.+/.+/(.+)$", GLib.RegexCompileFlags.CASELESS, 0);
-                       GLib.MatchInfo match;
-                       if (regex.match(account, GLib.RegexMatchFlags.ANCHORED, out match)) {
-                               if (match.matches())
-                                       info.details = decode_telepathy_id (match.fetch(1));
-                       }
-               } catch (GLib.RegexError err) {
-                       GLib.critical("%s", err.message);
-                       return;
-               }
-       }
-
-       if (info.label == null)
-               info.label = display;
-       if (info.details == null)
-               info.details = GLib.Markup.escape_text (account);
-}
-
-private void telepathy_custom(string? display,
-                              GLib.HashTable<string, string>? attrs,
-                              ref DisplayInfo info)
-{
-       var account = get_attribute_string (attrs, "account");
-       if (account != null && display != null && display.index_of(account) != -1) {
-               try {
-                       var regex = new GLib.Regex("^.+/.+/(.+)$", GLib.RegexCompileFlags.CASELESS, 0);
-                       GLib.MatchInfo match;
-                       if (regex.match(account, GLib.RegexMatchFlags.ANCHORED, out match)) {
-                               if (match.matches()) {
-                                       var identifier = match.fetch(1);
-                                       info.label = decode_telepathy_id(identifier);
-                               }
-                       }
-               } catch (GLib.RegexError err) {
-                       GLib.critical("%s", err.message);
-                       return;
-               }
-       }
-
-       if(info.label == null)
-               info.label = display;
-       if(account != null)
-               info.details = GLib.Markup.escape_text(account);
-}
-
-private void network_manager_connection_custom(string? display,
-                                               HashTable<string, string>? attrs,
-                                               ref DisplayInfo info) {
-    var setting_name = get_attribute_string(attrs, "setting-name");
-    if (setting_name == "802-11-wireless-security") {
-        info.icon = new ThemedIcon("network-wireless-symbolic");
-        info.description = _("Wi-Fi password");
-    }
-}
-
-private const DisplayEntry[] DISPLAY_ENTRIES = {
-       { GENERIC_SECRET, N_("Password or secret"), null},
-       { NETWORK_PASSWORD, N_("Network password"), network_custom },
-       { KEYRING_NOTE, N_("Stored note"), null },
-       { CHAINED_KEYRING, N_("Keyring password"), null },
-       { ENCRYPTION_KEY, N_("Encryption key password"), null },
-       { PK_STORAGE, N_("Key storage password"), null },
-       { EPIPHANY_PASSWORD, N_("GNOME Web password"), epiphany_custom },
-       { CHROME_PASSWORD, N_("Google Chrome password"), chrome_custom },
-       { GOA_PASSWORD, N_("GNOME Online Accounts password"), null },
-       { TELEPATHY_PASSWORD, N_("Telepathy password"), telepathy_custom },
-       { EMPATHY_PASSWORD, N_("Instant messaging password"), empathy_custom },
-       { NETWORK_MANAGER_SECRET, N_("Network Manager secret"), null },
-    { NETWORK_MANAGER_CONNECTION, N_("Network connection secret"), network_manager_connection_custom },
-};
-
 private struct MappingEntry {
     unowned string item_type;
     unowned string mapped_type;
@@ -527,10 +274,8 @@ private const MappingEntry[] MAPPING_ENTRIES = {
     { GENERIC_SECRET, NETWORK_MANAGER_SECRET, "connection-uuid", null },
 };
 
-private string map_item_type_to_specific(string? item_type,
-                                         GLib.HashTable<string, string>? attrs)
-{
-
+private unowned string map_item_type_to_specific(string? item_type,
+                                                 HashTable<string, string>? attrs) {
     if (item_type == null)
         return GENERIC_SECRET;
     if (attrs == null)
@@ -543,7 +288,9 @@ private string map_item_type_to_specific(string? item_type,
         if (mapping.match_attribute == null)
             return mapping.mapped_type;
 
-        var value = get_attribute_string (attrs, mapping.match_attribute);
+        unowned string? value = null;
+        if (attrs != null)
+            value = attrs.lookup(mapping.match_attribute);
         if (value != null && mapping.match_pattern != null) {
             if (GLib.PatternSpec.match_simple(mapping.match_pattern, value))
                 return mapping.mapped_type;
@@ -556,43 +303,42 @@ private string map_item_type_to_specific(string? item_type,
 }
 
 class ItemDeleter : Deleter {
-       private GLib.List<Item> _items;
-
-       public override Gtk.Dialog create_confirm(Gtk.Window? parent) {
-               var num = this._items.length();
-               if (num == 1) {
-                       var label = ((Secret.Item)_items.data).label;
-                       return new DeleteDialog(parent, _("Are you sure you want to delete the password 
ā€œ%sā€?"), label);
-               } else {
-                       return new DeleteDialog(parent, GLib.ngettext ("Are you sure you want to delete %d 
password?",
-                                                                      "Are you sure you want to delete %d 
passwords?", num), num);
-               }
-       }
-
-       public ItemDeleter(Item item) {
-               if (!add_object(item))
-                       GLib.assert_not_reached();
-       }
-
-       public override unowned GLib.List<GLib.Object> get_objects() {
-               return this._items;
-       }
-
-       public override bool add_object (GLib.Object obj) {
-               if (obj is Item) {
-                       this._items.append((Item)obj);
-                       return true;
-               }
-               return false;
-       }
-
-       public override async bool delete(GLib.Cancellable? cancellable) throws GLib.Error {
-               var items = _items.copy();
-               foreach (var item in items)
-                       yield item.delete(cancellable);
-               return true;
-       }
-}
+    private GLib.List<Item> _items;
+
+    public override Gtk.Dialog create_confirm(Gtk.Window? parent) {
+        var num = this._items.length();
+        if (num == 1) {
+            var label = ((Secret.Item)_items.data).label;
+            return new DeleteDialog(parent, _("Are you sure you want to delete the password ā€œ%sā€?"), label);
+        } else {
+            return new DeleteDialog(parent, ngettext("Are you sure you want to delete %d password?",
+                                                     "Are you sure you want to delete %d passwords?", num), 
num);
+        }
+    }
+
+    public ItemDeleter(Item item) {
+        if (!add_object(item))
+            assert_not_reached();
+    }
+
+    public override unowned GLib.List<GLib.Object> get_objects() {
+        return this._items;
+    }
 
+    public override bool add_object (GLib.Object obj) {
+        if (obj is Item) {
+            this._items.append((Item)obj);
+            return true;
+        }
+        return false;
+    }
+
+    public override async bool delete(GLib.Cancellable? cancellable) throws GLib.Error {
+        var items = _items.copy();
+        foreach (var item in items)
+            yield item.delete(cancellable);
+        return true;
+    }
 }
+
 }
diff --git a/gkr/meson.build b/gkr/meson.build
index 668885a1..74561884 100644
--- a/gkr/meson.build
+++ b/gkr/meson.build
@@ -2,6 +2,7 @@ gkr_sources = [
   'gkr-backend.vala',
   'gkr-dialogs.vala',
   'gkr-item-add.vala',
+  'gkr-item-info.vala',
   'gkr-item-properties.vala',
   'gkr-item.vala',
   'gkr-keyring-add.vala',
diff --git a/po/POTFILES.in b/po/POTFILES.in
index f9941535..9bec9c9b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -20,6 +20,7 @@ data/org.gnome.seahorse.Application.appdata.xml.in
 data/org.gnome.seahorse.Application.desktop.in.in
 gkr/gkr-backend.vala
 gkr/gkr-item-add.vala
+gkr/gkr-item-info.vala
 gkr/gkr-item-properties.vala
 gkr/gkr-item.vala
 gkr/gkr-keyring-add.vala
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index c2d34fcd..3bbaf8bf 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -12,6 +12,7 @@ common/validity.c
 data/org.gnome.seahorse.Application.desktop.in
 gkr/gkr-backend.c
 gkr/gkr-item-add.c
+gkr/gkr-item-info.c
 gkr/gkr-item.c
 gkr/gkr-item-properties.c
 gkr/gkr-keyring-add.c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]