Browse Source

network: add singleton accessor classmethod, port trustedcoin to aiohttp

3.3.3.1
Janus 7 years ago
parent
commit
52b877ac3d
  1. 11
      electrum/exchange_rate.py
  2. 9
      electrum/gui/kivy/uix/dialogs/crash_reporter.py
  3. 9
      electrum/gui/qt/exception_window.py
  4. 8
      electrum/network.py
  5. 60
      electrum/plugins/trustedcoin/trustedcoin.py

11
electrum/exchange_rate.py

@ -17,7 +17,7 @@ from .bitcoin import COIN
from .i18n import _
from .util import PrintError, ThreadJob, make_dir, aiosafe
from .util import make_aiohttp_session
from .network import Network
# See https://en.wikipedia.org/wiki/ISO_4217
CCY_PRECISIONS = {'BHD': 3, 'BIF': 0, 'BYR': 0, 'CLF': 4, 'CLP': 0,
@ -27,8 +27,6 @@ CCY_PRECISIONS = {'BHD': 3, 'BIF': 0, 'BYR': 0, 'CLF': 4, 'CLP': 0,
'RWF': 0, 'TND': 3, 'UGX': 0, 'UYI': 0, 'VND': 0,
'VUV': 0, 'XAF': 0, 'XAU': 4, 'XOF': 0, 'XPF': 0}
PROXY = None
class ExchangeBase(PrintError):
def __init__(self, on_quotes, on_history):
@ -40,14 +38,14 @@ class ExchangeBase(PrintError):
async def get_raw(self, site, get_string):
# APIs must have https
url = ''.join(['https://', site, get_string])
async with make_aiohttp_session(PROXY) as session:
async with make_aiohttp_session(Network.get_instance().proxy) as session:
async with session.get(url) as response:
return await response.text()
async def get_json(self, site, get_string):
# APIs must have https
url = ''.join(['https://', site, get_string])
async with make_aiohttp_session(PROXY) as session:
async with make_aiohttp_session(Network.get_instance().proxy) as session:
async with session.get(url) as response:
return await response.json()
@ -448,11 +446,8 @@ class FxThread(ThreadJob):
self.trigger.set()
self.set_exchange(self.config_exchange())
make_dir(self.cache_dir)
self.set_proxy('bogus', self.network.proxy)
def set_proxy(self, trigger_name, *args):
global PROXY
PROXY = args[0]
self.trigger.set()
def get_currencies(self, h):

9
electrum/gui/kivy/uix/dialogs/crash_reporter.py

@ -103,11 +103,6 @@ class CrashReporter(BaseCrashReporter, Factory.Popup):
self.ids.crash_message.text = BaseCrashReporter.CRASH_MESSAGE
self.ids.request_help_message.text = BaseCrashReporter.REQUEST_HELP_MESSAGE
self.ids.describe_error_message.text = BaseCrashReporter.DESCRIBE_ERROR_MESSAGE
self.proxy = self.main_window.network.proxy
self.main_window.network.register_callback(self.set_proxy, ['proxy_set'])
def set_proxy(self, evt, proxy):
self.proxy = proxy
def show_contents(self):
details = CrashReportDetails(self.get_report_string())
@ -121,7 +116,9 @@ class CrashReporter(BaseCrashReporter, Factory.Popup):
def send_report(self):
try:
response = json.loads(BaseCrashReporter.send_report(self, self.main_window.network.asyncio_loop, self.proxy, "/crash.json"))
loop = self.main_window.network.asyncio_loop
proxy = self.main_window.network.proxy
response = json.loads(BaseCrashReporter.send_report(self, loop, proxy, "/crash.json"))
except (ValueError, ClientError):
self.show_popup(_('Unable to send report'), _("Please check your network connection."))
else:

9
electrum/gui/qt/exception_window.py

@ -42,9 +42,6 @@ class Exception_Window(BaseCrashReporter, QWidget, MessageBoxMixin):
BaseCrashReporter.__init__(self, exctype, value, tb)
self.main_window = main_window
self.proxy = self.main_window.network.proxy
self.main_window.network.register_callback(self.set_proxy, ['proxy_set'])
QWidget.__init__(self)
self.setWindowTitle('Electrum - ' + _('An Error Occurred'))
self.setMinimumSize(600, 300)
@ -92,12 +89,10 @@ class Exception_Window(BaseCrashReporter, QWidget, MessageBoxMixin):
self.setLayout(main_box)
self.show()
def set_proxy(self, evt, proxy):
self.proxy = proxy
def send_report(self):
try:
response = BaseCrashReporter.send_report(self, self.main_window.network.asyncio_loop, self.proxy)
proxy = self.main_window.network.proxy
response = BaseCrashReporter.send_report(self, self.main_window.network.asyncio_loop, proxy)
except BaseException as e:
traceback.print_exc(file=sys.stderr)
self.main_window.show_critical(_('There was a problem with the automatic reporting:') + '\n' +

8
electrum/network.py

@ -158,6 +158,8 @@ def deserialize_server(server_str):
def serialize_server(host, port, protocol):
return str(':'.join([host, port, protocol]))
INSTANCE = None
class Network(PrintError):
"""The Network class manages a set of connections to remote electrum
servers, each connected socket is handled by an Interface() object.
@ -173,6 +175,8 @@ class Network(PrintError):
verbosity_filter = 'n'
def __init__(self, config=None):
global INSTANCE
INSTANCE = self
if config is None:
config = {} # Do not use mutables as default values!
self.config = SimpleConfig(config) if isinstance(config, dict) else config
@ -244,6 +248,10 @@ class Network(PrintError):
# just to not trigger a warning from switch_to_interface the first time we change default_server
self.server_info_job.set_result(1)
@staticmethod
def get_instance():
return INSTANCE
def with_interface_lock(func):
def func_wrapper(self, *args, **kwargs):
with self.interface_lock:

60
electrum/plugins/trustedcoin/trustedcoin.py

@ -22,10 +22,9 @@
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import asyncio
import socket
import os
import requests
import json
import base64
from urllib.parse import urljoin
@ -38,8 +37,9 @@ from electrum.mnemonic import Mnemonic
from electrum.wallet import Multisig_Wallet, Deterministic_Wallet
from electrum.i18n import _
from electrum.plugin import BasePlugin, hook
from electrum.util import NotEnoughFunds
from electrum.util import NotEnoughFunds, make_aiohttp_session
from electrum.storage import STO_EV_USER_PW
from electrum.network import Network
# signing_xpub is hardcoded so that the wallet can be restored from seed, without TrustedCoin's server
def get_signing_xpub():
@ -104,34 +104,44 @@ class TrustedCoinCosignerClient(object):
self.user_agent = user_agent
def send_request(self, method, relative_url, data=None):
kwargs = {'headers': {}}
if self.user_agent:
kwargs['headers']['user-agent'] = self.user_agent
if method == 'get' and data:
kwargs['params'] = data
elif method == 'post' and data:
kwargs['data'] = json.dumps(data)
kwargs['headers']['content-type'] = 'application/json'
print("send_req")
return asyncio.run_coroutine_threadsafe(self._send_request(method, relative_url, data), Network.get_instance().asyncio_loop).result()
async def handle_response(self, resp):
if resp.status != 200:
try:
r = await resp.json()
message = r['message']
except:
message = await resp.text()
raise TrustedCoinException(message, resp.status)
try:
return await resp.json()
except:
return await resp.text()
async def _send_request(self, method, relative_url, data):
url = urljoin(self.base_url, relative_url)
if self.debug:
print('%s %s %s' % (method, url, data))
headers = {}
if self.user_agent:
headers['user-agent'] = self.user_agent
try:
response = requests.request(method, url, **kwargs)
proxy = Network.get_instance().proxy
async with make_aiohttp_session(proxy) as session:
if method == 'get':
async with session.get(url, params=data, headers=headers) as resp:
return await self.handle_response(resp)
elif method == 'post':
async with session.post(url, json=data, headers=headers) as resp:
return await self.handle_response(resp)
else:
assert False
except TrustedCoinException:
raise
except Exception as e:
raise ErrorConnectingServer(e)
if self.debug:
print(response.text)
if response.status_code != 200:
message = str(response.text)
if response.headers.get('content-type') == 'application/json':
r = response.json()
if 'message' in r:
message = r['message']
raise TrustedCoinException(message, response.status_code)
if response.headers.get('content-type') == 'application/json':
return response.json()
else:
return response.text
def get_terms_of_service(self, billing_plan='electrum-per-tx-otp'):
"""

Loading…
Cancel
Save