def data(self, index, role): source_index = self.mapToSource(index) if source_index.isValid(): source_data = self.sourceModel().data(source_index, role) publication_col = CertifiersTableModel.columns_ids.index('publication') publication_index = self.sourceModel().index(source_index.row(), publication_col) expiration_col = CertifiersTableModel.columns_ids.index('expiration') expiration_index = self.sourceModel().index(source_index.row(), expiration_col) written_col = CertifiersTableModel.columns_ids.index('written') written_index = self.sourceModel().index(source_index.row(), written_col) publication_data = self.sourceModel().data(publication_index, Qt.DisplayRole) expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole) written_data = self.sourceModel().data(written_index, Qt.DisplayRole) current_time = QDateTime().currentDateTime().toMSecsSinceEpoch() warning_expiration_time = int((expiration_data - publication_data) / 3) #logging.debug("{0} > {1}".format(current_time, expiration_data)) if role == Qt.DisplayRole: if source_index.column() == CertifiersTableModel.columns_ids.index('expiration'): if source_data: ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data) return QLocale.toString( QLocale(), QDateTime.fromTime_t(ts), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) + " BAT" else: return "" if source_index.column() == CertifiersTableModel.columns_ids.index('publication'): if source_data: ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data) return QLocale.toString( QLocale(), QDateTime.fromTime_t(ts), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) + " BAT" else: return "" if source_index.column() == CertifiersTableModel.columns_ids.index('pubkey'): return source_data if role == Qt.FontRole: font = QFont() if not written_data: font.setItalic(True) return font if role == Qt.ForegroundRole: if current_time > ((expiration_data*1000) - (warning_expiration_time*1000)): return QColor("darkorange").darker(120) return source_data
def data(self, index, role): source_index = self.mapToSource(index) source_data = self.sourceModel().data(source_index, role) expiration_col = self.sourceModel().columns_ids.index('expiration') expiration_index = self.sourceModel().index(source_index.row(), expiration_col) expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole) current_time = QDateTime().currentDateTime().toMSecsSinceEpoch() sig_validity = self.community.parameters['sigValidity'] warning_expiration_time = int(sig_validity / 3) #logging.debug("{0} > {1}".format(current_time, expiration_data)) if expiration_data is not None: will_expire_soon = (current_time > expiration_data*1000 - warning_expiration_time*1000) if role == Qt.DisplayRole: if source_index.column() == self.sourceModel().columns_ids.index('renewed') \ or source_index.column() == self.sourceModel().columns_ids.index('expiration'): if source_data is not None: return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ) else: return "" if source_index.column() == self.sourceModel().columns_ids.index('pubkey'): return "pub:{0}".format(source_data[:5]) if role == Qt.ForegroundRole: if expiration_data: if will_expire_soon: return QColor(Qt.red) else: return QColor(Qt.blue) return source_data
def add_certified_node(self, identity, certified, certification, node_status): metadata = { 'text': certified.uid if certified.uid else certified.pubkey[:12], 'tooltip': certified.pubkey, 'identity': certified, 'status': node_status } self.nx_graph.add_node(certified.pubkey, attr_dict=metadata) arc_status = self.arc_status(certification.timestamp) sig_validity = self.blockchain_service.parameters().sig_validity arc = { 'status': arc_status, 'tooltip': QLocale.toString( QLocale(), QDateTime.fromTime_t(certification.timestamp + sig_validity).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat)), 'cert_time': certification.timestamp, 'confirmation_text': self.confirmation_text(certification.written_on) } self.nx_graph.add_edge(identity.pubkey, certified.pubkey, attr_dict=arc)
async def exec_test(): value = await referential.localized(units=True, international_system=True) self.assertEqual(value, "1.011000 mUD({0}) TC".format(QLocale.toString( QLocale(), QDateTime.fromTime_t(1452663088792).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) )))
async def exec_test(): value = await referential.diff_localized(units=True) self.assertEqual(value, "0.101100 UD({0}) TC".format(QLocale.toString( QLocale(), QDateTime.fromTime_t(1452663088792).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) )))
def message(cls, string, server_port=0): if cls._last_client_name and cls._last_client_name != 'daemon': sys.stderr.write('\n') sys.stderr.write('[\033[90mray-daemon\033[0m]\033[92m%s\033[0m\n' % string) log_dir = "%s/logs" % get_app_config_path() if server_port: log_file_path = "%s/%i" % (log_dir, server_port) else: log_file_path = "%s/dummy" % log_dir if not os.path.exists(log_dir): os.makedirs(log_dir) log_file = open(log_file_path, 'a') date_time = QDateTime.currentDateTime() locale = QLocale(QLocale.English) date_format = locale.toString(date_time, "ddd MMM d hh:mm:ss yyyy") log_file.write("%s: %s\n" % (date_format, string)) cls._last_client_name = 'daemon'
def add_certifier_node(self, certifier, identity, certification, node_status): sentry_symbol, sentry_text = sentry_display(certifier) name_text = certifier.uid if certifier.uid else certifier.pubkey[:12] metadata = { 'text': sentry_symbol + name_text, 'tooltip': sentry_text + certifier.pubkey, 'identity': certifier, 'status': node_status } self.nx_graph.add_node(certifier.pubkey, attr_dict=metadata) arc_status = self.arc_status(certification.timestamp) sig_validity = self.blockchain_service.parameters().sig_validity expiration = self.blockchain_service.adjusted_ts( certification.timestamp + sig_validity) arc = { 'status': arc_status, 'tooltip': QLocale.toString( QLocale(), QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat)) + " BAT", 'cert_time': certification.timestamp, 'confirmation_text': self.confirmation_text(certification.written_on) } self.nx_graph.add_edge(certifier.pubkey, identity.pubkey, attr_dict=arc)
def data(self, index, role): source_index = self.mapToSource(index) model = self.sourceModel() source_data = model.data(source_index, role) state_col = model.columns_types.index('state') state_index = model.index(source_index.row(), state_col) state_data = model.data(state_index, Qt.DisplayRole) if role == Qt.DisplayRole: if source_index.column() == model.columns_types.index('uid'): return source_data if source_index.column() == model.columns_types.index('date'): return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ) if source_index.column() == model.columns_types.index('payment') or \ source_index.column() == model.columns_types.index('deposit'): if source_data is not "": amount_ref = self.account.units_to_diff_ref(source_data, self.community) # if referential type is quantitative... if self.account.ref_type() == 'q': # display int values return QLocale().toString(float(amount_ref), 'f', 0) else: # display float values return QLocale().toString(amount_ref, 'f', 6) if role == Qt.FontRole: font = QFont() if state_data == Transfer.AWAITING: font.setItalic(True) elif state_data == Transfer.REFUSED: font.setItalic(True) elif state_data == Transfer.TO_SEND: font.setBold(True) else: font.setItalic(False) return font if role == Qt.ForegroundRole: if state_data == Transfer.REFUSED: return QColor(Qt.red) elif state_data == Transfer.TO_SEND: return QColor(Qt.blue) if role == Qt.TextAlignmentRole: if source_index.column() == self.sourceModel().columns_types.index( 'deposit') or source_index.column() == self.sourceModel().columns_types.index('payment'): return Qt.AlignRight | Qt.AlignVCenter if source_index.column() == self.sourceModel().columns_types.index('date'): return Qt.AlignCenter if role == Qt.ToolTipRole: if source_index.column() == self.sourceModel().columns_types.index('date'): return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate) return source_data
async def exec_test(): value = await referential.localized(units=True) self.assertEqual( value, "0.101000 UD({0}) TC".format( QLocale.toString( QLocale(), QDateTime.fromTime_t(1452663088792).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat))))
def data(self, index, role): source_index = self.mapToSource(index) source_model = self.sourceModel() if not source_index.isValid(): return QVariant() source_data = source_model.data(source_index, role) if role == Qt.DisplayRole: if index.column() == NetworkTableModel.columns_types.index('is_member'): value = {True: QT_TRANSLATE_NOOP("NetworkTableModel", 'yes'), False: QT_TRANSLATE_NOOP("NetworkTableModel", 'no'), None: QT_TRANSLATE_NOOP("NetworkTableModel", 'offline')} return value[source_data] if index.column() == NetworkTableModel.columns_types.index('pubkey'): return source_data[:5] if index.column() == NetworkTableModel.columns_types.index('current_block'): if source_data == -1: return "" else: return source_data if index.column() == NetworkTableModel.columns_types.index('address') \ or index.column() == NetworkTableModel.columns_types.index('port') \ or index.column() == NetworkTableModel.columns_types.index('api'): return "<p>" + source_data.replace('\n', "<br>") + "</p>" if index.column() == NetworkTableModel.columns_types.index('current_hash'): return source_data[:10] if index.column() == NetworkTableModel.columns_types.index('current_time') and source_data: ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data) return QLocale.toString( QLocale(), QDateTime.fromTime_t(ts), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) + " BAT" if role == Qt.TextAlignmentRole: if source_index.column() == NetworkTableModel.columns_types.index('address') \ or source_index.column() == self.sourceModel().columns_types.index('current_block'): return Qt.AlignRight | Qt.AlignVCenter if source_index.column() == NetworkTableModel.columns_types.index('is_member'): return Qt.AlignCenter if role == Qt.FontRole: is_root_col = NetworkTableModel.columns_types.index('is_root') index_root_col = source_model.index(source_index.row(), is_root_col) if source_model.data(index_root_col, Qt.DisplayRole): font = QFont() font.setBold(True) return font if role == Qt.BackgroundColorRole and self.app.parameters.dark_theme: return source_data.darker() return source_data
def new_blocks_handled(self): current_block = self.model.current_block() current_time = self.model.current_time() str_time = QLocale.toString( QLocale(), QDateTime.fromTime_t(current_time), QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat) ) self.view.status_label.setText(self.tr("Blockchain sync : {0} ({1})").format(str_time, str(current_block)[:15]))
async def exec_test(): value = await referential.diff_localized(units=False, international_system=True) self.assertEqual( value, "1.011000 mUD({0}) ".format( QLocale.toString( QLocale(), QDateTime.fromTime_t(1452663088792).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat))))
def update_time(self): dateTime = QDateTime.currentDateTime() self.label_time.setText("{0}".format( QLocale.toString( QLocale(), QDateTime.currentDateTime(), QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)))) timer = QTimer() timer.timeout.connect(self.update_time) timer.start(1000)
def refresh_status(self): """ Refresh status bar """ logging.debug("Refresh status") if self.community: text = "" current_block_number = self.community.network.current_blockid.number if current_block_number: text += self.tr(" Block {0}").format(current_block_number) try: block = yield from self.community.get_block(current_block_number) text += " ({0})".format(QLocale.toString( QLocale(), QDateTime.fromTime_t(block['medianTime']), QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat) )) except NoPeerAvailable as e: logging.debug(str(e)) text += " ( ### ) " except ValueError as e: logging.debug(str(e)) if len(self.community.network.synced_nodes) == 0: self.button_membership.setEnabled(False) self.button_certification.setEnabled(False) self.button_send_money.setEnabled(False) else: self.button_membership.setEnabled(True) self.button_certification.setEnabled(True) self.button_send_money.setEnabled(True) if self.community.network.quality > 0.66: icon = '<img src=":/icons/connected" width="12" height="12"/>' elif self.community.network.quality > 0.33: icon = '<img src=":/icons/weak_connect" width="12" height="12"/>' else: icon = '<img src=":/icons/disconnected" width="12" height="12"/>' status_infotext = " - ".join([self.app.notifications[info][0] for info in self.status_info]) label_text = "{0}{1}".format(icon, text) if status_infotext != "": label_text += " - {0}".format(status_infotext) if self.app.preferences['expert_mode']: try: members_pubkeys = yield from self.community.members_pubkeys() label_text += self.tr(" - Median fork window : {0}")\ .format(self.community.network.fork_window(members_pubkeys)) except NoPeerAvailable as e: logging.debug(str(e)) label_text += self.tr(" - Median fork window : {0}")\ .format("#") self.status_label.setText(label_text)
def update_time(self): dateTime = QDateTime.currentDateTime() self.label_time.setText("{0}".format(QLocale.toString( QLocale(), QDateTime.currentDateTime(), QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat) ))) timer = QTimer() timer.timeout.connect(self.update_time) timer.start(1000)
def data(self, index, role): source_index = self.mapToSource(index) if source_index.isValid(): source_data = self.sourceModel().data(source_index, role) expiration_col = self.sourceModel().columns_ids.index('expiration') expiration_index = self.sourceModel().index(source_index.row(), expiration_col) STATUS_NOT_MEMBER = 0 STATUS_MEMBER = 1 STATUS_EXPIRE_SOON = 3 status = STATUS_NOT_MEMBER expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole) current_time = QDateTime().currentDateTime().toMSecsSinceEpoch() sig_validity = self.sourceModel().sig_validity() warning_expiration_time = int(sig_validity / 3) #logging.debug("{0} > {1}".format(current_time, expiration_data)) if expiration_data is not None: status = STATUS_MEMBER if current_time > (expiration_data*1000): status = STATUS_NOT_MEMBER elif current_time > ((expiration_data*1000) - (warning_expiration_time*1000)): status = STATUS_EXPIRE_SOON if role == Qt.DisplayRole: if source_index.column() in (self.sourceModel().columns_ids.index('renewed'), self.sourceModel().columns_ids.index('expiration'), self.sourceModel().columns_ids.index('publication')): if source_data is not None: return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ) else: return "" if source_index.column() == self.sourceModel().columns_ids.index('pubkey'): return "pub:{0}".format(source_data[:5]) if role == Qt.ForegroundRole: if status == STATUS_EXPIRE_SOON: return QColor("darkorange").darker(120) elif status == STATUS_NOT_MEMBER: return QColor(Qt.red) else: return QColor(Qt.blue) if role == Qt.DecorationRole and source_index.column() == self.sourceModel().columns_ids.index('uid'): if status == STATUS_NOT_MEMBER: return QIcon(":/icons/not_member") elif status == STATUS_MEMBER: return QIcon(":/icons/member") elif status == STATUS_EXPIRE_SOON: return QIcon(":/icons/member_warning") return source_data
def data(self, index, role): source_index = self.mapToSource(index) source_model = self.sourceModel() if not source_index.isValid(): return QVariant() source_data = source_model.data(source_index, role) if role == Qt.DisplayRole: if index.column() == source_model.columns_types.index('is_member'): value = { True: self.tr('yes'), False: self.tr('no'), None: self.tr('offline') } return value[source_data] if index.column() == source_model.columns_types.index('pubkey'): return source_data[:5] if index.column() == source_model.columns_types.index( 'current_block'): if source_data == -1: return "" else: return source_data if index.column() == source_model.columns_types.index( 'current_hash'): return source_data[:10] if index.column() == source_model.columns_types.index( 'current_time') and source_data: return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)) if role == Qt.TextAlignmentRole: if source_index.column() == source_model.columns_types.index( 'address') or source_index.column() == self.sourceModel( ).columns_types.index('current_block'): return Qt.AlignRight | Qt.AlignVCenter if source_index.column() == source_model.columns_types.index( 'is_member'): return Qt.AlignCenter if role == Qt.FontRole: is_root_col = source_model.columns_types.index('is_root') index_root_col = source_model.index(source_index.row(), is_root_col) if source_model.data(index_root_col, Qt.DisplayRole): font = QFont() font.setBold(True) return font return source_data
async def refresh_status(self): """ Refresh status bar """ logging.debug("Refresh status") if self.community: text = "" current_block_number = self.community.network.current_blockUID.number if current_block_number: text += self.tr("Block {0}").format(current_block_number) try: block = await self.community.get_block(current_block_number ) text += " ({0})".format( QLocale.toString( QLocale(), QDateTime.fromTime_t(block['medianTime']), QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat))) except NoPeerAvailable as e: logging.debug(str(e)) text += " ( ### ) " except errors.DuniterError as e: if e.ucode == errors.BLOCK_NOT_FOUND: logging.debug(str(e)) if len(self.community.network.synced_nodes) == 0: self.button_membership.setEnabled(False) self.button_certification.setEnabled(False) self.button_send_money.setEnabled(False) else: self.button_send_money.setEnabled(True) self.refresh_quality_buttons() if self.community.network.quality > 0.66: icon = ':/icons/connected' elif self.community.network.quality > 0.33: icon = ':/icons/weak_connect' else: icon = ':/icons/disconnected' status_infotext = " - ".join([ self.account.notifications[info][0] for info in self.status_info ]) label_text = text if status_infotext != "": label_text += " - {0}".format(status_infotext) self.status_label.setText(label_text) self.label_icon.setPixmap( QPixmap(icon).scaled(24, 24, Qt.KeepAspectRatio, Qt.SmoothTransformation))
def add_certifier_list(self, certifier_list, person, person_account): """ Add list of certifiers to graph :param list certifier_list: List of certifiers from api :param Person person: Person instance which is certified :param Person person_account: Account person instance :return: """ # add certifiers of uid for certifier in tuple(certifier_list): # add only valid certification... if (time.time() - certifier['cert_time']['medianTime']) > self.signature_validity: continue # new node if certifier['pubkey'] not in self._graph.keys(): node_status = 0 if certifier['pubkey'] == person_account.pubkey: node_status += NODE_STATUS_HIGHLIGHTED if certifier['isMember'] is False: node_status += NODE_STATUS_OUT self._graph[certifier['pubkey']] = { 'id': certifier['pubkey'], 'arcs': list(), 'text': certifier['uid'], 'tooltip': certifier['pubkey'], 'status': node_status, 'connected': [person.pubkey] } # keep only the latest certification if self._graph[certifier['pubkey']]['arcs']: if certifier['cert_time']['medianTime'] < self._graph[certifier['pubkey']]['arcs'][0]['cert_time']: continue # display validity status if (time.time() - certifier['cert_time']['medianTime']) > self.ARC_STATUS_STRONG_time: arc_status = ARC_STATUS_WEAK else: arc_status = ARC_STATUS_STRONG arc = { 'id': person.pubkey, 'status': arc_status, 'tooltip': QLocale.toString( QLocale(), QDateTime.fromTime_t(certifier['cert_time']['medianTime'] + self.signature_validity).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ), 'cert_time': certifier['cert_time']['medianTime'] } # add arc to certifier self._graph[certifier['pubkey']]['arcs'].append(arc) # if certifier node not in person nodes if certifier['pubkey'] not in tuple(self._graph[person.pubkey]['connected']): # add certifier node to person node self._graph[person.pubkey]['connected'].append(certifier['pubkey'])
async def add_certified_list(self, certified_list, identity, account_identity): """ Add list of certified from api to graph :param list certified_list: List of certified from api :param identity identity: identity instance which is certifier :param identity account_identity: Account identity instance :return: """ if self.community: try: # add certified by uid for certified in tuple(certified_list): node_status = await self.node_status( certified['identity'], account_identity) metadata = { 'text': certified['identity'].uid, 'tooltip': certified['identity'].pubkey, 'status': node_status } self.nx_graph.add_node(certified['identity'].pubkey, attr_dict=metadata) arc_status = await self.arc_status(certified['cert_time']) sig_validity = (await self.community.parameters())['sigValidity'] arc = { 'status': arc_status, 'tooltip': QLocale.toString( QLocale(), QDateTime.fromTime_t(certified['cert_time'] + sig_validity).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat)), 'cert_time': certified['cert_time'], 'confirmation_text': self.confirmation_text(certified['block_number']) } self.nx_graph.add_edge(identity.pubkey, certified['identity'].pubkey, attr_dict=arc, weight=len(certified_list)) except NoPeerAvailable as e: logging.debug(str(e))
async def refresh(self): if self.identity and self.identity.local_state != LocalState.NOT_FOUND: self.ui.busy.show() self.ui.label_uid.setText(self.identity.uid) self.ui.label_properties.setText("") try: identity_selfcert = await self.identity.selfcert(self.community) publish_time = await self.community.time(identity_selfcert.timestamp.number) join_date = await self.identity.get_join_date(self.community) if join_date is None: join_date = self.tr('not a member') else: join_date = datetime.datetime.fromtimestamp(join_date).strftime("%d/%m/%Y %I:%M") except MembershipNotFoundError: join_date = "###" except (LookupFailureError, NoPeerAvailable): publish_time = None join_date = "###" if publish_time: uid_publish_date = QLocale.toString( QLocale(), QDateTime.fromTime_t(publish_time), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) else: uid_publish_date = "###" text = self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> """).format( self.tr('Public key'), self.identity.pubkey, self.tr('UID Published on'), uid_publish_date, self.tr('Join date'), join_date ) # close html text text += "</table>" # set text in label self.ui.label_properties.setText(text) self.ui.busy.hide()
def write_csv_row(self, file_ptr, elems): """ Writes list of values as a CSV row, converting values as cencessary (if value contains a character used as a CSV ddelimiter). """ delim = self.app_config.csv_delimiter if self.app_config else ';' delim_replacement = '_' if delim != '_' else '-' # elems = [str(elem if elem is not None else '').replace(delim, delim_replacement) for elem in elems] csv_row = [] for elem in elems: if elem is None: elem = '' elif not isinstance(elem, str): elem = QLocale.toString(self.app_config.get_default_locale(), elem if elem is not None else '') csv_row.append(elem.replace(delim, delim_replacement)) file_ptr.write(delim.join(csv_row) + '\n')
async def refresh_status(self): """ Refresh status bar """ logging.debug("Refresh status") if self.community: text = "" current_block_number = self.community.network.current_blockid.number if current_block_number: text += self.tr("Block {0}").format(current_block_number) try: block = await self.community.get_block(current_block_number) text += " ({0})".format(QLocale.toString( QLocale(), QDateTime.fromTime_t(block['medianTime']), QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat) )) except NoPeerAvailable as e: logging.debug(str(e)) text += " ( ### ) " except ValueError as e: logging.debug(str(e)) if len(self.community.network.synced_nodes) == 0: self.button_membership.setEnabled(False) self.button_certification.setEnabled(False) self.button_send_money.setEnabled(False) else: self.button_membership.setEnabled(True) self.button_certification.setEnabled(True) self.button_send_money.setEnabled(True) if self.community.network.quality > 0.66: icon = ':/icons/connected' elif self.community.network.quality > 0.33: icon = ':/icons/weak_connect' else: icon = ':/icons/disconnected' status_infotext = " - ".join([self.account.notifications[info][0] for info in self.status_info]) label_text = text if status_infotext != "": label_text += " - {0}".format(status_infotext) self.status_label.setText(label_text) self.label_icon.setPixmap(QPixmap(icon).scaled(24, 24, Qt.KeepAspectRatio, Qt.SmoothTransformation))
def data(self, index, role): source_index = self.mapToSource(index) source_model = self.sourceModel() if not source_index.isValid(): return QVariant() source_data = source_model.data(source_index, role) if role == Qt.DisplayRole: if index.column() == source_model.columns_types.index('is_member'): value = {True: self.tr('yes'), False: self.tr('no'), None: self.tr('offline')} return value[source_data] if index.column() == source_model.columns_types.index('pubkey'): return source_data[:5] if index.column() == source_model.columns_types.index('current_block'): if source_data == -1: return "" else: return source_data if index.column() == source_model.columns_types.index('current_hash') : return source_data[:10] if index.column() == source_model.columns_types.index('current_time') and source_data: return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) if role == Qt.TextAlignmentRole: if source_index.column() == source_model.columns_types.index('address') or source_index.column() == self.sourceModel().columns_types.index('current_block'): return Qt.AlignRight | Qt.AlignVCenter if source_index.column() == source_model.columns_types.index('is_member'): return Qt.AlignCenter if role == Qt.FontRole: is_root_col = source_model.columns_types.index('is_root') index_root_col = source_model.index(source_index.row(), is_root_col) if source_model.data(index_root_col, Qt.DisplayRole): font = QFont() font.setBold(True) return font return source_data
async def refresh(self): if self.identity and self.identity.local_state != LocalState.NOT_FOUND: self.ui.busy.show() self.ui.label_uid.setText(self.identity.uid) self.ui.label_properties.setText("") try: identity_selfcert = await self.identity.selfcert(self.community ) publish_time = await self.community.time( identity_selfcert.timestamp.number) join_date = await self.identity.get_join_date(self.community) if join_date is None: join_date = self.tr('not a member') else: join_date = datetime.datetime.fromtimestamp( join_date).strftime("%d/%m/%Y %I:%M") except MembershipNotFoundError: join_date = "###" except (LookupFailureError, NoPeerAvailable): publish_time = None join_date = "###" if publish_time: uid_publish_date = QLocale.toString( QLocale(), QDateTime.fromTime_t(publish_time), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)) else: uid_publish_date = "###" text = self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> """).format(self.tr('Public key'), self.identity.pubkey, self.tr('UID Published on'), uid_publish_date, self.tr('Join date'), join_date) # close html text text += "</table>" # set text in label self.ui.label_properties.setText(text) self.ui.busy.hide()
async def refresh(self): if self.identity: self.ui.busy.show() self.ui.label_uid.setText(self.identity.uid) self.ui.label_properties.setText("") try: join_date = await self.identity.get_join_date(self.community) except MembershipNotFoundError: join_date = None if join_date is None: join_date = self.tr('not a member') else: join_date = datetime.datetime.fromtimestamp(join_date).strftime("%d/%m/%Y %I:%M") identity_selfcert = await self.identity.selfcert(self.community) uid_publish_date = QLocale.toString( QLocale(), QDateTime.fromTime_t(identity_selfcert.timestamp), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) text = self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> """).format( self.tr('Public key'), self.identity.pubkey, self.tr('UID Published on'), uid_publish_date, self.tr('Join date'), join_date ) # close html text text += "</table>" # set text in label self.ui.label_properties.setText(text) self.ui.busy.hide()
def data(self, index, role): source_index = self.mapToSource(index) model = self.sourceModel() source_data = model.data(source_index, role) state_col = model.columns_types.index('state') state_index = model.index(source_index.row(), state_col) state_data = model.data(state_index, Qt.DisplayRole) if role == Qt.DisplayRole: if source_index.column() == model.columns_types.index('uid'): return source_data if source_index.column() == model.columns_types.index('date'): return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat)) if source_index.column() == model.columns_types.index('payment') or \ source_index.column() == model.columns_types.index('deposit'): return source_data if role == Qt.FontRole: font = QFont() return font if role == Qt.ForegroundRole: if state_data == TransferState.REFUSED: return QColor(Qt.red) elif state_data == TransferState.TO_SEND: return QColor(Qt.blue) if role == Qt.TextAlignmentRole: if source_index.column() == self.sourceModel().columns_types.index( 'date'): return Qt.AlignCenter if role == Qt.ToolTipRole: if source_index.column() == self.sourceModel().columns_types.index( 'date'): return QDateTime.fromTime_t(source_data).toString( Qt.SystemLocaleLongDate) return None return source_data
def data(self, index, role): source_index = self.mapToSource(index) model = self.sourceModel() source_data = model.data(source_index, role) state_col = model.columns_types.index('state') state_index = model.index(source_index.row(), state_col) state_data = model.data(state_index, Qt.DisplayRole) if role == Qt.DisplayRole: if source_index.column() == model.columns_types.index('uid'): return source_data if source_index.column() == model.columns_types.index('date'): return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ) if source_index.column() == model.columns_types.index('payment') or \ source_index.column() == model.columns_types.index('deposit'): return source_data if role == Qt.FontRole: font = QFont() return font if role == Qt.ForegroundRole: if state_data == TransferState.REFUSED: return QColor(Qt.red) elif state_data == TransferState.TO_SEND: return QColor(Qt.blue) if role == Qt.TextAlignmentRole: if source_index.column() == self.sourceModel().columns_types.index('date'): return Qt.AlignCenter if role == Qt.ToolTipRole: if source_index.column() == self.sourceModel().columns_types.index('date'): return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate) return None return source_data
async def diff_localized(self, units=False, international_system=False): from . import Relative value = await self.differential() block = await self.community.get_ud_block(0, self._block_number) prefix = "" if international_system and value != 0: localized_value, prefix = Relative.to_si(value, self.app.preferences['digits_after_comma']) else: localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma']) if units or international_system: return QCoreApplication.translate("RelativeToPast", RelativeToPast._REF_STR_)\ .format(localized_value, prefix, QLocale.toString( QLocale(), QDateTime.fromTime_t(block['medianTime']).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ), self.community.short_currency if units else "") else: return localized_value
async def localized(self, units=False, international_system=False): from . import Relative value = await self.value() block = await self.community.get_ud_block() prefix = "" if international_system: localized_value, prefix = Relative.to_si(value, self.app.preferences['digits_after_comma']) else: localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma']) if units or international_system: return QCoreApplication.translate("RelativeToPast", RelativeToPast._REF_STR_) \ .format(localized_value, prefix, QLocale.toString( QLocale(), QDateTime.fromTime_t(block['medianTime']).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ), self.community.short_currency if units else "") else: return localized_value
async def add_certified_list(self, certified_list, identity, account_identity): """ Add list of certified from api to graph :param list certified_list: List of certified from api :param identity identity: identity instance which is certifier :param identity account_identity: Account identity instance :return: """ if self.community: try: # add certified by uid for certified in tuple(certified_list): node_status = await self.node_status(certified['identity'], account_identity) metadata = { 'text': certified['identity'].uid, 'tooltip': certified['identity'].pubkey, 'status': node_status } self.nx_graph.add_node(certified['identity'].pubkey, attr_dict=metadata) arc_status = await self.arc_status(certified['cert_time']) sig_validity = (await self.community.parameters())['sigValidity'] arc = { 'status': arc_status, 'tooltip': QLocale.toString( QLocale(), QDateTime.fromTime_t(certified['cert_time'] + sig_validity).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ), 'cert_time': certified['cert_time'], 'confirmation_text': self.confirmation_text(certified['cert_time']) } self.nx_graph.add_edge(identity.pubkey, certified['identity'].pubkey, attr_dict=arc, weight=len(certified_list)) except NoPeerAvailable as e: logging.debug(str(e))
def data(self, index, role): source_index = self.mapToSource(index) source_data = self.sourceModel().data(source_index, role) expiration_col = self.sourceModel().columns_ids.index('expiration') expiration_index = self.sourceModel().index(source_index.row(), expiration_col) expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole) current_time = QDateTime().currentDateTime().toMSecsSinceEpoch() sig_validity = self.community.parameters['sigValidity'] warning_expiration_time = int(sig_validity / 3) #logging.debug("{0} > {1}".format(current_time, expiration_data)) if expiration_data is not None: will_expire_soon = (current_time > expiration_data * 1000 - warning_expiration_time * 1000) if role == Qt.DisplayRole: if source_index.column() == self.sourceModel().columns_ids.index('renewed') \ or source_index.column() == self.sourceModel().columns_ids.index('expiration'): if source_data is not None: return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat)) else: return "" if source_index.column() == self.sourceModel().columns_ids.index( 'pubkey'): return "pub:{0}".format(source_data[:5]) if role == Qt.ForegroundRole: if expiration_data: if will_expire_soon: return QColor(Qt.red) else: return QColor(Qt.blue) return source_data
def refresh_labels(self): self.busy.show() # try to request money parameters try: params = yield from self.community.parameters() except NoPeerAvailable as e: logging.debug('community parameters error : ' + str(e)) return False # try to request money variables from last ud block try: block_ud = yield from self.community.get_ud_block() except NoPeerAvailable as e: logging.debug('community get_ud_block error : ' + str(e)) return False try: block_ud_minus_1 = yield from self.community.get_ud_block(1) except NoPeerAvailable as e: logging.debug('community get_ud_block error : ' + str(e)) return False if block_ud: # display float values localized_ud = yield from self.account.current_ref(block_ud['dividend'], self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) computed_dividend = yield from self.community.computed_dividend() # display float values localized_ud_plus_1 = yield from self.account.current_ref(computed_dividend, self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) localized_mass = yield from self.account.current_ref(block_ud['monetaryMass'], self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) if block_ud_minus_1: mass_minus_1 = (float(0) if block_ud['membersCount'] == 0 else block_ud_minus_1['monetaryMass'] / block_ud['membersCount']) localized_mass_minus_1_per_member = yield from self.account.current_ref(mass_minus_1, self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) localized_mass_minus_1 = yield from self.account.current_ref(block_ud_minus_1['monetaryMass'], self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) else: localized_mass_minus_1_per_member = QLocale().toString( float(0), 'f', self.app.preferences['digits_after_comma'] ) localized_mass_minus_1 = QLocale().toString( float(0), 'f', self.app.preferences['digits_after_comma'] ) # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:2.2%} / {:} days</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( localized_ud, self.tr('Universal Dividend UD(t) in'), self.account.current_ref.diff_units(self.community.currency), localized_mass_minus_1, self.tr('Monetary Mass M(t-1) in'), self.account.current_ref.diff_units(self.community.currency), block_ud['membersCount'], self.tr('Members N(t)'), localized_mass_minus_1_per_member, self.tr('Monetary Mass per member M(t-1)/N(t) in'), self.account.current_ref.diff_units(self.community.currency), float(0) if block_ud['membersCount'] == 0 or block_ud_minus_1['monetaryMass'] == 0 else block_ud['dividend'] / (block_ud_minus_1['monetaryMass'] / block_ud['membersCount']), params['dt'] / 86400, self.tr('Actual growth c = UD(t)/[M(t-1)/N(t)]'), QLocale.toString( QLocale(), QDateTime.fromTime_t(block_ud_minus_1['medianTime']), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ), self.tr('Penultimate UD date and time (t-1)'), QLocale.toString( QLocale(), QDateTime.fromTime_t(block_ud['medianTime']), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ), self.tr('Last UD date and time (t)'), QLocale.toString( QLocale(), QDateTime.fromTime_t(block_ud['medianTime'] + params['dt']), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ), self.tr('Next UD date and time (t+1)') ) ) else: self.label_general.setText(self.tr('No Universal Dividend created yet.')) if block_ud: # set infos in label self.label_rules.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.tr('{:2.0%} / {:} days').format(params['c'], params['dt'] / 86400), self.tr('Fundamental growth (c) / Delta time (dt)'), self.tr('UD(t+1) = MAX { UD(t) ; c × M(t) / N(t+1) }'), self.tr('Universal Dividend (formula)'), self.tr('{:} = MAX {{ {:} {:} ; {:2.0%} × {:} {:} / {:} }}').format( localized_ud_plus_1, localized_ud, self.account.current_ref.diff_units(self.community.currency), params['c'], localized_mass, self.account.current_ref.diff_units(self.community.currency), block_ud['membersCount'] ), self.tr('Universal Dividend (computed)') ) ) else: self.label_rules.setText(self.tr('No Universal Dividend created yet.')) # set infos in label self.label_money.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr> </table> """).format( params['c'], params['dt'] / 86400, self.tr('Fundamental growth (c)'), params['ud0'], self.tr('Initial Universal Dividend UD(0) in'), self.community.short_currency, params['dt'] / 86400, self.tr('Time period (dt) in days (86400 seconds) between two UD'), params['medianTimeBlocks'], self.tr('Number of blocks used for calculating median time'), params['avgGenTime'], self.tr('The average time in seconds for writing 1 block (wished time)'), params['dtDiffEval'], self.tr('The number of blocks required to evaluate again PoWMin value'), params['blocksRot'], self.tr('The number of previous blocks to check for personalized difficulty'), params['percentRot'], self.tr('The percent of previous issuers to reach for personalized difficulty') ) ) # set infos in label self.label_wot.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( params['sigDelay'] / 86400, self.tr('Minimum delay between 2 identical certifications (in days)'), params['sigValidity'] / 86400, self.tr('Maximum age of a valid signature (in days)'), params['sigQty'], self.tr('Minimum quantity of signatures to be part of the WoT'), params['sigWoT'], self.tr('Minimum quantity of valid made certifications to be part of the WoT for distance rule'), params['msValidity'] / 86400, self.tr('Maximum age of a valid membership (in days)'), params['stepMax'], self.tr('Maximum distance between each WoT member and a newcomer'), ) ) self.busy.hide()
class ImapServer(QObject): socket.setdefaulttimeout(1) imap_signal = pyqtSignal() imap_signal_log = pyqtSignal(str) imap_signal_button_color = pyqtSignal(bool) imap_status_next_connection = pyqtSignal(int) imap_update_dt = 5 # in sec def __init__(self, send_mail_sleep, send_mail_parameters, send_mail_mission, imap_signal_stop_server, test_send_mission=None): super().__init__() self.serverIMAP = None self.mailbox = 'Inbox' # change function of imap server self.is_connected = False self.is_first_connection = True self.running = False self.imap_signal_log.emit("?") self.server_id = -1 self.thread = None self.db = DataBaseConnection(init_table=True) self.locale = QLocale(QLocale.English, QLocale.UnitedStates) self.start_sync = None send_mail_sleep.connect(self.send_mail_sleep) send_mail_parameters.connect(self.send_mail_parameters) send_mail_mission.connect(self.send_mail_mission) imap_signal_stop_server.connect(self.stop_server) if (test_send_mission != None): test_send_mission.connect(self.test_mission_file) def __del__(self): # with self.lock: self.running = False if (threading.active_count() != 0 and self.thread != None): self.thread.join() self.close_server() def send_mail_sleep(self, imei, duration): parser = IridiumMessageParser(DataBaseConnection(init_table=False)) data, type = parser.serialize_cmd_sleep(duration) print(data) if parser.flag_msg_ok: self.send_mail(imei, data, type) return def send_mail_parameters(self, imei, enable_mission, enable_flash, enable_depth, enable_engine, period_message): parser = IridiumMessageParser(DataBaseConnection(init_table=False)) data, type = parser.serialize_cmd_parameters(enable_mission, enable_flash, enable_depth, enable_engine, period_message) print(data) if parser.flag_msg_ok: self.send_mail(imei, data, type) return def test_mission_file(self, imei, mission, keep_old_mission): parser = IridiumMessageParser(DataBaseConnection(init_table=False)) data, msg_type = parser.serialize_cmd_mission(mission, keep_old_mission) if data == None: return print(data) if (len(data) > 270 or mission.get_nb_wp() > 256): msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Mission is too heavy " + str(len(data)) + "/270bytes " + str(mission.get_nb_wp()) + "/256 wp") msgBox.setWindowTitle("Seabot") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() return debug_path = expanduser("~") + '/sbd_message.sbd' filename = QFileDialog.getSaveFileName(None, "Save file", debug_path, "SBD File (*.sbd)") if (filename[0] != ''): local_file_sbd = open(filename[0], 'wb') local_file_sbd.write(data) local_file_sbd.close() db = DataBaseConnection(init_table=False) filename = imei + "_" + str(int( datetime.datetime.utcnow().timestamp())) + '.sbd' db.add_sbd_sent_to_icu(imei, filename, msg_type, data, datetime.datetime.utcnow().timestamp()) def send_mail_mission(self, imei, mission, keep_old_mission): parser = IridiumMessageParser(DataBaseConnection(init_table=False)) data, type = parser.serialize_cmd_mission(mission, keep_old_mission) if data == None: return print(data) # Check the length of the message if (len(data) > 270 or mission.get_nb_wp() > 256): msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Mission is too heavy " + str(len(data)) + "/270bytes " + str(mission.get_nb_wp()) + "/256 wp") msgBox.setWindowTitle("Seabot") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() return if parser.flag_msg_ok: self.send_mail(imei, data, type) return def send_mail(self, imei, data, msg_type): if (self.is_connected): db = DataBaseConnection(init_table=False) login_data = db.get_server_data(self.server_id) sbd_msg = MIMEBase("application", "octet-stream") # x-zip-compressed filename = imei + "_" + str( int(datetime.datetime.utcnow().timestamp())) + ".sbd" sbd_msg.set_payload(base64.b64encode(data)) sbd_msg.add_header('Content-Disposition', 'attachment', filename=filename) sbd_msg.add_header('Content-Transfer-Encoding', 'base64') # encoders.encode_base64(sbd_msg) msg = MIMEMultipart('alternative') msg['Subject'] = imei msg['From'] = "<Seabot> <" + login_data["email"] + ">" msg['To'] = login_data["iridium_server_mail"] msg.attach(sbd_msg) msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Question) msgBox.setText("Are you sure you want to send the CMD " + str(msg_type)) msgBox.setWindowTitle("Seabot") msgBox.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok) msgBox.setDefaultButton(QMessageBox.Cancel) ret = msgBox.exec() if (ret != QMessageBox.Ok): return # Send message try: s = smtplib.SMTP(login_data["server_smtp_ip"], login_data["server_smtp_port"]) s.ehlo() context = ssl.SSLContext(ssl.PROTOCOL_TLS) s.starttls(context=context) s.ehlo() s.login(login_data["email"], login_data["password"]) s.sendmail(login_data["email"], login_data["iridium_server_mail"], msg.as_string()) s.close() except socket.error as e: print(e, flush=True) return print("Message sent to ", imei) db.add_sbd_sent_to_icu(imei, filename, msg_type, data, datetime.datetime.utcnow().timestamp()) msgBox = QMessageBox() msgBox.setText("The message was send to iridium server") msgBox.setWindowTitle("Seabot") msgBox.exec() else: print("Server Down") def start_server(self): # with self.lock: self.running = True self.thread = threading.Thread(target=self.update_imap, daemon=True) self.thread.start() def stop_server(self): print("STOP SERVER RECEIVED") # with self.lock: if (self.running == True): self.running = False self.close_server() if (self.thread != None): self.thread.join() def close_server(self): if self.is_connected == True: self.is_connected = False self.is_first_connection = True try: self.serverIMAP.close() self.serverIMAP.logout() self.imap_signal_log.emit("Disconnected") print("Server disconnected") except imaplib.IMAP4.error as err: print(err, flush=True) def update_imap(self): self.db = DataBaseConnection(init_table=False) time_counter = 0 freq = 2 # Hz while self.running: if (not self.is_connected): self.imap_signal_button_color.emit(False) self.connect_imap() if (time_counter == 0): if (self.is_connected and self.is_first_connection): self.update_first_connection() if (self.is_connected and not self.is_first_connection): self.update_recent() time_counter = freq * self.imap_update_dt time.sleep(1. / freq) time_counter -= 1 self.imap_status_next_connection.emit( math.ceil(time_counter / freq)) self.imap_status_next_connection.emit(0) def set_server_id(self, server_id): self.server_id = server_id def connect_imap(self): print("Try connect") try: rsp = None # Retreive data from DB login_data = self.db.get_server_data(self.server_id) if (len(login_data) == 0): raise Exception('wrong server_id ', self.server_id) print("Try Login") self.serverIMAP = imaplib.IMAP4_SSL(login_data["server_imap_ip"], login_data["server_imap_port"]) rsp = self.serverIMAP.login(login_data["email"], login_data["password"]) print(self.serverIMAP.list()) if (rsp[1][0].decode() == "LOGIN completed." or re.search( "Logged in", rsp[1][0].decode()).group(0) == "Logged in"): self.is_connected = True self.is_first_connection = True self.imap_signal_button_color.emit(True) rsp, nb_message_inbox = self.serverIMAP.select( mailbox=self.mailbox, readonly=False) print("select rsp = ", rsp, " nb_message = ", nb_message_inbox[0].decode()) self.imap_signal_log.emit("Connected") else: raise Exception('Failed to select') return True except imaplib.IMAP4.error as err: print("Error imap ", err) self.imap_signal_log.emit("Error IMAP\n" + str(err)) self.close_server() return False except sqlite3.Error as error: print("Error sqlite ", error) self.imap_signal_log.emit("Error SQLITE") self.close_server() return False except: print("Error ", sys.exc_info()) self.imap_signal_log.emit("Error - No connection\n" + str(sys.exc_info()[1])) self.close_server() return False def process_msg(self, msgnums): if (msgnums[0] != None): k = 1 list_msg_num = msgnums[0].split() for num in list_msg_num: if (not self.download_msg(num.decode())): return False self.imap_signal_log.emit("Update " + str(k) + "/" + str(len(list_msg_num)) + " (" + str(num.decode()) + ")") k += 1 if (k % 10 == 0): self.imap_signal.emit() self.imap_signal.emit() return True def update_recent(self): self.imap_signal_log.emit("Update " + str(datetime.datetime.now().replace( microsecond=0))) try: t = datetime.datetime.now() rsp, msgnums = self.serverIMAP.recent() if (not self.process_msg(msgnums)): return False self.db.update_last_sync( self.server_id, t.replace(microsecond=0).isoformat()) # without microsecond return True except imaplib.IMAP4.error as err: self.close_server() print(err, flush=True) self.imap_signal_log.emit("Error imaplib") return False except: print("Error ", sys.exc_info()) self.close_server() self.imap_signal_log.emit("Error (timeout)") return False def update_first_connection(self): print("Try update_first_connection") t = datetime.datetime.now() try: # Search for email since last sync date self.start_sync = self.db.get_last_sync(self.server_id) date_string = self.locale.toString(self.start_sync, "dd-MMM-yyyy") print(date_string) typ, msgnums = self.serverIMAP.search( None, 'SINCE {date}'.format(date=date_string), 'FROM "*****@*****.**"') if (not self.process_msg(msgnums)): return False self.is_first_connection = False self.db.update_last_sync(self.server_id, t) self.log = "Connected" return True except imaplib.IMAP4.error as err: self.close_server() self.imap_signal_log.emit("Error IMAP") print(err) return False except sqlite3.Error as error: self.close_server() self.imap_signal_log.emit("Error SQLITE") print(error) return False except: print("Error ", sys.exc_info()) self.close_server() self.imap_signal_log.emit("Error - No connection") return False def download_msg(self, msgnum): if (msgnum == "0"): return True print("Download msg ", msgnum) try: typ, data_msg = self.serverIMAP.fetch(msgnum, '(BODY.PEEK[])') except imaplib.IMAP4.error as err: self.close_server() self.imap_signal_log.emit("Error IMAP") print(err) return False # Parse received part (starting with "Received: ") mail = email.message_from_bytes(data_msg[0][1], policy=default) if (mail["From"] == "*****@*****.**"): # imei = mail["Subject"].split(": ")[1] # Determine type of mail sbd_received = mail["Subject"].startswith('SBD Msg From Unit: ') sbd_sent = mail["Subject"].startswith( 'SBD Mobile Terminated Message Queued for Unit: ') print(mail["Subject"]) imei = re.search("Unit: (.*)", mail["Subject"]).group(1) time_connection = calendar.timegm(parsedate(mail["Date"])) if (sbd_received): return self.process_received_sbd(imei, mail, time_connection) if (sbd_sent): return self.process_sent_sbd(imei, mail, time_connection) return True def process_received_sbd(self, imei, mail, time_connection): self.db.add_new_robot(imei) # Add new robot if not existing mail_message = mail.get_body('plain').get_content() momsn = int(re.search("MOMSN: (.*)", mail_message).group(1)) mtmsn = int(re.search("MTMSN: (.*)", mail_message).group(1)) print("momsn =", momsn, "mtmsn =", mtmsn) # Check if mtmsn validate previous sent message self.db.update_sbd_last_mtmsn(imei, mtmsn, time_connection) if mail.get_content_maintype() != 'multipart': print("No attachment") return True ## Extract enclosed file for part in mail.iter_attachments(): if part.get_content_maintype() == 'application': #print(part.get_content_maintype(), part.get_content_subtype()) # Extract momsn from attached file print(part.get_filename()) # Add new entry to the database with the association of the imei and momsn message_id = self.db.add_sbd_received(imei, momsn, mtmsn, time_connection) # Test if message is already saved if (message_id != None): msg_data = part.get_payload(decode=True) ip = IridiumMessageParser(self.db) ip.save_log_state(msg_data, message_id, time_connection) return True def process_sent_sbd(self, imei, mail, time_connection): mail_message = mail.get_body('plain').get_content() mtmsn = int(re.search("The MTMSN is (.*),", mail_message).group(1)) queue = int( re.search("the message is number (.*) in the queue", mail_message).group(1)) filename = re.search("Attachment Filename: (.*).sbd", mail_message).group(1) + '.sbd' print(len(filename)) print(filename) self.db.update_sbd_received_by_icu(imei, filename, mtmsn, queue, time_connection) return True
class SnapWidget(QWidget, Ui_SnapWidget): """ Class implementing the snapshot widget. """ ModeFullscreen = 0 ModeScreen = 1 ModeRectangle = 2 ModeFreehand = 3 ModeEllipse = 4 def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(SnapWidget, self).__init__(parent) self.setupUi(self) self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSaveAs.png")) self.takeButton.setIcon(UI.PixmapCache.getIcon("cameraPhoto.png")) self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png")) self.copyPreviewButton.setIcon(UI.PixmapCache.getIcon("editCopy.png")) self.setWindowIcon(UI.PixmapCache.getIcon("ericSnap.png")) self.modeCombo.addItem(self.tr("Fullscreen"), SnapWidget.ModeFullscreen) self.modeCombo.addItem(self.tr("Rectangular Selection"), SnapWidget.ModeRectangle) self.modeCombo.addItem(self.tr("Ellipical Selection"), SnapWidget.ModeEllipse) self.modeCombo.addItem(self.tr("Freehand Selection"), SnapWidget.ModeFreehand) if QApplication.desktop().screenCount() > 1: self.modeCombo.addItem(self.tr("Current Screen"), SnapWidget.ModeScreen) self.__mode = int(Preferences.Prefs.settings.value("Snapshot/Mode", 0)) index = self.modeCombo.findData(self.__mode) if index == -1: index = 0 self.modeCombo.setCurrentIndex(index) self.__delay = int( Preferences.Prefs.settings.value("Snapshot/Delay", 0)) self.delaySpin.setValue(self.__delay) if PYQT_VERSION_STR >= "5.0.0": from PyQt5.QtCore import QStandardPaths picturesLocation = QStandardPaths.writableLocation( QStandardPaths.PicturesLocation) else: from PyQt5.QtGui import QDesktopServices picturesLocation = QDesktopServices.storageLocation( QDesktopServices.PicturesLocation) self.__filename = Preferences.Prefs.settings.value( "Snapshot/Filename", os.path.join(picturesLocation, self.tr("snapshot") + "1.png")) self.__grabber = None self.__snapshot = QPixmap() self.__savedPosition = QPoint() self.__modified = False self.__locale = QLocale() self.__grabberWidget = QWidget(None, Qt.X11BypassWindowManagerHint) self.__grabberWidget.move(-10000, -10000) self.__grabberWidget.installEventFilter(self) self.__initFileFilters() self.__initShortcuts() self.preview.startDrag.connect(self.__dragSnapshot) from .SnapshotTimer import SnapshotTimer self.__grabTimer = SnapshotTimer() self.__grabTimer.timeout.connect(self.__grabTimerTimeout) self.__updateTimer = QTimer() self.__updateTimer.setSingleShot(True) self.__updateTimer.timeout.connect(self.__updatePreview) self.__updateCaption() self.takeButton.setFocus() def __initFileFilters(self): """ Private method to define the supported image file filters. """ filters = { 'bmp': self.tr("Windows Bitmap File (*.bmp)"), 'gif': self.tr("Graphic Interchange Format File (*.gif)"), 'ico': self.tr("Windows Icon File (*.ico)"), 'jpg': self.tr("JPEG File (*.jpg)"), 'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"), 'pbm': self.tr("Portable Bitmap File (*.pbm)"), 'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"), 'pgm': self.tr("Portable Graymap File (*.pgm)"), 'png': self.tr("Portable Network Graphics File (*.png)"), 'ppm': self.tr("Portable Pixmap File (*.ppm)"), 'sgi': self.tr("Silicon Graphics Image File (*.sgi)"), 'svg': self.tr("Scalable Vector Graphics File (*.svg)"), 'tga': self.tr("Targa Graphic File (*.tga)"), 'tif': self.tr("TIFF File (*.tif)"), 'xbm': self.tr("X11 Bitmap File (*.xbm)"), 'xpm': self.tr("X11 Pixmap File (*.xpm)"), } outputFormats = [] writeFormats = QImageWriter.supportedImageFormats() for writeFormat in writeFormats: try: outputFormats.append(filters[bytes(writeFormat).decode()]) except KeyError: pass outputFormats.sort() self.__outputFilter = ';;'.join(outputFormats) self.__defaultFilter = filters['png'] def __initShortcuts(self): """ Private method to initialize the keyboard shortcuts. """ self.__quitShortcut = QShortcut(QKeySequence(QKeySequence.Quit), self, self.close) self.__copyShortcut = QShortcut(QKeySequence(QKeySequence.Copy), self, self.copyButton.animateClick) self.__quickSaveShortcut = QShortcut(QKeySequence(Qt.Key_Q), self, self.__quickSave) self.__save1Shortcut = QShortcut(QKeySequence(QKeySequence.Save), self, self.saveButton.animateClick) self.__save2Shortcut = QShortcut(QKeySequence(Qt.Key_S), self, self.saveButton.animateClick) self.__grab1Shortcut = QShortcut(QKeySequence(QKeySequence.New), self, self.takeButton.animateClick) self.__grab2Shortcut = QShortcut(QKeySequence(Qt.Key_N), self, self.takeButton.animateClick) self.__grab3Shortcut = QShortcut(QKeySequence(Qt.Key_Space), self, self.takeButton.animateClick) def __quickSave(self): """ Private slot to save the snapshot bypassing the file selection dialog. """ if not self.__snapshot.isNull(): while os.path.exists(self.__filename): self.__autoIncFilename() if self.__saveImage(self.__filename): self.__modified = False self.__autoIncFilename() self.__updateCaption() @pyqtSlot() def on_saveButton_clicked(self): """ Private slot to save the snapshot. """ if not self.__snapshot.isNull(): while os.path.exists(self.__filename): self.__autoIncFilename() fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Snapshot"), self.__filename, self.__outputFilter, self.__defaultFilter, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fileName: return ext = QFileInfo(fileName).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fileName += ex if self.__saveImage(fileName): self.__modified = False self.__filename = fileName self.__autoIncFilename() self.__updateCaption() def __saveImage(self, fileName): """ Private method to save the snapshot. @param fileName name of the file to save to (string) @return flag indicating success (boolean) """ if QFileInfo(fileName).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Snapshot"), self.tr("<p>The file <b>{0}</b> already exists." " Overwrite it?</p>").format(fileName), icon=E5MessageBox.Warning) if not res: return False file = QFile(fileName) if not file.open(QFile.WriteOnly): E5MessageBox.warning( self, self.tr("Save Snapshot"), self.tr("Cannot write file '{0}:\n{1}.").format( fileName, file.errorString())) return False ok = self.__snapshot.save(file) file.close() if not ok: E5MessageBox.warning( self, self.tr("Save Snapshot"), self.tr("Cannot write file '{0}:\n{1}.").format( fileName, file.errorString())) return ok def __autoIncFilename(self): """ Private method to auto-increment the file name. """ # Extract the file name name = os.path.basename(self.__filename) # If the name contains a number, then increment it. numSearch = QRegExp("(^|[^\\d])(\\d+)") # We want to match as far left as possible, and when the number is # at the start of the name. # Does it have a number? start = numSearch.lastIndexIn(name) if start != -1: # It has a number, increment it. start = numSearch.pos(2) # Only the second group is of interest. numAsStr = numSearch.capturedTexts()[2] number = "{0:0{width}d}".format(int(numAsStr) + 1, width=len(numAsStr)) name = name[:start] + number + name[start + len(numAsStr):] else: # no number start = name.rfind('.') if start != -1: # has a '.' somewhere, e.g. it has an extension name = name[:start] + '1' + name[start:] else: # no extension, just tack it on to the end name += '1' self.__filename = os.path.join(os.path.dirname(self.__filename), name) self.__updateCaption() @pyqtSlot() def on_takeButton_clicked(self): """ Private slot to take a snapshot. """ self.__mode = self.modeCombo.itemData(self.modeCombo.currentIndex()) self.__delay = self.delaySpin.value() self.__savedPosition = self.pos() self.hide() if self.__delay: self.__grabTimer.start(self.__delay) else: QTimer.singleShot(200, self.__startUndelayedGrab) def __grabTimerTimeout(self): """ Private slot to perform a delayed grab operation. """ if self.__mode == SnapWidget.ModeRectangle: self.__grabRectangle() elif self.__mode == SnapWidget.ModeEllipse: self.__grabEllipse() elif self.__mode == SnapWidget.ModeFreehand: self.__grabFreehand() else: self.__performGrab() def __startUndelayedGrab(self): """ Private slot to perform an undelayed grab operation. """ if self.__mode == SnapWidget.ModeRectangle: self.__grabRectangle() elif self.__mode == SnapWidget.ModeEllipse: self.__grabEllipse() elif self.__mode == SnapWidget.ModeFreehand: self.__grabFreehand() else: if Globals.isMacPlatform(): self.__performGrab() else: self.__grabberWidget.show() self.__grabberWidget.grabMouse(Qt.CrossCursor) def __grabRectangle(self): """ Private method to grab a rectangular screen region. """ from .SnapshotRegionGrabber import SnapshotRegionGrabber self.__grabber = SnapshotRegionGrabber( mode=SnapshotRegionGrabber.Rectangle) self.__grabber.grabbed.connect(self.__captured) def __grabEllipse(self): """ Private method to grab an elliptical screen region. """ from .SnapshotRegionGrabber import SnapshotRegionGrabber self.__grabber = SnapshotRegionGrabber( mode=SnapshotRegionGrabber.Ellipse) self.__grabber.grabbed.connect(self.__captured) def __grabFreehand(self): """ Private method to grab a non-rectangular screen region. """ from .SnapshotFreehandGrabber import SnapshotFreehandGrabber self.__grabber = SnapshotFreehandGrabber() self.__grabber.grabbed.connect(self.__captured) def __performGrab(self): """ Private method to perform a screen grab other than a selected region. """ self.__grabberWidget.releaseMouse() self.__grabberWidget.hide() self.__grabTimer.stop() if self.__mode == SnapWidget.ModeFullscreen: desktop = QApplication.desktop() if qVersion() >= "5.0.0": self.__snapshot = QApplication.screens()[0].grabWindow( desktop.winId(), desktop.x(), desktop.y(), desktop.width(), desktop.height()) else: self.__snapshot = QPixmap.grabWindow(desktop.winId(), desktop.x(), desktop.y(), desktop.width(), desktop.height()) elif self.__mode == SnapWidget.ModeScreen: desktop = QApplication.desktop() screenId = desktop.screenNumber(QCursor.pos()) geom = desktop.screenGeometry(screenId) x = geom.x() y = geom.y() if qVersion() >= "5.0.0": self.__snapshot = QApplication.screens()[0].grabWindow( desktop.winId(), x, y, geom.width(), geom.height()) else: self.__snapshot = QPixmap.grabWindow(desktop.winId(), x, y, geom.width(), geom.height()) else: self.__snapshot = QPixmap() self.__redisplay() self.__modified = True self.__updateCaption() def __redisplay(self): """ Private method to redisplay the window. """ self.__updatePreview() QApplication.restoreOverrideCursor() if not self.__savedPosition.isNull(): self.move(self.__savedPosition) self.show() self.raise_() self.saveButton.setEnabled(not self.__snapshot.isNull()) self.copyButton.setEnabled(not self.__snapshot.isNull()) self.copyPreviewButton.setEnabled(not self.__snapshot.isNull()) @pyqtSlot() def on_copyButton_clicked(self): """ Private slot to copy the snapshot to the clipboard. """ if not self.__snapshot.isNull(): QApplication.clipboard().setPixmap(QPixmap(self.__snapshot)) @pyqtSlot() def on_copyPreviewButton_clicked(self): """ Private slot to copy the snapshot preview to the clipboard. """ QApplication.clipboard().setPixmap(self.preview.pixmap()) def __captured(self, pixmap): """ Private slot to show a preview of the snapshot. @param pixmap pixmap of the snapshot (QPixmap) """ self.__grabber.close() self.__snapshot = QPixmap(pixmap) self.__grabber.grabbed.disconnect(self.__captured) self.__grabber = None self.__redisplay() self.__modified = True self.__updateCaption() def __updatePreview(self): """ Private slot to update the preview picture. """ self.preview.setToolTip( self.tr("Preview of the snapshot image ({0} x {1})").format( self.__locale.toString(self.__snapshot.width()), self.__locale.toString(self.__snapshot.height()))) self.preview.setPreview(self.__snapshot) self.preview.adjustSize() def resizeEvent(self, evt): """ Protected method handling a resizing of the window. @param evt resize event (QResizeEvent) """ self.__updateTimer.start(200) def __dragSnapshot(self): """ Private slot handling the dragging of the preview picture. """ drag = QDrag(self) mimeData = QMimeData() mimeData.setImageData(self.__snapshot) drag.setMimeData(mimeData) drag.setPixmap(self.preview.pixmap()) drag.exec_(Qt.CopyAction) def eventFilter(self, obj, evt): """ Public method to handle event for other objects. @param obj reference to the object (QObject) @param evt reference to the event (QEvent) @return flag indicating that the event should be filtered out (boolean) """ if obj == self.__grabberWidget and \ evt.type() == QEvent.MouseButtonPress: if QWidget.mouseGrabber() != self.__grabberWidget: return False if evt.button() == Qt.LeftButton: self.__performGrab() return False def closeEvent(self, evt): """ Protected method handling the close event. @param evt close event (QCloseEvent) """ if self.__modified: res = E5MessageBox.question( self, self.tr("eric6 Snapshot"), self.tr("""The application contains an unsaved snapshot."""), E5MessageBox.StandardButtons(E5MessageBox.Abort | E5MessageBox.Discard | E5MessageBox.Save)) if res == E5MessageBox.Abort: evt.ignore() return elif res == E5MessageBox.Save: self.on_saveButton_clicked() Preferences.Prefs.settings.setValue("Snapshot/Delay", self.delaySpin.value()) Preferences.Prefs.settings.setValue( "Snapshot/Mode", self.modeCombo.itemData(self.modeCombo.currentIndex())) Preferences.Prefs.settings.setValue("Snapshot/Filename", self.__filename) Preferences.Prefs.settings.sync() def __updateCaption(self): """ Private method to update the window caption. """ self.setWindowTitle("{0}[*] - {1}".format( os.path.basename(self.__filename), self.tr("eric6 Snapshot"))) self.setWindowModified(self.__modified) self.pathNameEdit.setText(os.path.dirname(self.__filename))
def data(self, index, role): source_index = self.mapToSource(index) model = self.sourceModel() source_data = model.data(source_index, role) state_col = model.columns_types.index('state') state_index = model.index(source_index.row(), state_col) state_data = model.data(state_index, Qt.DisplayRole) if role == Qt.DisplayRole: if source_index.column() == model.columns_types.index('uid'): return source_data if source_index.column() == model.columns_types.index('date'): return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ) if source_index.column() == model.columns_types.index('payment') or \ source_index.column() == model.columns_types.index('deposit'): return source_data if role == Qt.FontRole: font = QFont() if state_data == TransferState.AWAITING or state_data == TransferState.VALIDATING: font.setItalic(True) elif state_data == TransferState.REFUSED: font.setItalic(True) elif state_data == TransferState.TO_SEND: font.setBold(True) else: font.setItalic(False) return font if role == Qt.ForegroundRole: if state_data == TransferState.REFUSED: return QColor(Qt.red) elif state_data == TransferState.TO_SEND: return QColor(Qt.blue) if role == Qt.TextAlignmentRole: if source_index.column() == self.sourceModel().columns_types.index( 'deposit') or source_index.column() == self.sourceModel().columns_types.index('payment'): return Qt.AlignRight | Qt.AlignVCenter if source_index.column() == self.sourceModel().columns_types.index('date'): return Qt.AlignCenter if role == Qt.ToolTipRole: if source_index.column() == self.sourceModel().columns_types.index('date'): return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate) if state_data == TransferState.VALIDATING or state_data == TransferState.AWAITING: block_col = model.columns_types.index('block_number') block_index = model.index(source_index.row(), block_col) block_data = model.data(block_index, Qt.DisplayRole) current_confirmations = 0 if state_data == TransferState.VALIDATING: current_blockid_number = self.community.network.current_blockid.number if current_blockid_number: current_confirmations = current_blockid_number - block_data elif state_data == TransferState.AWAITING: current_confirmations = 0 max_confirmations = self.sourceModel().max_confirmations() if self.app.preferences['expert_mode']: return self.tr("{0} / {1} confirmations").format(current_confirmations, max_confirmations) else: confirmation = current_confirmations / max_confirmations * 100 confirmation = 100 if confirmation > 100 else confirmation return self.tr("Confirming... {0} %").format(QLocale().toString(float(confirmation), 'f', 0)) return None return source_data
def data(self, index, role): source_index = self.mapToSource(index) if source_index.isValid(): source_data = self.sourceModel().data(source_index, role) expiration_col = self.sourceModel().columns_ids.index('expiration') expiration_index = self.sourceModel().index( source_index.row(), expiration_col) STATUS_NOT_MEMBER = 0 STATUS_MEMBER = 1 STATUS_EXPIRE_SOON = 3 status = STATUS_NOT_MEMBER expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole) current_time = QDateTime().currentDateTime().toMSecsSinceEpoch() sig_validity = self.sourceModel().sig_validity() warning_expiration_time = int(sig_validity / 3) #logging.debug("{0} > {1}".format(current_time, expiration_data)) if expiration_data is not None: status = STATUS_MEMBER if current_time > (expiration_data * 1000): status = STATUS_NOT_MEMBER elif current_time > ((expiration_data * 1000) - (warning_expiration_time * 1000)): status = STATUS_EXPIRE_SOON if role == Qt.DisplayRole: if source_index.column() in ( self.sourceModel().columns_ids.index('renewed'), self.sourceModel().columns_ids.index('expiration')): if source_data is not None: return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat)) else: return "" if source_index.column() == self.sourceModel( ).columns_ids.index('publication'): if source_data is not None: return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data), QLocale.dateTimeFormat(QLocale(), QLocale.LongFormat)) else: return "" if source_index.column() == self.sourceModel( ).columns_ids.index('pubkey'): return "pub:{0}".format(source_data[:5]) if role == Qt.ForegroundRole: if status == STATUS_EXPIRE_SOON: return QColor("darkorange").darker(120) elif status == STATUS_NOT_MEMBER: return QColor(Qt.red) else: return QColor(Qt.blue) if role == Qt.DecorationRole and source_index.column( ) == self.sourceModel().columns_ids.index('uid'): if status == STATUS_NOT_MEMBER: return QIcon(":/icons/not_member") elif status == STATUS_MEMBER: return QIcon(":/icons/member") elif status == STATUS_EXPIRE_SOON: return QIcon(":/icons/member_warning") return source_data
async def refresh_labels(self): self.busy.show() # try to request money parameters try: params = await self.community.parameters() except NoPeerAvailable as e: logging.debug('community parameters error : ' + str(e)) return False # try to request money variables from last ud block try: block_ud = await self.community.get_ud_block() except NoPeerAvailable as e: logging.debug('community get_ud_block error : ' + str(e)) return False try: block_ud_minus_1 = await self.community.get_ud_block(x=1) except NoPeerAvailable as e: logging.debug('community get_ud_block error : ' + str(e)) return False if block_ud: # display float values localized_ud = await self.account.current_ref.instance(block_ud['dividend'] * math.pow(10, block_ud['unitbase']), self.community, self.app) \ .diff_localized(True, self.app.preferences['international_system_of_units']) computed_dividend = await self.community.computed_dividend() # display float values localized_ud_plus_1 = await self.account.current_ref.instance(computed_dividend, self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) localized_mass = await self.account.current_ref.instance(block_ud['monetaryMass'], self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) localized_ud_median_time = QLocale.toString( QLocale(), QDateTime.fromTime_t(block_ud['medianTime']), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) localized_next_ud_median_time = QLocale.toString( QLocale(), QDateTime.fromTime_t(block_ud['medianTime'] + params['dt']), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) if block_ud_minus_1: mass_minus_1 = (float(0) if block_ud['membersCount'] == 0 else block_ud_minus_1['monetaryMass'] / block_ud['membersCount']) localized_mass_minus_1_per_member = await self.account.current_ref.instance(mass_minus_1, self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) localized_mass_minus_1 = await self.account.current_ref.instance(block_ud_minus_1['monetaryMass'], self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) # avoid divide by zero ! if block_ud['membersCount'] == 0 or block_ud_minus_1['monetaryMass'] == 0: actual_growth = float(0) else: actual_growth = (block_ud['dividend'] * math.pow(10, block_ud['unitbase'])) / (block_ud_minus_1['monetaryMass'] / block_ud['membersCount']) localized_ud_median_time_minus_1 = QLocale.toString( QLocale(), QDateTime.fromTime_t(block_ud_minus_1['medianTime']), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) else: localized_mass_minus_1_per_member = QLocale().toString( float(0), 'f', self.app.preferences['digits_after_comma'] ) localized_mass_minus_1 = QLocale().toString( float(0), 'f', self.app.preferences['digits_after_comma'] ) actual_growth = float(0) localized_ud_median_time_minus_1 = "####" # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:2.2%} / {:} days</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( localized_ud, self.tr('Universal Dividend UD(t) in'), self.account.current_ref.instance(0, self.community, self.app, None).diff_units, localized_mass_minus_1, self.tr('Monetary Mass M(t-1) in'), self.account.current_ref.instance(0, self.community, self.app, None).units, block_ud['membersCount'], self.tr('Members N(t)'), localized_mass_minus_1_per_member, self.tr('Monetary Mass per member M(t-1)/N(t) in'), self.account.current_ref.instance(0, self.community, self.app, None).diff_units, actual_growth, params['dt'] / 86400, self.tr('Actual growth c = UD(t)/[M(t-1)/N(t)]'), localized_ud_median_time_minus_1, self.tr('Penultimate UD date and time (t-1)'), localized_ud_median_time, self.tr('Last UD date and time (t)'), localized_next_ud_median_time, self.tr('Next UD date and time (t+1)') ) ) else: self.label_general.setText(self.tr('No Universal Dividend created yet.')) if block_ud: # set infos in label self.label_rules.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.tr('{:2.0%} / {:} days').format(params['c'], params['dt'] / 86400), self.tr('Fundamental growth (c) / Delta time (dt)'), self.tr('UD(t+1) = MAX { UD(t) ; c × M(t) / N(t+1) }'), self.tr('Universal Dividend (formula)'), self.tr('{:} = MAX {{ {:} {:} ; {:2.0%} × {:} {:} / {:} }}').format( localized_ud_plus_1, localized_ud, self.account.current_ref.instance(0, self.community, self.app, None).diff_units, params['c'], localized_mass, self.account.current_ref.instance(0, self.community, self.app, None).diff_units, block_ud['membersCount'] ), self.tr('Universal Dividend (computed)') ) ) else: self.label_rules.setText(self.tr('No Universal Dividend created yet.')) # set infos in label ref_template = """ <table cellpadding="5"> <tr><th>{:}</th><td>{:}</td></tr> <tr><th>{:}</th><td>{:}</td></tr> <tr><th>{:}</th><td>{:}</td></tr> <tr><th>{:}</th><td>{:}</td></tr> </table> """ templates = [] for ref_class in Referentials: ref = ref_class(0, self.community, self.app, None) # print(ref_class.__class__.__name__) # if ref_class.__class__.__name__ == 'RelativeToPast': # continue templates.append(ref_template.format(self.tr('Name'), ref.translated_name(), self.tr('Units'), ref.units, self.tr('Formula'), ref.formula, self.tr('Description'), ref.description ) ) self.label_referentials.setText('<hr>'.join(templates)) # set infos in label self.label_money.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr> </table> """).format( params['c'], params['dt'] / 86400, self.tr('Fundamental growth (c)'), params['ud0'], self.tr('Initial Universal Dividend UD(0) in'), self.community.short_currency, params['dt'] / 86400, self.tr('Time period (dt) in days (86400 seconds) between two UD'), params['medianTimeBlocks'], self.tr('Number of blocks used for calculating median time'), params['avgGenTime'], self.tr('The average time in seconds for writing 1 block (wished time)'), params['dtDiffEval'], self.tr('The number of blocks required to evaluate again PoWMin value'), params['blocksRot'], self.tr('The number of previous blocks to check for personalized difficulty'), params['percentRot'], self.tr('The percent of previous issuers to reach for personalized difficulty') ) ) # set infos in label self.label_wot.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( params['sigPeriod'] / 86400, self.tr('Minimum delay between 2 certifications (in days)'), params['sigValidity'] / 86400, self.tr('Maximum age of a valid signature (in days)'), params['sigQty'], self.tr('Minimum quantity of signatures to be part of the WoT'), params['sigStock'], self.tr('Maximum quantity of active certifications made by member.'), params['sigWindow'], self.tr('Maximum delay a certification can wait before being expired for non-writing.'), params['xpercent'], self.tr('Minimum percent of sentries to reach to match the distance rule'), params['msValidity'] / 86400, self.tr('Maximum age of a valid membership (in days)'), params['stepMax'], self.tr('Maximum distance between each WoT member and a newcomer'), ) ) self.busy.hide()
def refresh(self): parameters = self.community.parameters last_renewal = "" expiration = "" try: person = Person.lookup(self.account.pubkey, self.community) membership = person.membership(self.community) renew_block = membership['blockNumber'] last_renewal = self.community.get_block(renew_block).mediantime expiration = last_renewal + parameters['sigValidity'] except MembershipNotFoundError: last_renewal = None expiration = None certified = person.unique_valid_certified_by(self.community) certifiers = person.unique_valid_certifiers_of(self.community) if last_renewal and expiration: date_renewal = QLocale.toString( QLocale(), QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat) ) date_expiration = QLocale.toString( QLocale(), QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat) ) # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Membership"), self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration), self.tr("Your web of trust"), self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers), len(certified)) ) ) else: # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Not a member"), self.tr("Your web of trust"), self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers), len(certified)) ) ) amount = self.account.amount(self.community) maximum = self.community.monetary_mass # if referential type is quantitative... if self.account.ref_type() == 'q': # display int values localized_amount = QLocale().toString(float(self.get_referential_value(amount)), 'f', 0) localized_minimum = QLocale().toString(float(self.get_referential_value(0)), 'f', 0) localized_maximum = QLocale().toString(float(self.get_referential_value(maximum)), 'f', 0) else: # display float values localized_amount = QLocale().toString(float(self.get_referential_value(amount)), 'f', 6) localized_minimum = QLocale().toString(float(self.get_referential_value(0)), 'f', 6) localized_maximum = QLocale().toString(float(self.get_referential_value(maximum)), 'f', 6) # set infos in label self.label_balance.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.tr("Your money share "), self.tr("{:.2f}%").format(amount / maximum * 100) if maximum != 0 else "0%", self.tr("Your part "), self.tr("{:} {:} in [{:} ; {:}] {:}") .format( localized_amount, self.get_referential_name(), localized_minimum, localized_maximum, self.get_referential_name() ) ) ) wallets_model = WalletsTableModel(self.account, self.community) proxy_model = WalletsFilterProxyModel() proxy_model.setSourceModel(wallets_model) wallets_model.dataChanged.connect(self.wallet_changed) self.table_wallets.setModel(proxy_model) self.table_wallets.resizeColumnsToContents()
async def refresh_informations_frame(self): parameters = self.community.parameters try: identity = await self.account.identity(self.community) membership = identity.membership(self.community) renew_block = membership['blockNumber'] last_renewal = self.community.get_block(renew_block)['medianTime'] expiration = last_renewal + parameters['sigValidity'] except MembershipNotFoundError: last_renewal = None expiration = None certified = await identity.unique_valid_certified_by( self.app.identities_registry, self.community) certifiers = await identity.unique_valid_certifiers_of( self.app.identities_registry, self.community) if last_renewal and expiration: date_renewal = QLocale.toString( QLocale(), QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)) date_expiration = QLocale.toString( QLocale(), QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)) if self.account.pubkey in self.community.members_pubkeys(): # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Membership"), self.tr( "Last renewal on {:}, expiration on {:}").format( date_renewal, date_expiration), self.tr("Your web of trust"), self. tr("Certified by {:} members; Certifier of {:} members" ).format(len(certifiers), len(certified)))) else: # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Not a member"), self.tr( "Last renewal on {:}, expiration on {:}").format( date_renewal, date_expiration), self.tr("Your web of trust"), self. tr("Certified by {:} members; Certifier of {:} members" ).format(len(certifiers), len(certified)))) else: # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Not a member"), self.tr("Your web of trust"), self.tr( "Certified by {:} members; Certifier of {:} members"). format(len(certifiers), len(certified))))
def data(self, index, role): source_index = self.mapToSource(index) if source_index.isValid(): source_data = self.sourceModel().data(source_index, role) expiration_col = IdentitiesTableModel.columns_ids.index('expiration') expiration_index = self.sourceModel().index(source_index.row(), expiration_col) STATUS_NOT_MEMBER = 0 STATUS_MEMBER = 1 STATUS_UNKNOWN = 2 STATUS_EXPIRE_SOON = 3 status = STATUS_NOT_MEMBER expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole) current_time = QDateTime().currentDateTime().toMSecsSinceEpoch() sig_validity = self.sourceModel().sig_validity() warning_expiration_time = int(sig_validity / 3) #logging.debug("{0} > {1}".format(current_time, expiration_data)) if expiration_data == 0: status = STATUS_UNKNOWN elif expiration_data is not None: status = STATUS_MEMBER if current_time > (expiration_data*1000): status = STATUS_NOT_MEMBER elif current_time > ((expiration_data*1000) - (warning_expiration_time*1000)): status = STATUS_EXPIRE_SOON if role == Qt.DisplayRole: if source_index.column() in (IdentitiesTableModel.columns_ids.index('renewed'), IdentitiesTableModel.columns_ids.index('expiration')): if source_data: ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data) return QLocale.toString( QLocale(), QDateTime.fromTime_t(ts).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ) else: return "" if source_index.column() == IdentitiesTableModel.columns_ids.index('publication'): if source_data: ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data) return QLocale.toString( QLocale(), QDateTime.fromTime_t(ts), QLocale.dateTimeFormat(QLocale(), QLocale.LongFormat) ) else: return "" if source_index.column() == IdentitiesTableModel.columns_ids.index('pubkey'): return source_data if source_index.column() == IdentitiesTableModel.columns_ids.index('block'): return str(source_data)[:20] if role == Qt.ForegroundRole: if status == STATUS_EXPIRE_SOON: return QColor("darkorange").darker(120) elif status == STATUS_NOT_MEMBER: return QColor(Qt.red) elif status == STATUS_UNKNOWN: return QColor(Qt.black) else: return QColor(Qt.blue) if role == Qt.FontRole and status == STATUS_UNKNOWN: font = QFont() font.setItalic(True) return font if role == Qt.DecorationRole and source_index.column() == IdentitiesTableModel.columns_ids.index('uid'): if status == STATUS_NOT_MEMBER: return QIcon(":/icons/not_member") elif status == STATUS_MEMBER: return QIcon(":/icons/member") elif status == STATUS_EXPIRE_SOON: return QIcon(":/icons/member_warning") return source_data
class PipPackageDetailsDialog(QDialog, Ui_PipPackageDetailsDialog): """ Class implementing a dialog to show details about a package. """ def __init__(self, detailsData, parent=None): """ Constructor @param detailsData package details @type dict @param parent reference to the parent widget @type QWidget """ super(PipPackageDetailsDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.__locale = QLocale() self.__packageTypeMap = { "sdist": self.tr("Source"), "bdist_wheel": self.tr("Python Wheel"), "bdist_egg": self.tr("Python Egg"), "bdist_wininst": self.tr("MS Windows Installer"), "bdist_msi": self.tr("MS Windows Installer"), "bdist_rpm": self.tr("Unix Installer"), "bdist_deb": self.tr("Unix Installer"), "bdist_dumb": self.tr("Archive"), } self.__populateDetails(detailsData["info"]) self.__populateDownloadUrls(detailsData["urls"]) self.__populateRequiresProvides(detailsData["info"]) def __populateDetails(self, detailsData): """ Private method to populate the details tab. @param detailsData package details @type dict """ self.packageNameLabel.setText("<h1>{0} {1}</h1".format( self.__sanitize(detailsData["name"]), self.__sanitize(detailsData["version"]))) self.summaryLabel.setText(self.__sanitize( detailsData["summary"][:240])) self.descriptionEdit.setPlainText( self.__sanitize(detailsData["description"])) self.authorLabel.setText(self.__sanitize(detailsData["author"])) self.authorEmailLabel.setText('<a href="mailto:{0}">{0}</a>'.format( self.__sanitize(detailsData["author_email"]))) self.licenseLabel.setText(self.__sanitize(detailsData["license"])) self.platformLabel.setText(self.__sanitize(detailsData["platform"])) self.homePageLabel.setText('<a href="{0}">{0}</a>'.format( self.__sanitize(detailsData["home_page"], forUrl=True))) self.packageUrlLabel.setText('<a href="{0}">{0}</a>'.format( self.__sanitize(detailsData["package_url"], forUrl=True))) self.releaseUrlLabel.setText('<a href="{0}">{0}</a>'.format( self.__sanitize(detailsData["release_url"], forUrl=True))) self.docsUrlLabel.setText('<a href="{0}">{0}</a>'.format( self.__sanitize(detailsData["docs_url"], forUrl=True))) self.downloadsDayLabel.setText( self.__locale.toString(detailsData["downloads"]["last_day"])) self.downloadsWeekLabel.setText( self.__locale.toString(detailsData["downloads"]["last_week"])) self.downloadsMonthLabel.setText( self.__locale.toString(detailsData["downloads"]["last_month"])) self.classifiersList.addItems(detailsData["classifiers"]) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) def __populateDownloadUrls(self, downloadsData): """ Private method to populate the download URLs tab. @param downloadsData downloads information @type dict """ index = self.infoWidget.indexOf(self.urls) if downloadsData: self.infoWidget.setTabEnabled(index, True) for download in downloadsData: itm = QTreeWidgetItem(self.downloadUrlsList, [ "", self.__packageTypeMap[download["packagetype"]] if download["packagetype"] in self.__packageTypeMap else "", download["python_version"] if download["python_version"] != "source" else "", self.__locale.toString(download["downloads"]), self.__formatUploadDate(download["upload_time"]), self.__formatSize(download["size"]), ]) if download["has_sig"]: pgpLink = ' (<a href="{0}">pgp</a>)'.format( download["url"] + ".asc") else: pgpLink = "" urlLabel = QLabel('<a href="{0}#md5={2}">{1}</a>{3}'.format( download["url"], download["filename"], download["md5_digest"], pgpLink)) urlLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) urlLabel.setOpenExternalLinks(True) self.downloadUrlsList.setItemWidget(itm, 0, urlLabel) header = self.downloadUrlsList.header() header.resizeSections(QHeaderView.ResizeToContents) else: self.infoWidget.setTabEnabled(index, False) def __populateRequiresProvides(self, detailsData): """ Private method to populate the requires/provides tab. @param detailsData package details @type dict """ populatedItems = 0 if "requires" in detailsData and detailsData["requires"]: self.requiredPackagesList.addItems(detailsData["requires"]) populatedItems += len(detailsData["requires"]) if "requires_dist" in detailsData and detailsData["requires_dist"]: self.requiredDistributionsList.addItems( detailsData["requires_dist"]) populatedItems += len(detailsData["requires_dist"]) if "provides" in detailsData and detailsData["provides"]: self.providedPackagesList.addItems(detailsData["provides"]) populatedItems += len(detailsData["provides"]) if "provides_dist" in detailsData and detailsData["provides_dist"]: self.providedDistributionsList.addItems( detailsData["provides_dist"]) populatedItems += len(detailsData["provides_dist"]) index = self.infoWidget.indexOf(self.requires) self.infoWidget.setTabEnabled(index, populatedItems > 0) def __sanitize(self, text, forUrl=False): """ Private method to clean-up the given text. @param text raw text @type str @param forUrl flag indicating to sanitize an URL text @type bool @return processed text @rtype str """ if text == "UNKNOWN": text = "" elif text == "any": text = self.tr("any") elif text is None: text = "" if forUrl: if (not isinstance(text, str) or not text.startswith( ("http://", "https://", "ftp://"))): # ignore if the schema is not one of the listed ones text = "" return text def __formatUploadDate(self, datetime): """ Private method to format the upload date. @param datetime upload date and time @type xmlrpc.DateTime or str @return formatted date string @rtype str """ if isinstance(datetime, str): return datetime.split("T")[0] else: date = datetime.value.split("T")[0] return "{0}-{1}-{2}".format(date[:4], date[4:6], date[6:]) def __formatSize(self, size): """ Private slot to format the size. @param size size to be formatted @type int @return formatted size @rtype str """ unit = "" if size < 1024: unit = self.tr("B") elif size < 1024 * 1024: size /= 1024 unit = self.tr("KB") elif size < 1024 * 1024 * 1024: size /= 1024 * 1024 unit = self.tr("MB") else: size /= 1024 * 1024 * 1024 unit = self.tr("GB") return self.tr("{0:.1f} {1}", "value, unit").format(size, unit)
def get_localized_data(self): localized_data = {} # try to request money parameters try: params = self.blockchain_service.parameters() except NoPeerAvailable as e: logging.debug('community parameters error : ' + str(e)) return None localized_data['currency'] = ROOT_SERVERS[ self.connection.currency]["display"] localized_data['growth'] = params.c localized_data['days_per_dividend'] = QLocale().toString( params.dt / 86400, 'f', 2) last_ud, last_ud_base = self.blockchain_service.last_ud() members_count = self.blockchain_service.last_members_count() previous_ud, previous_ud_base = self.blockchain_service.previous_ud() previous_ud_time = self.blockchain_service.previous_ud_time() previous_monetary_mass = self.blockchain_service.previous_monetary_mass( ) previous_members_count = self.blockchain_service.previous_members_count( ) localized_data['units'] = self.app.current_ref.instance( 0, self.connection.currency, self.app, None).units localized_data['diff_units'] = self.app.current_ref.instance( 0, self.connection.currency, self.app, None).diff_units if last_ud: # display float values localized_data['ud'] = self.app.current_ref.instance( last_ud * math.pow(10, last_ud_base), self.connection.currency, self.app).diff_localized(False, True) localized_data[ 'members_count'] = self.blockchain_service.current_members_count( ) computed_dividend = self.blockchain_service.computed_dividend() # display float values localized_data['ud_plus_1'] = self.app.current_ref.instance( computed_dividend, self.connection.currency, self.app).diff_localized(False, True) localized_data['mass'] = self.app.current_ref.instance( self.blockchain_service.current_mass(), self.connection.currency, self.app).localized(False, True) ud_median_time = self.blockchain_service.last_ud_time() ud_median_time = self.blockchain_processor.adjusted_ts( self.app.currency, ud_median_time) localized_data['ud_median_time'] = QLocale.toString( QLocale(), QDateTime.fromTime_t(ud_median_time), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)) next_ud_median_time = self.blockchain_service.last_ud_time( ) + params.dt next_ud_median_time = self.blockchain_processor.adjusted_ts( self.app.currency, next_ud_median_time) localized_data['next_ud_median_time'] = QLocale.toString( QLocale(), QDateTime.fromTime_t(next_ud_median_time), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)) next_ud_reeval = self.blockchain_service.next_ud_reeval() next_ud_reeval = self.blockchain_processor.adjusted_ts( self.app.currency, next_ud_reeval) localized_data['next_ud_reeval'] = QLocale.toString( QLocale(), QDateTime.fromTime_t(next_ud_reeval), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)) if previous_ud: mass_minus_1_per_member = (float(0) if previous_ud == 0 or previous_members_count == 0 else previous_monetary_mass / previous_members_count) localized_data['mass_minus_1_per_member'] = self.app.current_ref.instance(mass_minus_1_per_member, self.connection.currency, self.app) \ .localized(False, True) localized_data['mass_minus_1'] = self.app.current_ref.instance(previous_monetary_mass, self.connection.currency, self.app) \ .localized(False, True) # avoid divide by zero ! if members_count == 0 or previous_members_count == 0: localized_data['actual_growth'] = float(0) else: localized_data['actual_growth'] = (last_ud * math.pow( 10, last_ud_base)) / (previous_monetary_mass / members_count) previous_ud_time = self.blockchain_processor.adjusted_ts( self.app.currency, previous_ud_time) localized_data['ud_median_time_minus_1'] = QLocale.toString( QLocale(), QDateTime.fromTime_t(previous_ud_time), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)) return localized_data
def start(self, fn): """ Public slot to start the code metrics determination. @param fn file or list of files or directory to show the code metrics for (string or list of strings) """ self.cancelled = False self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() loc = QLocale() if isinstance(fn, list): files = fn elif os.path.isdir(fn): files = Utilities.direntries(fn, True, '*.py', False) else: files = [fn] files.sort() # check for missing files for f in files[:]: if not os.path.exists(f): files.remove(f) self.checkProgress.setMaximum(len(files)) QApplication.processEvents() total = {} CodeMetrics.summarize(total, 'files', len(files)) progress = 0 try: # disable updates of the list for speed self.resultList.setUpdatesEnabled(False) self.resultList.setSortingEnabled(False) # now go through all the files for file in files: if self.cancelled: return stats = CodeMetrics.analyze(file, total) v = self.__getValues(loc, stats, 'TOTAL ') fitm = self.__createResultItem(self.resultList, [file] + v) identifiers = stats.identifiers for identifier in identifiers: v = self.__getValues(loc, stats, identifier) self.__createResultItem(fitm, [identifier] + v) self.resultList.expandItem(fitm) progress += 1 self.checkProgress.setValue(progress) QApplication.processEvents() finally: # reenable updates of the list self.resultList.setSortingEnabled(True) self.resultList.setUpdatesEnabled(True) self.__resizeResultColumns() # now do the summary stuff self.__createSummaryItem(self.tr("files"), loc.toString(total['files'])) self.__createSummaryItem(self.tr("lines"), loc.toString(total['lines'])) self.__createSummaryItem(self.tr("bytes"), loc.toString(total['bytes'])) self.__createSummaryItem(self.tr("comments"), loc.toString(total['comments'])) self.__createSummaryItem(self.tr("comment lines"), loc.toString(total['commentlines'])) self.__createSummaryItem(self.tr("empty lines"), loc.toString(total['empty lines'])) self.__createSummaryItem(self.tr("non-commentary lines"), loc.toString(total['non-commentary lines'])) self.__resizeSummaryColumns() self.__finish()
class SymbolsModel(QAbstractTableModel): """ Class implementing the model for the symbols widget. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(SymbolsModel, self).__init__(parent) self.__locale = QLocale() self.__headerData = [ self.tr("Code"), self.tr("Char"), self.tr("Hex"), self.tr("HTML"), self.tr("Name"), ] self.__tables = [ # first last display name (0x0, 0x1f, self.tr("Control Characters")), (0x20, 0x7f, self.tr("Basic Latin")), (0x80, 0xff, self.tr("Latin-1 Supplement")), (0x100, 0x17f, self.tr("Latin Extended-A")), (0x180, 0x24f, self.tr("Latin Extended-B")), (0x250, 0x2af, self.tr("IPA Extensions")), (0x2b0, 0x2ff, self.tr("Spacing Modifier Letters")), (0x300, 0x36f, self.tr("Combining Diacritical Marks")), (0x370, 0x3ff, self.tr("Greek and Coptic")), (0x400, 0x4ff, self.tr("Cyrillic")), (0x500, 0x52f, self.tr("Cyrillic Supplement")), (0x530, 0x58f, self.tr("Armenian")), (0x590, 0x5ff, self.tr("Hebrew")), (0x600, 0x6ff, self.tr("Arabic")), (0x700, 0x74f, self.tr("Syriac")), (0x780, 0x7bf, self.tr("Thaana")), (0x7c0, 0x7ff, self.tr("N'Ko")), (0x800, 0x83f, self.tr("Samaritan")), (0x840, 0x85f, self.tr("Mandaic")), (0x8a0, 0x8ff, self.tr("Arabic Extended-A")), (0x900, 0x97f, self.tr("Devanagari")), (0x980, 0x9ff, self.tr("Bengali")), (0xa00, 0xa7f, self.tr("Gurmukhi")), (0xa80, 0xaff, self.tr("Gujarati")), (0xb00, 0xb7f, self.tr("Oriya")), (0xb80, 0xbff, self.tr("Tamil")), (0xc00, 0xc7f, self.tr("Telugu")), (0xc80, 0xcff, self.tr("Kannada")), (0xd00, 0xd7f, self.tr("Malayalam")), (0xd80, 0xdff, self.tr("Sinhala")), (0xe00, 0xe7f, self.tr("Thai")), (0xe80, 0xeff, self.tr("Lao")), (0xf00, 0xfff, self.tr("Tibetan")), (0x1000, 0x109f, self.tr("Myanmar")), (0x10a0, 0x10ff, self.tr("Georgian")), (0x1100, 0x11ff, self.tr("Hangul Jamo")), (0x1200, 0x137f, self.tr("Ethiopic")), (0x1380, 0x139f, self.tr("Ethiopic Supplement")), (0x13a0, 0x13ff, self.tr("Cherokee")), (0x1400, 0x167f, self.tr("Unified Canadian Aboriginal Syllabics")), (0x1680, 0x169f, self.tr("Ogham")), (0x16a0, 0x16ff, self.tr("Runic")), (0x1700, 0x171f, self.tr("Tagalog")), (0x1720, 0x173f, self.tr("Hanunoo")), (0x1740, 0x175f, self.tr("Buhid")), (0x1760, 0x177f, self.tr("Tagbanwa")), (0x1780, 0x17ff, self.tr("Khmer")), (0x1800, 0x18af, self.tr("Mongolian")), (0x18b0, 0x18ff, self.tr("Unified Canadian Aboriginal Syllabics Extended")), (0x1900, 0x194f, self.tr("Limbu")), (0x1950, 0x197f, self.tr("Tai Le")), (0x19e0, 0x19ff, self.tr("Khmer Symbols")), (0x1a00, 0x1a1f, self.tr("Buginese")), (0x1a20, 0x1aaf, self.tr("Tai Tham")), (0x1b00, 0x1b7f, self.tr("Balinese")), (0x1b80, 0x1bbf, self.tr("Sundanese")), (0x1bc0, 0x1bff, self.tr("Batak")), (0x1c00, 0x1c4f, self.tr("Lepcha")), (0x1c50, 0x1c7f, self.tr("Ol Chiki")), (0x1cc0, 0x1ccf, self.tr("Sundanese Supplement")), (0x1cd0, 0x1cff, self.tr("Vedic Extensions")), (0x1d00, 0x1d7f, self.tr("Phonetic Extensions")), (0x1d80, 0x1dbf, self.tr("Phonetic Extensions Supplement")), (0x1dc0, 0x1dff, self.tr("Combining Diacritical Marks Supplement")), (0x1e00, 0x1eff, self.tr("Latin Extended Additional")), (0x1f00, 0x1fff, self.tr("Greek Extended")), (0x2000, 0x206f, self.tr("General Punctuation")), (0x2070, 0x209f, self.tr("Superscripts and Subscripts")), (0x20a0, 0x20cf, self.tr("Currency Symbols")), (0x20d0, 0x20ff, self.tr("Combining Diacritical Marks")), (0x2100, 0x214f, self.tr("Letterlike Symbols")), (0x2150, 0x218f, self.tr("Number Forms")), (0x2190, 0x21ff, self.tr("Arcolumns")), (0x2200, 0x22ff, self.tr("Mathematical Operators")), (0x2300, 0x23ff, self.tr("Miscellaneous Technical")), (0x2400, 0x243f, self.tr("Control Pictures")), (0x2440, 0x245f, self.tr("Optical Character Recognition")), (0x2460, 0x24ff, self.tr("Enclosed Alphanumerics")), (0x2500, 0x257f, self.tr("Box Drawing")), (0x2580, 0x259f, self.tr("Block Elements")), (0x25A0, 0x25ff, self.tr("Geometric Shapes")), (0x2600, 0x26ff, self.tr("Miscellaneous Symbols")), (0x2700, 0x27bf, self.tr("Dingbats")), (0x27c0, 0x27ef, self.tr("Miscellaneous Mathematical Symbols-A")), (0x27f0, 0x27ff, self.tr("Supplement Arcolumns-A")), (0x2800, 0x28ff, self.tr("Braille Patterns")), (0x2900, 0x297f, self.tr("Supplement Arcolumns-B")), (0x2980, 0x29ff, self.tr("Miscellaneous Mathematical Symbols-B")), (0x2a00, 0x2aff, self.tr("Supplemental Mathematical Operators")), (0x2b00, 0x2bff, self.tr("Miscellaneous Symbols and Arcolumns")), (0x2c00, 0x2c5f, self.tr("Glagolitic")), (0x2c60, 0x2c7f, self.tr("Latin Extended-C")), (0x2c80, 0x2cff, self.tr("Coptic")), (0x2d00, 0x2d2f, self.tr("Georgian Supplement")), (0x2d30, 0x2d7f, self.tr("Tifinagh")), (0x2d80, 0x2ddf, self.tr("Ethiopic Extended")), (0x2de0, 0x2dff, self.tr("Cyrillic Extended-A")), (0x2e00, 0x2e7f, self.tr("Supplemental Punctuation")), (0x2e80, 0x2eff, self.tr("CJK Radicals Supplement")), (0x2f00, 0x2fdf, self.tr("KangXi Radicals")), (0x2ff0, 0x2fff, self.tr("Ideographic Description Chars")), (0x3000, 0x303f, self.tr("CJK Symbols and Punctuation")), (0x3040, 0x309f, self.tr("Hiragana")), (0x30a0, 0x30ff, self.tr("Katakana")), (0x3100, 0x312f, self.tr("Bopomofo")), (0x3130, 0x318f, self.tr("Hangul Compatibility Jamo")), (0x3190, 0x319f, self.tr("Kanbun")), (0x31a0, 0x31bf, self.tr("Bopomofo Extended")), (0x31c0, 0x31ef, self.tr("CJK Strokes")), (0x31f0, 0x31ff, self.tr("Katakana Phonetic Extensions")), (0x3200, 0x32ff, self.tr("Enclosed CJK Letters and Months")), (0x3300, 0x33ff, self.tr("CJK Compatibility")), (0x3400, 0x4dbf, self.tr("CJK Unified Ideogr. Ext. A")), (0x4dc0, 0x4dff, self.tr("Yijing Hexagram Symbols")), (0x4e00, 0x9fff, self.tr("CJK Unified Ideographs")), (0xa000, 0xa48f, self.tr("Yi Syllables")), (0xa490, 0xa4cf, self.tr("Yi Radicals")), (0xa4d0, 0xa4ff, self.tr("Lisu")), (0xa500, 0xa63f, self.tr("Vai")), (0xa640, 0xa69f, self.tr("Cyrillic Extended-B")), (0xa6a0, 0xa6ff, self.tr("Bamum")), (0xa700, 0xa71f, self.tr("Modifier Tone Letters")), (0xa720, 0xa7ff, self.tr("Latin Extended-D")), (0xa800, 0xa82f, self.tr("Syloti Nagri")), (0xa830, 0xa83f, self.tr("Common Indic Number Forms")), (0xa840, 0xa87f, self.tr("Phags-pa")), (0xa880, 0xa8df, self.tr("Saurashtra")), (0xa8e0, 0xa8ff, self.tr("Devanagari Extended")), (0xa900, 0xa92f, self.tr("Kayah Li")), (0xa930, 0xa95f, self.tr("Rejang")), (0xa960, 0xa97f, self.tr("Hangul Jamo Extended-A")), (0xa980, 0xa9df, self.tr("Javanese")), (0xaa00, 0xaa5f, self.tr("Cham")), (0xaa60, 0xaa7f, self.tr("Myanmar Extended-A")), (0xaa80, 0xaadf, self.tr("Tai Viet")), (0xaae0, 0xaaff, self.tr("Meetei Mayek Extensions")), (0xab00, 0xab2f, self.tr("Ethiopic Extended-A")), (0xabc0, 0xabff, self.tr("Meetei Mayek")), (0xac00, 0xd7af, self.tr("Hangul Syllables")), (0xd7b0, 0xd7ff, self.tr("Hangul Jamo Extended-B")), (0xd800, 0xdb7f, self.tr("High Surrogates")), (0xdb80, 0xdbff, self.tr("High Private Use Surrogates")), (0xdc00, 0xdfff, self.tr("Low Surrogates")), (0xe000, 0xf8ff, self.tr("Private Use")), (0xf900, 0xfaff, self.tr("CJK Compatibility Ideographs")), (0xfb00, 0xfb4f, self.tr("Alphabetic Presentation Forms")), (0xfb50, 0xfdff, self.tr("Arabic Presentation Forms-A")), (0xfe00, 0xfe0f, self.tr("Variation Selectors")), (0xfe10, 0xfe1f, self.tr("Vertical Forms")), (0xfe20, 0xfe2f, self.tr("Combining Half Marks")), (0xfe30, 0xfe4f, self.tr("CJK Compatibility Forms")), (0xfe50, 0xfe6f, self.tr("Small Form Variants")), (0xfe70, 0xfeff, self.tr("Arabic Presentation Forms-B")), (0xff00, 0xffef, self.tr("Half- and Fullwidth Forms")), (0xfff0, 0xffff, self.tr("Specials")), ] if sys.maxunicode > 0xffff: self.__tables.extend([ (0x10000, 0x1007f, self.tr("Linear B Syllabary")), (0x10080, 0x100ff, self.tr("Linear B Ideograms")), (0x10100, 0x1013f, self.tr("Aegean Numbers")), (0x10140, 0x1018f, self.tr("Ancient Greek Numbers")), (0x10190, 0x101cf, self.tr("Ancient Symbols")), (0x101d0, 0x101ff, self.tr("Phaistos Disc")), (0x10280, 0x1029f, self.tr("Lycian")), (0x102a0, 0x102df, self.tr("Carian")), (0x10300, 0x1032f, self.tr("Old Italic")), (0x10330, 0x1034f, self.tr("Gothic")), (0x10380, 0x1039f, self.tr("Ugaritic")), (0x103a0, 0x103df, self.tr("Old Persian")), (0x10400, 0x1044f, self.tr("Deseret")), (0x10450, 0x1047f, self.tr("Shavian")), (0x10480, 0x104af, self.tr("Osmanya")), (0x10800, 0x1083f, self.tr("Cypriot Syllabary")), (0x10840, 0x1085f, self.tr("Imperial Aramaic")), (0x10900, 0x1091f, self.tr("Phoenician")), (0x10920, 0x1093f, self.tr("Lydian")), (0x10980, 0x1099f, self.tr("Meroitic Hieroglyphs")), (0x109a0, 0x109ff, self.tr("Meroitic Cursive")), (0x10a00, 0x10a5f, self.tr("Kharoshthi")), (0x10a60, 0x10a7f, self.tr("Old South Arabian")), (0x10b00, 0x10b3f, self.tr("Avestan")), (0x10b40, 0x10b5f, self.tr("Inscriptional Parthian")), (0x10b60, 0x10b7f, self.tr("Inscriptional Pahlavi")), (0x10c00, 0x10c4f, self.tr("Old Turkic")), (0x10e60, 0x10e7f, self.tr("Rumi Numeral Symbols")), (0x11000, 0x1107f, self.tr("Brahmi")), (0x11080, 0x110cf, self.tr("Kaithi")), (0x110d0, 0x110ff, self.tr("Sora Sompeng")), (0x11100, 0x1114f, self.tr("Chakma")), (0x11180, 0x111df, self.tr("Sharada")), (0x11680, 0x116cf, self.tr("Takri")), (0x12000, 0x123ff, self.tr("Cuneiform")), (0x12400, 0x1247f, self.tr("Cuneiform Numbers and Punctuation")), (0x13000, 0x1342f, self.tr("Egyptian Hieroglyphs")), (0x16800, 0x16a3f, self.tr("Bamum Supplement")), (0x16f00, 0x16f9f, self.tr("Miao")), (0x1b000, 0x1b0ff, self.tr("Kana Supplement")), (0x1d000, 0x1d0ff, self.tr("Byzantine Musical Symbols")), (0x1d100, 0x1d1ff, self.tr("Musical Symbols")), (0x1d200, 0x1d24f, self.tr("Ancient Greek Musical Notation")), (0x1d300, 0x1d35f, self.tr("Tai Xuan Jing Symbols")), (0x1d360, 0x1d37f, self.tr("Counting Rod Numerals")), (0x1d400, 0x1d7ff, self.tr("Mathematical Alphanumeric Symbols")), (0x1ee00, 0x1eeff, self.tr("Arabic Mathematical Alphabetic Symbols")), (0x1f000, 0x1f02f, self.tr("Mahjong Tiles")), (0x1f030, 0x1f09f, self.tr("Domino Tiles")), (0x1f0a0, 0x1f0ff, self.tr("Playing Cards")), (0x1f100, 0x1f1ff, self.tr("Enclosed Alphanumeric Supplement")), (0x1f200, 0x1f2ff, self.tr("Enclosed Ideographic Supplement")), (0x1f300, 0x1f5ff, self.tr("Miscellaneous Symbols And Pictographs")), (0x1f600, 0x1f64f, self.tr("Emoticons")), (0x1f680, 0x1f6ff, self.tr("Transport And Map Symbols")), (0x1f700, 0x1f77f, self.tr("Alchemical Symbols")), (0x20000, 0x2a6df, self.tr("CJK Unified Ideogr. Ext. B")), (0x2a700, 0x2b73f, self.tr("CJK Unified Ideographs Extension C")), (0x2b740, 0x2b81f, self.tr("CJK Unified Ideographs Extension D")), (0x2f800, 0x2fa1f, self.tr("CJK Compatapility Ideogr. Suppl.")), (0xe0000, 0xe007f, self.tr("Tags")), (0xe0100, 0xe01ef, self.tr("Variation Selectors Supplement")), (0xf0000, 0xfffff, self.tr("Supplementary Private Use Area-A")), (0x100000, 0x10ffff, self.tr("Supplementary Private Use Area-B")), ]) self.__currentTableIndex = 0 def getTableNames(self): """ Public method to get a list of table names. @return list of table names (list of strings) """ return [table[2] for table in self.__tables] def getTableBoundaries(self, index): """ Public method to get the first and last character position of the given table. @param index index of the character table (integer) @return first and last character position (integer, integer) """ return self.__tables[index][0], self.__tables[index][1] def getTableIndex(self): """ Public method to get the current table index. @return current table index (integer) """ return self.__currentTableIndex def selectTable(self, index): """ Public method to select the shown character table. @param index index of the character table (integer) """ self.beginResetModel() self.__currentTableIndex = index self.endResetModel() def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get header data from the model. @param section section number (integer) @param orientation orientation (Qt.Orientation) @param role role of the data to retrieve (integer) @return requested data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.__headerData[section] return QAbstractTableModel.headerData(self, section, orientation, role) def data(self, index, role=Qt.DisplayRole): """ Public method to get data from the model. @param index index to get data for (QModelIndex) @param role role of the data to retrieve (integer) @return requested data """ id = self.__tables[self.__currentTableIndex][0] + index.row() if role == Qt.DisplayRole: col = index.column() if col == 0: return self.__locale.toString(id) elif col == 1: return chr(id) elif col == 2: return "0x{0:04x}".format(id) elif col == 3: if id in html_entities.codepoint2name: return "&{0};".format(html_entities.codepoint2name[id]) elif col == 4: return unicodedata.name(chr(id), '').title() if role == Qt.BackgroundColorRole: if index.column() == 0: return QColor(Qt.lightGray) if role == Qt.TextColorRole: char = chr(id) if self.__isDigit(char): return QColor(Qt.darkBlue) elif self.__isLetter(char): return QColor(Qt.darkGreen) elif self.__isMark(char): return QColor(Qt.darkRed) elif self.__isSymbol(char): return QColor(Qt.black) elif self.__isPunct(char): return QColor(Qt.darkMagenta) else: return QColor(Qt.darkGray) if role == Qt.TextAlignmentRole: if index.column() in [0, 1, 3]: return Qt.AlignHCenter return None def columnCount(self, parent): """ Public method to get the number of columns of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.column() > 0: return 0 else: return len(self.__headerData) def rowCount(self, parent): """ Public method to get the number of rows of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.isValid(): return 0 else: first, last = self.__tables[self.__currentTableIndex][:2] return last - first + 1 def __isDigit(self, char): """ Private method to check, if a character is a digit. @param char character to test (one character string) @return flag indicating a digit (boolean) """ return unicodedata.category(str(char)) == "Nd" def __isLetter(self, char): """ Private method to check, if a character is a letter. @param char character to test (one character string) @return flag indicating a letter (boolean) """ return unicodedata.category(str(char)) in ["Lu", "Ll", "Lt", "Lm", "Lo"] def __isMark(self, char): """ Private method to check, if a character is a mark character. @param char character to test (one character string) @return flag indicating a mark character (boolean) """ return unicodedata.category(str(char)) in ["Mn", "Mc", "Me"] def __isSymbol(self, char): """ Private method to check, if a character is a symbol. @param char character to test (one character string) @return flag indicating a symbol (boolean) """ return unicodedata.category(str(char)) in ["Sm", "Sc", "Sk", "So"] def __isPunct(self, char): """ Private method to check, if a character is a punctuation character. @param char character to test (one character string) @return flag indicating a punctuation character (boolean) """ return unicodedata.category(str(char)) in ["Pc", "Pd", "Ps", "Pe", "Pi", "Pf", "Po"] def getLocale(self): """ Public method to get the used locale. @return used locale @rtype QLocale """ return self.__locale
class SnapshotRegionGrabber(QWidget): """ Class implementing a grabber widget for a rectangular snapshot region. @signal grabbed(QPixmap) emitted after the region was grabbed """ grabbed = pyqtSignal(QPixmap) StrokeMask = 0 FillMask = 1 Rectangle = 0 Ellipse = 1 def __init__(self, mode=Rectangle): """ Constructor @param mode region grabber mode (SnapshotRegionGrabber.Rectangle or SnapshotRegionGrabber.Ellipse) """ super(SnapshotRegionGrabber, self).__init__( None, Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) assert mode in [SnapshotRegionGrabber.Rectangle, SnapshotRegionGrabber.Ellipse] self.__mode = mode self.__selection = QRect() self.__mouseDown = False self.__newSelection = False self.__handleSize = 10 self.__mouseOverHandle = None self.__showHelp = True self.__grabbing = False self.__dragStartPoint = QPoint() self.__selectionBeforeDrag = QRect() self.__locale = QLocale() # naming conventions for handles # T top, B bottom, R Right, L left # 2 letters: a corner # 1 letter: the handle on the middle of the corresponding side self.__TLHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__TRHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BLHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BRHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__LHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__THandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__RHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__handles = [self.__TLHandle, self.__TRHandle, self.__BLHandle, self.__BRHandle, self.__LHandle, self.__THandle, self.__RHandle, self.__BHandle] self.__helpTextRect = QRect() self.__helpText = self.tr( "Select a region using the mouse. To take the snapshot, press" " the Enter key or double click. Press Esc to quit.") self.__pixmap = QPixmap() self.setMouseTracking(True) QTimer.singleShot(200, self.__initialize) def __initialize(self): """ Private slot to initialize the rest of the widget. """ self.__desktop = QApplication.desktop() x = self.__desktop.x() y = self.__desktop.y() if qVersion() >= "5.0.0": self.__pixmap = QApplication.screens()[0].grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) else: self.__pixmap = QPixmap.grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) self.resize(self.__pixmap.size()) self.move(x, y) self.setCursor(Qt.CrossCursor) self.show() self.grabMouse() self.grabKeyboard() self.activateWindow() def paintEvent(self, evt): """ Protected method handling paint events. @param evt paint event (QPaintEvent) """ if self.__grabbing: # grabWindow() should just get the background return painter = QPainter(self) pal = QPalette(QToolTip.palette()) font = QToolTip.font() handleColor = pal.color(QPalette.Active, QPalette.Highlight) handleColor.setAlpha(160) overlayColor = QColor(0, 0, 0, 160) textColor = pal.color(QPalette.Active, QPalette.Text) textBackgroundColor = pal.color(QPalette.Active, QPalette.Base) painter.drawPixmap(0, 0, self.__pixmap) painter.setFont(font) r = QRect(self.__selection) if not self.__selection.isNull(): grey = QRegion(self.rect()) if self.__mode == SnapshotRegionGrabber.Ellipse: reg = QRegion(r, QRegion.Ellipse) else: reg = QRegion(r) grey = grey.subtracted(reg) painter.setClipRegion(grey) painter.setPen(Qt.NoPen) painter.setBrush(overlayColor) painter.drawRect(self.rect()) painter.setClipRect(self.rect()) drawRect(painter, r, handleColor) if self.__showHelp: painter.setPen(textColor) painter.setBrush(textBackgroundColor) self.__helpTextRect = painter.boundingRect( self.rect().adjusted(2, 2, -2, -2), Qt.TextWordWrap, self.__helpText).translated( -self.__desktop.x(), -self.__desktop.y()) self.__helpTextRect.adjust(-2, -2, 4, 2) drawRect(painter, self.__helpTextRect, textColor, textBackgroundColor) painter.drawText( self.__helpTextRect.adjusted(3, 3, -3, -3), Qt.TextWordWrap, self.__helpText) if self.__selection.isNull(): return # The grabbed region is everything which is covered by the drawn # rectangles (border included). This means that there is no 0px # selection, since a 0px wide rectangle will always be drawn as a line. txt = "{0}, {1} ({2} x {3})".format( self.__locale.toString(self.__selection.x()), self.__locale.toString(self.__selection.y()), self.__locale.toString(self.__selection.width()), self.__locale.toString(self.__selection.height()) ) textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt) boundingRect = textRect.adjusted(-4, 0, 0, 0) if textRect.width() < r.width() - 2 * self.__handleSize and \ textRect.height() < r.height() - 2 * self.__handleSize and \ r.width() > 100 and \ r.height() > 100: # center, unsuitable for small selections boundingRect.moveCenter(r.center()) textRect.moveCenter(r.center()) elif r.y() - 3 > textRect.height() and \ r.x() + textRect.width() < self.rect().width(): # on top, left aligned boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3)) textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3)) elif r.x() - 3 > textRect.width(): # left, top aligned boundingRect.moveTopRight(QPoint(r.x() - 3, r.y())) textRect.moveTopRight(QPoint(r.x() - 5, r.y())) elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \ r.right() > textRect.width(): # at bottom, right aligned boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3)) textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3)) elif r.right() + textRect.width() + 3 < self.rect().width(): # right, bottom aligned boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom())) textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom())) # If the above didn't catch it, you are running on a very # tiny screen... drawRect(painter, boundingRect, textColor, textBackgroundColor) painter.drawText(textRect, Qt.AlignHCenter, txt) if (r.height() > self.__handleSize * 2 and r.width() > self.__handleSize * 2) or \ not self.__mouseDown: self.__updateHandles() painter.setPen(Qt.NoPen) painter.setBrush(handleColor) painter.setClipRegion( self.__handleMask(SnapshotRegionGrabber.StrokeMask)) painter.drawRect(self.rect()) handleColor.setAlpha(60) painter.setBrush(handleColor) painter.setClipRegion( self.__handleMask(SnapshotRegionGrabber.FillMask)) painter.drawRect(self.rect()) def resizeEvent(self, evt): """ Protected method to handle resize events. @param evt resize event (QResizeEvent) """ if self.__selection.isNull(): return r = QRect(self.__selection) r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect())) r.setBottomRight(self.__limitPointToRect(r.bottomRight(), self.rect())) if r.width() <= 1 or r.height() <= 1: # This just results in ugly drawing... self.__selection = QRect() else: self.__selection = self.__normalizeSelection(r) def mousePressEvent(self, evt): """ Protected method to handle mouse button presses. @param evt mouse press event (QMouseEvent) """ self.__showHelp = not self.__helpTextRect.contains(evt.pos()) if evt.button() == Qt.LeftButton: self.__mouseDown = True self.__dragStartPoint = evt.pos() self.__selectionBeforeDrag = QRect(self.__selection) if not self.__selection.contains(evt.pos()): self.__newSelection = True self.__selection = QRect() else: self.setCursor(Qt.ClosedHandCursor) elif evt.button() == Qt.RightButton: self.__newSelection = False self.__selection = QRect() self.setCursor(Qt.CrossCursor) self.update() def mouseMoveEvent(self, evt): """ Protected method to handle mouse movements. @param evt mouse move event (QMouseEvent) """ shouldShowHelp = not self.__helpTextRect.contains(evt.pos()) if shouldShowHelp != self.__showHelp: self.__showHelp = shouldShowHelp self.update() if self.__mouseDown: if self.__newSelection: p = evt.pos() r = self.rect() self.__selection = self.__normalizeSelection( QRect(self.__dragStartPoint, self.__limitPointToRect(p, r))) elif self.__mouseOverHandle is None: # moving the whole selection r = self.rect().normalized() s = self.__selectionBeforeDrag.normalized() p = s.topLeft() + evt.pos() - self.__dragStartPoint r.setBottomRight( r.bottomRight() - QPoint(s.width(), s.height()) + QPoint(1, 1)) if not r.isNull() and r.isValid(): self.__selection.moveTo(self.__limitPointToRect(p, r)) else: # dragging a handle r = QRect(self.__selectionBeforeDrag) offset = evt.pos() - self.__dragStartPoint if self.__mouseOverHandle in \ [self.__TLHandle, self.__THandle, self.__TRHandle]: r.setTop(r.top() + offset.y()) if self.__mouseOverHandle in \ [self.__TLHandle, self.__LHandle, self.__BLHandle]: r.setLeft(r.left() + offset.x()) if self.__mouseOverHandle in \ [self.__BLHandle, self.__BHandle, self.__BRHandle]: r.setBottom(r.bottom() + offset.y()) if self.__mouseOverHandle in \ [self.__TRHandle, self.__RHandle, self.__BRHandle]: r.setRight(r.right() + offset.x()) r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect())) r.setBottomRight( self.__limitPointToRect(r.bottomRight(), self.rect())) self.__selection = self.__normalizeSelection(r) self.update() else: if self.__selection.isNull(): return found = False for r in self.__handles: if r.contains(evt.pos()): self.__mouseOverHandle = r found = True break if not found: self.__mouseOverHandle = None if self.__selection.contains(evt.pos()): self.setCursor(Qt.OpenHandCursor) else: self.setCursor(Qt.CrossCursor) else: if self.__mouseOverHandle in [self.__TLHandle, self.__BRHandle]: self.setCursor(Qt.SizeFDiagCursor) elif self.__mouseOverHandle in [self.__TRHandle, self.__BLHandle]: self.setCursor(Qt.SizeBDiagCursor) elif self.__mouseOverHandle in [self.__LHandle, self.__RHandle]: self.setCursor(Qt.SizeHorCursor) elif self.__mouseOverHandle in [self.__THandle, self.__BHandle]: self.setCursor(Qt.SizeVerCursor) def mouseReleaseEvent(self, evt): """ Protected method to handle mouse button releases. @param evt mouse release event (QMouseEvent) """ self.__mouseDown = False self.__newSelection = False if self.__mouseOverHandle is None and \ self.__selection.contains(evt.pos()): self.setCursor(Qt.OpenHandCursor) self.update() def mouseDoubleClickEvent(self, evt): """ Protected method to handle mouse double clicks. @param evt mouse double click event (QMouseEvent) """ self.__grabRect() def keyPressEvent(self, evt): """ Protected method to handle key presses. @param evt key press event (QKeyEvent) """ if evt.key() == Qt.Key_Escape: self.grabbed.emit(QPixmap()) elif evt.key() in [Qt.Key_Enter, Qt.Key_Return]: self.__grabRect() else: evt.ignore() def __updateHandles(self): """ Private method to update the handles. """ r = QRect(self.__selection) s2 = self.__handleSize // 2 self.__TLHandle.moveTopLeft(r.topLeft()) self.__TRHandle.moveTopRight(r.topRight()) self.__BLHandle.moveBottomLeft(r.bottomLeft()) self.__BRHandle.moveBottomRight(r.bottomRight()) self.__LHandle.moveTopLeft(QPoint(r.x(), r.y() + r.height() // 2 - s2)) self.__THandle.moveTopLeft(QPoint(r.x() + r.width() // 2 - s2, r.y())) self.__RHandle.moveTopRight( QPoint(r.right(), r.y() + r.height() // 2 - s2)) self.__BHandle.moveBottomLeft( QPoint(r.x() + r.width() // 2 - s2, r.bottom())) def __handleMask(self, maskType): """ Private method to calculate the handle mask. @param maskType type of the mask to be used (SnapshotRegionGrabber.FillMask or SnapshotRegionGrabber.StrokeMask) @return calculated mask (QRegion) """ mask = QRegion() for rect in self.__handles: if maskType == SnapshotRegionGrabber.StrokeMask: r = QRegion(rect) mask += r.subtracted(QRegion(rect.adjusted(1, 1, -1, -1))) else: mask += QRegion(rect.adjusted(1, 1, -1, -1)) return mask def __limitPointToRect(self, point, rect): """ Private method to limit the given point to the given rectangle. @param point point to be limited (QPoint) @param rect rectangle the point shall be limited to (QRect) @return limited point (QPoint) """ q = QPoint() if point.x() < rect.x(): q.setX(rect.x()) elif point.x() < rect.right(): q.setX(point.x()) else: q.setX(rect.right()) if point.y() < rect.y(): q.setY(rect.y()) elif point.y() < rect.bottom(): q.setY(point.y()) else: q.setY(rect.bottom()) return q def __normalizeSelection(self, sel): """ Private method to normalize the given selection. @param sel selection to be normalized (QRect) @return normalized selection (QRect) """ rect = QRect(sel) if rect.width() <= 0: left = rect.left() width = rect.width() rect.setLeft(left + width - 1) rect.setRight(left) if rect.height() <= 0: top = rect.top() height = rect.height() rect.setTop(top + height - 1) rect.setBottom(top) return rect def __grabRect(self): """ Private method to grab the selected rectangle (i.e. do the snapshot). """ if self.__mode == SnapshotRegionGrabber.Ellipse: ell = QRegion(self.__selection, QRegion.Ellipse) if not ell.isEmpty(): self.__grabbing = True xOffset = self.__pixmap.rect().x() - ell.boundingRect().x() yOffset = self.__pixmap.rect().y() - ell.boundingRect().y() translatedEll = ell.translated(xOffset, yOffset) pixmap2 = QPixmap(ell.boundingRect().size()) pixmap2.fill(Qt.transparent) pt = QPainter() pt.begin(pixmap2) if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff): pt.setRenderHints( QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.SmoothPixmapTransform, True) pt.setBrush(Qt.black) pt.setPen(QPen(QBrush(Qt.black), 0.5)) pt.drawEllipse(translatedEll.boundingRect()) pt.setCompositionMode(QPainter.CompositionMode_SourceIn) else: pt.setClipRegion(translatedEll) pt.setCompositionMode(QPainter.CompositionMode_Source) pt.drawPixmap(pixmap2.rect(), self.__pixmap, ell.boundingRect()) pt.end() self.grabbed.emit(pixmap2) else: r = QRect(self.__selection) if not r.isNull() and r.isValid(): self.__grabbing = True self.grabbed.emit(self.__pixmap.copy(r))
def refresh(self): # try to request money parameters try: params = self.community.parameters except Exception as e: logging.debug('community parameters error : ' + str(e)) return False # try to request money variables from last ud block try: block = self.community.get_ud_block() except Exception as e: logging.debug('community get_ud_block error : ' + str(e)) return False try: block_t_minus_1 = self.community.get_ud_block(1) except Exception as e: logging.debug('community get_ud_block error : ' + str(e)) return False if block: ud = self.get_referential_diff_value(block['dividend']) # if referential type is quantitative... if self.account.ref_type() == 'q': # display int values # use the float type of 64bits, to avoid display a 32bit signed integer... localized_ud = QLocale().toString(float(ud), 'f', 0) localized_mass_per_member = QLocale().toString( float(self.get_referential_diff_value(block['monetaryMass'] / block['membersCount'])), 'f', 0 ) localized_monetary_mass = QLocale().toString( float(self.get_referential_diff_value(block['monetaryMass'])), 'f', 0 ) else: # display float values localized_ud = QLocale().toString(ud, 'f', 6) localized_mass_per_member = QLocale().toString( self.get_referential_diff_value(block['monetaryMass'] / block['membersCount']), 'f', 6 ) localized_monetary_mass = QLocale().toString( self.get_referential_diff_value(block['monetaryMass']), 'f', 6 ) # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:2.2%} / {:} days</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( localized_ud, self.tr('Universal Dividend UD(t) in'), self.get_referential_diff_name(), localized_monetary_mass, self.tr('Monetary Mass M(t) in'), self.get_referential_diff_name(), block['membersCount'], self.tr('Members N(t)'), localized_mass_per_member, self.tr('Monetary Mass per member M(t)/N(t) in'), self.get_referential_diff_name(), block['dividend'] / (block_t_minus_1['monetaryMass'] / block_t_minus_1['membersCount']), params['dt'] / 86400, self.tr('Actual growth c = UD(t)/[M(t-1)/N(t-1)]'), QLocale.toString( QLocale(), QDateTime.fromTime_t(block['medianTime'] + params['dt']), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ), self.tr('Next UD date and time (t+1)') ) ) else: self.label_general.setText(self.tr('No Universal Dividend created yet.')) if block: # if referential type is quantitative... if self.account.ref_type() == 'q': # display int values localized_ud_t1 = QLocale().toString( float( self.get_referential_diff_value( math.ceil( max(block['dividend'], params['c'] * block['monetaryMass'] / block['membersCount']) ) ) ), 'f', 0 ) else: # display float values localized_ud_t1 = QLocale().toString( float( self.get_referential_diff_value( math.ceil( max(block['dividend'], params['c'] * block['monetaryMass'] / block['membersCount']) ) ) ), 'f', 6 ) # set infos in label self.label_rules.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.tr('{:2.0%} / {:} days').format(params['c'], params['dt'] / 86400), self.tr('Fundamental growth (c) / Delta time (dt)'), self.tr('UD(t+1) = MAX { UD(t) ; c × M(t) / N(t) }'), self.tr('Universal Dividend (formula)'), self.tr('{:} = MAX {{ {:} {:} ; {:2.0%} × {:} {:} / {:} }}').format( localized_ud_t1, localized_ud, self.get_referential_diff_name(), params['c'], localized_monetary_mass, self.get_referential_diff_name(), block['membersCount'] ), self.tr('Universal Dividend (computed)') ) ) else: self.label_rules.setText(self.tr('No Universal Dividend created yet.')) # set infos in label self.label_money.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr> </table> """).format( params['c'], params['dt'] / 86400, self.tr('Fundamental growth (c)'), params['ud0'], self.tr('Initial Universal Dividend UD(0) in'), self.community.short_currency, params['dt'] / 86400, self.tr('Time period (dt) in days (86400 seconds) between two UD'), params['medianTimeBlocks'], self.tr('Number of blocks used for calculating median time'), params['avgGenTime'], self.tr('The average time in seconds for writing 1 block (wished time)'), params['dtDiffEval'], self.tr('The number of blocks required to evaluate again PoWMin value'), params['blocksRot'], self.tr('The number of previous blocks to check for personalized difficulty'), params['percentRot'], self.tr('The percent of previous issuers to reach for personalized difficulty') ) ) # set infos in label self.label_wot.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( params['sigDelay'] / 86400, self.tr('Minimum delay between 2 identical certifications (in days)'), params['sigValidity'] / 86400, self.tr('Maximum age of a valid signature (in days)'), params['sigQty'], self.tr('Minimum quantity of signatures to be part of the WoT'), params['sigWoT'], self.tr('Minimum quantity of valid made certifications to be part of the WoT for distance rule'), params['msValidity'] / 86400, self.tr('Maximum age of a valid membership (in days)'), params['stepMax'], self.tr('Maximum distance between each WoT member and a newcomer'), ) )
def data(self, index, role): source_index = self.mapToSource(index) model = self.sourceModel() source_data = model.data(source_index, role) state_col = model.columns_types.index('state') state_index = model.index(source_index.row(), state_col) state_data = model.data(state_index, Qt.DisplayRole) block_col = model.columns_types.index('block_number') block_index = model.index(source_index.row(), block_col) block_data = model.data(block_index, Qt.DisplayRole) if state_data == Transaction.VALIDATED and block_data: current_confirmations = self.blockchain_service.current_buid( ).number - block_data else: current_confirmations = 0 if role == Qt.DisplayRole: if source_index.column() == model.columns_types.index('uid'): return source_data if source_index.column() == model.columns_types.index('date'): return QLocale.toString( QLocale(), QDateTime.fromTime_t(source_data).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat)) if source_index.column() == model.columns_types.index('amount'): amount = self.app.current_ref.instance( source_data, model.connection.currency, self.app, block_data).diff_localized(False, False) return amount if role == Qt.FontRole: font = QFont() if state_data == Transaction.AWAITING or \ (state_data == Transaction.VALIDATED and current_confirmations < MAX_CONFIRMATIONS): font.setItalic(True) elif state_data == Transaction.REFUSED: font.setItalic(True) elif state_data == Transaction.TO_SEND: font.setBold(True) else: font.setItalic(False) return font if role == Qt.ForegroundRole: if state_data == Transaction.REFUSED: return QColor(Qt.darkGray) elif state_data == Transaction.TO_SEND: return QColor(Qt.blue) if source_index.column() == model.columns_types.index('amount'): if source_data < 0: return QColor(Qt.darkRed) elif state_data == HistoryTableModel.DIVIDEND: return QColor(Qt.darkBlue) if role == Qt.TextAlignmentRole: if self.sourceModel().columns_types.index('amount'): return Qt.AlignRight | Qt.AlignVCenter if source_index.column() == model.columns_types.index('date'): return Qt.AlignCenter if role == Qt.ToolTipRole: if source_index.column() == model.columns_types.index('date'): return QDateTime.fromTime_t(source_data).toString( Qt.SystemLocaleLongDate) if state_data == Transaction.VALIDATED or state_data == Transaction.AWAITING: if current_confirmations >= MAX_CONFIRMATIONS: return None elif self.app.parameters.expert_mode: return self.tr("{0} / {1} confirmations").format( current_confirmations, MAX_CONFIRMATIONS) else: confirmation = current_confirmations / MAX_CONFIRMATIONS * 100 confirmation = 100 if confirmation > 100 else confirmation return self.tr("Confirming... {0} %").format( QLocale().toString(float(confirmation), 'f', 0)) return None return source_data
def refresh_informations_frame(self): parameters = self.community.parameters try: identity = yield from self.account.identity(self.community) membership = identity.membership(self.community) renew_block = membership['blockNumber'] last_renewal = self.community.get_block(renew_block)['medianTime'] expiration = last_renewal + parameters['sigValidity'] except MembershipNotFoundError: last_renewal = None expiration = None certified = yield from identity.unique_valid_certified_by(self.app.identities_registry, self.community) certifiers = yield from identity.unique_valid_certifiers_of(self.app.identities_registry, self.community) if last_renewal and expiration: date_renewal = QLocale.toString( QLocale(), QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat) ) date_expiration = QLocale.toString( QLocale(), QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat) ) if self.account.pubkey in self.community.members_pubkeys(): # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Membership"), self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration), self.tr("Your web of trust"), self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers), len(certified)) ) ) else: # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Not a member"), self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration), self.tr("Your web of trust"), self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers), len(certified)) ) ) else: # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Not a member"), self.tr("Your web of trust"), self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers), len(certified)) ) )
def refresh(self): parameters = self.community.parameters last_renewal = "" expiration = "" try: person = Person.lookup(self.account.pubkey, self.community) membership = person.membership(self.community) renew_block = membership['blockNumber'] last_renewal = self.community.get_block(renew_block).mediantime expiration = last_renewal + parameters['sigValidity'] except MembershipNotFoundError: last_renewal = None expiration = None certified = person.unique_valid_certified_by(self.community) certifiers = person.unique_valid_certifiers_of(self.community) if last_renewal and expiration: date_renewal = QLocale.toString( QLocale(), QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)) date_expiration = QLocale.toString( QLocale(), QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)) # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Membership"), self.tr("Last renewal on {:}, expiration on {:}").format( date_renewal, date_expiration), self.tr("Your web of trust"), self.tr( "Certified by {:} members; Certifier of {:} members"). format(len(certifiers), len(certified)))) else: # set infos in label self.label_general.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.account.name, self.account.pubkey, self.tr("Not a member"), self.tr("Your web of trust"), self.tr( "Certified by {:} members; Certifier of {:} members"). format(len(certifiers), len(certified)))) amount = self.account.amount(self.community) maximum = self.community.monetary_mass # if referential type is quantitative... if self.account.ref_type() == 'q': # display int values localized_amount = QLocale().toString( float(self.get_referential_value(amount)), 'f', 0) localized_minimum = QLocale().toString( float(self.get_referential_value(0)), 'f', 0) localized_maximum = QLocale().toString( float(self.get_referential_value(maximum)), 'f', 0) else: # display float values localized_amount = QLocale().toString( float(self.get_referential_value(amount)), 'f', 6) localized_minimum = QLocale().toString( float(self.get_referential_value(0)), 'f', 6) localized_maximum = QLocale().toString( float(self.get_referential_value(maximum)), 'f', 6) # set infos in label self.label_balance.setText( self.tr(""" <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( self.tr("Your money share "), self.tr("{:.2f}%").format(amount / maximum * 100) if maximum != 0 else "0%", self.tr("Your part "), self.tr("{:} {:} in [{:} ; {:}] {:}").format( localized_amount, self.get_referential_name(), localized_minimum, localized_maximum, self.get_referential_name()))) wallets_model = WalletsTableModel(self.account, self.community) proxy_model = WalletsFilterProxyModel() proxy_model.setSourceModel(wallets_model) wallets_model.dataChanged.connect(self.wallet_changed) self.table_wallets.setModel(proxy_model) self.table_wallets.resizeColumnsToContents()
def get_localized_data(self): localized_data = {} # try to request money parameters try: params = self.blockchain_service.parameters() except NoPeerAvailable as e: logging.debug('community parameters error : ' + str(e)) return None localized_data['currency'] = ROOT_SERVERS[self.connection.currency]["display"] localized_data['growth'] = params.c localized_data['days_per_dividend'] = QLocale().toString(params.dt / 86400, 'f', 2) last_ud, last_ud_base = self.blockchain_service.last_ud() members_count = self.blockchain_service.last_members_count() previous_ud, previous_ud_base = self.blockchain_service.previous_ud() previous_ud_time = self.blockchain_service.previous_ud_time() previous_monetary_mass = self.blockchain_service.previous_monetary_mass() previous_members_count = self.blockchain_service.previous_members_count() localized_data['units'] = self.app.current_ref.instance(0, self.connection.currency, self.app, None).units localized_data['diff_units'] = self.app.current_ref.instance(0, self.connection.currency, self.app, None).diff_units if last_ud: # display float values localized_data['ud'] = self.app.current_ref.instance(last_ud * math.pow(10, last_ud_base), self.connection.currency, self.app).diff_localized(False, True) localized_data['members_count'] = self.blockchain_service.current_members_count() computed_dividend = self.blockchain_service.computed_dividend() # display float values localized_data['ud_plus_1'] = self.app.current_ref.instance(computed_dividend, self.connection.currency, self.app).diff_localized(False, True) localized_data['mass'] = self.app.current_ref.instance(self.blockchain_service.current_mass(), self.connection.currency, self.app).localized(False, True) ud_median_time = self.blockchain_service.last_ud_time() ud_median_time = self.blockchain_processor.adjusted_ts(self.app.currency, ud_median_time) localized_data['ud_median_time'] = QLocale.toString( QLocale(), QDateTime.fromTime_t(ud_median_time), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) next_ud_median_time = self.blockchain_service.last_ud_time() + params.dt next_ud_median_time = self.blockchain_processor.adjusted_ts(self.app.currency, next_ud_median_time) localized_data['next_ud_median_time'] = QLocale.toString( QLocale(), QDateTime.fromTime_t(next_ud_median_time), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) next_ud_reeval = self.blockchain_service.next_ud_reeval() next_ud_reeval = self.blockchain_processor.adjusted_ts(self.app.currency, next_ud_reeval) localized_data['next_ud_reeval'] = QLocale.toString( QLocale(), QDateTime.fromTime_t(next_ud_reeval), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) if previous_ud: mass_minus_1_per_member = (float(0) if previous_ud == 0 or previous_members_count == 0 else previous_monetary_mass / previous_members_count) localized_data['mass_minus_1_per_member'] = self.app.current_ref.instance(mass_minus_1_per_member, self.connection.currency, self.app) \ .localized(False, True) localized_data['mass_minus_1'] = self.app.current_ref.instance(previous_monetary_mass, self.connection.currency, self.app) \ .localized(False, True) # avoid divide by zero ! if members_count == 0 or previous_members_count == 0: localized_data['actual_growth'] = float(0) else: localized_data['actual_growth'] = (last_ud * math.pow(10, last_ud_base)) / ( previous_monetary_mass / members_count) previous_ud_time = self.blockchain_processor.adjusted_ts(self.app.currency, previous_ud_time) localized_data['ud_median_time_minus_1'] = QLocale.toString( QLocale(), QDateTime.fromTime_t(previous_ud_time), QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) ) return localized_data
class SnapshotFreehandGrabber(QWidget): """ Class implementing a grabber widget for a freehand snapshot region. @signal grabbed(QPixmap) emitted after the region was grabbed """ grabbed = pyqtSignal(QPixmap) def __init__(self): """ Constructor """ super(SnapshotFreehandGrabber, self).__init__( None, Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) self.__selection = QPolygon() self.__mouseDown = False self.__newSelection = False self.__handleSize = 10 self.__showHelp = True self.__grabbing = False self.__dragStartPoint = QPoint() self.__selectionBeforeDrag = QPolygon() self.__locale = QLocale() self.__helpTextRect = QRect() self.__helpText = self.tr( "Select a region using the mouse. To take the snapshot," " press the Enter key or double click. Press Esc to quit.") self.__pixmap = QPixmap() self.__pBefore = QPoint() self.setMouseTracking(True) QTimer.singleShot(200, self.__initialize) def __initialize(self): """ Private slot to initialize the rest of the widget. """ self.__desktop = QApplication.desktop() x = self.__desktop.x() y = self.__desktop.y() if qVersion() >= "5.0.0": self.__pixmap = QApplication.screens()[0].grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) else: self.__pixmap = QPixmap.grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) self.resize(self.__pixmap.size()) self.move(x, y) self.setCursor(Qt.CrossCursor) self.show() self.grabMouse() self.grabKeyboard() self.activateWindow() def paintEvent(self, evt): """ Protected method handling paint events. @param evt paint event (QPaintEvent) """ if self.__grabbing: # grabWindow() should just get the background return painter = QPainter(self) pal = QPalette(QToolTip.palette()) font = QToolTip.font() handleColor = pal.color(QPalette.Active, QPalette.Highlight) handleColor.setAlpha(160) overlayColor = QColor(0, 0, 0, 160) textColor = pal.color(QPalette.Active, QPalette.Text) textBackgroundColor = pal.color(QPalette.Active, QPalette.Base) painter.drawPixmap(0, 0, self.__pixmap) painter.setFont(font) pol = QPolygon(self.__selection) if not self.__selection.boundingRect().isNull(): # Draw outline around selection. # Important: the 1px-wide outline is *also* part of the # captured free-region pen = QPen(handleColor, 1, Qt.SolidLine, Qt.SquareCap, Qt.BevelJoin) painter.setPen(pen) painter.drawPolygon(pol) # Draw the grey area around the selection. grey = QRegion(self.rect()) grey = grey - QRegion(pol) painter.setClipRegion(grey) painter.setPen(Qt.NoPen) painter.setBrush(overlayColor) painter.drawRect(self.rect()) painter.setClipRect(self.rect()) drawPolygon(painter, pol, handleColor) if self.__showHelp: painter.setPen(textColor) painter.setBrush(textBackgroundColor) self.__helpTextRect = painter.boundingRect( self.rect().adjusted(2, 2, -2, -2), Qt.TextWordWrap, self.__helpText).translated( -self.__desktop.x(), -self.__desktop.y()) self.__helpTextRect.adjust(-2, -2, 4, 2) drawPolygon(painter, self.__helpTextRect, textColor, textBackgroundColor) painter.drawText( self.__helpTextRect.adjusted(3, 3, -3, -3), Qt.TextWordWrap, self.__helpText) if self.__selection.isEmpty(): return # The grabbed region is everything which is covered by the drawn # rectangles (border included). This means that there is no 0px # selection, since a 0px wide rectangle will always be drawn as a line. boundingRect = self.__selection.boundingRect() txt = "{0}, {1} ({2} x {3})".format( self.__locale.toString(boundingRect.x()), self.__locale.toString(boundingRect.y()), self.__locale.toString(boundingRect.width()), self.__locale.toString(boundingRect.height()) ) textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt) boundingRect = textRect.adjusted(-4, 0, 0, 0) polBoundingRect = pol.boundingRect() if (textRect.width() < polBoundingRect.width() - 2 * self.__handleSize) and \ (textRect.height() < polBoundingRect.height() - 2 * self.__handleSize) and \ polBoundingRect.width() > 100 and \ polBoundingRect.height() > 100: # center, unsuitable for small selections boundingRect.moveCenter(polBoundingRect.center()) textRect.moveCenter(polBoundingRect.center()) elif polBoundingRect.y() - 3 > textRect.height() and \ polBoundingRect.x() + textRect.width() < self.rect().width(): # on top, left aligned boundingRect.moveBottomLeft( QPoint(polBoundingRect.x(), polBoundingRect.y() - 3)) textRect.moveBottomLeft( QPoint(polBoundingRect.x() + 2, polBoundingRect.y() - 3)) elif polBoundingRect.x() - 3 > textRect.width(): # left, top aligned boundingRect.moveTopRight( QPoint(polBoundingRect.x() - 3, polBoundingRect.y())) textRect.moveTopRight( QPoint(polBoundingRect.x() - 5, polBoundingRect.y())) elif (polBoundingRect.bottom() + 3 + textRect.height() < self.rect().bottom()) and \ polBoundingRect.right() > textRect.width(): # at bottom, right aligned boundingRect.moveTopRight( QPoint(polBoundingRect.right(), polBoundingRect.bottom() + 3)) textRect.moveTopRight( QPoint(polBoundingRect.right() - 2, polBoundingRect.bottom() + 3)) elif polBoundingRect.right() + textRect.width() + 3 < \ self.rect().width(): # right, bottom aligned boundingRect.moveBottomLeft( QPoint(polBoundingRect.right() + 3, polBoundingRect.bottom())) textRect.moveBottomLeft( QPoint(polBoundingRect.right() + 5, polBoundingRect.bottom())) # If the above didn't catch it, you are running on a very # tiny screen... drawPolygon(painter, boundingRect, textColor, textBackgroundColor) painter.drawText(textRect, Qt.AlignHCenter, txt) if (polBoundingRect.height() > self.__handleSize * 2 and polBoundingRect.width() > self.__handleSize * 2) or \ not self.__mouseDown: painter.setBrush(Qt.transparent) painter.setClipRegion(QRegion(pol)) painter.drawPolygon(QPolygon(self.rect())) def mousePressEvent(self, evt): """ Protected method to handle mouse button presses. @param evt mouse press event (QMouseEvent) """ self.__pBefore = evt.pos() self.__showHelp = not self.__helpTextRect.contains(evt.pos()) if evt.button() == Qt.LeftButton: self.__mouseDown = True self.__dragStartPoint = evt.pos() self.__selectionBeforeDrag = QPolygon(self.__selection) if not self.__selection.containsPoint(evt.pos(), Qt.WindingFill): self.__newSelection = True self.__selection = QPolygon() else: self.setCursor(Qt.ClosedHandCursor) elif evt.button() == Qt.RightButton: self.__newSelection = False self.__selection = QPolygon() self.setCursor(Qt.CrossCursor) self.update() def mouseMoveEvent(self, evt): """ Protected method to handle mouse movements. @param evt mouse move event (QMouseEvent) """ shouldShowHelp = not self.__helpTextRect.contains(evt.pos()) if shouldShowHelp != self.__showHelp: self.__showHelp = shouldShowHelp self.update() if self.__mouseDown: if self.__newSelection: p = evt.pos() self.__selection.append(p) else: # moving the whole selection p = evt.pos() - self.__pBefore # Offset self.__pBefore = evt.pos() # save position for next iteration self.__selection.translate(p) self.update() else: if self.__selection.boundingRect().isEmpty(): return if self.__selection.containsPoint(evt.pos(), Qt.WindingFill): self.setCursor(Qt.OpenHandCursor) else: self.setCursor(Qt.CrossCursor) def mouseReleaseEvent(self, evt): """ Protected method to handle mouse button releases. @param evt mouse release event (QMouseEvent) """ self.__mouseDown = False self.__newSelection = False if self.__selection.containsPoint(evt.pos(), Qt.WindingFill): self.setCursor(Qt.OpenHandCursor) self.update() def mouseDoubleClickEvent(self, evt): """ Protected method to handle mouse double clicks. @param evt mouse double click event (QMouseEvent) """ self.__grabRegion() def keyPressEvent(self, evt): """ Protected method to handle key presses. @param evt key press event (QKeyEvent) """ if evt.key() == Qt.Key_Escape: self.grabbed.emit(QPixmap()) elif evt.key() in [Qt.Key_Enter, Qt.Key_Return]: self.__grabRegion() else: evt.ignore() def __grabRegion(self): """ Private method to grab the selected region (i.e. do the snapshot). """ pol = QPolygon(self.__selection) if not pol.isEmpty(): self.__grabbing = True xOffset = self.__pixmap.rect().x() - pol.boundingRect().x() yOffset = self.__pixmap.rect().y() - pol.boundingRect().y() translatedPol = pol.translated(xOffset, yOffset) pixmap2 = QPixmap(pol.boundingRect().size()) pixmap2.fill(Qt.transparent) pt = QPainter() pt.begin(pixmap2) if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff): pt.setRenderHints( QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.SmoothPixmapTransform, True) pt.setBrush(Qt.black) pt.setPen(QPen(QBrush(Qt.black), 0.5)) pt.drawPolygon(translatedPol) pt.setCompositionMode(QPainter.CompositionMode_SourceIn) else: pt.setClipRegion(QRegion(translatedPol)) pt.setCompositionMode(QPainter.CompositionMode_Source) pt.drawPixmap(pixmap2.rect(), self.__pixmap, pol.boundingRect()) pt.end() self.grabbed.emit(pixmap2)
class SnapWidget(QWidget, Ui_SnapWidget): """ Class implementing the snapshot widget. """ ModeFullscreen = 0 ModeScreen = 1 ModeRectangle = 2 ModeFreehand = 3 ModeEllipse = 4 def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(SnapWidget, self).__init__(parent) self.setupUi(self) self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSaveAs.png")) self.takeButton.setIcon(UI.PixmapCache.getIcon("cameraPhoto.png")) self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png")) self.copyPreviewButton.setIcon(UI.PixmapCache.getIcon("editCopy.png")) self.setWindowIcon(UI.PixmapCache.getIcon("ericSnap.png")) self.modeCombo.addItem(self.tr("Fullscreen"), SnapWidget.ModeFullscreen) self.modeCombo.addItem(self.tr("Rectangular Selection"), SnapWidget.ModeRectangle) self.modeCombo.addItem(self.tr("Ellipical Selection"), SnapWidget.ModeEllipse) self.modeCombo.addItem(self.tr("Freehand Selection"), SnapWidget.ModeFreehand) if QApplication.desktop().screenCount() > 1: self.modeCombo.addItem(self.tr("Current Screen"), SnapWidget.ModeScreen) self.__mode = int(Preferences.Prefs.settings.value("Snapshot/Mode", 0)) index = self.modeCombo.findData(self.__mode) if index == -1: index = 0 self.modeCombo.setCurrentIndex(index) self.__delay = int( Preferences.Prefs.settings.value("Snapshot/Delay", 0)) self.delaySpin.setValue(self.__delay) if PYQT_VERSION_STR >= "5.0.0": from PyQt5.QtCore import QStandardPaths picturesLocation = QStandardPaths.writableLocation( QStandardPaths.PicturesLocation) else: from PyQt5.QtGui import QDesktopServices picturesLocation = QDesktopServices.storageLocation( QDesktopServices.PicturesLocation) self.__filename = Preferences.Prefs.settings.value( "Snapshot/Filename", os.path.join(picturesLocation, self.tr("snapshot") + "1.png")) self.__grabber = None self.__snapshot = QPixmap() self.__savedPosition = QPoint() self.__modified = False self.__locale = QLocale() self.__grabberWidget = QWidget(None, Qt.X11BypassWindowManagerHint) self.__grabberWidget.move(-10000, -10000) self.__grabberWidget.installEventFilter(self) self.__initFileFilters() self.__initShortcuts() self.preview.startDrag.connect(self.__dragSnapshot) from .SnapshotTimer import SnapshotTimer self.__grabTimer = SnapshotTimer() self.__grabTimer.timeout.connect(self.__grabTimerTimeout) self.__updateTimer = QTimer() self.__updateTimer.setSingleShot(True) self.__updateTimer.timeout.connect(self.__updatePreview) self.__updateCaption() self.takeButton.setFocus() def __initFileFilters(self): """ Private method to define the supported image file filters. """ filters = { 'bmp': self.tr("Windows Bitmap File (*.bmp)"), 'gif': self.tr("Graphic Interchange Format File (*.gif)"), 'ico': self.tr("Windows Icon File (*.ico)"), 'jpg': self.tr("JPEG File (*.jpg)"), 'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"), 'pbm': self.tr("Portable Bitmap File (*.pbm)"), 'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"), 'pgm': self.tr("Portable Graymap File (*.pgm)"), 'png': self.tr("Portable Network Graphics File (*.png)"), 'ppm': self.tr("Portable Pixmap File (*.ppm)"), 'sgi': self.tr("Silicon Graphics Image File (*.sgi)"), 'svg': self.tr("Scalable Vector Graphics File (*.svg)"), 'tga': self.tr("Targa Graphic File (*.tga)"), 'tif': self.tr("TIFF File (*.tif)"), 'xbm': self.tr("X11 Bitmap File (*.xbm)"), 'xpm': self.tr("X11 Pixmap File (*.xpm)"), } outputFormats = [] writeFormats = QImageWriter.supportedImageFormats() for writeFormat in writeFormats: try: outputFormats.append(filters[bytes(writeFormat).decode()]) except KeyError: pass outputFormats.sort() self.__outputFilter = ';;'.join(outputFormats) self.__defaultFilter = filters['png'] def __initShortcuts(self): """ Private method to initialize the keyboard shortcuts. """ self.__quitShortcut = QShortcut( QKeySequence(QKeySequence.Quit), self, self.close) self.__copyShortcut = QShortcut( QKeySequence(QKeySequence.Copy), self, self.copyButton.animateClick) self.__quickSaveShortcut = QShortcut( QKeySequence(Qt.Key_Q), self, self.__quickSave) self.__save1Shortcut = QShortcut( QKeySequence(QKeySequence.Save), self, self.saveButton.animateClick) self.__save2Shortcut = QShortcut( QKeySequence(Qt.Key_S), self, self.saveButton.animateClick) self.__grab1Shortcut = QShortcut( QKeySequence(QKeySequence.New), self, self.takeButton.animateClick) self.__grab2Shortcut = QShortcut( QKeySequence(Qt.Key_N), self, self.takeButton.animateClick) self.__grab3Shortcut = QShortcut( QKeySequence(Qt.Key_Space), self, self.takeButton.animateClick) def __quickSave(self): """ Private slot to save the snapshot bypassing the file selection dialog. """ if not self.__snapshot.isNull(): while os.path.exists(self.__filename): self.__autoIncFilename() if self.__saveImage(self.__filename): self.__modified = False self.__autoIncFilename() self.__updateCaption() @pyqtSlot() def on_saveButton_clicked(self): """ Private slot to save the snapshot. """ if not self.__snapshot.isNull(): while os.path.exists(self.__filename): self.__autoIncFilename() fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Snapshot"), self.__filename, self.__outputFilter, self.__defaultFilter, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fileName: return ext = QFileInfo(fileName).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fileName += ex if self.__saveImage(fileName): self.__modified = False self.__filename = fileName self.__autoIncFilename() self.__updateCaption() def __saveImage(self, fileName): """ Private method to save the snapshot. @param fileName name of the file to save to (string) @return flag indicating success (boolean) """ if QFileInfo(fileName).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Snapshot"), self.tr("<p>The file <b>{0}</b> already exists." " Overwrite it?</p>").format(fileName), icon=E5MessageBox.Warning) if not res: return False file = QFile(fileName) if not file.open(QFile.WriteOnly): E5MessageBox.warning( self, self.tr("Save Snapshot"), self.tr("Cannot write file '{0}:\n{1}.") .format(fileName, file.errorString())) return False ok = self.__snapshot.save(file) file.close() if not ok: E5MessageBox.warning( self, self.tr("Save Snapshot"), self.tr("Cannot write file '{0}:\n{1}.") .format(fileName, file.errorString())) return ok def __autoIncFilename(self): """ Private method to auto-increment the file name. """ # Extract the file name name = os.path.basename(self.__filename) # If the name contains a number, then increment it. numSearch = QRegExp("(^|[^\\d])(\\d+)") # We want to match as far left as possible, and when the number is # at the start of the name. # Does it have a number? start = numSearch.lastIndexIn(name) if start != -1: # It has a number, increment it. start = numSearch.pos(2) # Only the second group is of interest. numAsStr = numSearch.capturedTexts()[2] number = "{0:0{width}d}".format( int(numAsStr) + 1, width=len(numAsStr)) name = name[:start] + number + name[start + len(numAsStr):] else: # no number start = name.rfind('.') if start != -1: # has a '.' somewhere, e.g. it has an extension name = name[:start] + '1' + name[start:] else: # no extension, just tack it on to the end name += '1' self.__filename = os.path.join(os.path.dirname(self.__filename), name) self.__updateCaption() @pyqtSlot() def on_takeButton_clicked(self): """ Private slot to take a snapshot. """ self.__mode = self.modeCombo.itemData(self.modeCombo.currentIndex()) self.__delay = self.delaySpin.value() self.__savedPosition = self.pos() self.hide() if self.__delay: self.__grabTimer.start(self.__delay) else: QTimer.singleShot(200, self.__startUndelayedGrab) def __grabTimerTimeout(self): """ Private slot to perform a delayed grab operation. """ if self.__mode == SnapWidget.ModeRectangle: self.__grabRectangle() elif self.__mode == SnapWidget.ModeEllipse: self.__grabEllipse() elif self.__mode == SnapWidget.ModeFreehand: self.__grabFreehand() else: self.__performGrab() def __startUndelayedGrab(self): """ Private slot to perform an undelayed grab operation. """ if self.__mode == SnapWidget.ModeRectangle: self.__grabRectangle() elif self.__mode == SnapWidget.ModeEllipse: self.__grabEllipse() elif self.__mode == SnapWidget.ModeFreehand: self.__grabFreehand() else: if Globals.isMacPlatform(): self.__performGrab() else: self.__grabberWidget.show() self.__grabberWidget.grabMouse(Qt.CrossCursor) def __grabRectangle(self): """ Private method to grab a rectangular screen region. """ from .SnapshotRegionGrabber import SnapshotRegionGrabber self.__grabber = SnapshotRegionGrabber( mode=SnapshotRegionGrabber.Rectangle) self.__grabber.grabbed.connect(self.__captured) def __grabEllipse(self): """ Private method to grab an elliptical screen region. """ from .SnapshotRegionGrabber import SnapshotRegionGrabber self.__grabber = SnapshotRegionGrabber( mode=SnapshotRegionGrabber.Ellipse) self.__grabber.grabbed.connect(self.__captured) def __grabFreehand(self): """ Private method to grab a non-rectangular screen region. """ from .SnapshotFreehandGrabber import SnapshotFreehandGrabber self.__grabber = SnapshotFreehandGrabber() self.__grabber.grabbed.connect(self.__captured) def __performGrab(self): """ Private method to perform a screen grab other than a selected region. """ self.__grabberWidget.releaseMouse() self.__grabberWidget.hide() self.__grabTimer.stop() if self.__mode == SnapWidget.ModeFullscreen: desktop = QApplication.desktop() if qVersion() >= "5.0.0": self.__snapshot = QApplication.screens()[0].grabWindow( desktop.winId(), desktop.x(), desktop.y(), desktop.width(), desktop.height()) else: self.__snapshot = QPixmap.grabWindow( desktop.winId(), desktop.x(), desktop.y(), desktop.width(), desktop.height()) elif self.__mode == SnapWidget.ModeScreen: desktop = QApplication.desktop() screenId = desktop.screenNumber(QCursor.pos()) geom = desktop.screenGeometry(screenId) x = geom.x() y = geom.y() if qVersion() >= "5.0.0": self.__snapshot = QApplication.screens()[0].grabWindow( desktop.winId(), x, y, geom.width(), geom.height()) else: self.__snapshot = QPixmap.grabWindow( desktop.winId(), x, y, geom.width(), geom.height()) else: self.__snapshot = QPixmap() self.__redisplay() self.__modified = True self.__updateCaption() def __redisplay(self): """ Private method to redisplay the window. """ self.__updatePreview() QApplication.restoreOverrideCursor() if not self.__savedPosition.isNull(): self.move(self.__savedPosition) self.show() self.raise_() self.saveButton.setEnabled(not self.__snapshot.isNull()) self.copyButton.setEnabled(not self.__snapshot.isNull()) self.copyPreviewButton.setEnabled(not self.__snapshot.isNull()) @pyqtSlot() def on_copyButton_clicked(self): """ Private slot to copy the snapshot to the clipboard. """ if not self.__snapshot.isNull(): QApplication.clipboard().setPixmap(QPixmap(self.__snapshot)) @pyqtSlot() def on_copyPreviewButton_clicked(self): """ Private slot to copy the snapshot preview to the clipboard. """ QApplication.clipboard().setPixmap(self.preview.pixmap()) def __captured(self, pixmap): """ Private slot to show a preview of the snapshot. @param pixmap pixmap of the snapshot (QPixmap) """ self.__grabber.close() self.__snapshot = QPixmap(pixmap) self.__grabber.grabbed.disconnect(self.__captured) self.__grabber = None self.__redisplay() self.__modified = True self.__updateCaption() def __updatePreview(self): """ Private slot to update the preview picture. """ self.preview.setToolTip(self.tr( "Preview of the snapshot image ({0} x {1})").format( self.__locale.toString(self.__snapshot.width()), self.__locale.toString(self.__snapshot.height())) ) self.preview.setPreview(self.__snapshot) self.preview.adjustSize() def resizeEvent(self, evt): """ Protected method handling a resizing of the window. @param evt resize event (QResizeEvent) """ self.__updateTimer.start(200) def __dragSnapshot(self): """ Private slot handling the dragging of the preview picture. """ drag = QDrag(self) mimeData = QMimeData() mimeData.setImageData(self.__snapshot) drag.setMimeData(mimeData) drag.setPixmap(self.preview.pixmap()) drag.exec_(Qt.CopyAction) def eventFilter(self, obj, evt): """ Public method to handle event for other objects. @param obj reference to the object (QObject) @param evt reference to the event (QEvent) @return flag indicating that the event should be filtered out (boolean) """ if obj == self.__grabberWidget and \ evt.type() == QEvent.MouseButtonPress: if QWidget.mouseGrabber() != self.__grabberWidget: return False if evt.button() == Qt.LeftButton: self.__performGrab() return False def closeEvent(self, evt): """ Protected method handling the close event. @param evt close event (QCloseEvent) """ if self.__modified: res = E5MessageBox.question( self, self.tr("eric6 Snapshot"), self.tr( """The application contains an unsaved snapshot."""), E5MessageBox.StandardButtons( E5MessageBox.Abort | E5MessageBox.Discard | E5MessageBox.Save)) if res == E5MessageBox.Abort: evt.ignore() return elif res == E5MessageBox.Save: self.on_saveButton_clicked() Preferences.Prefs.settings.setValue( "Snapshot/Delay", self.delaySpin.value()) Preferences.Prefs.settings.setValue( "Snapshot/Mode", self.modeCombo.itemData(self.modeCombo.currentIndex())) Preferences.Prefs.settings.setValue( "Snapshot/Filename", self.__filename) Preferences.Prefs.settings.sync() def __updateCaption(self): """ Private method to update the window caption. """ self.setWindowTitle("{0}[*] - {1}".format( os.path.basename(self.__filename), self.tr("eric6 Snapshot"))) self.setWindowModified(self.__modified) self.pathNameEdit.setText(os.path.dirname(self.__filename))
class SnapshotRegionGrabber(QWidget): """ Class implementing a grabber widget for a rectangular snapshot region. @signal grabbed(QPixmap) emitted after the region was grabbed """ grabbed = pyqtSignal(QPixmap) StrokeMask = 0 FillMask = 1 Rectangle = 0 Ellipse = 1 def __init__(self, mode=Rectangle): """ Constructor @param mode region grabber mode (SnapshotRegionGrabber.Rectangle or SnapshotRegionGrabber.Ellipse) """ super(SnapshotRegionGrabber, self).__init__( None, Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) assert mode in [ SnapshotRegionGrabber.Rectangle, SnapshotRegionGrabber.Ellipse ] self.__mode = mode self.__selection = QRect() self.__mouseDown = False self.__newSelection = False self.__handleSize = 10 self.__mouseOverHandle = None self.__showHelp = True self.__grabbing = False self.__dragStartPoint = QPoint() self.__selectionBeforeDrag = QRect() self.__locale = QLocale() # naming conventions for handles # T top, B bottom, R Right, L left # 2 letters: a corner # 1 letter: the handle on the middle of the corresponding side self.__TLHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__TRHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BLHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BRHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__LHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__THandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__RHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__handles = [ self.__TLHandle, self.__TRHandle, self.__BLHandle, self.__BRHandle, self.__LHandle, self.__THandle, self.__RHandle, self.__BHandle ] self.__helpTextRect = QRect() self.__helpText = self.tr( "Select a region using the mouse. To take the snapshot, press" " the Enter key or double click. Press Esc to quit.") self.__pixmap = QPixmap() self.setMouseTracking(True) QTimer.singleShot(200, self.__initialize) def __initialize(self): """ Private slot to initialize the rest of the widget. """ self.__desktop = QApplication.desktop() x = self.__desktop.x() y = self.__desktop.y() if qVersion() >= "5.0.0": self.__pixmap = QApplication.screens()[0].grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) else: self.__pixmap = QPixmap.grabWindow(self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) self.resize(self.__pixmap.size()) self.move(x, y) self.setCursor(Qt.CrossCursor) self.show() self.grabMouse() self.grabKeyboard() self.activateWindow() def paintEvent(self, evt): """ Protected method handling paint events. @param evt paint event (QPaintEvent) """ if self.__grabbing: # grabWindow() should just get the background return painter = QPainter(self) pal = QPalette(QToolTip.palette()) font = QToolTip.font() handleColor = pal.color(QPalette.Active, QPalette.Highlight) handleColor.setAlpha(160) overlayColor = QColor(0, 0, 0, 160) textColor = pal.color(QPalette.Active, QPalette.Text) textBackgroundColor = pal.color(QPalette.Active, QPalette.Base) painter.drawPixmap(0, 0, self.__pixmap) painter.setFont(font) r = QRect(self.__selection) if not self.__selection.isNull(): grey = QRegion(self.rect()) if self.__mode == SnapshotRegionGrabber.Ellipse: reg = QRegion(r, QRegion.Ellipse) else: reg = QRegion(r) grey = grey.subtracted(reg) painter.setClipRegion(grey) painter.setPen(Qt.NoPen) painter.setBrush(overlayColor) painter.drawRect(self.rect()) painter.setClipRect(self.rect()) drawRect(painter, r, handleColor) if self.__showHelp: painter.setPen(textColor) painter.setBrush(textBackgroundColor) self.__helpTextRect = painter.boundingRect( self.rect().adjusted(2, 2, -2, -2), Qt.TextWordWrap, self.__helpText).translated(-self.__desktop.x(), -self.__desktop.y()) self.__helpTextRect.adjust(-2, -2, 4, 2) drawRect(painter, self.__helpTextRect, textColor, textBackgroundColor) painter.drawText(self.__helpTextRect.adjusted(3, 3, -3, -3), Qt.TextWordWrap, self.__helpText) if self.__selection.isNull(): return # The grabbed region is everything which is covered by the drawn # rectangles (border included). This means that there is no 0px # selection, since a 0px wide rectangle will always be drawn as a line. txt = "{0}, {1} ({2} x {3})".format( self.__locale.toString(self.__selection.x()), self.__locale.toString(self.__selection.y()), self.__locale.toString(self.__selection.width()), self.__locale.toString(self.__selection.height())) textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt) boundingRect = textRect.adjusted(-4, 0, 0, 0) if textRect.width() < r.width() - 2 * self.__handleSize and \ textRect.height() < r.height() - 2 * self.__handleSize and \ r.width() > 100 and \ r.height() > 100: # center, unsuitable for small selections boundingRect.moveCenter(r.center()) textRect.moveCenter(r.center()) elif r.y() - 3 > textRect.height() and \ r.x() + textRect.width() < self.rect().width(): # on top, left aligned boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3)) textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3)) elif r.x() - 3 > textRect.width(): # left, top aligned boundingRect.moveTopRight(QPoint(r.x() - 3, r.y())) textRect.moveTopRight(QPoint(r.x() - 5, r.y())) elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \ r.right() > textRect.width(): # at bottom, right aligned boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3)) textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3)) elif r.right() + textRect.width() + 3 < self.rect().width(): # right, bottom aligned boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom())) textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom())) # If the above didn't catch it, you are running on a very # tiny screen... drawRect(painter, boundingRect, textColor, textBackgroundColor) painter.drawText(textRect, Qt.AlignHCenter, txt) if (r.height() > self.__handleSize * 2 and r.width() > self.__handleSize * 2) or \ not self.__mouseDown: self.__updateHandles() painter.setPen(Qt.NoPen) painter.setBrush(handleColor) painter.setClipRegion( self.__handleMask(SnapshotRegionGrabber.StrokeMask)) painter.drawRect(self.rect()) handleColor.setAlpha(60) painter.setBrush(handleColor) painter.setClipRegion( self.__handleMask(SnapshotRegionGrabber.FillMask)) painter.drawRect(self.rect()) def resizeEvent(self, evt): """ Protected method to handle resize events. @param evt resize event (QResizeEvent) """ if self.__selection.isNull(): return r = QRect(self.__selection) r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect())) r.setBottomRight(self.__limitPointToRect(r.bottomRight(), self.rect())) if r.width() <= 1 or r.height() <= 1: # This just results in ugly drawing... self.__selection = QRect() else: self.__selection = self.__normalizeSelection(r) def mousePressEvent(self, evt): """ Protected method to handle mouse button presses. @param evt mouse press event (QMouseEvent) """ self.__showHelp = not self.__helpTextRect.contains(evt.pos()) if evt.button() == Qt.LeftButton: self.__mouseDown = True self.__dragStartPoint = evt.pos() self.__selectionBeforeDrag = QRect(self.__selection) if not self.__selection.contains(evt.pos()): self.__newSelection = True self.__selection = QRect() else: self.setCursor(Qt.ClosedHandCursor) elif evt.button() == Qt.RightButton: self.__newSelection = False self.__selection = QRect() self.setCursor(Qt.CrossCursor) self.update() def mouseMoveEvent(self, evt): """ Protected method to handle mouse movements. @param evt mouse move event (QMouseEvent) """ shouldShowHelp = not self.__helpTextRect.contains(evt.pos()) if shouldShowHelp != self.__showHelp: self.__showHelp = shouldShowHelp self.update() if self.__mouseDown: if self.__newSelection: p = evt.pos() r = self.rect() self.__selection = self.__normalizeSelection( QRect(self.__dragStartPoint, self.__limitPointToRect(p, r))) elif self.__mouseOverHandle is None: # moving the whole selection r = self.rect().normalized() s = self.__selectionBeforeDrag.normalized() p = s.topLeft() + evt.pos() - self.__dragStartPoint r.setBottomRight(r.bottomRight() - QPoint(s.width(), s.height()) + QPoint(1, 1)) if not r.isNull() and r.isValid(): self.__selection.moveTo(self.__limitPointToRect(p, r)) else: # dragging a handle r = QRect(self.__selectionBeforeDrag) offset = evt.pos() - self.__dragStartPoint if self.__mouseOverHandle in \ [self.__TLHandle, self.__THandle, self.__TRHandle]: r.setTop(r.top() + offset.y()) if self.__mouseOverHandle in \ [self.__TLHandle, self.__LHandle, self.__BLHandle]: r.setLeft(r.left() + offset.x()) if self.__mouseOverHandle in \ [self.__BLHandle, self.__BHandle, self.__BRHandle]: r.setBottom(r.bottom() + offset.y()) if self.__mouseOverHandle in \ [self.__TRHandle, self.__RHandle, self.__BRHandle]: r.setRight(r.right() + offset.x()) r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect())) r.setBottomRight( self.__limitPointToRect(r.bottomRight(), self.rect())) self.__selection = self.__normalizeSelection(r) self.update() else: if self.__selection.isNull(): return found = False for r in self.__handles: if r.contains(evt.pos()): self.__mouseOverHandle = r found = True break if not found: self.__mouseOverHandle = None if self.__selection.contains(evt.pos()): self.setCursor(Qt.OpenHandCursor) else: self.setCursor(Qt.CrossCursor) else: if self.__mouseOverHandle in [ self.__TLHandle, self.__BRHandle ]: self.setCursor(Qt.SizeFDiagCursor) elif self.__mouseOverHandle in [ self.__TRHandle, self.__BLHandle ]: self.setCursor(Qt.SizeBDiagCursor) elif self.__mouseOverHandle in [ self.__LHandle, self.__RHandle ]: self.setCursor(Qt.SizeHorCursor) elif self.__mouseOverHandle in [ self.__THandle, self.__BHandle ]: self.setCursor(Qt.SizeVerCursor) def mouseReleaseEvent(self, evt): """ Protected method to handle mouse button releases. @param evt mouse release event (QMouseEvent) """ self.__mouseDown = False self.__newSelection = False if self.__mouseOverHandle is None and \ self.__selection.contains(evt.pos()): self.setCursor(Qt.OpenHandCursor) self.update() def mouseDoubleClickEvent(self, evt): """ Protected method to handle mouse double clicks. @param evt mouse double click event (QMouseEvent) """ self.__grabRect() def keyPressEvent(self, evt): """ Protected method to handle key presses. @param evt key press event (QKeyEvent) """ if evt.key() == Qt.Key_Escape: self.grabbed.emit(QPixmap()) elif evt.key() in [Qt.Key_Enter, Qt.Key_Return]: self.__grabRect() else: evt.ignore() def __updateHandles(self): """ Private method to update the handles. """ r = QRect(self.__selection) s2 = self.__handleSize // 2 self.__TLHandle.moveTopLeft(r.topLeft()) self.__TRHandle.moveTopRight(r.topRight()) self.__BLHandle.moveBottomLeft(r.bottomLeft()) self.__BRHandle.moveBottomRight(r.bottomRight()) self.__LHandle.moveTopLeft(QPoint(r.x(), r.y() + r.height() // 2 - s2)) self.__THandle.moveTopLeft(QPoint(r.x() + r.width() // 2 - s2, r.y())) self.__RHandle.moveTopRight( QPoint(r.right(), r.y() + r.height() // 2 - s2)) self.__BHandle.moveBottomLeft( QPoint(r.x() + r.width() // 2 - s2, r.bottom())) def __handleMask(self, maskType): """ Private method to calculate the handle mask. @param maskType type of the mask to be used (SnapshotRegionGrabber.FillMask or SnapshotRegionGrabber.StrokeMask) @return calculated mask (QRegion) """ mask = QRegion() for rect in self.__handles: if maskType == SnapshotRegionGrabber.StrokeMask: r = QRegion(rect) mask += r.subtracted(QRegion(rect.adjusted(1, 1, -1, -1))) else: mask += QRegion(rect.adjusted(1, 1, -1, -1)) return mask def __limitPointToRect(self, point, rect): """ Private method to limit the given point to the given rectangle. @param point point to be limited (QPoint) @param rect rectangle the point shall be limited to (QRect) @return limited point (QPoint) """ q = QPoint() if point.x() < rect.x(): q.setX(rect.x()) elif point.x() < rect.right(): q.setX(point.x()) else: q.setX(rect.right()) if point.y() < rect.y(): q.setY(rect.y()) elif point.y() < rect.bottom(): q.setY(point.y()) else: q.setY(rect.bottom()) return q def __normalizeSelection(self, sel): """ Private method to normalize the given selection. @param sel selection to be normalized (QRect) @return normalized selection (QRect) """ rect = QRect(sel) if rect.width() <= 0: left = rect.left() width = rect.width() rect.setLeft(left + width - 1) rect.setRight(left) if rect.height() <= 0: top = rect.top() height = rect.height() rect.setTop(top + height - 1) rect.setBottom(top) return rect def __grabRect(self): """ Private method to grab the selected rectangle (i.e. do the snapshot). """ if self.__mode == SnapshotRegionGrabber.Ellipse: ell = QRegion(self.__selection, QRegion.Ellipse) if not ell.isEmpty(): self.__grabbing = True xOffset = self.__pixmap.rect().x() - ell.boundingRect().x() yOffset = self.__pixmap.rect().y() - ell.boundingRect().y() translatedEll = ell.translated(xOffset, yOffset) pixmap2 = QPixmap(ell.boundingRect().size()) pixmap2.fill(Qt.transparent) pt = QPainter() pt.begin(pixmap2) if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff): pt.setRenderHints( QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.SmoothPixmapTransform, True) pt.setBrush(Qt.black) pt.setPen(QPen(QBrush(Qt.black), 0.5)) pt.drawEllipse(translatedEll.boundingRect()) pt.setCompositionMode(QPainter.CompositionMode_SourceIn) else: pt.setClipRegion(translatedEll) pt.setCompositionMode(QPainter.CompositionMode_Source) pt.drawPixmap(pixmap2.rect(), self.__pixmap, ell.boundingRect()) pt.end() self.grabbed.emit(pixmap2) else: r = QRect(self.__selection) if not r.isNull() and r.isValid(): self.__grabbing = True self.grabbed.emit(self.__pixmap.copy(r))
def add_certifier_list(self, certifier_list, identity, identity_account): """ Add list of certifiers to graph :param list certifier_list: List of certifiers from api :param identity identity: identity instance which is certified :param identity identity_account: Account identity instance :return: """ if self.community: try: yield from self.refresh_signature_validity() # add certifiers of uid for certifier in tuple(certifier_list): # add only valid certification... if (time.time() - certifier['cert_time']) > self.signature_validity: continue # new node if certifier['identity'].pubkey not in self._graph.keys(): node_status = 0 is_member = yield from certifier['identity'].is_member(self.community) if certifier['identity'].pubkey == identity_account.pubkey: node_status += NODE_STATUS_HIGHLIGHTED if is_member is False: node_status += NODE_STATUS_OUT self._graph[certifier['identity'].pubkey] = { 'id': certifier['identity'].pubkey, 'arcs': list(), 'text': certifier['identity'].uid, 'tooltip': certifier['identity'].pubkey, 'status': node_status, 'connected': [identity.pubkey] } # keep only the latest certification if self._graph[certifier['identity'].pubkey]['arcs']: if certifier['cert_time'] < self._graph[certifier['identity'].pubkey]['arcs'][0]['cert_time']: continue # display validity status if (time.time() - certifier['cert_time']) > self.ARC_STATUS_STRONG_time: arc_status = ARC_STATUS_WEAK else: arc_status = ARC_STATUS_STRONG arc = { 'id': identity.pubkey, 'status': arc_status, 'tooltip': QLocale.toString( QLocale(), QDateTime.fromTime_t(certifier['cert_time'] + self.signature_validity).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ), 'cert_time': certifier['cert_time'] } current_block_number = self.community.network.current_blockid.number if current_block_number and certifier['block_number']: current_confirmations = current_block_number - certifier['block_number'] + 1 else: current_confirmations = 0 members_pubkeys = yield from self.community.members_pubkeys() max_confirmation = self.community.network.fork_window(members_pubkeys) + 1 # Current confirmation can be negative if self.community.network.current_blockid.number # is not refreshed yet if max_confirmation > current_confirmations >= 0: if self.app.preferences['expert_mode']: arc['confirmation_text'] = "{0}/{1}".format(current_confirmations, max_confirmation) else: confirmation = current_confirmations / max_confirmation * 100 arc['confirmation_text'] = "{0} %".format(QLocale().toString(float(confirmation), 'f', 0)) else: arc['confirmation_text'] = None # add arc to certifier self._graph[certifier['identity'].pubkey]['arcs'].append(arc) # if certifier node not in identity nodes if certifier['identity'].pubkey not in tuple(self._graph[identity.pubkey]['connected']): # add certifier node to identity node self._graph[identity.pubkey]['connected'].append(certifier['identity'].pubkey) except NoPeerAvailable as e: logging.debug(str(e))
class SymbolsModel(QAbstractTableModel): """ Class implementing the model for the symbols widget. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(SymbolsModel, self).__init__(parent) self.__locale = QLocale() self.__headerData = [ self.tr("Code"), self.tr("Char"), self.tr("Hex"), self.tr("HTML"), self.tr("Name"), ] self.__tables = [ # first last display name (0x0, 0x1f, self.tr("Control Characters")), (0x20, 0x7f, self.tr("Basic Latin")), (0x80, 0xff, self.tr("Latin-1 Supplement")), (0x100, 0x17f, self.tr("Latin Extended-A")), (0x180, 0x24f, self.tr("Latin Extended-B")), (0x250, 0x2af, self.tr("IPA Extensions")), (0x2b0, 0x2ff, self.tr("Spacing Modifier Letters")), (0x300, 0x36f, self.tr("Combining Diacritical Marks")), (0x370, 0x3ff, self.tr("Greek and Coptic")), (0x400, 0x4ff, self.tr("Cyrillic")), (0x500, 0x52f, self.tr("Cyrillic Supplement")), (0x530, 0x58f, self.tr("Armenian")), (0x590, 0x5ff, self.tr("Hebrew")), (0x600, 0x6ff, self.tr("Arabic")), (0x700, 0x74f, self.tr("Syriac")), (0x780, 0x7bf, self.tr("Thaana")), (0x7c0, 0x7ff, self.tr("N'Ko")), (0x800, 0x83f, self.tr("Samaritan")), (0x840, 0x85f, self.tr("Mandaic")), (0x8a0, 0x8ff, self.tr("Arabic Extended-A")), (0x900, 0x97f, self.tr("Devanagari")), (0x980, 0x9ff, self.tr("Bengali")), (0xa00, 0xa7f, self.tr("Gurmukhi")), (0xa80, 0xaff, self.tr("Gujarati")), (0xb00, 0xb7f, self.tr("Oriya")), (0xb80, 0xbff, self.tr("Tamil")), (0xc00, 0xc7f, self.tr("Telugu")), (0xc80, 0xcff, self.tr("Kannada")), (0xd00, 0xd7f, self.tr("Malayalam")), (0xd80, 0xdff, self.tr("Sinhala")), (0xe00, 0xe7f, self.tr("Thai")), (0xe80, 0xeff, self.tr("Lao")), (0xf00, 0xfff, self.tr("Tibetan")), (0x1000, 0x109f, self.tr("Myanmar")), (0x10a0, 0x10ff, self.tr("Georgian")), (0x1100, 0x11ff, self.tr("Hangul Jamo")), (0x1200, 0x137f, self.tr("Ethiopic")), (0x1380, 0x139f, self.tr("Ethiopic Supplement")), (0x13a0, 0x13ff, self.tr("Cherokee")), (0x1400, 0x167f, self.tr("Unified Canadian Aboriginal Syllabics")), (0x1680, 0x169f, self.tr("Ogham")), (0x16a0, 0x16ff, self.tr("Runic")), (0x1700, 0x171f, self.tr("Tagalog")), (0x1720, 0x173f, self.tr("Hanunoo")), (0x1740, 0x175f, self.tr("Buhid")), (0x1760, 0x177f, self.tr("Tagbanwa")), (0x1780, 0x17ff, self.tr("Khmer")), (0x1800, 0x18af, self.tr("Mongolian")), (0x18b0, 0x18ff, self.tr("Unified Canadian Aboriginal Syllabics Extended")), (0x1900, 0x194f, self.tr("Limbu")), (0x1950, 0x197f, self.tr("Tai Le")), (0x19e0, 0x19ff, self.tr("Khmer Symbols")), (0x1a00, 0x1a1f, self.tr("Buginese")), (0x1a20, 0x1aaf, self.tr("Tai Tham")), (0x1b00, 0x1b7f, self.tr("Balinese")), (0x1b80, 0x1bbf, self.tr("Sundanese")), (0x1bc0, 0x1bff, self.tr("Batak")), (0x1c00, 0x1c4f, self.tr("Lepcha")), (0x1c50, 0x1c7f, self.tr("Ol Chiki")), (0x1cc0, 0x1ccf, self.tr("Sundanese Supplement")), (0x1cd0, 0x1cff, self.tr("Vedic Extensions")), (0x1d00, 0x1d7f, self.tr("Phonetic Extensions")), (0x1d80, 0x1dbf, self.tr("Phonetic Extensions Supplement")), (0x1dc0, 0x1dff, self.tr("Combining Diacritical Marks Supplement")), (0x1e00, 0x1eff, self.tr("Latin Extended Additional")), (0x1f00, 0x1fff, self.tr("Greek Extended")), (0x2000, 0x206f, self.tr("General Punctuation")), (0x2070, 0x209f, self.tr("Superscripts and Subscripts")), (0x20a0, 0x20cf, self.tr("Currency Symbols")), (0x20d0, 0x20ff, self.tr("Combining Diacritical Marks")), (0x2100, 0x214f, self.tr("Letterlike Symbols")), (0x2150, 0x218f, self.tr("Number Forms")), (0x2190, 0x21ff, self.tr("Arcolumns")), (0x2200, 0x22ff, self.tr("Mathematical Operators")), (0x2300, 0x23ff, self.tr("Miscellaneous Technical")), (0x2400, 0x243f, self.tr("Control Pictures")), (0x2440, 0x245f, self.tr("Optical Character Recognition")), (0x2460, 0x24ff, self.tr("Enclosed Alphanumerics")), (0x2500, 0x257f, self.tr("Box Drawing")), (0x2580, 0x259f, self.tr("Block Elements")), (0x25A0, 0x25ff, self.tr("Geometric Shapes")), (0x2600, 0x26ff, self.tr("Miscellaneous Symbols")), (0x2700, 0x27bf, self.tr("Dingbats")), (0x27c0, 0x27ef, self.tr("Miscellaneous Mathematical Symbols-A")), (0x27f0, 0x27ff, self.tr("Supplement Arcolumns-A")), (0x2800, 0x28ff, self.tr("Braille Patterns")), (0x2900, 0x297f, self.tr("Supplement Arcolumns-B")), (0x2980, 0x29ff, self.tr("Miscellaneous Mathematical Symbols-B")), (0x2a00, 0x2aff, self.tr("Supplemental Mathematical Operators")), (0x2b00, 0x2bff, self.tr("Miscellaneous Symbols and Arcolumns")), (0x2c00, 0x2c5f, self.tr("Glagolitic")), (0x2c60, 0x2c7f, self.tr("Latin Extended-C")), (0x2c80, 0x2cff, self.tr("Coptic")), (0x2d00, 0x2d2f, self.tr("Georgian Supplement")), (0x2d30, 0x2d7f, self.tr("Tifinagh")), (0x2d80, 0x2ddf, self.tr("Ethiopic Extended")), (0x2de0, 0x2dff, self.tr("Cyrillic Extended-A")), (0x2e00, 0x2e7f, self.tr("Supplemental Punctuation")), (0x2e80, 0x2eff, self.tr("CJK Radicals Supplement")), (0x2f00, 0x2fdf, self.tr("KangXi Radicals")), (0x2ff0, 0x2fff, self.tr("Ideographic Description Chars")), (0x3000, 0x303f, self.tr("CJK Symbols and Punctuation")), (0x3040, 0x309f, self.tr("Hiragana")), (0x30a0, 0x30ff, self.tr("Katakana")), (0x3100, 0x312f, self.tr("Bopomofo")), (0x3130, 0x318f, self.tr("Hangul Compatibility Jamo")), (0x3190, 0x319f, self.tr("Kanbun")), (0x31a0, 0x31bf, self.tr("Bopomofo Extended")), (0x31c0, 0x31ef, self.tr("CJK Strokes")), (0x31f0, 0x31ff, self.tr("Katakana Phonetic Extensions")), (0x3200, 0x32ff, self.tr("Enclosed CJK Letters and Months")), (0x3300, 0x33ff, self.tr("CJK Compatibility")), (0x3400, 0x4dbf, self.tr("CJK Unified Ideogr. Ext. A")), (0x4dc0, 0x4dff, self.tr("Yijing Hexagram Symbols")), (0x4e00, 0x9fff, self.tr("CJK Unified Ideographs")), (0xa000, 0xa48f, self.tr("Yi Syllables")), (0xa490, 0xa4cf, self.tr("Yi Radicals")), (0xa4d0, 0xa4ff, self.tr("Lisu")), (0xa500, 0xa63f, self.tr("Vai")), (0xa640, 0xa69f, self.tr("Cyrillic Extended-B")), (0xa6a0, 0xa6ff, self.tr("Bamum")), (0xa700, 0xa71f, self.tr("Modifier Tone Letters")), (0xa720, 0xa7ff, self.tr("Latin Extended-D")), (0xa800, 0xa82f, self.tr("Syloti Nagri")), (0xa830, 0xa83f, self.tr("Common Indic Number Forms")), (0xa840, 0xa87f, self.tr("Phags-pa")), (0xa880, 0xa8df, self.tr("Saurashtra")), (0xa8e0, 0xa8ff, self.tr("Devanagari Extended")), (0xa900, 0xa92f, self.tr("Kayah Li")), (0xa930, 0xa95f, self.tr("Rejang")), (0xa960, 0xa97f, self.tr("Hangul Jamo Extended-A")), (0xa980, 0xa9df, self.tr("Javanese")), (0xaa00, 0xaa5f, self.tr("Cham")), (0xaa60, 0xaa7f, self.tr("Myanmar Extended-A")), (0xaa80, 0xaadf, self.tr("Tai Viet")), (0xaae0, 0xaaff, self.tr("Meetei Mayek Extensions")), (0xab00, 0xab2f, self.tr("Ethiopic Extended-A")), (0xabc0, 0xabff, self.tr("Meetei Mayek")), (0xac00, 0xd7af, self.tr("Hangul Syllables")), (0xd7b0, 0xd7ff, self.tr("Hangul Jamo Extended-B")), (0xd800, 0xdb7f, self.tr("High Surrogates")), (0xdb80, 0xdbff, self.tr("High Private Use Surrogates")), (0xdc00, 0xdfff, self.tr("Low Surrogates")), (0xe000, 0xf8ff, self.tr("Private Use")), (0xf900, 0xfaff, self.tr("CJK Compatibility Ideographs")), (0xfb00, 0xfb4f, self.tr("Alphabetic Presentation Forms")), (0xfb50, 0xfdff, self.tr("Arabic Presentation Forms-A")), (0xfe00, 0xfe0f, self.tr("Variation Selectors")), (0xfe10, 0xfe1f, self.tr("Vertical Forms")), (0xfe20, 0xfe2f, self.tr("Combining Half Marks")), (0xfe30, 0xfe4f, self.tr("CJK Compatibility Forms")), (0xfe50, 0xfe6f, self.tr("Small Form Variants")), (0xfe70, 0xfeff, self.tr("Arabic Presentation Forms-B")), (0xff00, 0xffef, self.tr("Half- and Fullwidth Forms")), (0xfff0, 0xffff, self.tr("Specials")), ] if sys.maxunicode > 0xffff: self.__tables.extend([ (0x10000, 0x1007f, self.tr("Linear B Syllabary")), (0x10080, 0x100ff, self.tr("Linear B Ideograms")), (0x10100, 0x1013f, self.tr("Aegean Numbers")), (0x10140, 0x1018f, self.tr("Ancient Greek Numbers")), (0x10190, 0x101cf, self.tr("Ancient Symbols")), (0x101d0, 0x101ff, self.tr("Phaistos Disc")), (0x10280, 0x1029f, self.tr("Lycian")), (0x102a0, 0x102df, self.tr("Carian")), (0x10300, 0x1032f, self.tr("Old Italic")), (0x10330, 0x1034f, self.tr("Gothic")), (0x10380, 0x1039f, self.tr("Ugaritic")), (0x103a0, 0x103df, self.tr("Old Persian")), (0x10400, 0x1044f, self.tr("Deseret")), (0x10450, 0x1047f, self.tr("Shavian")), (0x10480, 0x104af, self.tr("Osmanya")), (0x10800, 0x1083f, self.tr("Cypriot Syllabary")), (0x10840, 0x1085f, self.tr("Imperial Aramaic")), (0x10900, 0x1091f, self.tr("Phoenician")), (0x10920, 0x1093f, self.tr("Lydian")), (0x10980, 0x1099f, self.tr("Meroitic Hieroglyphs")), (0x109a0, 0x109ff, self.tr("Meroitic Cursive")), (0x10a00, 0x10a5f, self.tr("Kharoshthi")), (0x10a60, 0x10a7f, self.tr("Old South Arabian")), (0x10b00, 0x10b3f, self.tr("Avestan")), (0x10b40, 0x10b5f, self.tr("Inscriptional Parthian")), (0x10b60, 0x10b7f, self.tr("Inscriptional Pahlavi")), (0x10c00, 0x10c4f, self.tr("Old Turkic")), (0x10e60, 0x10e7f, self.tr("Rumi Numeral Symbols")), (0x11000, 0x1107f, self.tr("Brahmi")), (0x11080, 0x110cf, self.tr("Kaithi")), (0x110d0, 0x110ff, self.tr("Sora Sompeng")), (0x11100, 0x1114f, self.tr("Chakma")), (0x11180, 0x111df, self.tr("Sharada")), (0x11680, 0x116cf, self.tr("Takri")), (0x12000, 0x123ff, self.tr("Cuneiform")), (0x12400, 0x1247f, self.tr("Cuneiform Numbers and Punctuation")), (0x13000, 0x1342f, self.tr("Egyptian Hieroglyphs")), (0x16800, 0x16a3f, self.tr("Bamum Supplement")), (0x16f00, 0x16f9f, self.tr("Miao")), (0x1b000, 0x1b0ff, self.tr("Kana Supplement")), (0x1d000, 0x1d0ff, self.tr("Byzantine Musical Symbols")), (0x1d100, 0x1d1ff, self.tr("Musical Symbols")), (0x1d200, 0x1d24f, self.tr("Ancient Greek Musical Notation")), (0x1d300, 0x1d35f, self.tr("Tai Xuan Jing Symbols")), (0x1d360, 0x1d37f, self.tr("Counting Rod Numerals")), (0x1d400, 0x1d7ff, self.tr("Mathematical Alphanumeric Symbols")), (0x1ee00, 0x1eeff, self.tr("Arabic Mathematical Alphabetic Symbols")), (0x1f000, 0x1f02f, self.tr("Mahjong Tiles")), (0x1f030, 0x1f09f, self.tr("Domino Tiles")), (0x1f0a0, 0x1f0ff, self.tr("Playing Cards")), (0x1f100, 0x1f1ff, self.tr("Enclosed Alphanumeric Supplement")), (0x1f200, 0x1f2ff, self.tr("Enclosed Ideographic Supplement")), (0x1f300, 0x1f5ff, self.tr("Miscellaneous Symbols And Pictographs")), (0x1f600, 0x1f64f, self.tr("Emoticons")), (0x1f680, 0x1f6ff, self.tr("Transport And Map Symbols")), (0x1f700, 0x1f77f, self.tr("Alchemical Symbols")), (0x20000, 0x2a6df, self.tr("CJK Unified Ideogr. Ext. B")), (0x2a700, 0x2b73f, self.tr("CJK Unified Ideographs Extension C")), (0x2b740, 0x2b81f, self.tr("CJK Unified Ideographs Extension D")), (0x2f800, 0x2fa1f, self.tr("CJK Compatapility Ideogr. Suppl.")), (0xe0000, 0xe007f, self.tr("Tags")), (0xe0100, 0xe01ef, self.tr("Variation Selectors Supplement")), (0xf0000, 0xfffff, self.tr("Supplementary Private Use Area-A")), (0x100000, 0x10ffff, self.tr("Supplementary Private Use Area-B")), ]) self.__currentTableIndex = 0 def getTableNames(self): """ Public method to get a list of table names. @return list of table names (list of strings) """ return [table[2] for table in self.__tables] def getTableBoundaries(self, index): """ Public method to get the first and last character position of the given table. @param index index of the character table (integer) @return first and last character position (integer, integer) """ return self.__tables[index][0], self.__tables[index][1] def getTableIndex(self): """ Public method to get the current table index. @return current table index (integer) """ return self.__currentTableIndex def selectTable(self, index): """ Public method to select the shown character table. @param index index of the character table (integer) """ self.beginResetModel() self.__currentTableIndex = index self.endResetModel() def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get header data from the model. @param section section number (integer) @param orientation orientation (Qt.Orientation) @param role role of the data to retrieve (integer) @return requested data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.__headerData[section] return QAbstractTableModel.headerData(self, section, orientation, role) def data(self, index, role=Qt.DisplayRole): """ Public method to get data from the model. @param index index to get data for (QModelIndex) @param role role of the data to retrieve (integer) @return requested data """ symbolId = self.__tables[self.__currentTableIndex][0] + index.row() if role == Qt.DisplayRole: col = index.column() if col == 0: return self.__locale.toString(symbolId) elif col == 1: return chr(symbolId) elif col == 2: return "0x{0:04x}".format(symbolId) elif col == 3: if symbolId in html.entities.codepoint2name: return "&{0};".format( html.entities.codepoint2name[symbolId]) elif col == 4: return unicodedata.name(chr(symbolId), '').title() if role == Qt.BackgroundColorRole: if index.column() == 0: return QColor(Qt.lightGray) if role == Qt.TextColorRole: char = chr(symbolId) if self.__isDigit(char): return QColor(Qt.darkBlue) elif self.__isLetter(char): return QColor(Qt.darkGreen) elif self.__isMark(char): return QColor(Qt.darkRed) elif self.__isSymbol(char): return QColor(Qt.black) elif self.__isPunct(char): return QColor(Qt.darkMagenta) else: return QColor(Qt.darkGray) if role == Qt.TextAlignmentRole: if index.column() in [0, 1, 3]: return Qt.AlignHCenter return None def columnCount(self, parent): """ Public method to get the number of columns of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.column() > 0: return 0 else: return len(self.__headerData) def rowCount(self, parent): """ Public method to get the number of rows of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.isValid(): return 0 else: first, last = self.__tables[self.__currentTableIndex][:2] return last - first + 1 def __isDigit(self, char): """ Private method to check, if a character is a digit. @param char character to test (one character string) @return flag indicating a digit (boolean) """ return unicodedata.category(str(char)) == "Nd" def __isLetter(self, char): """ Private method to check, if a character is a letter. @param char character to test (one character string) @return flag indicating a letter (boolean) """ return unicodedata.category( str(char)) in ["Lu", "Ll", "Lt", "Lm", "Lo"] def __isMark(self, char): """ Private method to check, if a character is a mark character. @param char character to test (one character string) @return flag indicating a mark character (boolean) """ return unicodedata.category(str(char)) in ["Mn", "Mc", "Me"] def __isSymbol(self, char): """ Private method to check, if a character is a symbol. @param char character to test (one character string) @return flag indicating a symbol (boolean) """ return unicodedata.category(str(char)) in ["Sm", "Sc", "Sk", "So"] def __isPunct(self, char): """ Private method to check, if a character is a punctuation character. @param char character to test (one character string) @return flag indicating a punctuation character (boolean) """ return unicodedata.category( str(char)) in ["Pc", "Pd", "Ps", "Pe", "Pi", "Pf", "Po"] def getLocale(self): """ Public method to get the used locale. @return used locale @rtype QLocale """ return self.__locale
def add_certified_list(self, certified_list, identity, identity_account): """ Add list of certified from api to graph :param list certified_list: List of certified from api :param identity identity: identity instance which is certifier :param identity identity_account: Account identity instance :return: """ if self.community: try: yield from self.refresh_signature_validity() # add certified by uid for certified in tuple(certified_list): # add only valid certification... if (time.time() - certified['cert_time']) > self.signature_validity: continue if certified['identity'].pubkey not in self._graph.keys(): node_status = 0 is_member = yield from certified['identity'].is_member(self.community) if certified['identity'].pubkey == identity_account.pubkey: node_status += NODE_STATUS_HIGHLIGHTED if is_member is False: node_status += NODE_STATUS_OUT self._graph[certified['identity'].pubkey] = { 'id': certified['identity'].pubkey, 'arcs': list(), 'text': certified['identity'].uid, 'tooltip': certified['identity'].pubkey, 'status': node_status, 'connected': [identity.pubkey] } # display validity status if (time.time() - certified['cert_time']) > self.ARC_STATUS_STRONG_time: arc_status = ARC_STATUS_WEAK else: arc_status = ARC_STATUS_STRONG arc = { 'id': certified['identity'].pubkey, 'status': arc_status, 'tooltip': QLocale.toString( QLocale(), QDateTime.fromTime_t(certified['cert_time'] + self.signature_validity).date(), QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ), 'cert_time': certified['cert_time'] } current_block_number = self.community.network.current_blockid.number if current_block_number and certified['block_number']: current_confirmations = current_block_number - certified['block_number'] + 1 else: current_confirmations = 0 members_pubkeys = yield from self.community.members_pubkeys() max_confirmations = self.community.network.fork_window(members_pubkeys) + 1 if max_confirmations > current_confirmations >= 0: if self.app.preferences['expert_mode']: arc['confirmation_text'] = "{0}/{1}".format(current_confirmations, max_confirmations) else: confirmation = current_confirmations / max_confirmations * 100 confirmation = 100 if confirmation > 100 else confirmation arc['confirmation_text'] = "{0} %".format(QLocale().toString(float(confirmation), 'f', 0)) else: arc['confirmation_text'] = None # replace old arc if this one is more recent new_arc = True index = 0 for a in self._graph[identity.pubkey]['arcs']: # if same arc already exists... if a['id'] == arc['id']: # if arc more recent, dont keep old one... if arc['cert_time'] >= a['cert_time']: self._graph[identity.pubkey]['arcs'][index] = arc new_arc = False index += 1 # if arc not in graph... if new_arc: # add arc in graph self._graph[identity.pubkey]['arcs'].append(arc) # if certified node not in identity nodes if certified['identity'].pubkey not in tuple(self._graph[identity.pubkey]['connected']): # add certified node to identity node self._graph[identity.pubkey]['connected'].append(certified['identity'].pubkey) except NoPeerAvailable as e: logging.debug(str(e))