Skip to content
Snippets Groups Projects
Commit 76cc8a77 authored by inso's avatar inso
Browse files

Proxy for aiohttp + Diverses fixes :

- Pressing Ok in tests
- Handling timeout errors
parent 4b45a318
No related branches found
No related tags found
No related merge requests found
...@@ -25,7 +25,7 @@ __nonsense__ = 'uCoin' ...@@ -25,7 +25,7 @@ __nonsense__ = 'uCoin'
PROTOCOL_VERSION = "1" PROTOCOL_VERSION = "1"
import aiohttp, requests, asyncio, logging, json import aiohttp, asyncio, logging, json
logger = logging.getLogger("ucoin") logger = logging.getLogger("ucoin")
...@@ -42,6 +42,7 @@ class ConnectionHandler(object): ...@@ -42,6 +42,7 @@ class ConnectionHandler(object):
self.server = server self.server = server
self.port = port self.port = port
self.connector = None
def __str__(self): def __str__(self):
return 'connection info: %s:%d' % (self.server, self.port) return 'connection info: %s:%d' % (self.server, self.port)
...@@ -50,6 +51,8 @@ class ConnectionHandler(object): ...@@ -50,6 +51,8 @@ class ConnectionHandler(object):
class API(object): class API(object):
"""APIRequest is a class used as an interface. The intermediate derivated classes are the modules and the leaf classes are the API requests.""" """APIRequest is a class used as an interface. The intermediate derivated classes are the modules and the leaf classes are the API requests."""
aiohttp_connector = None
def __init__(self, connection_handler, module): def __init__(self, connection_handler, module):
""" """
Asks a module in order to create the url used then by derivated classes. Asks a module in order to create the url used then by derivated classes.
...@@ -110,7 +113,7 @@ class API(object): ...@@ -110,7 +113,7 @@ class API(object):
""" """
logging.debug("Request : {0}".format(self.reverse_url(path))) logging.debug("Request : {0}".format(self.reverse_url(path)))
response = yield from asyncio.wait_for(aiohttp.get(self.reverse_url(path), params=kwargs, response = yield from asyncio.wait_for(aiohttp.get(self.reverse_url(path), params=kwargs,
headers=self.headers), 15) headers=self.headers, connector=API.aiohttp_connector), timeout=15)
if response.status != 200: if response.status != 200:
raise ValueError('status code != 200 => %d (%s)' % (response.status, (yield from response.text()))) raise ValueError('status code != 200 => %d (%s)' % (response.status, (yield from response.text())))
...@@ -129,7 +132,8 @@ class API(object): ...@@ -129,7 +132,8 @@ class API(object):
logging.debug("POST : {0}".format(kwargs)) logging.debug("POST : {0}".format(kwargs))
response = yield from asyncio.wait_for( response = yield from asyncio.wait_for(
aiohttp.post(self.reverse_url(path), data=kwargs, headers=self.headers), aiohttp.post(self.reverse_url(path), data=kwargs, headers=self.headers,
connector=API.aiohttp_connector),
timeout=15) timeout=15)
return response return response
......
...@@ -16,7 +16,7 @@ print(sys.path) ...@@ -16,7 +16,7 @@ print(sys.path)
includes = ["sip", "re", "json", "logging", includes = ["sip", "re", "json", "logging",
"hashlib", "os", "urllib", "hashlib", "os", "urllib",
"ucoinpy", "pylibscrypt"] "ucoinpy", "pylibscrypt"]
excludes = ['.git'] exclude = ['.git']
packages = ["libnacl", "encodings"] packages = ["libnacl", "encodings"]
includefiles = [] includefiles = []
...@@ -62,7 +62,7 @@ else: ...@@ -62,7 +62,7 @@ else:
options = {"path": sys.path, options = {"path": sys.path,
"includes": includes, "includes": includes,
"include_files": includefiles, "include_files": includefiles,
"excludes": excludes, "excludes": exclude,
"packages": packages, "packages": packages,
} }
......
...@@ -10,17 +10,19 @@ import tarfile ...@@ -10,17 +10,19 @@ import tarfile
import shutil import shutil
import json import json
import datetime import datetime
import i18n_rc import asyncio
import aiohttp
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, \ from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, \
QUrl, QTranslator, QCoreApplication, QLocale QUrl, QTranslator, QCoreApplication, QLocale
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest, QNetworkProxy from ucoinpy.api.bma import API
from aiohttp.connector import ProxyConnector
from . import config from . import config
from .account import Account from .account import Account
from .registry.identities import IdentitiesRegistry from .registry.identities import IdentitiesRegistry
from .. import __version__ from .. import __version__
from ..tools.exceptions import NameAlreadyExists, BadAccountFile from ..tools.exceptions import NameAlreadyExists, BadAccountFile
from ..tools.decorators import asyncify
class Application(QObject): class Application(QObject):
...@@ -73,12 +75,9 @@ class Application(QObject): ...@@ -73,12 +75,9 @@ class Application(QObject):
app.load() app.load()
app.switch_language() app.switch_language()
if app.preferences['enable_proxy'] is True: if app.preferences['enable_proxy'] is True:
proxytypes = {"HTTP": QNetworkProxy.HttpProxy, API.aiohttp_connector = ProxyConnector("http://{0}:{1}".format(
"SOCKS5": QNetworkProxy.Socks5Proxy}
qtproxy = QNetworkProxy(proxytypes[app.preferences.get('proxy_type', "HTTP")],
app.preferences['proxy_address'], app.preferences['proxy_address'],
app.preferences['proxy_port']) app.preferences['proxy_port']))
#network_manager.setProxy(qtproxy)
if app.preferences["account"] != "": if app.preferences["account"] != "":
account = app.get_account(app.preferences["account"]) account = app.get_account(app.preferences["account"])
...@@ -456,32 +455,35 @@ class Application(QObject): ...@@ -456,32 +455,35 @@ class Application(QObject):
self.save_registries() self.save_registries()
@asyncify
@asyncio.coroutine
def get_last_version(self): def get_last_version(self):
url = QUrl("https://api.github.com/repos/ucoin-io/cutecoin/releases") if self.preferences['enable_proxy'] is True:
"""request = QNetworkRequest(url) connector = ProxyConnector("http://{0}:{1}".format(
reply = self._network_manager.get(request) self.preferences['proxy_address'],
reply.finished.connect(self.read_available_version)""" self.preferences['proxy_port']))
else:
@pyqtSlot(QNetworkReply) connector = None
def read_available_version(self): try:
latest = None response = yield from asyncio.wait_for(aiohttp.get("https://api.github.com/repos/ucoin-io/cutecoin/releases",
reply = self.sender() connector=connector), timeout=15)
releases = reply.readAll().data().decode('utf-8') if response.status == 200:
logging.debug(releases) releases = yield from response.json()
if reply.error() == QNetworkReply.NoError: for r in releases:
for r in json.loads(releases): if not latest:
if not latest:
latest = r
else:
latest_date = datetime.datetime.strptime(latest['published_at'], "%Y-%m-%dT%H:%M:%SZ")
date = datetime.datetime.strptime(r['published_at'], "%Y-%m-%dT%H:%M:%SZ")
if latest_date < date:
latest = r latest = r
latest_version = latest["tag_name"] else:
version = (__version__ == latest_version, latest_date = datetime.datetime.strptime(latest['published_at'], "%Y-%m-%dT%H:%M:%SZ")
latest_version, date = datetime.datetime.strptime(r['published_at'], "%Y-%m-%dT%H:%M:%SZ")
latest["html_url"]) if latest_date < date:
logging.debug("Found version : {0}".format(latest_version)) latest = r
logging.debug("Current version : {0}".format(__version__)) latest_version = latest["tag_name"]
self.available_version = version version = (__version__ == latest_version,
self.version_requested.emit() latest_version,
latest["html_url"])
logging.debug("Found version : {0}".format(latest_version))
logging.debug("Current version : {0}".format(__version__))
self.available_version = version
self.version_requested.emit()
except aiohttp.errors.ClientError as e:
logging.debug("Could not connect to github : {0}".format(str(e)))
...@@ -169,6 +169,8 @@ class BmaAccess(QObject): ...@@ -169,6 +169,8 @@ class BmaAccess(QObject):
tries += 1 tries += 1
except ClientError: except ClientError:
tries += 1 tries += 1
except TimeoutError:
tries += 1
if len(nodes) == 0 or json_data is None: if len(nodes) == 0 or json_data is None:
raise NoPeerAvailable("", len(nodes)) raise NoPeerAvailable("", len(nodes))
return json_data return json_data
...@@ -186,8 +188,19 @@ class BmaAccess(QObject): ...@@ -186,8 +188,19 @@ class BmaAccess(QObject):
if len(nodes) > 0: if len(nodes) > 0:
node = random.choice(nodes) node = random.choice(nodes)
req = request(node.endpoint.conn_handler(), **req_args) req = request(node.endpoint.conn_handler(), **req_args)
json_data = yield from req.get(**get_args) tries = 0
return json_data while tries < 3:
try:
json_data = yield from req.get(**get_args)
return json_data
except ValueError as e:
if '404' in str(e) or '400' in str(e):
raise
tries += 1
except ClientError:
tries += 1
except TimeoutError:
tries += 1
else: else:
raise NoPeerAvailable("", len(nodes)) raise NoPeerAvailable("", len(nodes))
...@@ -212,8 +225,16 @@ class BmaAccess(QObject): ...@@ -212,8 +225,16 @@ class BmaAccess(QObject):
logging.debug("Trying to connect to : " + node.pubkey) logging.debug("Trying to connect to : " + node.pubkey)
conn_handler = node.endpoint.conn_handler() conn_handler = node.endpoint.conn_handler()
req = request(conn_handler, **req_args) req = request(conn_handler, **req_args)
reply = yield from req.post(**post_args) try:
replies.append(reply) reply = yield from req.post(**post_args)
replies.append(reply)
except ValueError as e:
if '404' in str(e) or '400' in str(e):
raise
except ClientError:
pass
except TimeoutError:
pass
else: else:
raise NoPeerAvailable("", len(nodes)) raise NoPeerAvailable("", len(nodes))
return tuple(replies) return tuple(replies)
...@@ -296,6 +296,7 @@ class Node(QObject): ...@@ -296,6 +296,7 @@ class Node(QObject):
try: try:
block_data = yield from bma.blockchain.Current(conn_handler).get() block_data = yield from bma.blockchain.Current(conn_handler).get()
block_hash = block_data['hash'] block_hash = block_data['hash']
self.state = Node.ONLINE
if not self.block or block_hash != self.block['hash']: if not self.block or block_hash != self.block['hash']:
self.set_block(block_data) self.set_block(block_data)
...@@ -324,6 +325,7 @@ class Node(QObject): ...@@ -324,6 +325,7 @@ class Node(QObject):
logging.debug(peering_data) logging.debug(peering_data)
node_pubkey = peering_data["pubkey"] node_pubkey = peering_data["pubkey"]
node_currency = peering_data["currency"] node_currency = peering_data["currency"]
self.state = Node.ONLINE
change = False change = False
if node_pubkey != self.pubkey: if node_pubkey != self.pubkey:
...@@ -354,6 +356,7 @@ class Node(QObject): ...@@ -354,6 +356,7 @@ class Node(QObject):
summary_data = yield from bma.node.Summary(conn_handler).get() summary_data = yield from bma.node.Summary(conn_handler).get()
self.software = summary_data["ucoin"]["software"] self.software = summary_data["ucoin"]["software"]
self.version = summary_data["ucoin"]["version"] self.version = summary_data["ucoin"]["version"]
self.state = Node.ONLINE
if "forkWindowSize" in summary_data["ucoin"]: if "forkWindowSize" in summary_data["ucoin"]:
self.fork_window = summary_data["ucoin"]["forkWindowSize"] self.fork_window = summary_data["ucoin"]["forkWindowSize"]
else: else:
...@@ -372,6 +375,7 @@ class Node(QObject): ...@@ -372,6 +375,7 @@ class Node(QObject):
conn_handler = self.endpoint.conn_handler() conn_handler = self.endpoint.conn_handler()
try: try:
data = yield from bma.wot.Lookup(conn_handler, self.pubkey).get() data = yield from bma.wot.Lookup(conn_handler, self.pubkey).get()
self.state = Node.ONLINE
timestamp = 0 timestamp = 0
for result in data['results']: for result in data['results']:
if result["pubkey"] == self.pubkey: if result["pubkey"] == self.pubkey:
...@@ -402,6 +406,7 @@ class Node(QObject): ...@@ -402,6 +406,7 @@ class Node(QObject):
try: try:
peers_data = yield from bma.network.peering.Peers(conn_handler).get(leaves='true') peers_data = yield from bma.network.peering.Peers(conn_handler).get(leaves='true')
self.state = Node.ONLINE
if peers_data['root'] != self._last_merkle['root']: if peers_data['root'] != self._last_merkle['root']:
leaves = [leaf for leaf in peers_data['leaves'] leaves = [leaf for leaf in peers_data['leaves']
if leaf not in self._last_merkle['leaves']] if leaf not in self._last_merkle['leaves']]
......
...@@ -84,6 +84,9 @@ class HomeScreenWidget(QWidget, Ui_HomescreenWidget): ...@@ -84,6 +84,9 @@ class HomeScreenWidget(QWidget, Ui_HomescreenWidget):
:param QShowEvent: :param QShowEvent:
:return: :return:
""" """
for tile in self.frame_communities:
tile.refresh()
self.status_label.setText("") self.status_label.setText("")
def changeEvent(self, event): def changeEvent(self, event):
......
...@@ -86,7 +86,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -86,7 +86,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def startup(self): def startup(self):
self.update_time() self.update_time()
self.app.get_last_version() # FIXME : Need python 3.5 self.app.get_last_version()
if self.app.preferences['maximized']: if self.app.preferences['maximized']:
self.showMaximized() self.showMaximized()
else: else:
......
...@@ -11,7 +11,7 @@ from PyQt5.QtGui import QCursor, QDesktopServices ...@@ -11,7 +11,7 @@ from PyQt5.QtGui import QCursor, QDesktopServices
from PyQt5.QtWidgets import QWidget, QMenu, QAction from PyQt5.QtWidgets import QWidget, QMenu, QAction
from PyQt5.QtCore import Qt, QModelIndex, pyqtSlot, QUrl, QEvent from PyQt5.QtCore import Qt, QModelIndex, pyqtSlot, QUrl, QEvent
from ..models.network import NetworkTableModel, NetworkFilterProxyModel from ..models.network import NetworkTableModel, NetworkFilterProxyModel
from ..core.net.api import bma as bma from ucoinpy.api import bma
from ..gen_resources.network_tab_uic import Ui_NetworkTabWidget from ..gen_resources.network_tab_uic import Ui_NetworkTabWidget
......
...@@ -5,7 +5,8 @@ import quamash ...@@ -5,7 +5,8 @@ import quamash
import time import time
import logging import logging
from ucoinpy.documents.peer import BMAEndpoint from ucoinpy.documents.peer import BMAEndpoint
from PyQt5.QtWidgets import QDialog, QDialogButtonBox from quamash import QApplication
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox
from PyQt5.QtCore import QLocale, Qt from PyQt5.QtCore import QLocale, Qt
from PyQt5.QtTest import QTest from PyQt5.QtTest import QTest
from ucoinpy.api.bma import API from ucoinpy.api.bma import API
...@@ -85,6 +86,11 @@ class TestCertificationDialog(unittest.TestCase): ...@@ -85,6 +86,11 @@ class TestCertificationDialog(unittest.TestCase):
QTest.mouseClick(certification_dialog.radio_pubkey, Qt.LeftButton) QTest.mouseClick(certification_dialog.radio_pubkey, Qt.LeftButton)
QTest.keyClicks(certification_dialog.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn") QTest.keyClicks(certification_dialog.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn")
QTest.mouseClick(certification_dialog.button_box.button(QDialogButtonBox.Ok), Qt.LeftButton) QTest.mouseClick(certification_dialog.button_box.button(QDialogButtonBox.Ok), Qt.LeftButton)
yield from asyncio.sleep(1)
topWidgets = QApplication.topLevelWidgets()
for w in topWidgets:
if type(w) is QMessageBox:
QTest.keyClick(w, Qt.Key_Enter)
self.lp.call_later(15, close_dialog) self.lp.call_later(15, close_dialog)
asyncio.async(exec_test()) asyncio.async(exec_test())
......
...@@ -4,8 +4,8 @@ import asyncio ...@@ -4,8 +4,8 @@ import asyncio
import quamash import quamash
import time import time
import logging import logging
from ucoinpy.documents.peer import BMAEndpoint as PyBMAEndpoint from quamash import QApplication
from PyQt5.QtWidgets import QDialog, QDialogButtonBox from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox
from PyQt5.QtCore import QLocale, Qt from PyQt5.QtCore import QLocale, Qt
from PyQt5.QtTest import QTest from PyQt5.QtTest import QTest
from ucoinpy.api.bma import API from ucoinpy.api.bma import API
...@@ -85,6 +85,11 @@ class TestTransferDialog(unittest.TestCase): ...@@ -85,6 +85,11 @@ class TestTransferDialog(unittest.TestCase):
QTest.mouseClick(transfer_dialog.radio_pubkey, Qt.LeftButton) QTest.mouseClick(transfer_dialog.radio_pubkey, Qt.LeftButton)
QTest.keyClicks(transfer_dialog.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn") QTest.keyClicks(transfer_dialog.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn")
QTest.mouseClick(transfer_dialog.button_box.button(QDialogButtonBox.Cancel), Qt.LeftButton) QTest.mouseClick(transfer_dialog.button_box.button(QDialogButtonBox.Cancel), Qt.LeftButton)
yield from asyncio.sleep(1)
topWidgets = QApplication.topLevelWidgets()
for w in topWidgets:
if type(w) is QMessageBox:
QTest.keyClick(w, Qt.Key_Enter)
self.lp.call_later(15, close_dialog) self.lp.call_later(15, close_dialog)
asyncio.async(exec_test()) asyncio.async(exec_test())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment