Something went wrong on our end
"""
Created on 2 févr. 2014
@author: inso
"""
import time
import logging
from PyQt5.QtWidgets import QWidget, QMessageBox, QDialog
from PyQt5.QtCore import QModelIndex, pyqtSlot, QDateTime, QLocale, QEvent
from PyQt5.QtGui import QIcon
from ..core.net.api import bma as qtbma
from .wot_tab import WotTabWidget
from .identities_tab import IdentitiesTabWidget
from .transactions_tab import TransactionsTabWidget
from .network_tab import NetworkTabWidget
from . import toast
import asyncio
from ..tools.exceptions import MembershipNotFoundError, LookupFailureError
from ..gen_resources.community_view_uic import Ui_CommunityWidget
class CommunityWidget(QWidget, Ui_CommunityWidget):
"""
classdocs
"""
def __init__(self, app, status_label):
"""
Constructor
"""
super().__init__()
self.app = app
self.community = None
self.password_asker = None
self.status_label = status_label
self.status_info = []
self.status_infotext = {'membership_expire_soon':
self.tr("Warning : Your membership is expiring soon."),
'warning_certifications':
self.tr("Warning : Your could miss certifications soon.")
}
super().setupUi(self)
self.tab_wot = WotTabWidget(self.app)
self.tab_identities = IdentitiesTabWidget(self.app)
self.tab_history = TransactionsTabWidget(self.app)
self.tab_network = NetworkTabWidget(self.app)
self.tabs.addTab(self.tab_history,
QIcon(':/icons/tx_icon'),
self.tr("Transactions"))
self.tabs.addTab(self.tab_wot,
QIcon(':/icons/wot_icon'),
self.tr("Web of Trust"))
self.tabs.addTab(self.tab_identities,
QIcon(':/icons/members_icon'),
self.tr("Search Identities"))
self.tabs.addTab(self.tab_network,
QIcon(":/icons/network_icon"),
self.tr("Network"))
def change_account(self, account):
self.account = account
self.tab_wot.change_account(account)
self.tab_identities.change_account(account)
def change_community(self, community):
self.tab_network.change_community(community)
self.tab_wot.change_community(community)
self.tab_history.change_community(community)
self.tab_identities.change_community(community)
if self.community:
self.community.network.new_block_mined.disconnect(self.refresh_block)
self.community.network.nodes_changed.disconnect(self.refresh_status)
self.community.inner_data_changed.disconnect(self.refresh_status)
if community:
community.network.new_block_mined.connect(self.refresh_block)
community.network.nodes_changed.connect(self.refresh_status)
community.inner_data_changed.connect(self.refresh_status)
self.label_currency.setText(community.currency)
self.community = community
self.refresh_quality_buttons()
@pyqtSlot(str)
def display_error(self, error):
QMessageBox.critical(self, ":(",
error,
QMessageBox.Ok)
@pyqtSlot(int)
def refresh_block(self, block_number):
"""
When a new block is found, start handling data.
@param: block_number: The number of the block mined
"""
logging.debug("Refresh block")
self.status_info.clear()
try:
person = self.app.identities_registry.find(self.app.current_account.pubkey, self.community)
expiration_time = person.membership_expiration_time(self.community)
sig_validity = self.community.parameters['sigValidity']
warning_expiration_time = int(sig_validity / 3)
will_expire_soon = (expiration_time < warning_expiration_time)
logging.debug("Try")
if will_expire_soon:
days = int(expiration_time / 3600 / 24)
if days > 0:
self.status_info.append('membership_expire_soon')
if self.app.preferences['notifications']:
toast.display(self.tr("Membership expiration"),
self.tr("<b>Warning : Membership expiration in {0} days</b>").format(days))
certifiers_of = person.unique_valid_certifiers_of(self.app.identities_registry, self.community)
if len(certifiers_of) < self.community.parameters['sigQty']:
self.status_info.append('warning_certifications')
if self.app.preferences['notifications']:
toast.display(self.tr("Certifications number"),
self.tr("<b>Warning : You are certified by only {0} persons, need {1}</b>")
.format(len(certifiers_of),
self.community.parameters['sigQty']))
except MembershipNotFoundError as e:
pass
self.tab_history.start_progress()
self.refresh_data()
def refresh_quality_buttons(self):
pass
def refresh_data(self):
"""
Refresh data when the blockchain watcher finished handling datas
"""
self.tab_history.refresh_balance()
self.refresh_status()
@pyqtSlot()
def refresh_status(self):
"""
Refresh status bar
"""
logging.debug("Refresh status")
if self.community:
text = self.tr(" Block {0}").format(self.community.network.latest_block_number)
block = self.community.get_block(self.community.network.latest_block_number)
if block != qtbma.blockchain.Block.null_value:
text += " ( {0} )".format(QLocale.toString(
QLocale(),
QDateTime.fromTime_t(block['medianTime']),
QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
))
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.status_infotext[info] 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']:
label_text += self.tr(" - Median fork window : {0}").format(self.community.network.fork_window(self.community.members_pubkeys()))
self.status_label.setText(label_text)
def refresh_quality_buttons(self):
if self.account and self.community:
try:
if self.account.identity(self.community).published_uid(self.community):
logging.debug("UID Published")
if self.account.identity(self.community).is_member(self.community):
self.button_membership.setText(self.tr("Renew membership"))
self.button_membership.show()
self.button_certification.show()
else:
logging.debug("Not a member")
self.button_membership.setText(self.tr("Send membership demand"))
self.button_membership.show()
if self.community.get_block(0) != qtbma.blockchain.Block.null_value:
self.button_certification.hide()
else:
logging.debug("UID not published")
self.button_membership.hide()
self.button_certification.hide()
except LookupFailureError:
self.button_membership.hide()
self.button_certification.hide()
def showEvent(self, event):
self.refresh_status()
def referential_changed(self):
if self.community and self.tab_history.table_history.model():
self.tab_history.table_history.model().dataChanged.emit(
QModelIndex(),
QModelIndex(),
[])
self.tab_history.refresh_balance()
def send_membership_demand(self):
password = self.password_asker.exec_()
if self.password_asker.result() == QDialog.Rejected:
return
asyncio.async(self.account.send_membership(password, self.community, 'IN'))
def send_membership_leaving(self):
reply = QMessageBox.warning(self, self.tr("Warning"),
self.tr("""Are you sure ?
Sending a leaving demand cannot be canceled.
The process to join back the community later will have to be done again.""")
.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
if reply == QMessageBox.Ok:
password = self.password_asker.exec_()
if self.password_asker.result() == QDialog.Rejected:
return
asyncio.async(self.account.send_membership(password, self.community, 'OUT'))
def publish_uid(self):
reply = QMessageBox.warning(self, self.tr("Warning"),
self.tr("""Are you sure ?
Publishing your UID can be canceled by Revoke UID.""")
.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
if reply == QMessageBox.Ok:
password = self.password_asker.exec_()
if self.password_asker.result() == QDialog.Rejected:
return
try:
self.account.send_selfcert(password, self.community)
toast.display(self.tr("UID Publishing"),
self.tr("Success publishing your UID"))
except ValueError as e:
QMessageBox.critical(self, self.tr("Publish UID error"),
str(e))
except NoPeerAvailable as e:
QMessageBox.critical(self, self.tr("Network error"),
self.tr("Couldn't connect to network : {0}").format(e),
QMessageBox.Ok)
except Exception as e:
QMessageBox.critical(self, self.tr("Error"),
"{0}".format(e),
QMessageBox.Ok)
def revoke_uid(self):
reply = QMessageBox.warning(self, self.tr("Warning"),
self.tr("""Are you sure ?
Revoking your UID can only success if it is not already validated by the network.""")
.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
if reply == QMessageBox.Ok:
password = self.password_asker.exec_()
if self.password_asker.result() == QDialog.Rejected:
return
asyncio.async(self.account.revoke(password, self.community))
def handle_membership_broadcasted(self):
if self.app.preferences['notifications']:
toast.display(self.tr("Membership"), self.tr("Success sending Membership demand"))
else:
QMessageBox.information(self, self.tr("Membership"), self.tr("Success sending Membership demand"))
def handle_revoke_broadcasted(self):
if self.app.preferences['notifications']:
toast.display(self.tr("Revoke"), self.tr("Success sending Revoke demand"))
else:
QMessageBox.information(self, self.tr("Revoke"), self.tr("Success sending Revoke demand"))
def handle_selfcert_broadcasted(self):
if self.app.preferences['notifications']:
toast.display(self.tr("Self Certification"), self.tr("Success sending Self Certification document"))
else:
QMessageBox.information(self.tr("Self Certification"), self.tr("Success sending Self Certification document"))
def changeEvent(self, event):
"""
Intercepte LanguageChange event to translate UI
:param QEvent QEvent: Event
:return:
"""
if event.type() == QEvent.LanguageChange:
self.retranslateUi(self)
self.refresh_status()
return super(CommunityWidget, self).changeEvent(event)