Last active
October 4, 2019 11:54
-
-
Save destan/df5cff0c1cf0a2bd8394ebeedb292212 to your computer and use it in GitHub Desktop.
encrypt selection selected text cryptselection extension for zim
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# cryptselection plugin for zim | |
# | |
# Copyright 2015 Klaus Holler <[email protected]> | |
# License: same as zim (gpl) | |
# | |
# Installation/Usage: | |
# * Put the cryptselection/ directory to your ~/.local/share/zim/plugins subdirectory | |
# i.e. cd ~/.local/share/zim/plugins && | |
# git clone https://github.com/k3ho/zim-plugin-cryptselection.git cryptselection | |
# * Then (re)start zim, and setup once the 'Crypt Selection' plugin: | |
# * enable it in Edit>Preferences>Plugins and | |
# * set the encryption/decryption commands via 'Configure' button | |
# * For in-place decryption gpg-agent should be started before starting zim and be | |
# configured properly to display a pinentry popup to ask for the PGP key passphrase. | |
# gpg -c --armor --passphrase | |
# gpg --passphrase | |
from __future__ import with_statement | |
import gtk | |
import re | |
from subprocess import Popen, PIPE | |
from zim.plugins import PluginClass, extends, WindowExtension | |
from zim.actions import action | |
from zim.gui.widgets import ui_environment, MessageDialog | |
import logging | |
logger = logging.getLogger('zim.plugins.cryptselection') | |
class CryptSelectionPlugin(PluginClass): | |
plugin_info = { | |
'name': _('Crypt Selection'), # T: plugin name | |
'description': _('''\ | |
This plugin encrypts or decrypts the current selection | |
with a specified encryption command (e.g. gpg). | |
If -----BEGIN PGP MESSAGE----- is found at selection | |
start and -----END PGP MESSAGE----- found at selection | |
end then decrypt, otherwise encrypt. | |
'''), # T: plugin description | |
'author': 'Klaus Holler', | |
'help': 'Plugins:Crypt Selection', | |
} | |
plugin_preferences = [ | |
# key, type, label, default | |
('encryption_command', 'string', | |
_('Encryption Command (reads plaintext from stdin)'), | |
'/usr/bin/gpg2 --always-trust -ear RECIPIENT'), # T: plugin preference | |
('decryption_command', 'string', | |
_('Decryption Command (reads encrypted text from stdin)'), | |
'/usr/bin/gpg2 -d'), # T: plugin preference | |
] | |
@extends('MainWindow') | |
class MainWindowExtension(WindowExtension): | |
uimanager_xml = ''' | |
<ui> | |
<menubar name='menubar'> | |
<menu action='edit_menu'> | |
<placeholder name='plugin_items'> | |
<menuitem action='crypt_selection'/> | |
</placeholder> | |
</menu> | |
</menubar> | |
</ui> | |
''' | |
def __init__(self, plugin, window): | |
WindowExtension.__init__(self, plugin, window) | |
self.preferences = plugin.preferences | |
@action(_('Cr_ypt selection')) # T: menu item | |
# TODO: add stock parameter to set icon | |
def crypt_selection(self): | |
buffer = self.window.pageview.view.get_buffer() | |
try: | |
sel_start, sel_end = buffer.get_selection_bounds() | |
except ValueError: | |
MessageDialog(self.window.ui, | |
_('Please select the text to be encrypted, first.')).run() | |
# T: Error message in "crypt selection" dialog, %s will be replaced | |
# by application name | |
return | |
first_lineno = sel_start.get_line() | |
last_lineno = sel_end.get_line() | |
with buffer.user_action: | |
assert buffer.get_has_selection(), 'No Selection present' | |
sel_text = self.window.pageview.get_selection(format='wiki') | |
self_bounds = (sel_start.get_offset(), sel_end.get_offset()) | |
passphrase = self.show_password_dialog() | |
if ((re.match(r'[\n\s]*\-{5}BEGIN PGP MESSAGE\-{5}', sel_text) is None) or | |
re.search(r'\s*\-{5}END PGP MESSAGE\-{5}[\n\s]*$', sel_text) is None): | |
# default is encryption: | |
encrypt = True | |
cryptcmd = self.preferences['encryption_command'].split(" ") | |
cryptcmd.append(passphrase) | |
else: | |
# on-the-fly decryption if selection is a full PGP encrypted block | |
encrypt = False | |
cryptcmd = self.preferences['decryption_command'].split(" ") | |
cryptcmd.append(passphrase) | |
newtext = None | |
p = Popen(cryptcmd, stdin=PIPE, stdout=PIPE) | |
newtext, err = p.communicate(input=sel_text) | |
print "newtext: " | |
print newtext | |
print "err: " | |
print err | |
if p.returncode == 0: | |
print "ERROR 0" | |
# replace selection only if crypt command was successful | |
# (incidated by returncode 0) | |
if encrypt is True: | |
bounds = map(buffer.get_iter_at_offset, self_bounds) | |
print "bounds" | |
print bounds | |
buffer.delete(*bounds) | |
buffer.insert_at_cursor("\n%s\n" % newtext) | |
else: | |
# just show decrypted text in popup | |
MessageDialog(self.window.ui, | |
_("Decrypted Text: \n" + newtext)).run() | |
else: | |
logger.warn("crypt command '%s' returned code %d." % (cryptcmd, | |
p.returncode)) | |
def show_password_dialog(self): | |
messagedialog = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_OK, message_format="Following passphrase will be used in encryption/decryption.") | |
messagedialog.set_title("Enter passphrase") | |
action_area = messagedialog.get_content_area() | |
entry = gtk.Entry() | |
entry.set_visibility(False) | |
action_area.pack_start(entry) | |
messagedialog.show_all() | |
messagedialog.run() | |
passphrase = entry.get_text() | |
messagedialog.destroy() | |
return passphrase | |
# :mode=python:tabSize=4:indentSize=4:noTabs=true:wrap=soft:maxLineLen=90: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment