diff --git a/lang/py3-pyme/examples/PyGtkGpgKeys.glade b/lang/py3-pyme/examples/PyGtkGpgKeys.glade
deleted file mode 100644
index 51338b1a..00000000
--- a/lang/py3-pyme/examples/PyGtkGpgKeys.glade
+++ /dev/null
@@ -1,1394 +0,0 @@
-
-
-
-
-
-
- True
- GPG Keyring
- GTK_WINDOW_TOPLEVEL
- GTK_WIN_POS_NONE
- False
- 800
- 400
- True
- False
- True
- False
- False
- GDK_WINDOW_TYPE_HINT_NORMAL
- GDK_GRAVITY_NORTH_WEST
-
-
-
-
- True
- False
- 0
-
-
-
- True
- GTK_SHADOW_OUT
- GTK_POS_LEFT
- GTK_POS_TOP
-
-
-
-
-
-
- 0
- False
- True
-
-
-
-
-
- True
- True
- GTK_POLICY_AUTOMATIC
- GTK_POLICY_AUTOMATIC
- GTK_SHADOW_ETCHED_IN
- GTK_CORNER_TOP_LEFT
-
-
-
- True
- True
- True
- True
- False
- False
-
-
-
-
-
- 0
- True
- True
-
-
-
-
-
- True
- True
-
-
- 0
- False
- False
-
-
-
-
-
-
-
- GPG Password
- GTK_WINDOW_TOPLEVEL
- GTK_WIN_POS_NONE
- True
- False
- True
- True
- False
- False
- GDK_WINDOW_TYPE_HINT_DIALOG
- GDK_GRAVITY_NORTH_WEST
- True
-
-
-
- True
- False
- 0
-
-
-
- True
- GTK_BUTTONBOX_END
-
-
-
- True
- True
- True
- gtk-cancel
- True
- GTK_RELIEF_NORMAL
- True
- -6
-
-
-
-
-
- True
- True
- True
- gtk-ok
- True
- GTK_RELIEF_NORMAL
- True
- -5
-
-
-
-
- 0
- False
- True
- GTK_PACK_END
-
-
-
-
-
- True
- False
- 0
-
-
-
- True
- password:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 0.5
- 0.5
- 0
- 0
-
-
- 0
- False
- False
-
-
-
-
-
- True
- True
- True
- False
- 0
-
- True
- *
- False
-
-
- 0
- False
- False
-
-
-
-
- 0
- True
- True
-
-
-
-
-
-
-
- New Key Properties
- GTK_WINDOW_TOPLEVEL
- GTK_WIN_POS_NONE
- False
- True
- True
- True
- False
- False
- GDK_WINDOW_TYPE_HINT_DIALOG
- GDK_GRAVITY_NORTH_WEST
- True
-
-
-
- True
- False
- 0
-
-
-
- True
- GTK_BUTTONBOX_END
-
-
-
- True
- True
- True
- gtk-cancel
- True
- GTK_RELIEF_NORMAL
- True
- -6
-
-
-
-
-
- True
- True
- True
- gtk-ok
- True
- GTK_RELIEF_NORMAL
- True
- -5
-
-
-
-
- 0
- False
- True
- GTK_PACK_END
-
-
-
-
-
- True
- 12
- 2
- False
- 0
- 0
-
-
-
- True
- Key-Length:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 1
- 2
- fill
-
-
-
-
-
-
- True
- Key-Type:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 0
- 1
- fill
-
-
-
-
-
-
- True
- Key-Usage:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 2
- 3
- fill
-
-
-
-
-
-
- True
- Subkey-Type:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 3
- 4
- fill
-
-
-
-
-
-
- True
- Subkey-Length:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 4
- 5
- fill
-
-
-
-
-
-
- True
- Subkey-Usage:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 5
- 6
- fill
-
-
-
-
-
-
- True
- Name-Real:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 6
- 7
- fill
-
-
-
-
-
-
- True
- Name-Comment:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 7
- 8
- fill
-
-
-
-
-
-
- True
- Name-Email:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 8
- 9
- fill
-
-
-
-
-
-
- True
- Expire-Date:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 9
- 10
- fill
-
-
-
-
-
-
- True
- DSA
-RSA
-
-
-
- 1
- 2
- 0
- 1
- fill
-
-
-
-
-
- True
- True
- 1
- 0
- False
- GTK_UPDATE_ALWAYS
- False
- False
- 1024 1024 4096 1 1024 10
-
-
- 1
- 2
- 1
- 2
-
-
-
-
-
-
- True
- False
- 0
-
-
-
- True
- True
- encrypt
- True
- GTK_RELIEF_NORMAL
- True
- False
- False
- True
-
-
- 0
- False
- False
-
-
-
-
-
- True
- True
- sign
- True
- GTK_RELIEF_NORMAL
- True
- False
- False
- True
-
-
- 0
- False
- False
-
-
-
-
- 1
- 2
- 2
- 3
- fill
- fill
-
-
-
-
-
- True
-
-DSA
-ELG-E
-RSA
-
-
-
- 1
- 2
- 3
- 4
- fill
- fill
-
-
-
-
-
- True
- True
- 1
- 0
- False
- GTK_UPDATE_ALWAYS
- False
- False
- 1024 1024 4096 1 1024 10
-
-
- 1
- 2
- 4
- 5
-
-
-
-
-
-
- True
- False
- 0
-
-
-
- True
- True
- encrypt
- True
- GTK_RELIEF_NORMAL
- True
- False
- False
- True
-
-
- 0
- False
- False
-
-
-
-
-
- True
- True
- sign
- True
- GTK_RELIEF_NORMAL
- True
- False
- False
- True
-
-
- 0
- False
- False
-
-
-
-
- 1
- 2
- 5
- 6
- fill
- fill
-
-
-
-
-
- True
- True
- True
- True
- 0
-
- True
- *
- False
-
-
- 1
- 2
- 6
- 7
-
-
-
-
-
-
-
- 1
- 2
- 7
- 8
-
-
-
-
-
-
- True
- True
- True
- True
- 0
-
- True
- *
- False
-
-
- 1
- 2
- 8
- 9
-
-
-
-
-
-
- True
- Passphrase:
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 10
- 11
- fill
-
-
-
-
-
-
- True
- (repeat):
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 1
- 0.5
- 0
- 0
-
-
- 0
- 1
- 11
- 12
- fill
-
-
-
-
-
-
- True
- True
- True
- False
- 0
-
- True
- *
- False
-
-
- 1
- 2
- 10
- 11
-
-
-
-
-
-
- True
- True
- True
- False
- 0
-
- True
- *
- False
-
-
- 1
- 2
- 11
- 12
-
-
-
-
-
-
- True
- True
- False
- 0
-
-
-
- True
- True
- GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES
-
-
-
-
-
-
- True
- Unlimited
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 0.5
- 0.5
- 0
- 0
-
-
- label_item
-
-
-
-
- 1
- 2
- 9
- 10
- fill
- fill
-
-
-
-
- 0
- True
- True
-
-
-
-
-
-
-
- Generating the key...
- GTK_WINDOW_TOPLEVEL
- GTK_WIN_POS_NONE
- True
- 600
- 400
- True
- True
- True
- False
- False
- GDK_WINDOW_TYPE_HINT_DIALOG
- GDK_GRAVITY_NORTH_WEST
- True
-
-
-
- True
- False
- 0
-
-
-
- True
- GTK_BUTTONBOX_END
-
-
-
- True
- True
- True
- gtk-cancel
- True
- GTK_RELIEF_NORMAL
- True
- -6
-
-
-
-
-
- 0
- False
- True
- GTK_PACK_END
-
-
-
-
-
- True
- False
- 0
-
-
-
- True
- gtk-dialog-info
- 6
- 0.5
- 0.5
- 0
- 0
-
-
- 0
- False
- False
-
-
-
-
-
- True
- True
- GTK_POLICY_AUTOMATIC
- GTK_POLICY_AUTOMATIC
- GTK_SHADOW_IN
- GTK_CORNER_TOP_LEFT
-
-
-
- True
- False
- True
- False
- False
- True
- GTK_JUSTIFY_LEFT
- GTK_WRAP_CHAR
- False
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
- 0
- True
- True
-
-
-
-
- 0
- True
- True
-
-
-
-
-
-
-
- About PyGtkGpgKeys
- GTK_WINDOW_TOPLEVEL
- GTK_WIN_POS_NONE
- False
- False
- True
- True
- False
- False
- GDK_WINDOW_TYPE_HINT_DIALOG
- GDK_GRAVITY_NORTH_WEST
- True
-
-
-
- True
- False
- 0
-
-
-
- True
- GTK_BUTTONBOX_END
-
-
-
- True
- True
- True
- gtk-ok
- True
- GTK_RELIEF_NORMAL
- True
- -5
-
-
-
-
- 0
- False
- True
- GTK_PACK_END
-
-
-
-
-
- True
- False
- 0
-
-
-
- True
- gtk-about
- 6
- 0.5
- 0.5
- 0
- 0
-
-
- 0
- False
- False
-
-
-
-
-
- 6
- True
- False
- 0
-
-
-
- True
- <b>PyGtkGpgKeys</b>
-Graphical example of PyMe abilities.
- False
- True
- GTK_JUSTIFY_CENTER
- False
- False
- 0.5
- 0.5
- 0
- 0
-
-
- 10
- True
- True
-
-
-
-
-
- True
- <i>GNU Public License</i>
- False
- True
- GTK_JUSTIFY_LEFT
- False
- False
- 0.5
- 0.5
- 0
- 0
-
-
- 10
- True
- True
-
-
-
-
-
- True
- <small>(C) 2005 Igor Belyi</small>
- False
- True
- GTK_JUSTIFY_CENTER
- False
- False
- 0.5
- 0.5
- 0
- 0
-
-
- 10
- True
- True
-
-
-
-
- 0
- True
- True
-
-
-
-
- 0
- True
- True
-
-
-
-
-
-
-
diff --git a/lang/py3-pyme/examples/PyGtkGpgKeys.gladep b/lang/py3-pyme/examples/PyGtkGpgKeys.gladep
deleted file mode 100644
index 466acc84..00000000
--- a/lang/py3-pyme/examples/PyGtkGpgKeys.gladep
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- GtkGpgKeys
- GtkGpgKeys
- FALSE
-
diff --git a/lang/py3-pyme/examples/PyGtkGpgKeys.py b/lang/py3-pyme/examples/PyGtkGpgKeys.py
deleted file mode 100755
index 0221b05c..00000000
--- a/lang/py3-pyme/examples/PyGtkGpgKeys.py
+++ /dev/null
@@ -1,663 +0,0 @@
-#!/usr/bin/env python3
-# $Id$
-# Copyright (C) 2005,2008 Igor Belyi
-#
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import gtk, gobject, gtk.glade
-import time, sys, os
-from pyme import callbacks, core, errors
-from pyme.core import Data, Context, pubkey_algo_name
-from pyme import constants
-from pyme.constants import validity
-from pyme.constants.keylist import mode
-
-# Thanks to Bernhard Reiter for pointing out the following:
-# gpgme_check_version() necessary for initialisation according to
-# gpgme 1.1.6 and this is not done automatically in pyme-0.7.0
-print("gpgme version:", core.check_version(None))
-
-# Convert trust constant into a string
-trusts = {validity.UNKNOWN: "",
- validity.UNDEFINED: "Undefined",
- validity.NEVER: "Never",
- validity.MARGINAL: "Marginal",
- validity.FULL: "Full",
- validity.ULTIMATE: "Ultimate"}
-
-# Convert seconds into a date
-def sec2str(secs):
- if secs > 0: return time.strftime("%Y-%m-%d", time.gmtime(secs))
- elif secs == 0: return "Unlimited"
- else: return ""
-
-index = 0
-class KeyColumn:
- "Helper class for data columns."
- def __init__(self, name, gtype, vattr=None, tcols=None,
- func=lambda x:x, view=None):
- """new(name, qtype, vattr, column, ocolumn, func):
- name - column title
- qtype - gobject type to use in TreeStore for this column
- vattr - column data is visible if method vattr present in the object
- tcols - list of type specific columns to append its name to.
- func - function converting object data into viewable presentation
- view - to put or not the column in the view menu"""
- global index
- self.name = name
- self.type = gtype
- self.vattr = vattr
- self.func = func
- self.view = view
- self.index = index
- self.attrs = {}
- if tcols != None: tcols.append(name)
- index += 1
-
-# List column names specific to an object type
-key_columns = [] # names only in key
-uid_columns = [] # names only in uids
-sub_columns = [] # names only in subkeys
-sign_columns = [] # names only in signatures
-sub_sign_columns = [] # names in subkeys and signatures
-
-# Explicite columns
-visible_columns = [
- KeyColumn("Secret", gobject.TYPE_BOOLEAN, "subkeys"),
- KeyColumn("Name", gobject.TYPE_STRING, "name", uid_columns,
- lambda x: x.name+(x.comment and " (%s)"%x.comment)),
- KeyColumn("Email", gobject.TYPE_STRING, "email", uid_columns,
- lambda x: x.email),
- KeyColumn("Owner Trust", gobject.TYPE_STRING, "owner_trust", key_columns,
- lambda x: trusts[x.owner_trust], True),
- KeyColumn("Type", gobject.TYPE_STRING, "pubkey_algo", sub_sign_columns,
- lambda x: pubkey_algo_name(x.pubkey_algo)),
- KeyColumn("Length", gobject.TYPE_INT, "length", sub_columns,
- lambda x: x.length),
- KeyColumn("Can Auth", gobject.TYPE_BOOLEAN,"can_authenticate", sub_columns,
- lambda x: x.can_authenticate, False),
- KeyColumn("Can Cert", gobject.TYPE_BOOLEAN, "can_certify", sub_columns,
- lambda x: x.can_certify, False),
- KeyColumn("Can Encr", gobject.TYPE_BOOLEAN, "can_encrypt", sub_columns,
- lambda x: x.can_encrypt, False),
- KeyColumn("Can Sign", gobject.TYPE_BOOLEAN, "can_sign", sub_columns,
- lambda x: x.can_sign, False),
- KeyColumn("Created", gobject.TYPE_STRING, "timestamp", sub_sign_columns,
- lambda x: sec2str(x.timestamp), True),
- KeyColumn("Expires", gobject.TYPE_STRING, "expires", sub_sign_columns,
- lambda x: sec2str(x.expires), True),
- KeyColumn("Id", gobject.TYPE_STRING, "keyid", sub_sign_columns,
- lambda x: x.keyid)
- ]
-
-helper_columns = [
- KeyColumn("Name Invalid", gobject.TYPE_BOOLEAN, None, uid_columns,
- lambda x: x.revoked or x.invalid),
- KeyColumn("Subkey Invalid", gobject.TYPE_BOOLEAN, None, sub_sign_columns,
- lambda x: x.revoked or x.invalid or x.expired),
- KeyColumn("FPR", gobject.TYPE_STRING, None, sub_columns,
- lambda x: x.fpr)
- ]
-
-# Calculate implicite columns - defining visibility of the data in a column.
-# In the same loop calculate tuple for rows having only name in them.
-name_only = ()
-for item in visible_columns:
- vis_item = KeyColumn("Show"+item.name, gobject.TYPE_BOOLEAN)
- helper_columns.append(vis_item)
- item.attrs["visible"] = vis_item.index
- name_only += (vis_item.index, item.name == "Name")
-
-columns = {}
-for item in visible_columns + helper_columns:
- columns[item.name] = item
-
-# Use strikethrough to indicate revoked or invalid keys and uids
-columns["Name"].attrs["strikethrough"] = columns["Name Invalid"].index
-columns["Id"].attrs["strikethrough"] = columns["Subkey Invalid"].index
-
-def pair(name, value):
- "pair(name, value) creates (index, func(value)) tuple based on column name"
- item = columns[name]
- if item.index < len(visible_columns):
- return (item.index, item.func(value), columns["Show"+name].index, True)
- else:
- return (item.index, item.func(value))
-
-class PyGtkGpgKeys:
- "Main class representing PyGtkGpgKeys application"
- def error_message(self, text, parent=None):
- dialog = gtk.MessageDialog(parent or self.mainwin,
- gtk.DIALOG_MODAL |
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_ERROR,
- gtk.BUTTONS_OK,
- text)
- dialog.run()
- dialog.destroy()
-
- def yesno_message(self, text, parent=None):
- dialog = gtk.MessageDialog(parent or self.mainwin,
- gtk.DIALOG_MODAL |
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_QUESTION,
- gtk.BUTTONS_YES_NO,
- text)
- result = dialog.run() == gtk.RESPONSE_YES
- dialog.destroy()
- return result
-
- def load_keys(self, first_time=False):
- if not first_time: self.model.clear()
- secret_keys = {}
- for key in self.context.op_keylist_all(None, 1):
- secret_keys[key.subkeys[0].fpr] = 1
- for key in self.context.op_keylist_all(None, 0):
- self.add_key(key, key.subkeys[0].fpr in secret_keys)
-
- def add_key(self, key, secret):
- "self.add_key(key) - add key to the TreeStore model"
- iter = self.model.append(None)
- # Can delete only the whole key
- param = (iter,) + pair("Secret", secret)
- # Key information is a combination of the key and first uid and subkey
- for col in key_columns: param += pair(col, key)
- for col in uid_columns: param += pair(col, key.uids[0])
- for col in sub_columns: param += pair(col, key.subkeys[0])
- for col in sub_sign_columns: param += pair(col, key.subkeys[0])
- self.model.set(*param)
- if key.uids:
- self.add_signatures(key.uids[0].signatures, iter)
- self.add_uids(key.uids[1:], iter)
- self.add_subkeys(key.subkeys[1:], iter)
-
- def add_subkeys(self, subkeys, iter):
- "self.add_subkeys(subkey, iter) - add subkey as child to key's iter"
- if not subkeys:
- return
- key_iter = self.model.append(iter)
- self.model.set(key_iter, columns["Name"].index, "Subkeys", *name_only)
- for subkey in subkeys:
- child_iter = self.model.append(key_iter)
- param = (child_iter,)
- for col in sub_columns: param += pair(col, subkey)
- for col in sub_sign_columns: param += pair(col, subkey)
- self.model.set(*param)
-
- def add_uids(self, uids, iter):
- "self.add_uids(uid, iter) - add uid as a child to key's iter"
- if not uids:
- return
- uid_iter = self.model.append(iter)
- self.model.set(uid_iter,columns["Name"].index,"Other UIDs",*name_only)
- for uid in uids:
- child_iter = self.model.append(uid_iter)
- param = (child_iter,)
- for col in uid_columns: param += pair(col, uid)
- self.model.set(*param)
- self.add_signatures(uid.signatures, child_iter)
-
- def add_signatures(self, signs, iter):
- "self.add_signatures(sign, iter) - add signature as a child to iter"
- if not signs:
- return
- sign_iter = self.model.append(iter)
- self.model.set(sign_iter,columns["Name"].index,"Signatures",*name_only)
- for sign in signs:
- child_iter = self.model.append(sign_iter)
- param = (child_iter,)
- for col in uid_columns: param += pair(col, sign)
- for col in sign_columns: param += pair(col, sign)
- for col in sub_sign_columns: param += pair(col, sign)
- self.model.set(*param)
-
- def add_columns(self):
- "Add viewable columns for the data in TreeStore model"
- view_menu = gtk.Menu()
- for item in visible_columns:
- if item.type == gobject.TYPE_BOOLEAN:
- renderer = gtk.CellRendererToggle()
- item.attrs["active"] = item.index
- else:
- renderer = gtk.CellRendererText()
- item.attrs["text"] = item.index
- column = self.treeview.insert_column_with_attributes(
- item.index, item.name, renderer, **item.attrs)
- column.set_sort_column_id(item.index)
- # Create callback for a View menu item
- if item.view != None:
- check = gtk.CheckMenuItem(item.name)
- check.set_active(item.view)
- check.connect("activate",
- lambda x, y: y.set_visible(x.get_active()),
- column)
- view_menu.append(check)
- column.set_visible(check.get_active())
-
- view_menu.show_all()
- self.wtree.get_widget("view_menu").set_submenu(view_menu)
-
- def on_GPGKeysView_button_press_event(self, obj, event):
- if event.button != 3:
- return False
-
- menu = gtk.Menu()
- for title, callback in [
- ("Reload", self.on_reload_activate),
- (None, None),
- ("Delete", self.on_delete_activate),
- ("Export (txt)", self.on_export_keys_text_activate),
- ("Export (bin)", self.on_export_keys_activate)
- ]:
- if title:
- item = gtk.MenuItem(title)
- item.connect("activate", callback)
- else:
- item = gtk.SeparatorMenuItem()
- menu.append(item)
- menu.show_all()
-
- menu.popup(None, None, None, event.button, event.time)
- return True
-
- def editor_func(self, status, args, val_dict):
- state = val_dict["state"]
- prompt = "%s %s" % (state, args)
- if prompt in val_dict:
- val_dict["state"] = val_dict[prompt][0]
- return val_dict[prompt][1]
- elif args:
- sys.stderr.write("Unexpected prompt in editor_func: %s\n" % prompt)
- raise EOFError()
- return ""
-
- def change_key_trust(self, key, new_trust):
- val_dict = {
- "state": "start",
- "start keyedit.prompt": ("trust", "trust"),
- "trust edit_ownertrust.value": ("prompt", "%d" % new_trust),
- "prompt edit_ownertrust.set_ultimate.okay": ("prompt", "Y"),
- "prompt keyedit.prompt": ("finish", "quit")
- }
- out = Data()
- self.context.op_edit(key, self.editor_func, val_dict, out)
-
- def on_change_trust(self, new_trust):
- selection = self.treeview.get_selection()
- if selection.count_selected_rows() <= 0:
- return
-
- key_list = []
- selection.selected_foreach(self.collect_keys, key_list)
-
- message = "Change trust to %s on the following keys?\n" % \
- trusts[new_trust]
- for key, row in key_list:
- message += "\n%s\t" % key.subkeys[0].keyid
- if key.uids: message += key.uids[0].uid
- else: message += ""
- if self.yesno_message(message):
- for key, row in key_list:
- if key.owner_trust != new_trust:
- self.change_key_trust(key, new_trust)
- row[columns["Owner Trust"].index] = trusts[new_trust]
-
- def on_undefined_trust_activate(self, obj):
- self.on_change_trust(1)
-
- def on_never_trust_activate(self, obj):
- self.on_change_trust(2)
-
- def on_marginal_trust_activate(self, obj):
- self.on_change_trust(3)
-
- def on_full_trust_activate(self, obj):
- self.on_change_trust(4)
-
- def on_ultimate_trust_activate(self, obj):
- self.on_change_trust(5)
-
- def collect_keys(self, model, path, iter, key_list):
- row = model[path[:1]]
- keyid = row[columns["FPR"].index]
- key = self.context.get_key(keyid, 0)
- key_list.append((key, row))
-
- def export_keys(self):
- selection = self.treeview.get_selection()
- if selection.count_selected_rows() <= 0:
- return
-
- export_file = None
- dialog = gtk.FileChooserDialog("Export Keys (Public only) into a File",
- self.mainwin,
- gtk.FILE_CHOOSER_ACTION_SAVE,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OK, gtk.RESPONSE_OK))
- while dialog.run() == gtk.RESPONSE_OK:
- filename = dialog.get_filename()
- if os.path.exists(filename):
- if os.path.isdir(filename):
- self.error_message("%s is a directory!" % filename,
- dialog)
- continue
- elif not self.yesno_message("%s exists. Override?" % filename,
- dialog):
- continue
-
- # FIXME. Verify that file can be written to
- export_file = open(filename, "wb")
- break
- dialog.destroy()
- if export_file == None:
- return
-
- key_list = []
- selection.selected_foreach(self.collect_keys, key_list)
- expkeys = Data()
- for key, row in key_list:
- self.context.op_export(key.subkeys[0].fpr, 0, expkeys)
- expkeys.seek(0,0)
- export_file.write(expkeys.read())
- export_file.close()
-
- def on_export_keys_activate(self, obj):
- self.context.set_armor(0)
- self.export_keys()
-
- def on_export_keys_text_activate(self, obj):
- self.context.set_armor(1)
- self.export_keys()
-
- def on_import_keys_activate(self, obj):
- import_file = None
- dialog = gtk.FileChooserDialog("Import Keys from a File",
- self.mainwin,
- gtk.FILE_CHOOSER_ACTION_OPEN,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OK, gtk.RESPONSE_OK))
- while dialog.run() == gtk.RESPONSE_OK:
- filename = dialog.get_filename()
- if os.path.exists(filename):
- if os.path.isdir(filename):
- self.error_message("%s is a directory!" % filename,
- dialog)
- else:
- # FIXME. Verify that file can be open.
- import_file = filename
- break
- else:
- self.error_message("%s does not exist." % filename,
- dialog)
- dialog.destroy()
- if import_file == None:
- return
-
- impkeys = Data(file=import_file)
- status = self.context.op_import(impkeys)
- if status:
- self.error_message("Import return an error message %d" % status)
- result = self.context.op_import_result()
- if result.considered == 0:
- self.error_message("There's no keys in the file.")
- # FIXME. Instead of rereading everything we could find out what's new
- # from the result based on the ORed value of impkey:
- # constants.import.NEW - The key was new.
- # constants.import.UID - The key contained new user IDs.
- # constants.import.SIG - The key contained new signatures.
- # constants.import.SUBKEY - The key contained new sub keys.
- # constants.import.SECRET - The key contained a secret key.
- # It would be nice to highlight new things as well.
- self.load_keys()
- #if result:
- # impkey = result.imports
- # while impkey:
- # if impkey.status & constants.import.NEW:
- # self.add_key(self.context.get_key(impkey.fpr, 0))
- # impkey = impkey.next
-
- def on_delete_activate(self, obj):
- "self.on_delete_activate(obj) - callback for key deletion request"
- selection = self.treeview.get_selection()
- if selection.count_selected_rows() > 0:
- key_list = []
- selection.selected_foreach(self.collect_keys, key_list)
-
- message = "Delete selected keys?\n"
- for key, row in key_list:
- message += "\n%s\t" % key.subkeys[0].keyid
- if key.uids: message += key.uids[0].uid
- else: message += ""
- if self.yesno_message(message):
- for key, row in key_list:
- self.context.op_delete(key, 1)
- row.model.remove(row.iter)
-
- def get_widget_values(self, widgets):
- "Create an array of values from widgets' getter methods"
- return [getattr(self.wtree.get_widget(w),"get_"+f)() for w,f in widgets]
-
- def set_widget_values(self, widgets, values):
- "Set values using widgets' setter methods"
- for (w,f), v in zip(widgets, values):
- # ComboBox.set_active_iter(None) does not reset active. Fixing.
- if f == "active_iter" and v == None:
- f, v = "active", -1
- getattr(self.wtree.get_widget(w), "set_"+f)(v)
-
- def key_type_changed(self, which):
- """self.key_type_changed([\"key\"|\"subkey\"]) - helper function to
- adjust allowed key length based on the Algorithm selected"""
- (key_type,) = self.get_widget_values([(which+"_type", "active_iter")])
- if key_type:
- key_type = self.wtree.get_widget(which+"_type").get_model(
- ).get_value(key_type,0)
- length_widget = self.wtree.get_widget(which+"_length")
- if key_type == "DSA":
- length_widget.set_range(1024, 1024)
- length_widget.set_value(1024)
- elif key_type == "RSA" or key_type == "ELG-E":
- length_widget.set_range(1024, 4096)
-
- def on_key_type_changed(self, obj):
- self.key_type_changed("key")
-
- def on_subkey_type_changed(self, obj):
- self.key_type_changed("subkey")
-
- def on_expire_calendar_day_selected(self, obj):
- "Callback for selecting a day on the calendar"
- (year, month, day)=self.wtree.get_widget("expire_calendar").get_date()
- expander = self.wtree.get_widget("expire_date")
- # Past dates means no expiration date
- if time.localtime() < (year, month+1, day):
- expander.set_label("%04d-%02d-%02d" % (year, month+1, day))
- else:
- expander.set_label("Unlimited")
- expander.set_expanded(False)
-
- def on_generate_activate(self, obj):
- "Callback to generate new key"
-
- # Set of (widget, common suffix of getter/setter function) tuples
- # from the GenerateDialog prompt for new key properties.
- widgets = [
- ("key_type", "active_iter"),
- ("key_length", "value"),
- ("key_encrypt", "active"),
- ("key_sign", "active"),
- ("subkey_type", "active_iter"),
- ("subkey_length", "value"),
- ("subkey_encrypt", "active"),
- ("subkey_sign", "active"),
- ("name_real", "text"),
- ("name_comment", "text"),
- ("name_email", "text"),
- ("expire_date", "label"),
- ("passphrase", "text"),
- ("passphrase_repeat", "text")
- ]
-
- saved_values = self.get_widget_values(widgets)
- result = None
- dialog = self.wtree.get_widget("GenerateDialog")
- if dialog.run() == gtk.RESPONSE_OK:
- (key_type, key_length, key_encrypt, key_sign,
- subkey_type, subkey_length, subkey_encrypt, subkey_sign,
- name_real, name_comment, name_email, expire_date,
- passphrase, passphrase2) = self.get_widget_values(widgets)
- if key_type and passphrase == passphrase2:
- key_type = self.wtree.get_widget("key_type").get_model(
- ).get_value(key_type,0)
- result = "\n"
- result += "Key-Type: %s\n" % key_type
- result += "Key-Length: %d\n" % int(key_length)
- if key_encrypt or key_sign:
- result += "Key-Usage:" + \
- ((key_encrypt and " encrypt") or "") + \
- ((key_sign and " sign") or "") + "\n"
- if subkey_type:
- subkey_type=self.wtree.get_widget("subkey_type").get_model(
- ).get_value(subkey_type,0)
- result += "Subkey-Type: %s\n" % subkey_type
- result += "Subkey-Length: %d\n" % int(subkey_length)
- if subkey_encrypt or subkey_sign:
- result += "Subkey-Usage:" + \
- ((subkey_encrypt and " encrypt") or "") + \
- ((subkey_sign and " sign") or "") + "\n"
- if name_real:
- result += "Name-Real: %s\n" % name_real
- if name_comment:
- result += "Name-Comment: %s\n" % name_comment
- if name_email:
- result += "Name-Email: %s\n" % name_email
- if passphrase:
- result += "Passphrase: %s\n" % passphrase
- if expire_date != "Unlimited":
- result += "Expire-Date: %s\n" % expire_date
- else:
- result += "Expire-Date: 0\n"
- result += "\n"
- else:
- if not key_type:
- message = "Type of the primary key is not specified."
- elif passphrase != passphrase2:
- message = "Passphrases do not match."
- else:
- message = "Unknown error."
- self.error_message(message, dialog)
- else:
- self.set_widget_values(widgets, saved_values)
-
- dialog.hide()
- if result:
- # Setup and show progress Dialog
- self.progress = ""
- self.progress_entry = self.wtree.get_widget(
- "progress_entry").get_buffer()
- self.progress_entry.set_text("")
- gobject.timeout_add(500, self.update_progress)
- self.wtree.get_widget("GenerateProgress").show_all()
- # Start asynchronous key generation
- self.context.op_genkey_start(result, None, None)
-
- def gen_progress(self, what=None, type=None, current=None,
- total=None, hook=None):
- "Gpg's progress_cb"
- if self.progress != None:
- self.progress += "%c" % type
- else:
- sys.stderr.write("%c" % type)
-
- def update_progress(self):
- "Timeout callback to yeild to gpg and update progress Dialog view"
- status = self.context.wait(False)
- if status == None:
- self.progress_entry.set_text(self.progress)
- return True
- elif status == 0:
- fpr = self.context.op_genkey_result().fpr
- self.add_key(self.context.get_key(fpr, 0), True)
- self.wtree.get_widget("GenerateProgress").hide()
- self.progress = None
-
- if status:
- self.error_message("Got an error during key generation:\n%s" %
- errors.GPGMEError(status).getstring())
-
- # Let callback to be removed.
- return False
-
- def on_generating_close_clicked(self, obj):
- # Request cancelation of the outstanding asynchronous call
- self.context.cancel()
-
- def get_password(self, hint, desc, hook):
- "Gpg's password_cb"
- dialog = self.wtree.get_widget("PasswordDialog")
- label = self.wtree.get_widget("pwd_prompt")
- entry = self.wtree.get_widget("password")
- label.set_text("Please supply %s's password%s:" %
- (hint, (hook and (' '+hook)) or ''))
- if dialog.run() == gtk.RESPONSE_OK:
- result = entry.get_text()
- else:
- result = ""
- entry.set_text("")
- dialog.hide()
- return result
-
- def on_reload_activate(self, obj):
- self.load_keys()
-
- def on_about_activate(self, obj):
- about = self.wtree.get_widget("AboutDialog")
- about.run()
- about.hide()
-
- def __init__(self, path):
- "new(path) path - location of the glade file"
- gladefile = os.path.join(path, "PyGtkGpgKeys.glade")
- self.wtree = gtk.glade.XML(gladefile)
- self.wtree.signal_autoconnect(self)
-
- self.mainwin = self.wtree.get_widget("GPGAdminWindow")
- self.treeview = self.wtree.get_widget("GPGKeysView")
-
- self.model = gtk.TreeStore(*[x.type for x in visible_columns +
- helper_columns])
-
- self.context = Context()
- self.context.set_passphrase_cb(self.get_password, "")
- self.progress = None
- self.context.set_progress_cb(self.gen_progress, None)
- # Use mode.SIGS to include signatures in the list.
- self.context.set_keylist_mode(mode.SIGS)
- self.load_keys(True)
-
- self.treeview.set_model(self.model)
- self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
- self.add_columns()
-
- gtk.main()
-
- def on_Exit(self, obj):
- gtk.main_quit()
-
-try:
- # Glade file is expected to be in the same location as this script
- PyGtkGpgKeys(os.path.dirname(sys.argv[0]))
-except IOError as message:
- print("%s:%s" %(sys.argv[0], message))