diff --git a/src/cutecoin/core/app.py b/src/cutecoin/core/app.py index fa449c57a099fdf06c4cbfba37d47dca1a8c5fe1..a061860aedbb20419cb9ee871c5d453cd2138402 100644 --- a/src/cutecoin/core/app.py +++ b/src/cutecoin/core/app.py @@ -33,7 +33,7 @@ class Application(QObject): version_requested = pyqtSignal() - def __init__(self, argv, qapp, loop): + def __init__(self, qapp, loop, network_manager, identities_registry): """ Create a new "cutecoin" application @@ -47,15 +47,25 @@ class Application(QObject): self.available_version = (True, __version__, "") - self.identity_registry = None - config.parse_arguments(argv) - self._network_manager = QNetworkAccessManager() - self._identities_registry = IdentitiesRegistry() + self._identities_registry = identities_registry + self._network_manager = network_manager self.preferences = {'account': "", 'lang': 'en_GB', 'ref': 0 } + @classmethod + def startup(cls, argv, qapp, loop): + config.parse_arguments(argv) + network_manager = QNetworkAccessManager() + identities_registry = IdentitiesRegistry() + app = cls(qapp, loop, network_manager, identities_registry) + + app.load() + app.switch_language() + return app + + def switch_language(self): translator = QTranslator(self.qapp) logging.debug("Loading translations") diff --git a/src/cutecoin/gui/mainwindow.py b/src/cutecoin/gui/mainwindow.py index cde0152d0681d52a4cd486460632ac03f8d29a66..56f45d804fb32272401c5e0134aa3ad9e0467cb4 100644 --- a/src/cutecoin/gui/mainwindow.py +++ b/src/cutecoin/gui/mainwindow.py @@ -41,30 +41,20 @@ class MainWindow(QMainWindow, Ui_MainWindow): """ # Set up the user interface from Designer. super().__init__() - self.setupUi(self) - QApplication.setWindowIcon(QIcon(":/icons/cutecoin_logo")) self.app = app - self.initialized = False - if self.app.preferences["account"] != "": - account = self.app.get_account(self.app.preferences["account"]) - self.app.change_current_account(account) - # no default account... - else: - # if at least one account exists, set it as default... - if len(self.app.accounts) > 0: - # capture names sorted alphabetically - names = list(self.app.accounts.keys()) - names.sort() - # set first name in list as default in preferences - self.app.preferences['account'] = names[0] - self.app.save_preferences(self.app.preferences) - # open it - logging.debug("No default account in preferences. Set %s as default account." % names[0]) - self.action_change_account(self.app.get_account(self.app.preferences['account'])) - self.password_asker = None - # + self.combo_referential = QComboBox(self) + self.status_label = QLabel("", self) + self.label_time = QLabel("", self) + self.import_dialog = None + self.export_dialog = None + self.setupUi() + + def setupUi(self): + super().setupUi(self) + QApplication.setWindowIcon(QIcon(":/icons/cutecoin_logo")) + # self.busybar = QProgressBar(self.statusbar) # self.busybar.setMinimum(0) # self.busybar.setMaximum(0) @@ -72,21 +62,15 @@ class MainWindow(QMainWindow, Ui_MainWindow): # #self.statusbar.addWidget(self.busybar) # self.busybar.hide() self.app.version_requested.connect(self.latest_version_requested) - self.app.get_last_version() - self.combo_referential = QComboBox(self) self.combo_referential.setEnabled(False) self.combo_referential.currentIndexChanged.connect(self.referential_changed) - self.status_label = QLabel("", self) self.status_label.setTextFormat(Qt.RichText) - - self.label_time = QLabel("", self) # # self.statusbar.addPermanentWidget(self.status_label, 1) # self.statusbar.addPermanentWidget(self.label_time) # self.statusbar.addPermanentWidget(self.combo_referential) - self.update_time() # # self.homescreen = HomeScreenWidget(self.app) # self.centralWidget().layout().addWidget(self.homescreen) @@ -95,11 +79,9 @@ class MainWindow(QMainWindow, Ui_MainWindow): # self.open_ucoin_info = lambda: QDesktopServices.openUrl(QUrl("http://ucoin.io/theoretical/")) # self.homescreen.button_info.clicked.connect(self.open_ucoin_info) - self.import_dialog = None - self.export_dialog = None - - # TODO: There are too much refresh() calls on startup - #self.refresh() + def startup(self): + self.update_time() + self.app.get_last_version() def open_add_account_dialog(self): dialog = ProcessConfigureAccount(self.app, None) diff --git a/src/cutecoin/main.py b/src/cutecoin/main.py index ae2f0ac3a1ede143cd8e97bb84567eebe56953b5..5b31c2ba60079c35b38d46f64a79de805ec1dae9 100755 --- a/src/cutecoin/main.py +++ b/src/cutecoin/main.py @@ -19,12 +19,11 @@ if __name__ == '__main__': cutecoin = QApplication(sys.argv) loop = QEventLoop(cutecoin) - app = Application(sys.argv, cutecoin, loop) - app.load() - app.switch_language() asyncio.set_event_loop(loop) logging.debug("Debug enabled : {0}".format(loop.get_debug())) + with loop: + app = Application.startup(sys.argv, cutecoin, loop) window = MainWindow(app) window.showMaximized() loop.run_forever() diff --git a/src/cutecoin/tests/main_window/__init__.py b/src/cutecoin/tests/main_window/__init__.py index 8b137891791fe96927ad78e64b0aad7bded08bdc..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/src/cutecoin/tests/main_window/__init__.py +++ b/src/cutecoin/tests/main_window/__init__.py @@ -1 +0,0 @@ - diff --git a/src/cutecoin/tests/main_window/test_main_window_dialogs.py b/src/cutecoin/tests/main_window/test_main_window_dialogs.py index 4c5236a622a2cd3aa988808b82938d166bc5b24d..2389f380f70e36334538cd59bd488f6b923fd45b 100644 --- a/src/cutecoin/tests/main_window/test_main_window_dialogs.py +++ b/src/cutecoin/tests/main_window/test_main_window_dialogs.py @@ -7,9 +7,12 @@ import quamash import PyQt5 from PyQt5.QtWidgets import QMenu from PyQt5.QtCore import QLocale, QTimer +from PyQt5.QtNetwork import QNetworkAccessManager from cutecoin.gui.mainwindow import MainWindow from cutecoin.core.app import Application +from cutecoin.tests.stubs.core.registry import IdentitiesRegistry + # Qapplication cause a core dumped when re-run in setup # set it as global var @@ -35,7 +38,9 @@ class MainWindowDialogsTest(unittest.TestCase): self.lp.set_exception_handler(except_handler) - self.application = Application(sys.argv, self.qapplication, self.lp) + network_manager = QNetworkAccessManager() + + self.application = Application(self.qapplication, self.lp, network_manager, IdentitiesRegistry()) self.main_window = MainWindow(self.application) def tearDown(self): @@ -60,16 +65,15 @@ class MainWindowDialogsTest(unittest.TestCase): raise exc['exception'] # def test_action_about(self): - # pass - # select menu - # self.main_window.actionAbout.trigger() - # widgets = self.qapplication.topLevelWidgets() - # for widget in widgets: - # if isinstance(widget, PyQt5.QtWidgets.QDialog): - # if widget.isVisible(): - # self.assertEqual('AboutPopup', widget.objectName()) - # widget.close() - # break + # #select menu + # self.main_window.actionAbout.trigger() + # widgets = self.qapplication.topLevelWidgets() + # for widget in widgets: + # if isinstance(widget, PyQt5.QtWidgets.QDialog): + # if widget.isVisible(): + # self.assertEqual('AboutPopup', widget.objectName()) + # widget.close() + # break # # def test_action_add_account(self): # pass diff --git a/src/cutecoin/tests/main_window/test_main_window_menus.py b/src/cutecoin/tests/main_window/test_main_window_menus.py index 7a2d24bfcf3b3df92fbd2dbf8486e16abf70927a..87fd81b90cbb4f71e51d38ebc3b8cd9290dcc1b9 100644 --- a/src/cutecoin/tests/main_window/test_main_window_menus.py +++ b/src/cutecoin/tests/main_window/test_main_window_menus.py @@ -37,7 +37,7 @@ class MainWindowMenusTest(unittest.TestCase): self.lp.set_exception_handler(except_handler) - self.application = Application(sys.argv, qapplication, self.lp) + self.application = Application(qapplication, self.lp, None, None) self.main_window = MainWindow(self.application) def tearDown(self): @@ -98,3 +98,4 @@ class MainWindowMenusTest(unittest.TestCase): if __name__ == '__main__': unittest.main() + qapplication.exit() diff --git a/src/cutecoin/tests/stubs/__init__.py b/src/cutecoin/tests/stubs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/cutecoin/tests/stubs/core/__init__.py b/src/cutecoin/tests/stubs/core/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/cutecoin/tests/stubs/core/net/__init__.py b/src/cutecoin/tests/stubs/core/net/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8779e25f1cc4a979a682c0b5fb9e2833540fe6df --- /dev/null +++ b/src/cutecoin/tests/stubs/core/net/__init__.py @@ -0,0 +1 @@ +from .network import Network \ No newline at end of file diff --git a/src/cutecoin/tests/stubs/core/net/network.py b/src/cutecoin/tests/stubs/core/net/network.py new file mode 100644 index 0000000000000000000000000000000000000000..d14181f48c365cd30dd653c75b3433218bc19557 --- /dev/null +++ b/src/cutecoin/tests/stubs/core/net/network.py @@ -0,0 +1,98 @@ +""" +Created on 24 févr. 2015 + +@author: inso +""" +import asyncio + +from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject + + +class Network(QObject): + """ + A network is managing nodes polling and crawling of a + given community. + """ + nodes_changed = pyqtSignal() + new_block_mined = pyqtSignal(int) + + def __init__(self, network_manager, currency, nodes): + """ + Constructor of a network + + :param str currency: The currency name of the community + :param list nodes: The root nodes of the network + """ + super().__init__() + self.currency = currency + self.network_manager = network_manager + + @classmethod + def create(cls, network_manager, node) + nodes = [node] + network = cls(network_manager, node.currency, nodes) + return network + + def merge_with_json(self, json_data): + pass + + @classmethod + def from_json(cls, network_manager, currency, json_data): + nodes = [] + network = cls(network_manager, currency, nodes) + return network + + def jsonify(self): + data = [] + return data + + @property + def quality(self): + return 0.33 + + def stop_coroutines(self): + pass + + def continue_crawling(self): + return False + + @property + def synced_nodes(self): + return self.nodes + + @property + def online_nodes(self): + return self.nodes + + @property + def nodes(self): + """ + Get all knew nodes. + """ + return self._nodes + + @property + def root_nodes(self): + return self._root_nodes + + @property + def latest_block(self): + return 20000 + + def add_node(self, node): + pass + + def add_root_node(self, node): + pass + + def remove_root_node(self, index):pass + + def is_root_node(self, node): + return True + + def root_node_index(self, index): + return self.nodes[0] + + @asyncio.coroutine + def discover_network(self): + pass diff --git a/src/cutecoin/tests/stubs/core/registry/__init__.py b/src/cutecoin/tests/stubs/core/registry/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4ab046a19ff274331c3bc1ffd25e16bd19985478 --- /dev/null +++ b/src/cutecoin/tests/stubs/core/registry/__init__.py @@ -0,0 +1,2 @@ +from .identities import IdentitiesRegistry +from .identity import Identity \ No newline at end of file diff --git a/src/cutecoin/tests/stubs/core/registry/identities.py b/src/cutecoin/tests/stubs/core/registry/identities.py new file mode 100644 index 0000000000000000000000000000000000000000..e06ecb447f7cd9574c109773994a81b4ca0b2fd0 --- /dev/null +++ b/src/cutecoin/tests/stubs/core/registry/identities.py @@ -0,0 +1,29 @@ +from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, QTimer +from cutecoin.core.net.api import bma as qtbma +from .identity import Identity + +import asyncio + + +class IdentitiesRegistry: + def __init__(self, instances={}): + pass + + def load_json(self, json_data): + pass + + def jsonify(self): + return {'registry': []} + + def lookup(self, pubkey, community): + identity = Identity.empty(pubkey) + return identity + + @asyncio.coroutine + def future_lookup(self, pubkey, community): + identity = Identity.empty(pubkey) + yield from asyncio.sleep(1) + return identity + + def from_metadata(self, metadata): + return Identity() diff --git a/src/cutecoin/tests/stubs/core/registry/identity.py b/src/cutecoin/tests/stubs/core/registry/identity.py new file mode 100644 index 0000000000000000000000000000000000000000..7c0e3a5c4b796facded48ce0e372bb3ed24341b8 --- /dev/null +++ b/src/cutecoin/tests/stubs/core/registry/identity.py @@ -0,0 +1,114 @@ +""" +Created on 11 févr. 2014 + +@author: inso +""" + +import logging +import time +import asyncio + +from ucoinpy.documents.certification import SelfCertification +from cutecoin.tools.exceptions import Error, NoPeerAvailable,\ + MembershipNotFoundError +from cutecoin.core.net.api import bma as qtbma +from cutecoin.core.net.api.bma import PROTOCOL_VERSION +from PyQt5.QtCore import QObject, pyqtSignal + + +class Identity(QObject): + """ + A person with a uid and a pubkey + """ + FOUND = 1 + NOT_FOUND = 0 + + inner_data_changed = pyqtSignal(str) + + def __init__(self, uid, pubkey, status): + """ + Initializing a person object. + + :param str uid: The person uid, also known as its uid on the network + :param str pubkey: The person pubkey + :param int status: The local status of the identity + """ + super().__init__() + assert(status in (Identity.FOUND, Identity.NOT_FOUND)) + self.uid = uid + self.pubkey = pubkey + self.status = status + + @classmethod + def empty(cls, pubkey): + return cls("", pubkey, Identity.NOT_FOUND) + + @classmethod + def from_metadata(cls, metadata): + return cls(metadata["text"], metadata["id"], Identity.NOT_FOUND) + + @classmethod + def from_json(cls, json_data): + """ + Create a person from json data + + :param dict json_data: The person as a dict in json format + :return: A new person if pubkey wasn't known, else a new person instance. + """ + pubkey = json_data['pubkey'] + uid = json_data['uid'] + status = json_data['status'] + + return cls(uid, pubkey, status) + + @asyncio.coroutine + def selfcert(self, community): + yield from asyncio.sleep(1) + return None + + def get_join_date(self, community): + return time.time() + 100000000 + + def get_expiration_date(self, community): + return time.time() + 1000000000 + + def membership(self, community): + raise MembershipNotFoundError() + + def published_uid(self, community): + return False + + def is_member(self, community): + return False + + def certifiers_of(self, community): + return list() + + def unique_valid_certifiers_of(self, community): + return list() + + def certified_by(self, community): + return list() + + def unique_valid_certified_by(self, community): + return list() + + def membership_expiration_time(self, community): + current_time = time.time() + return current_time+1000000 + + def jsonify(self): + """ + Get the community as dict in json format. + :return: The community as a dict in json format + """ + data = {'uid': self.uid, + 'pubkey': self.pubkey, + 'status': self.status} + return data + + def __str__(self): + status_str = ("NOT_FOUND", "FOUND") + return "{0} - {1} - {2}".format(self.uid, + self.pubkey, + status_str[self.status]) \ No newline at end of file