timestamp = op["timestamp"] if share_type.lower() in ["sharetransfer"]: if op["shares"] > 0 and op["sponsor"] in member_data and op["account"] in member_data: if op["shares"] > member_data[op["account"]]["shares"]: continue member_data[op["account"]]["shares"] -= op["shares"] member_data[op["sponsor"]]["shares"] += op["shares"] member_data[op["sponsor"]]["latest_enrollment"] = timestamp member_data[op["sponsor"]].append_share_age(timestamp, op["shares"]) elif share_type.lower() in ["delegation"]: if op["shares"] > 0 and op["sponsor"] in member_data: # print("del. bonus_shares: %s - %d" % (op["sponsor"], op["shares"])) delegation[op["sponsor"]] = op["shares"] elif op["vests"] > 0 and op["sponsor"] in member_data: sp = stm.vests_to_sp(float(op["vests"])) delegation[op["sponsor"]] = int(sp / sp_share_ratio) # memo_sp_delegation(transferMemos, memo_transfer_acc, op["sponsor"], delegation[op["sponsor"]], sp_share_ratio) delegation_timestamp[op["sponsor"]] = timestamp elif share_type.lower() in ["removeddelegation"]: delegation[op["sponsor"]] = 0 delegation_timestamp[op["sponsor"]] = None elif share_type.lower() in ["mgmttransfer"]: if op["shares"] > 0 and op["sponsor"] in member_data and op["account"] in member_data: if op["shares"] > member_data[op["account"]]["bonus_shares"]: continue member_data[op["account"]]["bonus_shares"] -= op["shares"] member_data[op["sponsor"]]["bonus_shares"] += op["shares"] member_data[op["sponsor"]]["latest_enrollment"] = timestamp
stm = Steem() price = Amount(stm.get_current_median_history()["base"]) reps = [0] for i in range(26, 91): reps.append(int(10**((i - 25) / 9 + 9))) # reps = np.logspace(9, 16, 60) used_power = stm._calc_resulting_vote() last_sp = 0 sp_list = [] rep_score_list = [] for goal_rep in reps: score = reputation_to_score(goal_rep) rep_score_list.append(score) needed_rshares = int(goal_rep) << 6 needed_vests = needed_rshares / used_power / 100 needed_sp = stm.vests_to_sp(needed_vests) sp_list.append(needed_sp / 1000) # print("| %.1f | %.2f | %.2f | " % (score, needed_sp / 1000, needed_sp / 1000 - last_sp / 1000)) last_sp = needed_sp plt.figure(figsize=(12, 6)) opts = {'linestyle': '-', 'marker': '.'} plt.semilogx(sp_list, rep_score_list, label="Reputation", **opts) plt.grid() plt.legend() plt.title("Required number of 1k SP upvotes to reach certain reputation") plt.xlabel("1k SP votes") plt.ylabel("Reputation") plt.show() # plt.savefig("rep_based_on_votes.png")
delegation_list.append(d) for d in trxStorage.get_share_type(share_type="DelegationLeased"): if d["share_type"] == "DelegationLeased": delegation_list.append(d) for d in trxStorage.get_share_type(share_type="RemovedDelegation"): if d["share_type"] == "RemovedDelegation": delegation_list.append(d) sorted_delegation_list = sorted( delegation_list, key=lambda x: (datetime.utcnow() - x["timestamp"]).total_seconds(), reverse=True) for d in sorted_delegation_list: if d["share_type"] == "Delegation": delegation[d["account"]] = stm.vests_to_sp(float(d["vests"])) delegation_timestamp[d["account"]] = d["timestamp"] delegation_shares[d["account"]] = d["shares"] elif d["share_type"] == "DelegationLeased": delegation[d["account"]] = 0 delegation_timestamp[d["account"]] = d["timestamp"] delegation_shares[d["account"]] = d["shares"] elif d["share_type"] == "RemovedDelegation": delegation[d["account"]] = 0 delegation_timestamp[d["account"]] = d["timestamp"] delegation_shares[d["account"]] = 0 delegation_leased = {} delegation_shares = {} print("update delegation") delegation_account = delegation
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(QMainWindow, self).__init__() # Set up the user interface from Designer. self.setupUi(self) self.setAccessibleName("Hive Desktop") self.redrawLock = Lock() self.updateLock = Lock() self.optionsDialog = dialogs.Options(self) self.aboutDialog = dialogs.About( self, copyright='holger80', programName='Hive Desktop', version=VERSION, website='https://github.com/holgern/hivedesktop', websiteLabel='Github', comments= '"Welcome to Hive desktop!\n This is the first release for testing qt5.\n Please vote for holger80 as witness, if you like this :).', licenseName='GPL-3.0', # licenseUrl=helpers.joinpath_to_cwd('LICENSE').as_uri(), authors=('holger80', ), # dependencies=[l.strip() for l in requirements.readlines()], ) self.mdrenderer = MDRenderer(str(helpers.joinpath_to_cwd('themes'))) # tmpfile = helpers.mktemp(prefix='hivedesktop', suffix='.html') self.post = {"body": "##test", "authorperm": "@test/test"} self.thread = threads.MDThread(self) # self.webview.url = tmpfile.as_uri() self.feedListWidget.currentRowChanged.connect( self.change_displayed_post, Qt.QueuedConnection) self.timer = QTimer() self.timer.timeout.connect(self.refresh_account_thread) self.timer2 = QTimer() self.timer2.timeout.connect(self.update_account_hist_thread) self.timer3 = QTimer() self.timer3.timeout.connect(self.update_account_feed_thread) self.cache_path = QStandardPaths.writableLocation( QStandardPaths.CacheLocation) self.db_type = "shelve" self.feed = [] self.post = None # Get settings settings = QSettings() # Get checkbox state with speciying type of checkbox: # type=bool is a replacement of toBool() in PyQt5 check_state = settings.value(SETTINGS_TRAY, True, type=bool) hist_info_check_state = settings.value(SETTINGS_HIST_INFO, True, type=bool) account_state = settings.value(SETTINGS_ACCOUNT, "", type=str) # Set state self.accountHistNotificationCheckBox.setChecked(hist_info_check_state) self.autoRefreshCheckBox.setChecked(check_state) if check_state: self.timer.start(5000) self.timer2.start(15000) self.timer3.start(60000) self.accountLineEdit.setText(account_state) # connect the slot to the signal by clicking the checkbox to save the state settings self.autoRefreshCheckBox.clicked.connect(self.save_check_box_settings) self.accountHistNotificationCheckBox.clicked.connect( self.save_check_box_settings) self.accountLineEdit.editingFinished.connect( self.save_account_settings) self.actionAbout.triggered.connect(self.about) self.actionOptions.triggered.connect(self.options) self.threadpool = QThreadPool() self.minimizeAction = QAction("Mi&nimize", self, triggered=self.hide) self.maximizeAction = QAction("Ma&ximize", self, triggered=self.showMaximized) self.restoreAction = QAction("&Restore", self, triggered=self.showNormal) menu = QMenu() menu.addAction(self.minimizeAction) menu.addAction(self.maximizeAction) menu.addAction(self.restoreAction) menu.addSeparator() # aboutAction = menu.addAction("about") # aboutAction.triggered.connect(self.about) exitAction = menu.addAction("Exit") exitAction.triggered.connect(self.closeApp) self.tray = QSystemTrayIcon(QIcon(':/icons/icon.ico')) self.tray.setContextMenu(menu) self.tray.setToolTip("Hive Desktop!") self.tray.setObjectName("Hive Desktop") self.setWindowTitle("Hive Desktop") self.tray.show() splash_pix = QPixmap(':/icons/splash.png') splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint) splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) splash.setEnabled(False) splash.show() splash.showMessage("<h1><font color='green'>starting...</font></h1>", Qt.AlignTop | Qt.AlignCenter, Qt.black) account = account_state nodelist = NodeList() nodelist.update_nodes() self.stm = Steem(node=nodelist.get_nodes(hive=True)) if account != "": try: self.hist_account = Account(account, steem_instance=self.stm) except: self.hist_account = None else: self.hist_account = None if self.hasFocus is not None: self.init_new_account() # self.button.clicked.connect(lambda: self.text.setText(_get_quote(self.hist_account, self.stm))) self.refreshPushButton.clicked.connect(self.refresh_account_thread) self.refreshPushButton.clicked.connect(self.update_account_hist_thread) self.accountLineEdit.editingFinished.connect(self.update_account_info) splash.deleteLater() self.tray.showMessage("Ready", "Account history loaded!") def triggeredPreview(self): self.authorLabel.setText(self.post["author"]) self.titleLabel.setText(self.post["title"]) self.thread.start() @pyqtSlot(str) def cbMDThread(self, html): self.webview.setHtml(html) def closeEvent(self, event): if self.tray.isVisible(): QMessageBox.information( self, "Hive Desktop", "The program will keep running in the system tray. To " "terminate the program, choose <b>Quit</b> in the " "context menu of the system tray entry.") self.hide() event.ignore() def closeApp(self): self.store_account_hist() sys.exit() def about(self): self.aboutDialog.exec_() def options(self): self.optionsDialog.exec_() # Slot checkbox to save the settings def save_check_box_settings(self): settings = QSettings() settings.setValue(SETTINGS_HIST_INFO, self.accountHistNotificationCheckBox.isChecked()) settings.setValue(SETTINGS_TRAY, self.autoRefreshCheckBox.isChecked()) if self.autoRefreshCheckBox.isChecked(): self.timer.start(5000) self.timer2.start(15000) self.timer3.start(60000) else: self.timer.stop() self.timer2.stop() self.timer3.stop() settings.sync() # Slot checkbox to save the settings def save_account_settings(self): settings = QSettings() settings.setValue(SETTINGS_ACCOUNT, self.accountLineEdit.text()) settings.sync() def update_account_info(self): if self.hist_account is None or self.hist_account[ "name"] != self.accountLineEdit.text(): self.store_account_hist() try: self.hist_account = Account(self.accountLineEdit.text(), steem_instance=self.stm) except: self.hist_account = None self.init_new_account() def init_new_account(self): if self.hist_account is not None: self.db = database.Database(self.db_type, self.cache_path, self.hist_account["name"]) self.refresh_account() self.init_account_hist() self.update_account_hist() self.update_account_feed() self.store_account_hist() def refresh_account_thread(self): worker = Worker(self.refresh_account) self.threadpool.start(worker) def refresh_account(self): if self.hist_account is None: return self.hist_account.refresh() self.accountInfoGroupBox.setTitle( "%s (%.3f)" % (self.hist_account["name"], self.hist_account.rep)) with self.redrawLock: self.votePowerProgressBar.setValue(int(self.hist_account.vp)) if self.hist_account.vp == 100: self.votePowerProgressBar.setFormat("%.2f %%" % (self.hist_account.vp)) else: self.votePowerProgressBar.setFormat( "%.2f %%, full in %s" % (self.hist_account.vp, self.hist_account.get_recharge_time_str())) down_vp = self.hist_account.get_downvoting_power() with self.redrawLock: self.downvotePowerProgressBar.setValue(int(down_vp)) if down_vp == 100: self.downvotePowerProgressBar.setFormat("%.2f %%" % (down_vp)) else: self.downvotePowerProgressBar.setFormat( "%.2f %%, full in %s" % (down_vp, self.hist_account.get_recharge_time( starting_voting_power=down_vp))) self.votePowerLabel.setText("Vote Power, a 100%% vote is %.3f $" % (self.hist_account.get_voting_value_SBD())) self.downvotePowerLabel.setText("DownVote Power") self.STEEMLabel.setText(str(self.hist_account["balance"])) self.SBDLabel.setText(str(self.hist_account["sbd_balance"])) self.SPLabel.setText( "%.3f HP" % self.stm.vests_to_sp(self.hist_account["vesting_shares"])) try: rc_manabar = self.hist_account.get_rc_manabar() with self.redrawLock: self.RCProgressBar.setValue(int(rc_manabar["current_pct"])) self.RCProgressBar.setFormat( "%.2f %%, full in %s" % (rc_manabar["current_pct"], self.hist_account.get_manabar_recharge_time_str( rc_manabar))) rc = self.hist_account.get_rc() estimated_rc = int(rc["max_rc"]) * rc_manabar["current_pct"] / 100 rc_calc = RC(steem_instance=self.stm) self.RCLabel.setText( "RC (%.0f G RC of %.0f G RC)" % (estimated_rc / 10**9, int(rc["max_rc"]) / 10**9)) ret = "--- Approx Costs ---\n" ret += "comment - %.2f G RC - enough RC for %d comments\n" % ( rc_calc.comment() / 10**9, int( estimated_rc / rc_calc.comment())) ret += "vote - %.2f G RC - enough RC for %d votes\n" % ( rc_calc.vote() / 10**9, int(estimated_rc / rc_calc.vote())) ret += "transfer - %.2f G RC - enough RC for %d transfers\n" % ( rc_calc.transfer() / 10**9, int(estimated_rc / rc_calc.transfer())) ret += "custom_json - %.2f G RC - enough RC for %d custom_json\n" % ( rc_calc.custom_json() / 10**9, int(estimated_rc / rc_calc.custom_json())) self.text.setText(ret) except: rc_manabar = None def store_account_hist(self): if self.hist_account is None: return self.db.store_account_hist(self.account_history, self.append_hist_info["trx_ids"]) def init_account_hist(self): if self.hist_account is None: return b = Blockchain(steem_instance=self.stm) latest_block_num = b.get_current_block_num() start_block_num = latest_block_num - (20 * 60 * 24) self.account_history = [] self.account_hist_info = {"start_block": 0, "trx_ids": []} self.append_hist_info = {"start_block": 0, "trx_ids": []} if self.db.has_account_hist(): self.account_history, trx_ids = self.db.load_account_hist() if self.account_history[0]["block"] <= start_block_num: self.append_hist_info["start_block"] = self.account_history[ -1]["block"] self.append_hist_info["trx_ids"] = trx_ids return self.lastUpvotesListWidget.clear() self.lastCurationListWidget.clear() self.lastAuthorListWidget.clear() self.accountHistListWidget.clear() start_block = 0 trx_ids = [] for op in self.hist_account.history(start=start_block_num): if op["block"] < start_block: continue elif op["block"] == start_block: if op["trx_id"] in trx_ids: continue else: trx_ids.append(op["trx_id"]) else: trx_ids = [op["trx_id"]] start_block = op["block"] self.account_history.append(op) self.append_hist_info["start_block"] = start_block self.append_hist_info["trx_ids"] = trx_ids def append_account_hist(self): if self.hist_account is None: return start_block = self.append_hist_info["start_block"] trx_ids = self.append_hist_info["trx_ids"] for op in self.hist_account.history(start=start_block - 20, use_block_num=True): if op["block"] < start_block: continue elif op["block"] == start_block: if op["trx_id"] in trx_ids: continue else: trx_ids.append(op["trx_id"]) else: trx_ids = [op["trx_id"]] start_block = op["block"] # print("Write %d" % op["index"]) self.account_history.append(op) self.append_hist_info["start_block"] = start_block self.append_hist_info["trx_ids"] = trx_ids def update_account_hist_thread(self): worker = Worker(self.update_account_hist) self.threadpool.start(worker) def update_account_feed_thread(self): worker = Worker(self.update_account_feed) self.threadpool.start(worker) @pyqtSlot(int) def change_displayed_post(self, row): if row < 0: return if len(self.feed) == 0: return if len(self.feed) <= row: return #index = self.feedListWidget.currentIndex() #row = index.row() self.post = self.feed[row] with self.updateLock: self.triggeredPreview() def update_account_feed(self): if self.hist_account is None: return updated_feed = self.hist_account.get_account_posts() if len(self.feed) == 0: self.feed = updated_feed else: for post in updated_feed[::-1]: found = False for p in self.feed: if post["authorperm"] == p["authorperm"]: found = True if not found: self.feed.insert(0, post) self.tray.showMessage(post["author"], post["title"]) with self.updateLock: if self.post is None: self.post = self.feed[0] self.triggeredPreview() self.feedListWidget.currentRowChanged.disconnect( self.change_displayed_post) self.feedListWidget.clear() for post in self.feed[::-1]: post_text = "%s - %s" % (post["author"], post["title"]) post_item = QListWidgetItem() post_item.setText(post_text) post_item.setToolTip(post["author"]) self.feedListWidget.insertItem(0, post_item) self.feedListWidget.currentRowChanged.connect( self.change_displayed_post, Qt.QueuedConnection) def update_account_hist(self): if self.hist_account is None: return votes = [] daily_curation = 0 daily_author_SP = 0 daily_author_SBD = 0 daily_author_STEEM = 0 self.append_account_hist() new_op_found = False start_block = self.account_hist_info["start_block"] if start_block == 0: first_call = True else: first_call = False trx_ids = self.account_hist_info["trx_ids"] for op in self.account_history: if op["block"] < start_block: # last_block = op["block"] continue elif op["block"] == start_block: if op["trx_id"] in trx_ids: continue else: trx_ids.append(op["trx_id"]) else: trx_ids = [op["trx_id"]] start_block = op["block"] new_op_found = True op_timedelta = formatTimedelta( addTzInfo(datetime.utcnow()) - formatTimeString(op["timestamp"])) op_local_time = formatTimeString(op["timestamp"]).astimezone( tz.tzlocal()) # print("Read %d" % op["index"]) if op["type"] == "vote": if op["voter"] == self.hist_account["name"]: continue if op["weight"] >= 0: self.lastUpvotesListWidget.insertItem( 0, "%s - %s (%.2f %%) upvote %s" % (op_timedelta, op["voter"], op["weight"] / 100, op["permlink"])) hist_item = "%s - %s - %s (%.2f %%) upvote %s" % ( op_local_time, op["type"], op["voter"], op["weight"] / 100, op["permlink"]) tray_item = "%s - %s (%.2f %%) upvote %s" % ( op["type"], op["voter"], op["weight"] / 100, op["permlink"]) else: hist_item = "%s - %s - %s (%.2f %%) downvote %s" % ( op_local_time, op["type"], op["voter"], op["weight"] / 100, op["permlink"]) tray_item = "%s - %s (%.2f %%) downvote %s" % ( op["type"], op["voter"], op["weight"] / 100, op["permlink"]) self.accountHistListWidget.insertItem(0, hist_item) elif op["type"] == "curation_reward": curation_reward = self.stm.vests_to_sp( Amount(op["reward"], steem_instance=self.stm)) self.lastCurationListWidget.insertItem( 0, "%s - %.3f HP for %s" % (op_timedelta, curation_reward, construct_authorperm(op["comment_author"], op["comment_permlink"]))) hist_item = "%s - %s - %.3f HP for %s" % ( op_local_time, op["type"], curation_reward, construct_authorperm(op["comment_author"], op["comment_permlink"])) tray_item = "%s - %.3f HP for %s" % ( op["type"], curation_reward, construct_authorperm(op["comment_author"], op["comment_permlink"])) self.accountHistListWidget.insertItem(0, hist_item) elif op["type"] == "author_reward": sbd_payout = (Amount(op["sbd_payout"], steem_instance=self.stm)) steem_payout = (Amount(op["steem_payout"], steem_instance=self.stm)) sp_payout = self.stm.vests_to_sp( Amount(op["vesting_payout"], steem_instance=self.stm)) self.lastAuthorListWidget.insertItem( 0, "%s - %s %s %.3f HP for %s" % (op_timedelta, str(sbd_payout), str(steem_payout), sp_payout, op["permlink"])) hist_item = "%s - %s - %s %s %.3f SP for %s" % ( op_local_time, op["type"], str(sbd_payout), str(steem_payout), sp_payout, op["permlink"]) tray_item = "%s - %s %s %.3f SP for %s" % ( op["type"], str(sbd_payout), str(steem_payout), sp_payout, op["permlink"]) self.accountHistListWidget.insertItem(0, hist_item) elif op["type"] == "custom_json": hist_item = "%s - %s - %s" % (op_local_time, op["type"], op["id"]) tray_item = "%s - %s" % (op["type"], op["id"]) self.accountHistListWidget.insertItem(0, hist_item) elif op["type"] == "transfer": hist_item = "%s - %s - %s from %s" % ( op_local_time, op["type"], str(Amount(op["amount"], steem_instance=self.stm)), op["from"]) tray_item = "%s - %s from %s" % ( op["type"], str(Amount(op["amount"], steem_instance=self.stm)), op["from"]) self.accountHistListWidget.insertItem(0, hist_item) elif op["type"] == "comment": comment_type = "post" if op["parent_author"] != "": hist_item = "%s - comment on %s - %s from %s" % ( op_local_time, construct_authorperm( op["parent_author"], op["parent_permlink"]), op["title"], op["author"]) tray_item = "comment from %s: %s on %s" % ( op["author"], op["body"][:100], op["title"]) else: hist_item = "%s - post - %s from %s" % ( op_local_time, op["title"], op["author"]) tray_item = "post from %s: %s" % (op["author"], op["title"]) self.accountHistListWidget.insertItem(0, hist_item) else: hist_item = "%s - %s" % (op_local_time, op["type"]) tray_item = "%s" % (op["type"]) self.accountHistListWidget.insertItem(0, hist_item) if self.accountHistNotificationCheckBox.isChecked( ) and not first_call: self.tray.showMessage(self.hist_account["name"], tray_item) if new_op_found: self.account_hist_info["start_block"] = start_block self.account_hist_info["trx_ids"] = trx_ids for op in self.account_history: if op["type"] == "vote": if op["voter"] == self.hist_account["name"]: continue votes.append(op) elif op["type"] == "curation_reward": curation_reward = self.stm.vests_to_sp( Amount(op["reward"], steem_instance=self.stm)) daily_curation += curation_reward elif op["type"] == "author_reward": sbd_payout = (Amount(op["sbd_payout"], steem_instance=self.stm)) steem_payout = (Amount(op["steem_payout"], steem_instance=self.stm)) sp_payout = self.stm.vests_to_sp( Amount(op["vesting_payout"], steem_instance=self.stm)) daily_author_SP += sp_payout daily_author_STEEM += float(steem_payout) daily_author_SBD += float(sbd_payout) reward_text = "Curation reward (last 24 h): %.3f HP\n" % daily_curation reward_text += "Author reward (last 24 h):\n" reward_text += "%.3f HP - %.3f HIVE - %.3f HBD" % ( daily_author_SP, (daily_author_STEEM), (daily_author_SBD)) self.text2.setText(reward_text)
class RedFisher: def __init__(self): """Initialisation.""" self.load_settings() self.nodes = [ 'https://api.steemit.com', 'https://rpc.buildteam.io', 'https://api.steem.house', 'https://steemd.steemitdev.com', 'https://steemd.steemitstage.com', 'https://steemd.steemgigs.org' ] self.s = Steem(keys=self.posting_key) self.s.set_default_nodes(self.nodes) self.b = Blockchain(self.s) set_shared_steem_instance(self.s) self.p = Pool(4) def timer_start(self): """Set a timer to restart the program at 7pm the next day.""" # Calculate how many seconds until 7pm tomorrow now = datetime.today() print(now.day) a_time = now.replace(day=now.day + 1, hour=19, minute=0, microsecond=0) d_time = a_time - now secs = d_time.seconds + 1 # Reload settings from external file self.load_settings() # Start the timer t = threading.Timer(secs, self.redfisher) t.start() print('Timer set for ' + str(secs / 3600) + ' hours.') def load_settings(self): """Load the account requrements from an external file.""" # Load the external .json settings = json.loads(open('settings.json', 'r').read()) # Import the settings to variables self.days = settings['days'] self.posts_per_week = settings['posts_per_week'] self.min_sp = settings['min_sp'] self.max_sv = settings['max_sv'] self.posting_account = settings['posting_account'] self.posting_key = settings['posting_key'] print('settings loaded\ndays: %d\nposts per week: %d\nminimum steem ' 'power: %d' % (self.days, self.posts_per_week, self.min_sp)) def redfisher(self): """ Streams through all posts within given timeframe and sends accounts to be validated. """ t1 = time.process_time() # Calculate the start block based on how many days were specified # in the settings now = datetime.now() start_date = now - timedelta(days=self.days) start_block = self.b.get_estimated_block_num(start_date) # Get the end block end_block = self.b.get_current_block_num() # Create/reset approved user dictionary self.user_list = dict() # stream comments from start block to current block print('streaming comments now') # Create checked accounts list checked_accounts = list() # Infinite while allows for many node swaps while True: try: # Start/continue the stream from start/lastchecked block for post in self.b.stream(opNames=['comment'], start=start_block, stop=end_block): # Set start block to the one currently being checked start_block = post['block_num'] # Assure that the post is not a comment if post['parent_author'] == '': author = post['author'] # Don't check accounts that have already been checked if author not in checked_accounts: # Add account to checked accounts checked_accounts.append(author) # Add account to pool to be checked self.p.enqueue(func=self.check, user=author) self.p.run() # All checks completed, break loop break except Exception as e: # Switch nodes print(e) self.failover() time.sleep(1) t2 = time.process_time() print(t2 - t1) # Wait for task pool to empty while self.p.done() == False: time.sleep(2) # Attempt to post every 20 seconds until complete while True: try: self.post() break except: time.sleep(20) def get_account_age(self, acc): """Calculate how old an account is. Keyword arguments: acc -- the account to be checked -- type: Account """ # Declare account creation types types = [ 'create_claimed_account', 'account_create_with_delegation', 'account_create' ] # Look through history until account creation is found for i in acc.history(only_ops=types): # Get account creation timestamp creation_date_raw = i['timestamp'] break print(creation_date_raw) # Convert timestamp into datetime obj creation_date = datetime.strptime(creation_date_raw, '%Y-%m-%dT%H:%M:%S') # Calculate age in days now = datetime.now() acc_age = (now - creation_date).days return acc_age def post(self): """Make the post containing all the collected info for the round.""" # Get date in string format date = datetime.today().strftime('%Y-%m-%d') print(date) # Read the post body from external file post_body = open('post_body.txt', 'r').read() # Order the approved accounts by age sorted_ul = sorted(self.user_list.keys(), key=lambda y: (self.user_list[y]['age'])) # For each approved user, add them to the bottom of the post table for username in sorted_ul: data = self.user_list[username] sp = str(round(data['sp'], 3)) age = data['age'] svp = data['svp'] post_body += '\n@%s | %s | %s | %s' % (username, sp, age, svp) print(post_body) # Broadcast post transaction self.s.post(title='Small Accounts To Support - ' + date, body=post_body, author=self.posting_account, tags=[ 'onboarding', 'retention', 'steem', 'help', 'delegation', 'community', 'giveaway' ]) print('posted') # Reset the cycle self.refresh() def check(self, user): """ Check that the users meet the requirements. user -- the account to be checked -- type: Account/str """ # If an account wasn't passed, make str into account if type(user) != Account: acc = Account(user) # Check account steempower sp = self.sp_check(acc) print(user + " sp == " + str(sp)) if sp <= float(self.min_sp): print('min sp met') # Check account posts per week ppw_check = self.post_check(acc) print(user + " posts per week check == " + str(ppw_check)) if ppw_check: print('posts per week met') # Check self vote percent self_vote_pct = self.vote_check(acc) print(user + ' self votes == %' + str(self_vote_pct)) if self_vote_pct < self.max_sv: print('self vote check met') # Check for powerups and powerdowns powered_up, powered_down = self.vest_check(acc) print(user + " powered up == " + str(powered_up)) print(user + " powered down == " + str(powered_down)) if powered_up and not powered_down: print('vest check met') # All checks completed # Get account age age = self.get_account_age(acc) # Add account to list so their data is stored for the # daily post. self.user_list[user] = { 'sp': round(sp, 3), 'age': age, 'svp': round(self_vote_pct, 2) } print(self.user_list) def sp_check(self, acc): """ Return the users steem power (ignoring outgoing delegations). acc -- the account to be checked -- type: Account """ # Get absolute steempower sp = float(acc.get_steem_power()) # Get all outgoing delegations and add them to account sp for delegation in acc.get_vesting_delegations(): vests = float(delegation['vesting_shares']['amount']) precision = delegation['vesting_shares']['precision'] dele_sp_raw = self.s.vests_to_sp(vests) dele_sp = dele_sp_raw / 10**precision sp += dele_sp return sp def vest_check(self, acc): """Check for opwer ups/downs and return powered_up (bool), powered_down (bool). acc -- the account to be checked -- type: Account """ # get all time powerup and powerdown history powered_up = False powered_down = False vest_history = acc.history_reverse( only_ops=['withdraw_vesting', 'transfer_to_vesting']) # check for powerups and powerdowns for change in vest_history: if change['type'] == 'withdraw_vesting': powered_down = True if change['type'] == 'transfer_to_vesting': powered_up = True if powered_up and powered_down: break return powered_up, powered_down def vote_check(self, acc): """Return the self vote percentage based on weight. acc -- the account to be checked -- type: Account """ # Declare variables total = 0 self_vote = 0 # Date datetime for a week ago wa = self._get_date_past() # Go through all votes in the past week for i in acc.history_reverse(only_ops=['vote'], stop=wa): # Update total total += int(i['weight']) # Update self vote total if self vote if i['author'] == i['voter']: self_vote += int(i['weight']) # No votes made results in /0 error, return 0% self vote if total == 0: return 0 self_vote_pct = (self_vote / total) * 100 return self_vote_pct def post_check(self, acc): """Return true if posts per week requirement is met, false if not. acc -- the account to be checked -- type: Account """ # Get datetime for a week ago wa = self._get_date_past() # Get comment history for the last week blog_history = acc.history_reverse(only_ops=['comment'], stop=wa) # Count how many posts were made in the last week count = 0 for post in blog_history: # Check to make sure it isn't a reply if post['parent_author'] == '': count += 1 if self.posts_per_week >= count: return True return True def _get_date_past(self, days_ago=7): """Returns the datetime for the current time, x days ago. days_ago -- how many days ago you want the datetime for -- type: int """ now = datetime.now() return now - timedelta(days=days_ago) def refresh(self): """Called when the main module has finished executing and the post has been made. It resets all the settings and resets the cycle. """ self.user_list = dict() self.load_settings() self.timer_start() def failover(self): """Switch/cycle through nodes.""" self.nodes = self.nodes[1:] + [self.nodes[0]] print('Switching nodes to ' + self.nodes[0])
c_list = [] names=[] for c in acc.history_reverse(only_ops=["delegate_vesting_shares"]): data=re.findall("'delegator': '(.+?)'",str(c)),re.findall("'delegatee': '(.+?)'",str(c)),re.findall("'amount': '(.+?)'",str(c)) name=re.findall("'delegator': '(.+?)'",str(c)) if name not in names: print(re.findall("'delegator': '(.+?)'",str(c)),re.findall("'delegatee': '(.+?)'",str(c)),re.findall("'amount': '(.+?)'",str(c))) c_list.append(data) names.append(name) active=[] removed=[] for i in c_list: if str(i[2])=="['0']": data=i[0][0],i[2][0] removed.append(data) else: hive=stm.vests_to_sp(i[2][0])#.split(' ')[0])) data=i[0][0], hive #i[2][0] #print ('DATA 2', data) active.append(data) for i in active: print (i[0],':',round(i[1]/1000000,3),'HIVE') print ('ACTIVE:',len(active)) print ('LOST:',len(removed)) a=input ('Do you want to print the undelgator list?') if a=='y': for i in removed: print (i[0][0],':',i[1],'HIVE') else: exit
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(QMainWindow, self).__init__() # Set up the user interface from Designer. self.setupUi(self) self.setAccessibleName("Hive Desktop") self.redrawLock = Lock() self.updateLock = Lock() self.optionsDialog = dialogs.Options(self) self.aboutDialog = dialogs.About(self, copyright='holger80', programName='Hive Desktop', version=VERSION, website='https://github.com/holgern/hivedesktop', websiteLabel='Github', comments='"Welcome to Hive desktop!\n This is the first release for testing qt5.\n Please vote for holger80 as witness, if you like this :).', licenseName='GPL-3.0', # licenseUrl=helpers.joinpath_to_cwd('LICENSE').as_uri(), authors=('holger80',), # dependencies=[l.strip() for l in requirements.readlines()], ) self.mdrenderer = MDRenderer(str(helpers.joinpath_to_cwd('themes'))) # tmpfile = helpers.mktemp(prefix='hivedesktop', suffix='.html') self.post = {"body": "##test", "authorperm": "@test/test"} self.thread = threads.MDThread(self) # self.webview.url = tmpfile.as_uri() self.feedListWidget.currentRowChanged.connect(self.change_displayed_post, Qt.QueuedConnection) self.timer = QTimer() self.timer.timeout.connect(self.refresh_account_thread) self.timer2 = QTimer() self.timer2.timeout.connect(self.update_account_hist_thread) self.timer3 = QTimer() self.timer3.timeout.connect(self.update_account_feed_thread) self.cache_path = QStandardPaths.writableLocation(QStandardPaths.CacheLocation) self.db_type = "shelve" self.db_type = "sqlite" self.feed = [] self.post = None # Get settings settings = QSettings() # Get checkbox state with speciying type of checkbox: # type=bool is a replacement of toBool() in PyQt5 check_state = settings.value(SETTINGS_TRAY, True, type=bool) hist_info_check_state = settings.value(SETTINGS_HIST_INFO, True, type=bool) account_state = settings.value(SETTINGS_ACCOUNT, "", type=str) self.resize(settings.value(SETTINGS_SIZE, QSize(1053, 800))) self.move(settings.value(SETTINGS_POS, QPoint(50, 50))) #self.accountHistTableWidget.setColumnCount(5) #self.accountHistTableWidget.setHorizontalHeaderLabels(["type", "1", "2", "3", "timestamp"]) self.update_account_refreshtime = 5000 # Set state self.accountHistNotificationCheckBox.setChecked(hist_info_check_state) self.autoRefreshCheckBox.setChecked(check_state) if check_state: self.timer.start(self.update_account_refreshtime) self.timer2.start(15000) self.timer3.start(60000) self.accountLineEdit.setText(account_state) # connect the slot to the signal by clicking the checkbox to save the state settings self.autoRefreshCheckBox.clicked.connect(self.save_check_box_settings) self.accountHistNotificationCheckBox.clicked.connect(self.save_check_box_settings) self.accountLineEdit.editingFinished.connect(self.save_account_settings) self.actionAbout.triggered.connect(self.about) self.actionOptions.triggered.connect(self.options) self.threadpool = QThreadPool() self.minimizeAction = QAction("Mi&nimize", self, triggered=self.hide) self.maximizeAction = QAction("Ma&ximize", self, triggered=self.showMaximized) self.restoreAction = QAction("&Restore", self, triggered=self.showNormal) menu = QMenu() menu.addAction(self.minimizeAction) menu.addAction(self.maximizeAction) menu.addAction(self.restoreAction) menu.addSeparator() # aboutAction = menu.addAction("about") # aboutAction.triggered.connect(self.about) exitAction = menu.addAction("Exit") exitAction.triggered.connect(self.closeApp) self.tray = QSystemTrayIcon(QIcon(':/icons/icon.ico')) self.tray.setContextMenu(menu) self.tray.activated.connect(self.trayAction) self.tray.setToolTip("Hive Desktop!") self.tray.setObjectName("Hive Desktop") self.setWindowTitle("Hive Desktop") self.tray.show() splash_pix = QPixmap(':/icons/splash.png') splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint) splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) splash.setEnabled(False) #splash.show() #splash.showMessage("<h1><font color='green'>starting...</font></h1>", Qt.AlignTop | Qt.AlignCenter, Qt.black) account = account_state nodelist = NodeList() nodelist.update_nodes() self.stm = Steem(node=nodelist.get_nodes(hive=True)) set_shared_blockchain_instance(self.stm) if account != "": try: self.hist_account = Account(account, steem_instance=self.stm) except: self.hist_account = None else: self.hist_account = None self.refreshPushButton.clicked.connect(self.refresh_account) self.refreshPushButton.clicked.connect(self.update_account_hist_thread) self.accountLineEdit.editingFinished.connect(self.update_account_info) if self.hasFocus is not None: self.init_new_account() self.init_new_blocks() splash.deleteLater() def triggeredPreview(self): self.authorLabel.setText(self.post["author"]) self.titleLabel.setText(self.post["title"]) self.auhorpermLineEdit.setText(construct_authorperm(self.post["author"], self.post["permlink"])) self.thread.start() @pyqtSlot(str) def cbMDThread(self, html): self.webview.setHtml(html) @pyqtSlot(QSystemTrayIcon.ActivationReason) def trayAction(self, reason): if reason == QSystemTrayIcon.Trigger: if self.isHidden(): self.showNormal() else: self.hide() def closeEvent(self, event): if self.tray.isVisible(): #QMessageBox.information(self, "Hive Desktop", # "The program will keep running in the system tray. To " # "terminate the program, choose <b>Quit</b> in the " # "context menu of the system tray entry.") self.tray.showMessage("Hive Desktop", "The program will keep running in the system tray. To " "terminate the program, choose Quit in the " "context menu of the system tray entry.") self.hide() event.ignore() def hide(self): self.update_account_refreshtime = 60000 self.timer.start(self.update_account_refreshtime) QMainWindow.hide(self) def showNormal(self): self.update_account_refreshtime = 5000 self.timer.start(self.update_account_refreshtime) QMainWindow.showNormal(self) def showMaximized(self): self.update_account_refreshtime = 5000 self.timer.start(self.update_account_refreshtime) QMainWindow.showMaximized(self) def closeApp(self): settings = QSettings() settings.setValue(SETTINGS_SIZE, self.size()) settings.setValue(SETTINGS_POS, self.pos()) settings.sync() sys.exit() def about(self): self.aboutDialog.exec_() def options(self): self.optionsDialog.exec_() # Slot checkbox to save the settings def save_check_box_settings(self): settings = QSettings() settings.setValue(SETTINGS_HIST_INFO, self.accountHistNotificationCheckBox.isChecked()) settings.setValue(SETTINGS_TRAY, self.autoRefreshCheckBox.isChecked()) if self.autoRefreshCheckBox.isChecked(): self.timer.start(self.update_account_refreshtime) self.timer2.start(15000) self.timer3.start(60000) else: self.timer.stop() self.timer2.stop() self.timer3.stop() settings.sync() # Slot checkbox to save the settings def save_account_settings(self): settings = QSettings() settings.setValue(SETTINGS_ACCOUNT, self.accountLineEdit.text()) settings.sync() def update_account_info(self): if self.hist_account is None or self.hist_account["name"] != self.accountLineEdit.text(): try: self.hist_account = Account(self.accountLineEdit.text(), steem_instance=self.stm) except: self.hist_account = None self.init_new_account() def init_new_account(self): self.refresh_account() self.update_account_feed() if self.hist_account is not None: self.db = database.Database(self.db_type, self.cache_path, self.hist_account["name"]) self.loadingProgressBar.setMaximum(self.db.get_account().virtual_op_count()) self.iah_thread = threads.IAHThread(self, self.db) self.timer.stop() self.timer2.stop() self.refreshPushButton.setEnabled(False) self.accountLineEdit.setEnabled(False) self.iah_thread.start() else: self.init_account_hist() self.update_account_hist() def init_new_blocks(self): blockchain = Blockchain() self.block_db = database_blocks.DatabaseBlocks(self.db_type, self.cache_path) self.loadingBlocksProgressBar.setMaximum(self.block_db.block_history) self.blocks_thread = threads.BlocksThread(self, self.block_db, blockchain) self.blocks_thread.start() @pyqtSlot(str) def cIAHThread(self, dummy): self.init_account_hist() self.update_account_hist() self.refreshPushButton.setEnabled(True) self.accountLineEdit.setEnabled(True) self.tray.showMessage("Ready", "Account history loaded!") self.timer.start(self.update_account_refreshtime) self.timer2.start(15000) @pyqtSlot(str) def cBlocksThread(self, dummy): self.init_blocks() self.update_blocks() #self.timer.start(self.update_account_refreshtime) #self.timer2.start(15000) def refresh_account_thread(self): worker = Worker(self.refresh_account) self.threadpool.start(worker) def refresh_account(self): if self.hist_account is None: return self.hist_account.refresh() self.accountInfoGroupBox.setTitle("%s (%.3f)" % (self.hist_account["name"], self.hist_account.rep)) with self.redrawLock: self.votePowerProgressBar.setValue(int(self.hist_account.vp)) if self.hist_account.vp == 100: self.votePowerProgressBar.setFormat("%.2f %%" % (self.hist_account.vp)) else: self.votePowerProgressBar.setFormat("%.2f %%, full in %s" % (self.hist_account.vp, self.hist_account.get_recharge_time_str())) down_vp = self.hist_account.get_downvoting_power() with self.redrawLock: self.downvotePowerProgressBar.setValue(int(down_vp)) if down_vp == 100: self.downvotePowerProgressBar.setFormat("%.2f %%" % (down_vp)) else: self.downvotePowerProgressBar.setFormat("%.2f %%, full in %s" % (down_vp, self.hist_account.get_recharge_time(starting_voting_power=down_vp))) self.votePowerLabel.setText("Vote Power, a 100%% vote is %.3f $" % (self.hist_account.get_voting_value_SBD())) self.downvotePowerLabel.setText("DownVote Power") self.STEEMLabel.setText(str(self.hist_account["balance"])) self.SBDLabel.setText(str(self.hist_account["sbd_balance"])) self.SPLabel.setText("%.3f HP" % self.stm.vests_to_sp(self.hist_account["vesting_shares"])) try: rc_manabar = self.hist_account.get_rc_manabar() with self.redrawLock: self.RCProgressBar.setValue(int(rc_manabar["current_pct"])) self.RCProgressBar.setFormat("%.2f %%, full in %s" % (rc_manabar["current_pct"], self.hist_account.get_manabar_recharge_time_str(rc_manabar))) rc = self.hist_account.get_rc() estimated_rc = int(rc["max_rc"]) * rc_manabar["current_pct"] / 100 rc_calc = RC(steem_instance=self.stm) self.RCLabel.setText("RC (%.0f G RC of %.0f G RC)" % (estimated_rc / 10**9, int(rc["max_rc"]) / 10**9)) ret = "--- Approx Costs ---\n" ret += "comment - %.2f G RC - enough RC for %d comments\n" % (rc_calc.comment() / 10**9, int(estimated_rc / rc_calc.comment())) ret += "vote - %.2f G RC - enough RC for %d votes\n" % (rc_calc.vote() / 10**9, int(estimated_rc / rc_calc.vote())) ret += "transfer - %.2f G RC - enough RC for %d transfers\n" % (rc_calc.transfer() / 10**9, int(estimated_rc / rc_calc.transfer())) ret += "custom_json - %.2f G RC - enough RC for %d custom_json\n" % (rc_calc.custom_json() / 10**9, int(estimated_rc / rc_calc.custom_json())) self.text.setText(ret) except: rc_manabar = None @pyqtSlot(int) def set_loading_progress(self, val): with self.redrawLock: self.loadingProgressBar.setValue(val) @pyqtSlot(int) def set_loading_blocks_progress(self, val): with self.redrawLock: self.loadingBlocksProgressBar.setValue(val) def init_blocks(self): self.blockCountLabel.setText("%d entries" % self.block_db.get_block_count()) def init_account_hist(self): if self.hist_account is None: return self.account_hist_info = {"start_block": 0} self.append_hist_info = {"start_block": 0} #if not self.db.has_account_hist(): # ops = self.db.get_acc_hist() # self.db.store_account_hist(ops) #else: # start_op = self.db.get_last_op() # ops = self.db.read_missing_account_history_data(start_op) # self.db.store_account_hist(ops) self.accountHistoryLabel.setText("%d entries" % self.db.get_count()) self.accountHistTableWidget.clear() def append_blocks(self): start_op = self.block_db.get_last_op() data = self.block_db.read_missing_block_data(start_op) # print("finished") if len(data) > 0: # print(op["timestamp"]) self.block_db.append_blocks(data) self.blockCountLabel.setText("%d entries" % self.block_db.get_block_count()) def append_account_hist(self): if self.hist_account is None: return # print("loading db") start_op = self.db.get_last_op() data = self.db.read_missing_account_history_data(start_op) # print("finished") if len(data) > 0: # print(op["timestamp"]) self.db.append_account_hist(data) self.accountHistoryLabel.setText("%d entries" % self.db.get_count()) def update_account_hist_thread(self): worker = Worker(self.update_account_hist) self.threadpool.start(worker) def update_account_feed_thread(self): worker = Worker(self.update_account_feed) self.threadpool.start(worker) @pyqtSlot(int) def change_displayed_post(self, row): if row < 0: return if len(self.feed) == 0: return if len(self.feed) <= row: return #index = self.feedListWidget.currentIndex() #row = index.row() self.post = self.feed[row] with self.updateLock: self.triggeredPreview() replies = Comment(self.post).get_all_replies() is_shown = [0] * len(replies) max_depth = 0 for i in range(len(replies)): if replies[i].depth > max_depth: max_depth = replies[i].depth self.commentsTreeWidget.clear() def create_item(reply): item = QTreeWidgetItem() item.setText(0, reply["author"]) item.setText(1, reply["body"]) item.setToolTip(1, reply["body"]) return item for i in range(len(replies)): if is_shown[i] == 1: continue reply = replies[i] if reply.depth == 1: is_shown[i] = 1 item = create_item(reply) for j in range(len(replies)): rr = replies[j] if is_shown[j] == 1: continue if rr.depth == 2: is_shown[j] = 1 if rr.parent_author == reply["author"] and rr.parent_permlink == reply["permlink"]: rr_item = create_item(rr) if max_depth >= 3: for k in range(len(replies)): rrr = replies[k] if is_shown[k] == 1: continue if rrr.depth == 3: is_shown[k] = 1 if rrr.parent_author == rr["author"] and rrr.parent_permlink == rr["permlink"]: rrr_item = create_item(rrr) if max_depth >= 4: for l in range(len(replies)): rrrr = replies[l] if is_shown[l] == 1: continue if rrrr.depth == 4: is_shown[l] = 1 if rrrr.parent_author == rrr["author"] and rrrr.parent_permlink == rrr["permlink"]: rrrr_item = create_item(rrrr) rrr_item.addChild(rrrr_item) rr_item.addChild(rrr_item) item.addChild(rr_item) self.commentsTreeWidget.addTopLevelItem(item) def update_account_feed(self): if self.hist_account is None: return try: updated_feed = self.hist_account.get_account_posts() except: print("could not update feed") return if len(self.feed) == 0: self.feed = updated_feed else: for post in updated_feed[::-1]: found = False for p in self.feed: if post["authorperm"] == p["authorperm"]: found = True if not found: self.feed.insert(0, post) if (addTzInfo(datetime.utcnow()) - post["created"]).total_seconds() / 60 < 5: self.tray.showMessage(post["author"], post["title"]) with self.updateLock: if self.post is None: self.post = self.feed[0] self.triggeredPreview() self.feedListWidget.currentRowChanged.disconnect(self.change_displayed_post) self.feedListWidget.clear() for post in self.feed[::-1]: post_text = "%s - %s" % (post["author"], post["title"]) post_item = QListWidgetItem() post_item.setText(post_text) post_item.setToolTip(post["author"]) self.feedListWidget.insertItem(0, post_item) self.feedListWidget.currentRowChanged.connect(self.change_displayed_post, Qt.QueuedConnection) def update_blocks(self): return def update_account_hist(self): if self.hist_account is None: return votes = [] daily_curation = 0 daily_author_SP = 0 daily_author_SBD = 0 daily_author_STEEM = 0 self.append_account_hist() new_op_found = False start_block = self.account_hist_info["start_block"] if start_block == 0: first_call = True b = Blockchain() start_block = b.get_current_block_num() - 20 * 60 * 24 * 7 self.account_hist_info["start_block"] = start_block else: first_call = False ops = self.db.load_account_hist(start_block) for op in ops: if op["block"] < start_block: # last_block = op["block"] continue start_block = op["block"] new_op_found = True tray_item = None op_timedelta = formatTimedelta(addTzInfo(datetime.utcnow()) - addTzInfo(op["timestamp"])) op_local_time = addTzInfo(op["timestamp"]).astimezone(tz.tzlocal()) # print("Read %d" % op["index"]) self.accountHistTableWidget.insertRow(0) self.accountHistTableWidget.setItem(0, 4, QTableWidgetItem(str(op_local_time))) if op["type"] == "vote": if op["voter"] == self.hist_account["name"]: self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem("Vote")) self.accountHistTableWidget.setItem(0, 1, QTableWidgetItem(op["author"])) elif op["weight"] >= 0: self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem("Vote Post")) self.accountHistTableWidget.setItem(0, 1, QTableWidgetItem(op["voter"])) tray_item = "%s - %s (%.2f %%) vote %s" % (op["type"], op["voter"], op["weight"] / 100, op["permlink"]) else: self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem("Dowvote Post")) self.accountHistTableWidget.setItem(0, 1, QTableWidgetItem(op["voter"])) # hist_item.setToolTip(0, op["permlink"]) tray_item = "%s - %s (%.2f %%) downvote %s" % (op["type"], op["voter"], op["weight"] / 100, op["permlink"]) self.accountHistTableWidget.setItem(0, 2, QTableWidgetItem("%.2f %%" % (op["weight"] / 100))) elif op["type"] == "curation_reward": self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem(op["type"])) curation_reward = self.stm.vests_to_sp(Amount(op["reward"], steem_instance=self.stm)) self.accountHistTableWidget.setItem(0, 1, QTableWidgetItem("%.3f HP" % curation_reward)) self.accountHistTableWidget.setItem(0, 2, QTableWidgetItem(construct_authorperm(op["comment_author"], op["comment_permlink"]))) hist_item = "%s - %s - %.3f HP for %s" % (op_local_time, op["type"], curation_reward, construct_authorperm(op["comment_author"], op["comment_permlink"])) tray_item = "%s - %.3f HP for %s" % (op["type"], curation_reward, construct_authorperm(op["comment_author"], op["comment_permlink"])) elif op["type"] == "author_reward": self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem(op["type"])) sbd_payout = (Amount(op["sbd_payout"], steem_instance=self.stm)) steem_payout = (Amount(op["steem_payout"], steem_instance=self.stm)) sp_payout = self.stm.vests_to_sp(Amount(op["vesting_payout"], steem_instance=self.stm)) hist_item = "%s - %s - %s %s %.3f SP for %s" % (op_local_time, op["type"], str(sbd_payout), str(steem_payout), sp_payout, op["permlink"]) tray_item = "%s - %s %s %.3f SP for %s" % (op["type"], str(sbd_payout), str(steem_payout), sp_payout, op["permlink"]) elif op["type"] == "custom_json": self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem(op["type"])) self.accountHistTableWidget.setItem(0, 1, QTableWidgetItem(op["json_id"])) json_data = QTableWidgetItem(op["json"]) json_data.setToolTip(op["json"]) self.accountHistTableWidget.setItem(0, 2, json_data) hist_item = "%s - %s - %s" % (op_local_time, op["type"], op["id"]) tray_item = "%s - %s" % (op["type"], op["json_id"]) elif op["type"] == "transfer": self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem(op["type"])) hist_item = "%s - %s - %s from %s" % (op_local_time, op["type"], str(Amount(op["amount"], steem_instance=self.stm)), op["from"]) tray_item = "%s - %s from %s" % (op["type"], str(Amount(op["amount"], steem_instance=self.stm)), op["from"]) elif op["type"] == "comment": if op["parent_author"] != "": comment_type = "comment" hist_item = "%s - comment on %s - %s from %s" % (op_local_time, construct_authorperm(op["parent_author"], op["parent_permlink"]), op["title"], op["author"]) tray_item = "comment from %s: %s on %s" % (op["author"], op["body"][:100], op["title"]) self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem(op["type"])) self.accountHistTableWidget.setItem(0, 1, QTableWidgetItem(op["author"])) body = QTableWidgetItem(op["body"]) body.setToolTip(op["body"]) self.accountHistTableWidget.setItem(0, 2, body) else: comment_type = "post" hist_item = "%s - post - %s from %s" % (op_local_time, op["title"], op["author"]) tray_item = "post from %s: %s" % (op["author"], op["title"]) self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem(comment_type)) elif op["type"] == "producer_reward": self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem(op["type"])) self.accountHistTableWidget.setItem(0, 1, QTableWidgetItem(" %.3f HP" % float(self.stm.vests_to_sp(Amount(op["vesting_shares"]))))) hist_item = "%s - %s" % (op_local_time, op["type"]) tray_item = "%s - %.3f HP" % (op["type"], float(self.stm.vests_to_sp(Amount(op["vesting_shares"])))) else: self.accountHistTableWidget.setItem(0, 0, QTableWidgetItem(op["type"])) hist_item = "%s - %s" % (op_local_time, op["type"]) tray_item = "%s" % (op["type"]) if self.accountHistNotificationCheckBox.isChecked() and not first_call and tray_item is not None: self.tray.showMessage(self.hist_account["name"], tray_item) if new_op_found: self.account_hist_info["start_block"] = start_block for op in ops: if op["type"] == "vote": if op["voter"] == self.hist_account["name"]: continue votes.append(op) elif op["type"] == "curation_reward": curation_reward = self.stm.vests_to_sp(Amount(op["reward"], steem_instance=self.stm)) daily_curation += curation_reward elif op["type"] == "author_reward": sbd_payout = (Amount(op["sbd_payout"], steem_instance=self.stm)) steem_payout = (Amount(op["steem_payout"], steem_instance=self.stm)) sp_payout = self.stm.vests_to_sp(Amount(op["vesting_payout"], steem_instance=self.stm)) daily_author_SP += sp_payout daily_author_STEEM += float(steem_payout) daily_author_SBD += float(sbd_payout) reward_text = "Curation reward (last 24 h): %.3f HP\n" % daily_curation reward_text += "Author reward (last 24 h):\n" reward_text += "%.3f HP - %.3f HIVE - %.3f HBD" % (daily_author_SP, (daily_author_STEEM), (daily_author_SBD)) self.text2.setText(reward_text)