def update_data(self): old_keys = set(self.db.keys()) new_keys = set() for candidate in CurrentVote.get_candidates(): try: alias = Address.select().where(Address.address == candidate.address).first().alias except AttributeError: alias = 'unknown' if candidate.start_block == 0 and candidate.end_block == MAX_END_BLOCK: vote_count = CurrentVote.select().where( CurrentVote.address == candidate.address, CurrentVote.start_block == 0, CurrentVote.end_block == MAX_END_BLOCK).count() already_voted = CurrentVote.select().where( CurrentVote.address == candidate.address, CurrentVote.start_block == 0, CurrentVote.end_block == MAX_END_BLOCK, CurrentVote.given_from == Profile.get_active().address).count() > 0 if candidate.perm_type == Permission.ADMIN: required = math.ceil(Permission.num_guardians() * ADMIN_CONSENUS_ADMIN) else: required = math.ceil(Permission.num_guardians() * ADMIN_CONSENUS_MINE) key = (candidate.address, candidate.perm_type) new_keys.add(key) self.db[key] = [alias, candidate.address.address, candidate.perm_type, "{} of {}".format(vote_count, required), already_voted] deleted_keys = old_keys - new_keys for key in deleted_keys: del self.db[key]
def after_update(mapper, connection, alias): from app.models import Profile with profile_session_scope() as session: profile = Profile.get_active(session) if alias.address == profile.address: profile.alias = alias.alias signals.alias_list_changed.emit()
def __init__(self, parent): super().__init__(parent) with profile_session_scope() as session: self.profile = Profile.get_active(session) signals.profile_changed.connect(self.on_profile_changed) self.data = [] self.header = ["Time", "Hash", "Comment"]
def get_active_rpc_client(override=None): from app.models import Profile from app.models.db import profile_session_scope with profile_session_scope() as session: profile = override or Profile.get_active(session) assert isinstance(profile, Profile) return RpcClient(profile.rpc_host, profile.rpc_port, profile.rpc_user, profile.rpc_password, profile.rpc_use_ssl)
def listpermissions(self): own_votes = CurrentVote.select().where( CurrentVote.start_block == CurrentVote.end_block == 0, CurrentVote.given_from == Profile.get_active().address) for vote in own_votes: self.already_voted.append({ 'address': vote.address.address, 'perm_type': vote.perm_type })
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setupUi(self) from app.models.db import profile_session_scope with profile_session_scope() as session: self.profile = Profile.get_active(session) self.on_profile_changed(self.profile) signals.profile_changed.connect(self.on_profile_changed)
def getinfo(): """Update latest wallet balance on current profile""" client = get_active_rpc_client() profile = Profile.get_active() result = client.getinfo()['result'] if result['balance'] != profile.balance: profile.balance = result['balance'] profile.save()
def getruntimeparams(): """Update wallet main address on current profile""" client = get_active_rpc_client() with profile_session_scope() as session: profile = Profile.get_active(session) params = client.getruntimeparams() if params.handshakelocal != profile.address: profile.address = params.handshakelocal
def init_node_data_dir(): from app.models import Profile profile = Profile.get_active() ndd = os.path.join(app.DATA_DIR, 'node_' + profile.name) if profile.manage_node: if not os.path.exists(ndd): log.debug('create node data dir {}'.format(ndd)) os.makedirs(ndd, exist_ok=True) return ndd
def getruntimeparams(): """Update wallet main address on current profile""" client = get_active_rpc_client() profile = Profile.get_active() result = client.getruntimeparams()['result'] if result['handshakelocal'] != profile.address: profile.address = result['handshakelocal'] profile.save()
def already_granted(data_db): from app.models import Permission, Profile from app.models.db import profile_session_scope with profile_session_scope() as session: profile = Profile.get_active(session) return data_db.query( PendingVote.address_to, PendingVote.perm_type).filter( (PendingVote.address_from == profile.address) & (PendingVote.start_block == 0) & (PendingVote.end_block == Permission.MAX_END_BLOCK)).all()
def already_revoked(data_db, perm_type): from app.models import Profile from app.models.db import profile_session_scope with profile_session_scope() as session: profile = Profile.get_active(session) return data_db.query( PendingVote.address_to, PendingVote.perm_type).filter( (PendingVote.address_from == profile.address) & (PendingVote.start_block == 0) & (PendingVote.end_block == 0) & (PendingVote.perm_type == perm_type)).all()
def __init__(self, *args, **kwargs): self.perm_type = kwargs.pop('perm_type') QTableView.__init__(self, *args, **kwargs) self.setMinimumWidth(400) try: self.profile = self.parent().profile except AttributeError: # In case of standalone usage with profile_session_scope() as session: self.profile = Profile.get_active(session) signals.is_admin_changed.connect(self.is_admin_changed) # self.pressed.connect(self.on_cell_clicked) self.table_model = PermissionModel(self, perm_type=self.perm_type) self.setModel(self.table_model) font = QFont() font.setFamily("Roboto Light") font.setPointSize(10) self.setColumnHidden(5, not self.profile.is_admin) header = self.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.Interactive) header.setSectionResizeMode(1, QHeaderView.Stretch) header.setSectionResizeMode(2, QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QHeaderView.ResizeToContents) header.setSectionResizeMode(4, QHeaderView.ResizeToContents) header.setSectionResizeMode(5, QHeaderView.ResizeToContents) header.setFont(font) # Row height self.verticalHeader().setVisible(False) self.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) self.verticalHeader().setDefaultSectionSize(40) self.setFont(font) self.setAlternatingRowColors(True) self.setSelectionMode(QAbstractItemView.SingleSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setShowGrid(False) # TODO implement comminity tables sorting self.setSortingEnabled(False) self.setCornerButtonEnabled(True) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.openCustomMenu) self.balance_is_zero = True self.create_table_buttons(self.balance_is_zero) signals.on_balance_status_changed.connect( self.on_balance_status_changed)
def start(self, *args, **kwargs): """Start node with active profile settings. :param str initprivkey: Optional WIF encoded private key for first time init. """ initprivkey = kwargs.pop('initprivkey', None) try: self.profile = self.parent().profile except AttributeError: # In case of standalone usage from app.models.db import profile_session_scope with profile_session_scope() as session: self.profile = Profile.get_active(session) assert isinstance(self.profile, Profile) assert self.profile.manage_node, "active profile does not want to manage node" if self.state() == self.NotRunning: node_path = os.path.join(app.APP_DIR, 'app/bin/multichaind') if self.reindex_required: log.debug('starting node at: {} with -reindex=1'.format(node_path)) else: log.debug('starting node at: {}'.format(node_path)) # TODO only launch full bootstrap ip in first launch launch_args = [ app.NODE_BOOTSTRAP, '-server=1', # '-daemon', '-autosubscribe=assets,streams', '-autocombineminconf=4294967294', # '-maxshowndata=32', # '-printtoconsole', '-reindex=' + ("1" if self.reindex_required else "0"), # '-shortoutput', '-rpcuser={}'.format(self.profile.rpc_user), '-rpcpassword={}'.format(self.profile.rpc_password), '-rpcbind={}'.format(self.profile.rpc_host), '-rpcallowip={}'.format(self.profile.rpc_host), '-rpcport={}'.format(self.profile.rpc_port), '-datadir={}'.format(init_node_data_dir()), ] if initprivkey is not None: launch_args.append('-initprivkey={}'.format(initprivkey)) super().start(node_path, launch_args, QIODevice.ReadOnly) self.reindex_required = False else: log.debug('node already started - state: {}'.format(self.state()))
def getinfo(): """Update latest wallet balance on current profile""" client = get_active_rpc_client() with profile_session_scope() as session: profile = Profile.get_active(session) try: info = client.getinfo() signals.getinfo.emit(info) new_balance = Decimal(str(info.balance)) if new_balance != profile.balance: profile.balance = Decimal(info.balance) except Exception as e: log.debug(e)
def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) from app.models.db import profile_session_scope with profile_session_scope() as session: self.profile = Profile.get_active(session) self.on_profile_changed(self.profile) self.edit_alias.setText(self.profile.alias) self.edit_alias.textChanged.connect(self.on_alias_changed) signals.profile_changed.connect(self.on_profile_changed) self.adjustSize() self.buttonBox.button(QDialogButtonBox.Save).clicked.connect(self.save) self.buttonBox.button(QDialogButtonBox.Save).setDisabled(True)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setupUi(self) self.profile = Profile.get_active() self.on_profile_changed(self.profile) signals.profile_changed.connect(self.on_profile_changed) self.btn_wallet_alias_edit_save.hide() self.btn_wallet_alias_edit_cancel.hide() self.edit_alias.hide() self.btn_wallet_alias_edit_start.clicked.connect(self.start_edit_alias) self.btn_wallet_alias_edit_cancel.clicked.connect(self.stop_edit_alias) self.btn_wallet_alias_edit_save.clicked.connect(self.save_alias) self.edit_alias.returnPressed.connect(self.save_alias) self.lbl_wallet_address.setText(self.profile.address)
def run(self): synced_blockhash = '' with profile_session_scope() as profile_session: profile = Profile.get_active(profile_session) with data_session_scope() as data_session: profile.alias = Alias.get_alias_by_address(data_session, profile.address) while True: log.debug('check for new blocks') try: # This triggers Network Info widget update that we always want blockchain_info = sync.getblockchaininfo() # The node is downloading blocks if it has more headers than blocks if blockchain_info.blocks != blockchain_info.headers or blockchain_info.reindex: log.debug('blockchain syncing - skip expensive rpc calls') self.sleep(self.UPDATE_INTERVALL) continue node_block_hash = blockchain_info.bestblockhash except Exception as e: log.exception('cannot get bestblock via rpc: %s' % e) self.sleep(self.UPDATE_INTERVALL) continue sync.getinfo() if node_block_hash != synced_blockhash: log.debug('starting full sync round') for sync_func in self.sync_funcs: try: log.debug('updating %s' % sync_func.__name__) sync_func() except Exception as e: log.exception(e) synced_blockhash = node_block_hash signals.sync_cycle_finished.emit() self.sleep(self.UPDATE_INTERVALL)
def __init__(self, parent=None): super().__init__(parent) self.table_model = CandidateModel(self) self.setModel(self.table_model) self.setMinimumWidth(400) font = QFont() font.setFamily("Roboto Light") font.setPointSize(10) header = self.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.ResizeToContents) header.setSectionResizeMode(1, QHeaderView.Stretch) header.setSectionResizeMode(2, QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QHeaderView.ResizeToContents) header.setSectionResizeMode(4, QHeaderView.ResizeToContents) header.setFont(font) # Row height self.verticalHeader().setVisible(False) self.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) self.verticalHeader().setDefaultSectionSize(40) with profile_session_scope() as session: self.setColumnHidden(4, not Profile.get_active(session).is_admin) self.setFont(font) self.setAlternatingRowColors(True) self.setSelectionMode(QAbstractItemView.SingleSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setShowGrid(False) # TODO implement candidates table sorting self.setSortingEnabled(False) self.setCornerButtonEnabled(True) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.openCustomMenu) self.create_table_buttons() signals.is_admin_changed.connect(self.is_admin_changed)
def __init__(self, parent=None): super().__init__(parent) self.table_model = CandidateModel(self) self.setModel(self.table_model) self.setMinimumWidth(400) font = QtGui.QFont() font.setFamily("Roboto Light") font.setPointSize(10) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setSelectionMode(QAbstractItemView.SingleSelection) header = self.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.ResizeToContents) header.setSectionResizeMode(1, QHeaderView.Stretch) header.setSectionResizeMode(2, QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QHeaderView.ResizeToContents) header.setSectionResizeMode(4, QHeaderView.ResizeToContents) header.setFont(font) # Row height self.verticalHeader().setVisible(False) self.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) self.verticalHeader().setDefaultSectionSize(40) header.setSectionResizeMode(0, QHeaderView.ResizeToContents) self.setColumnHidden(4, not Profile.get_active().is_admin) self.setFont(font) self.setAlternatingRowColors(True) self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.setShowGrid(False) # TODO implement candidates table sorting self.setSortingEnabled(False) self.setCornerButtonEnabled(True) self.create_table_buttons()
def get_active_rpc_client(override=None): from app.models import Profile profile = override or Profile.get_active() assert isinstance(profile, Profile) return RpcClient(profile.rpc_host, profile.rpc_port, profile.rpc_user, profile.rpc_password, profile.rpc_use_ssl)
def __init__(self, **kwargs): super().__init__(**kwargs) # Instantiate workers self.updater = QApplication.instance().updater self.node = QApplication.instance().node self.data_dir = helpers.init_data_dir() self.profile_db = models.init_profile_db() self.node_data_dir = helpers.init_node_data_dir() self.data_db = models.init_data_db() self.profile = Profile.get_active() # Setup Widgets self.setupUi(self) self.on_profile_changed(self.profile) signals.profile_changed.connect(self.on_profile_changed) # Init Navigation self.btn_grp_nav.setId(self.btn_nav_wallet, 0) self.btn_grp_nav.setId(self.btn_nav_timestamp, 1) self.btn_grp_nav.setId(self.btn_nav_community, 2) self.btn_grp_nav.setId(self.btn_nav_settings, 3) self.btn_nav_wallet.setChecked(True) self.wgt_content.setCurrentIndex(0) # Patch custom widgets self.tab_widget_cummunity.setStyleSheet( 'QPushButton {padding: 5 12 5 12; font: 10pt "Roboto Light"}') self.gbox_wallet_transactions.setParent(None) self.gbox_wallet_send.setParent(None) wallet_send = WalletSend(self) self.lout_page_wallet_v.addWidget(wallet_send) wallet_history = WalletHistory(self) self.lout_page_wallet_v.addWidget(wallet_history) widget_timestamp = WidgetTimestamping(self) self.lout_page_timestamp_v.addWidget(widget_timestamp) self.table_validators.setParent(None) table_validators = CommunityTableView(self, perm_type=Permission.MINE) self.tab_validators.layout().insertWidget(0, table_validators) self.table_guardians.setParent(None) table_guardians = CommunityTableView(self, perm_type=Permission.ADMIN) self.tab_guardians.layout().insertWidget(0, table_guardians) self.table_candidates.setParent(None) table_candidates = CandidateTableView(self) self.tab_candidates.layout().insertWidget(0, table_candidates) # Dialog Button hookups invite_dialog = InviteDialog(self) self.button_invite_canditate.clicked.connect(invite_dialog.exec) apply_dialog = ApplyDialog(self) self.button_apply_guardian.clicked.connect(apply_dialog.exec) self.button_apply_validator.clicked.connect(apply_dialog.exec) # Settings self.check_box_exit_on_close.setChecked(self.profile.exit_on_close) self.check_box_exit_on_close.stateChanged['int'].connect( self.setting_changed_exit_on_close) self.check_manage_node.setChecked(self.profile.manage_node) self.check_manage_node.stateChanged['int'].connect( self.setting_changed_manage_node) # Connections signals.getblockchaininfo.connect(self.getblockchaininfo) signals.listpermissions.connect(self.listpermissions) signals.node_started.connect(self.node_started) if self.profile.manage_node: # Todo check for existing node process self.node.start() else: # No managed node to wait for... start updater self.updater.start() self.show()
def listpermissions(): client = get_active_rpc_client() node_height = client.getblockcount()['result'] perms = client.listpermissions() if not perms: log.warning('no permissions from api') return new_perms, new_votes = False, False Permission.delete().execute() CurrentVote.delete().execute() admin_addresses = set() miner_addresses = set() with data_db.atomic(): profile = Profile.get_active() for perm in perms['result']: perm_type = perm['type'] perm_start = perm['startblock'] perm_end = perm['endblock'] if perm_type not in Permission.PERM_TYPES: continue if perm_type == Permission.ADMIN and perm_start < node_height < perm_end: admin_addresses.add(perm['address']) if perm_type == Permission.MINE and perm_start < node_height < perm_end: miner_addresses.add(perm['address']) addr_obj, created = Address.get_or_create(address=perm['address']) for vote in perm['pending']: # If candidate has already the permission continue. if vote['startblock'] == perm['startblock'] and vote[ 'endblock'] == perm['endblock']: continue start_block = vote['startblock'] end_block = vote['endblock'] # new stuff start for admin in vote['admins']: admin_obj, created = Address.get_or_create(address=admin) vote_obj, created = CurrentVote.get_or_create( address=addr_obj, perm_type=perm_type, start_block=start_block, end_block=end_block, given_from=admin_obj) vote_obj.set_vote_type() # new stuff end approbations = len(vote['admins']) # TODO: Fix: current time of syncing is not the time of first_vote! start_block = perm['startblock'] end_block = perm['endblock'] # TODO Why get_or_create ... we just deleted all Permission objects perm_obj, created = Permission.get_or_create( address=addr_obj, perm_type=perm_type, defaults=dict(start_block=start_block, end_block=end_block)) if created: new_perms = True else: perm_obj.save() new_is_admin = profile.address in admin_addresses if profile.is_admin != new_is_admin: profile.is_admin = new_is_admin new_is_miner = profile.address in miner_addresses if profile.is_miner != new_is_miner: profile.is_miner = new_is_miner if profile.dirty_fields: profile.save() # Todo: maybe only trigger table updates on actual change? signals.listpermissions.emit() # triggers community tab updates signals.votes_changed.emit() # triggers community tab updates return {'new_perms': new_perms, 'new_votes': new_votes}
def liststreamitems_alias(): """ Sample stream item (none verbose): { 'blocktime': 1505905511, 'confirmations': 28948, 'data': '4d696e65722031', 'key': 'Miner_1', 'publishers': ['1899xJpqZN3kMQdpvTxESWqykxgFJwRddCE4Tr'], 'txid': 'caa1155e719803b9f39096860519a5e08e78214245ae9822beeea2b37a656178' } """ client = get_active_rpc_client() # TODO read and process only fresh stream data by storing a state cursor between runs # TODO read stream items 100 at a time stream_items = client.liststreamitems(Stream.alias.name, count=100000) if not stream_items['result']: log.debug('got no items from stream alias') return 0 by_addr = {} # address -> alias reseved = set() # reserved aliases # aggregate the final state of address to alias mappings from stream for item in stream_items['result']: confirmations = item['confirmations'] alias = item['key'] address = item['publishers'][0] data = item['data'] num_publishers = len(item['publishers']) # Sanity checks if confirmations < 1: log.debug('ignore alias - 0 confirmations for %s -> %s' % (address, alias)) continue if data: log.debug('ignore alias - alias item "%s" with data "%s..."' % (alias, data[:8])) continue if not is_valid_username(alias): log.debug('ignore alias - alias does not match our regex: %s' % alias) continue if num_publishers != 1: log.debug('ignore alias - alias has multiple publishers: %s' % alias) continue if alias in reseved: log.debug('ignore alias - alias "%s" already reserved by "%s"' % (alias, address)) continue is_new_address = address not in by_addr if is_new_address: by_addr[address] = alias reseved.add(alias) continue is_alias_change = by_addr[address] != alias if is_alias_change: log.debug('change alias of %s from %s to %s' % (address, by_addr[address], alias)) # reserve new name reseved.add(alias) # release old name reseved.remove(by_addr[address]) # set new name by_addr[address] = alias continue # update database profile = Profile.get_active() new_main_alias = by_addr.get(profile.address) if new_main_alias and profile.alias != new_main_alias: log.debug('sync found new alias. profile.alias from %s to %s' % (profile.alias, new_main_alias)) profile.alias = new_main_alias profile.save() with data_db.atomic(): old_addrs = set( Address.select(Address.address, Address.alias).tuples()) new_addrs = set(by_addr.items()) # set of elements that are only in new_addr but not in old_addr changed_addrs = new_addrs - old_addrs new_rows = [dict(address=i[0], alias=i[1]) for i in changed_addrs] if new_rows: log.debug('adding new aliases %s' % changed_addrs) # insert rows 100 at a time. for idx in range(0, len(new_rows), 100): Address.insert_many(new_rows[idx:idx + 100]).upsert(True).execute() return len(changed_addrs)
def process_permissions(): # todo: check if we have new perms / votes client = get_active_rpc_client() try: perms = client.listpermissions("*", "*", True) except Exception as e: log.debug(e) return with data_session_scope() as session: session.query(Permission).delete() session.query(PendingVote).delete() with data_session_scope() as session: for perm in perms: perm_type = perm['type'] perm_start = perm['startblock'] perm_end = perm['endblock'] address = perm['address'] Address.create_if_not_exists(session, address) if perm_type not in [ enums.ISSUE, enums.CREATE, enums.MINE, enums.ADMIN ]: continue perm_obj = Permission(address=address, perm_type=perm_type, start_block=perm_start, end_block=perm_end) session.add(perm_obj) for vote in perm['pending']: start_block = vote['startblock'] end_block = vote['endblock'] # If candidate has already the permission continue. if start_block == perm['startblock'] and end_block == perm[ 'endblock']: continue for admin in vote['admins']: Address.create_if_not_exists(session, admin) vote_obj = PendingVote(address_from=admin, address_to=address, perm_type=perm_type, start_block=start_block, end_block=end_block) session.add(vote_obj) signals.votes_changed.emit() with profile_session_scope() as profile_db: profile = Profile.get_active(profile_db) with data_session_scope() as data_db: is_admin, is_miner = Permission.get_permissions_for_address( data_db, profile.address) if is_admin != profile.is_admin: profile.is_admin = is_admin signals.is_admin_changed.emit(is_admin) if is_miner != profile.is_miner: profile.is_miner = is_miner signals.is_miner_changed.emit(is_miner) signals.permissions_changed.emit()
return self._call('validateaddress', address) #################### # Internal helpers # #################### @property def _url(self) -> str: url = '{}:{}@{}:{}'.format(self.user, self.pwd, self.host, self.port) return 'https://' + url if self.use_ssl else 'http://' + url def _call(self, method, *args) -> Optional[requests.Response]: args = [arg for arg in args if arg is not None] payload = {"id": method, "method": method, "params": args} serialized = json.dumps(payload, cls=DecimalEncoder) response = requests.post(self._url, data=serialized, verify=False) return response.json(parse_float=Decimal) if __name__ == '__main__': from pprint import pprint import app from app.models import Profile app.init() print(Profile.get_active()) client = get_active_rpc_client() # pprint(client.getmultibalances('*', '*', 1, False, False)) # pprint(client.getmultibalances('*', '*', 0, False, True)) print(client.getbestblockhash()) pprint(client.listwallettransactions(1))
from app.models import Profile from app.models.db import profile_session_scope with profile_session_scope() as session: profile = override or Profile.get_active(session) assert isinstance(profile, Profile) return RpcClient(profile.rpc_host, profile.rpc_port, profile.rpc_user, profile.rpc_password, profile.rpc_use_ssl) class DecimalEncoder(json.JSONEncoder): """Custom json encoder that supports Decimal""" def default(self, o): if isinstance(o, decimal.Decimal): return float(o) return super(DecimalEncoder, self).default(o) if __name__ == '__main__': from pprint import pprint import app from app.models import Profile from app.models.db import profile_session_scope app.init() with profile_session_scope() as session: print(Profile.get_active(session)) client = get_active_rpc_client() # pprint(client.getmultibalances('*', '*', 1, False, False)) # pprint(client.getmultibalances('*', '*', 0, False, True)) print(client.getbestblockhash()) pprint(client.listwallettransactions(1))
def __init__(self, **kwargs): super().__init__(**kwargs) # Instantiate workers self.updater = QApplication.instance().updater self.node = QApplication.instance().node self.data_dir = helpers.init_data_dir() self.node_data_dir = helpers.init_node_data_dir() with profile_session_scope() as session: self.profile = Profile.get_active(session) # Setup Widgets self.setupUi(self) # Hide information widget font = QFont('Roboto Light', 10) self.label_info_text.setFont(font) self.btn_close_info.setFont(font) font.setUnderline(True) self.btn_info_action.setFont(font) self.widget_information.setHidden(True) self.btn_close_info.clicked.connect(self.hide_information) signals.new_unconfirmed.connect(self.show_transaction_info) self.information_type = None self.on_profile_changed(self.profile) signals.profile_changed.connect(self.on_profile_changed) self.permissions_changed() signals.permissions_changed.connect(self.permissions_changed) # Init Navigation self.btn_grp_nav.setId(self.btn_nav_wallet, 0) self.btn_grp_nav.setId(self.btn_nav_iscc, 1) self.btn_grp_nav.setId(self.btn_nav_timestamp, 2) self.btn_grp_nav.setId(self.btn_nav_token, 3) self.btn_grp_nav.setId(self.btn_nav_community, 4) self.btn_grp_nav.setId(self.btn_nav_settings, 5) self.btn_nav_wallet.setChecked(True) self.wgt_content.setCurrentIndex(0) # Patch custom widgets self.tab_widget_cummunity.setStyleSheet( 'QPushButton {padding: 5 12 5 12; font: 10pt "Roboto Light"}') self.gbox_wallet_transactions.setParent(None) self.gbox_wallet_send.setParent(None) wallet_send = WalletSend(self) self.lout_page_wallet_v.addWidget(wallet_send) wallet_history = WalletHistory(self) self.lout_page_wallet_v.addWidget(wallet_history) widget_iscc = WidgetISCC(self) self.lout_page_iscc_v.addWidget(widget_iscc) widget_timestamp = WidgetTimestamping(self) self.lout_page_timestamp_v.addWidget(widget_timestamp) widget_token = WidgetToken(self) self.lout_page_token_v.addWidget(widget_token) self.table_validators.setParent(None) table_validators = CommunityTableView(self, perm_type=enums.MINE) self.tab_validators.layout().insertWidget(0, table_validators) self.table_guardians.setParent(None) table_guardians = CommunityTableView(self, perm_type=enums.ADMIN) self.tab_guardians.layout().insertWidget(0, table_guardians) self.table_candidates.setParent(None) table_candidates = CandidateTableView(self) self.tab_candidates.layout().insertWidget(0, table_candidates) # Statusbar self.label_statusbar = QtWidgets.QLabel('') self.statusbar.addPermanentWidget(self.label_statusbar) # Dialog Button hookups invite_dialog = InviteDialog(self) self.button_invite_canditate.clicked.connect(invite_dialog.exec) apply_dialog = ApplyDialog(self) self.button_apply_guardian.clicked.connect(apply_dialog.exec) self.button_apply_validator.clicked.connect(apply_dialog.exec) # Settings self.check_box_exit_on_close.setChecked(self.profile.exit_on_close) self.check_box_exit_on_close.stateChanged['int'].connect( self.setting_changed_exit_on_close) self.check_manage_node.setChecked(self.profile.manage_node) self.check_manage_node.stateChanged['int'].connect( self.setting_changed_manage_node) self.btn_alias_change.clicked.connect(self.on_change_alias) # Connections signals.getinfo.connect(self.getinfo) signals.getblockchaininfo.connect(self.getblockchaininfo) signals.node_started.connect(self.node_started) signals.rpc_error.connect(self.rpc_error) signals.blockschanged.connect(self.getdatabaseinfo) signals.on_balance_status_changed.connect( self.on_balance_status_changed) with data_session_scope() as session: from app.models import Block self.progress_bar_database_info.setValue( session.query(Block).count()) if self.profile.manage_node: # Todo check for existing node process self.node.start() else: # No managed node to wait for... start updater self.updater.start() self.show()