def update_data(self, conflicts, iscc): self.beginResetModel() with data_session_scope() as session: self.aliases = Alias.get_aliases(session) self.conflicts = conflicts self.iscc = iscc.split('-') self.endResetModel()
def edit_completer(self): if self.edit_completer_update_enabled == False: return address_list = [] with data_session_scope() as session: for address, alias in Alias.get_aliases(session).items(): address_list.append("{} ({})".format(alias, address)) for address in session.query(Address).all(): address_list.append(address.address) completer = QCompleter(address_list, self.edit_resale_to) completer_delegate = QStyledItemDelegate(completer) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.popup().setItemDelegate(completer_delegate) completer.popup().setStyleSheet(""" QAbstractItemView { font: 10pt "Roboto Light"; border: 1px solid #41ADFF; border-top: 0px; background-color: #FFF79A; border-radius: 2px; } QAbstractItemView::item { margin-top: 3px; } """) self.edit_resale_to.setCompleter(completer)
def show_conflicts(self): self.widget_generated_iscc.setHidden(False) self.iscc = self.meta_id + '-' + self.content_id + '-' + self.data_id + '-' + self.instance_id self.label_iscc.setText(self.iscc) img = qrcode.make(self.meta_id + self.content_id + self.data_id + self.instance_id) pixmap = QPixmap.fromImage(ImageQt(img)) pixmap = pixmap.scaledToWidth(128) pixmap = pixmap.scaledToHeight(128) self.label_qr.setPixmap(pixmap) with data_session_scope() as session: if not self.balance_is_zero: self.btn_register.setDisabled( ISCC.already_exists(session, self.meta_id, self.content_id, self.data_id, self.instance_id)) conflicts = ISCC.get_conflicts(session, self.meta_id, self.content_id, self.data_id, self.instance_id) if len(conflicts) > 0: self.label_title_conflicts.setHidden(False) self.table_conflicts.setHidden(False) self.table_conflicts.model().update_data(conflicts, self.iscc) if ISCC.conflict_in_meta(session, self.meta_id): self.widget_extra.setHidden(False) self.conflict_in_meta = True else: self.label_title_conflicts.setHidden(True) self.table_conflicts.setHidden(True) self.label_title_extra.setHidden(not self.conflict_in_meta)
def run(self): with data_session_scope() as session: for reward in MiningReward.mined_last_24h(session): self.parent().last_24_h_mine_count[ reward.address] = reward.count for reward in MiningReward.last_mined(session): self.parent().last_mined[reward.address] = reward.last_mined for vote in Vote.voted_last_24h(session): self.parent().last_24_h_vote_count[ vote.from_address] = vote.count for vote in Vote.last_voted(session): self.parent().last_voted[vote.from_address] = vote.last_voted for pending_vote in PendingVote.num_revokes( session, self.parent()._perm_type): self.parent().count_revokes[ pending_vote.address_to] = pending_vote.count self.parent().num_guardians = Permission.num_guardians(session) if self.parent()._perm_type == enums.MINE: self.parent()._data = list(Permission.validators(session)) elif self.parent()._perm_type == enums.ADMIN: self.parent()._data = list(Permission.guardians(session)) self.parent()._alias_list = Alias.get_aliases(session) self.parent().already_revoked = PendingVote.already_revoked( session, self.parent()._perm_type)
def run(self): with data_session_scope() as session: self.parent().candidates = PendingVote.get_candidates(session) self.parent().aliases = Alias.get_aliases(session) self.parent().already_granted = PendingVote.already_granted( session) self.parent().num_guardians = Permission.num_guardians(session)
def update_data(self, search_term=None): self.beginResetModel() with data_session_scope() as session: self.aliases = Alias.get_aliases(session) if search_term: self.isccs = ISCC.filter_iscc(session, search_term) else: self.isccs = ISCC.get_all_iscc(session) self.endResetModel()
def permissions_changed(self): with data_session_scope() as session: num_validators = Permission.num_validators(session) self.lbl_num_validators.setText(str(num_validators)) num_guardians = Permission.num_guardians(session) self.lbl_num_guardians.setText(str(num_guardians)) num_candidates = PendingVote.num_candidates(session) self.lbl_num_candidates.setText(str(num_candidates))
def run(self): with data_session_scope() as session: self.aliases = Alias.get_aliases(session) if self.search_term: self.isccs = ISCC.filter_iscc(session, self.search_term, page=0, page_size=1000) else: self.isccs = ISCC.get_all_iscc_paged(session, page=0, page_size=1000)
def page7_sync_initialize_page(self): if self._mnemonic and not self._address: self._address = main_address_from_mnemonic(self._mnemonic) self.label_address.setText(self._address) img = ImageQt(qrcode.make(self._address, box_size=3)) self.label_qr_code.setPixmap(QPixmap.fromImage(img)) if not exists(app.DATA_DIR): self.log('Creating data dir at: %s' % app.DATA_DIR) init_data_dir() self.log('Initialize profile database at: %s' % app.PROFILE_DB_FILEPATH) with profile_session_scope() as session: if self._manage_node: Profile.create_default_profile(session) elif self._connection_tested: session.merge( Profile( name=self.edit_rpc_host.text(), rpc_host=self.edit_rpc_host.text(), rpc_port=self.edit_rpc_port.text(), rpc_user=self.edit_rpc_user.text(), rpc_password=self.edit_rpc_password.text(), rpc_use_ssl=self.cbox_use_ssl.isChecked(), manage_node=False, exit_on_close=True, active=True, )) self.log('Initialize node-sync database') init_data_db() # This fixes our problem with the locked database # We have no idea why, but we shouldn't delete this code until we have a better solution with data_session_scope() as session: session.query('DELETE FROM mining_reward') if self._manage_node: self.node.start(initprivkey=main_wif_from_mnemonic(self._mnemonic)) else: self._database_sync = True if not self.updater.isRunning(): self.updater.start()
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 on_alias_changed(self, text): from app.models.db import data_session_scope text = text.lower() self.edit_alias.setText(text.lower()) is_valid = False with data_session_scope() as session: if not username_regex.match(text): self.lbl_error.setText( '- It may contain alphanumerical characters and "_", ".", "-"\n' '- It must not start or end with "-" or "."\n' '- It must be between 3 and 30 characters\n' '- It must not have consecutive "_", ".", "-" characters') elif text != self.profile.alias and Alias.alias_in_use( session, text): self.lbl_error.setText('Username already in use.') else: self.lbl_error.setText("") self.adjustSize() is_valid = True self.buttonBox.button(QDialogButtonBox.Save).setDisabled(not is_valid)
def get_timestamps(self): status_text = 'Checking timpestamp records for %s' % self.current_fingerprint self.label_processing_status.setText(status_text) # Set progress to indicate processing of undefined duration self.progress_bar.setValue(0) self.progress_bar.setMaximum(0) # Check for existing timestamps: try: from app.models.db import data_session_scope with data_session_scope() as session: timestamps = Timestamp.get_timestamps_for_hash( session, self.current_fingerprint) except RpcResponseError as e: QMessageBox.warning(self, 'Error reading timestamp stream', str(e)) timestamps = None if timestamps: self.label_verification.setText( 'Found existing timestamps for document:') self.gbox_verification.setEnabled(True) self.table_verification.setRowCount(len(timestamps)) for row_id, row in enumerate(timestamps): for col_id, col in enumerate(row): if col_id == 0: content = QTableWidgetItem('%s' % col) else: content = QTableWidgetItem(col) self.table_verification.setItem(row_id, col_id, content) else: self.table_verification.hide() self.label_verification.setText( 'No previous timestamps found for this document.') self.progress_bar.hide() self.label_processing_status.setText('Fingerprint: %s' % self.current_fingerprint) self.gbox_timestamp.setEnabled(True)
def process_blocks(): """ Find last valid Block, delete every Block above in DB and get all Blocks above from Node. Process through new Blocks: Add them to DB. Process through all transactions in block. """ client = get_active_rpc_client() ### get last valid block in DB ### last_valid_height = -1 last_block_is_valid = False with data_session_scope() as session: while not last_block_is_valid: latest_block = session.query(Block).order_by( Block.height.desc()).first() if not latest_block: break try: block_from_chain = client.getblock('{}'.format( latest_block.height)) except Exception as e: log.debug(e) return if latest_block.hash == unhexlify(block_from_chain['hash']): last_block_is_valid = True last_valid_height = latest_block.height else: session.delete(latest_block) blockchain_params = client.getblockchainparams() pubkeyhash_version = blockchain_params['address-pubkeyhash-version'] checksum_value = blockchain_params['address-checksum-value'] block_count_node = client.getblockcount() with data_session_scope() as session: # height is 0 indexed, for batch in batchwise(range(last_valid_height + 1, block_count_node), 100): try: with data_session_scope() as session: signals.batch_gui_updates_allowed.emit(False) new_blocks = client.listblocks(batch) first = True for block in new_blocks: # Allow emitting certain GUI update signals for the first block in the batch # or if we're close to the current node block count if first or block_count_node - block['height'] < 16: signals.batch_gui_updates_allowed.emit(True) block_obj = Block( hash=unhexlify(block['hash']), height=block['height'], mining_time=datetime.fromtimestamp(block['time']), ) session.add(block_obj) session.add( MiningReward(block=unhexlify(block['hash']), address=block['miner'])) Address.create_if_not_exists(session, block['miner']) if block['txcount'] > 1: process_transactions(session, block['height'], pubkeyhash_version, checksum_value, client) signals.database_blocks_updated.emit( block['height'], block_count_node) signals.blockschanged.emit( session.query(Block).count()) # Skip certain GUI update signals for the remainder of the batch if first: signals.batch_gui_updates_allowed.emit(False) first = False except Exception as e: signals.batch_gui_updates_allowed.emit(True) log.debug('Exception in process_blocks:') log.debug(e) return signals.batch_gui_updates_allowed.emit(True) if last_valid_height != block_count_node: # permissions and votes tables are completely refreshed after each new block process_permissions()
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()
def load_data(self): from app.models.db import data_session_scope with data_session_scope() as session: return Timestamp.get_timestamps_for_address( session, self.profile.address)
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()
def alias_list_changed(self): self.beginResetModel() with data_session_scope() as session: self._alias_list = Alias.get_aliases(session) self.endResetModel()
def update_num_guardians(self): with data_session_scope() as session: self.num_guardians = Permission.num_guardians(session)