URI: 
       temail plugin - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 126454c0e657a909ab4568f92b4ae059ec773f92
   DIR parent b9d270d438a826c944840bf34c5435be4260e09d
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Tue, 11 Nov 2014 11:08:25 +0100
       
       email plugin
       
       Diffstat:
         M plugins/__init__.py                 |       6 ++++++
         A plugins/email.py                    |     216 +++++++++++++++++++++++++++++++
       
       2 files changed, 222 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/plugins/__init__.py b/plugins/__init__.py
       t@@ -48,6 +48,12 @@ descriptions = [
                'available_for': ['qt'],
            },
            {
       +        'name': 'email',
       +        'fullname': 'Email',
       +        'description': _("Send and receive payment request with an email account"),
       +        'available_for': ['qt'],
       +    },
       +    {
                'name': 'exchange_rate',
                'fullname': _("Exchange rates"),
                'description': _("Exchange rates and currency conversion tools."),
   DIR diff --git a/plugins/email.py b/plugins/email.py
       t@@ -0,0 +1,216 @@
       +#!/usr/bin/env python
       +#
       +# Electrum - Lightweight Bitcoin Client
       +# Copyright (C) 2015 Thomas Voegtlin
       +#
       +# 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 3 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/>.
       +
       +from __future__ import absolute_import
       +
       +import socket
       +import time
       +import threading
       +import base64
       +import re
       +import platform
       +from decimal import Decimal
       +from Queue import Queue
       +
       +import smtplib
       +import imaplib
       +import email
       +from email.MIMEMultipart import MIMEMultipart
       +from email.MIMEBase import MIMEBase
       +from email import Encoders
       +
       +from PyQt4.QtGui import *
       +from PyQt4.QtCore import *
       +import PyQt4.QtCore as QtCore
       +import PyQt4.QtGui as QtGui
       +
       +from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_EXPIRED
       +from electrum.plugins import BasePlugin, hook
       +from electrum import util
       +from electrum.paymentrequest import PaymentRequest
       +from electrum.i18n import _
       +from electrum_gui.qt.util import text_dialog, EnterButton
       +
       +
       +
       +class Processor(threading.Thread):
       +    polling_interval = 5*60
       +
       +    def __init__(self, imap_server, username, password, callback):
       +        threading.Thread.__init__(self)
       +        self.daemon = True
       +        self.username = username
       +        self.password = password
       +        self.imap_server = imap_server
       +        self.on_receive = callback
       +
       +    def poll(self):
       +        try:
       +            self.M.select()
       +        except:
       +            return
       +        typ, data = self.M.search(None, 'ALL')
       +        for num in data[0].split():
       +            typ, msg_data = self.M.fetch(num, '(RFC822)')
       +            msg = email.message_from_string(msg_data[0][1])
       +            p = msg.get_payload()
       +            if not msg.is_multipart():
       +                p = [p]
       +                continue
       +            for item in p:
       +                if item.get_content_type() == "application/bitcoin-paymentrequest":
       +                    pr_str = item.get_payload()
       +                    pr_str = base64.b64decode(pr_str)
       +                    self.on_receive(pr_str)
       +
       +    def run(self):
       +        self.M = imaplib.IMAP4_SSL(self.imap_server)
       +        self.M.login(self.username, self.password)
       +        while True:
       +            self.poll()
       +            time.sleep(self.polling_interval)
       +        self.M.close()
       +        self.M.logout()
       +
       +    def send(self, recipient, message, payment_request):
       +        msg = MIMEMultipart()
       +        msg['Subject'] = message
       +        msg['To'] = recipient
       +        msg['From'] = self.username
       +        part = MIMEBase('application', "bitcoin-paymentrequest")
       +        part.set_payload(payment_request)
       +        Encoders.encode_base64(part)
       +        part.add_header('Content-Disposition', 'attachment; filename="payreq.btc"')
       +        msg.attach(part)
       +        s = smtplib.SMTP_SSL(self.imap_server, timeout=2)
       +        s.login(self.username, self.password)
       +        s.sendmail(self.username, [recipient], msg.as_string())
       +        s.quit()
       +
       +
       +class Plugin(BasePlugin):
       +
       +    def fullname(self):
       +        return 'Email'
       +
       +    def description(self):
       +        return _("Send and receive payment requests via email")
       +
       +    def is_available(self):
       +        return True
       +
       +    def __init__(self, a, b):
       +        BasePlugin.__init__(self, a, b)
       +        self.imap_server = self.config.get('email_server', '')
       +        self.username = self.config.get('email_username', '')
       +        self.password = self.config.get('email_password', '')
       +        if self.imap_server and self.username and self.password:
       +            self.processor = Processor(self.imap_server, self.username, self.password, self.on_receive)
       +            self.processor.start()
       +        self.win = None
       +
       +    def on_receive(self, pr_str):
       +        self.print_error('received payment request')
       +        self.pr = PaymentRequest(pr_str)
       +        if self.win:
       +            self.win.emit(SIGNAL('email:new_invoice'))
       +
       +    def new_invoice(self):
       +        self.win.invoices.add(self.pr)
       +        self.win.update_invoices_list()
       +
       +    @hook
       +    def init_qt(self, gui):
       +        from electrum_gui.qt.util import ThreadedButton
       +        self.win = gui.main_window
       +        self.win.connect(self.win, SIGNAL('email:new_invoice'), self.new_invoice)
       +
       +        self.send_button = EnterButton(_('Send'), self.send)
       +        self.win.receive_buttons.insertWidget(1, self.send_button)
       +
       +    def send(self):
       +        addr = str(self.win.receive_address_e.text())
       +        message = unicode(self.win.receive_message_e.text())
       +        payment_request = self.win.make_payment_request(addr)
       +
       +        if not self.win.save_payment_request():
       +            return
       +
       +        recipient, ok = QtGui.QInputDialog.getText(self.win, 'Send request', 'Send request to:')
       +        if not ok:
       +            return
       +
       +        recipient = str(recipient)
       +        self.print_error('sending mail to', recipient)
       +        try:
       +            self.processor.send(recipient, message, payment_request)
       +        except BaseException as e:
       +            self.win.show_message(str(e))
       +            return
       +
       +        self.win.show_message(_('Request sent.'))
       +
       +
       +    def requires_settings(self):
       +        return True
       +
       +    def settings_widget(self, window):
       +        return EnterButton(_('Settings'), self.settings_dialog)
       +
       +    def settings_dialog(self, x):
       +        from electrum_gui.qt.util import Buttons, CloseButton, OkButton
       +
       +        d = QDialog(self.window)
       +        d.setWindowTitle("Email settings")
       +        d.setMinimumSize(500, 200)
       +
       +        vbox = QVBoxLayout(d)
       +        grid = QGridLayout()
       +        vbox.addLayout(grid)
       +
       +        grid.addWidget(QLabel('Server'), 0, 0)
       +        server_e = QLineEdit()
       +        server_e.setText(self.imap_server)
       +        grid.addWidget(server_e, 0, 1)
       +
       +        grid.addWidget(QLabel('Username'), 1, 0)
       +        username_e = QLineEdit()
       +        username_e.setText(self.username)
       +        grid.addWidget(username_e, 1, 1)
       +
       +        grid.addWidget(QLabel('Password'), 2, 0)
       +        password_e = QLineEdit()
       +        password_e.setText(self.password)
       +        grid.addWidget(password_e, 2, 1)
       +
       +        vbox.addStretch()
       +        vbox.addLayout(Buttons(CloseButton(d), OkButton(d)))
       +
       +        if not d.exec_(): 
       +            return
       +
       +        server = str(server_e.text())
       +        self.config.set_key('email_server', server)
       +
       +        username = str(username_e.text())
       +        self.config.set_key('email_username', username)
       +
       +        password = str(password_e.text())
       +        self.config.set_key('email_password', password)
       +
       +