From 1cd0aef0afb196094d90673002d4c210a04911c9 Mon Sep 17 00:00:00 2001 From: Ben McGinnes Date: Sun, 2 Aug 2015 11:01:02 +1000 Subject: [PATCH] Removed GUI examples * GUI examples written with pygtk, which has not been ported to Python 3 and won't be as it is for GTK2 and GNOME is moving to GTK3. * New GUI examples may be required in future using any of several GUI frameworks (e.g. wxPython, PyQt, PySide, PyGObject, etc.). --- lang/py3-pyme/examples/PyGtkGpgKeys.glade | 1394 -------------------- lang/py3-pyme/examples/PyGtkGpgKeys.gladep | 8 - lang/py3-pyme/examples/PyGtkGpgKeys.py | 663 ---------- 3 files changed, 2065 deletions(-) delete mode 100644 lang/py3-pyme/examples/PyGtkGpgKeys.glade delete mode 100644 lang/py3-pyme/examples/PyGtkGpgKeys.gladep delete mode 100755 lang/py3-pyme/examples/PyGtkGpgKeys.py 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 - - - - True - - - - True - _File - True - - - - - - - True - Reload all keys from the keyring - _Reload - True - - - - - - - True - - - - - - True - gtk-quit - True - - - - - - - - - - - True - _Key Admin - True - - - - - - - True - Generate new key - _Generate - True - - - - - - - True - Delete selected keys (including secret ones) - _Delete - True - - - - - - - True - Import keys from a file - _Import - True - - - - - - - True - Export selected keys into a binary file - _Export (binary) - True - - - - - - - True - Export selected keys into an ASCII file - Export (_text) - True - - - - - - - True - T_rust - True - - - - - - - True - Unknown key - _Undefined - True - - - - - - - True - Do NOT trust anything this key does - _Never - True - - - - - - - True - Trust this key but unsure about keys it signed - _Marginal - True - - - - - - - True - Trust this key and keys it signed - _Full - True - - - - - - - True - This is my own another key - U_ltimate - True - - - - - - - - - - - True - - - - - - True - Unimplemented Item - _Edit - True - - - - - - - - - - - True - _View - True - - - - - - True - _Help - True - - - - - - - True - gtk-about - True - - - - - - - - - - - - 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 - - - - - - - True - True - True - True - 0 - - True - * - False - - - 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))