Skip to content

Commit

Permalink
Several improvemtents
Browse files Browse the repository at this point in the history
Account
* datetime.date is also supported
CLI
* curation improved
Comment
* doc improved
Transactionbuilder
* doc fixed
* owner key is taken, when no other permission is proved
utils
* datetime.date supported
Wallet
*   raise MissingKeyError when a wrong key is given by Steem(keys=[])
Unit tests
* several unit tests has to be changed as now it is really tested if a given wif belongs to the account or not.
  • Loading branch information
holgern committed May 27, 2018
1 parent 8201cac commit 818c8f1
Show file tree
Hide file tree
Showing 18 changed files with 365 additions and 272 deletions.
34 changes: 17 additions & 17 deletions beem/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from builtins import bytes, int, str
import pytz
import json
from datetime import datetime, timedelta
from datetime import datetime, timedelta, date, time
import math
import random
import logging
Expand Down Expand Up @@ -148,7 +148,7 @@ def json(self):
for p in parse_times:
if p in output:
date = output.get(p, datetime(1970, 1, 1, 0, 0))
if isinstance(date, datetime):
if isinstance(date, (datetime, date, time)):
output[p] = formatTimeString(date)
else:
output[p] = date
Expand Down Expand Up @@ -883,7 +883,7 @@ def estimate_virtual_op_num(self, blocktime, stop_diff=1, max_count=100):
created = self["created"]
if stop_diff <= 0:
raise ValueError("stop_diff <= 0 is not allowed and would lead to an endless lopp...")
if not isinstance(blocktime, datetime):
if not isinstance(blocktime, (datetime, date, time)):
b = Blockchain(steem_instance=self.steem)
created_blocknum = b.get_estimated_block_num(created, accurate=True)
if blocktime < created_blocknum:
Expand All @@ -901,7 +901,7 @@ def estimate_virtual_op_num(self, blocktime, stop_diff=1, max_count=100):
else:
return 0

if isinstance(blocktime, datetime):
if isinstance(blocktime, (datetime, date, time)):
account_lifespan_sec = (formatTimeString(last_trx["timestamp"]) - created).total_seconds()
if (formatTimeString(last_trx["timestamp"]) - blocktime).total_seconds() < 0:
return max_index
Expand Down Expand Up @@ -934,11 +934,11 @@ def estimate_virtual_op_num(self, blocktime, stop_diff=1, max_count=100):

if op_start_last is not None:
diff_op = (op_start_last[0][0] - estimated_op_num)
if isinstance(blocktime, datetime) and diff_op != 0:
if isinstance(blocktime, (datetime, date, time)) and diff_op != 0:
factor = (formatTimeString(op_start_last[0][1]["timestamp"]) - formatTimeString(trx["timestamp"])).total_seconds() / diff_op
elif not isinstance(blocktime, datetime) and diff_op != 0:
elif not isinstance(blocktime, (datetime, date, time)) and diff_op != 0:
factor = (op_start_last[0][1]["block"] - trx["block"]) / diff_op
if isinstance(blocktime, datetime):
if isinstance(blocktime, (datetime, date, time)):
op_diff = (blocktime - formatTimeString(trx["timestamp"])).total_seconds() / factor
else:
op_diff = (blocktime - trx["block"]) / factor
Expand Down Expand Up @@ -1029,7 +1029,7 @@ def get_account_history(self, index, limit, order=-1, start=None, stop=None, use
txs_list = txs
for item in txs_list:
item_index, event = item
if start and isinstance(start, datetime):
if start and isinstance(start, (datetime, date, time)):
timediff = start - formatTimeString(event["timestamp"])
if timediff.total_seconds() * float(order) > 0:
continue
Expand All @@ -1041,7 +1041,7 @@ def get_account_history(self, index, limit, order=-1, start=None, stop=None, use
continue
elif start and not use_block_num and order == -1 and item_index > start:
continue
if stop and isinstance(stop, datetime):
if stop and isinstance(stop, (datetime, date, time)):
timediff = stop - formatTimeString(event["timestamp"])
if timediff.total_seconds() * float(order) < 0:
return
Expand Down Expand Up @@ -1164,12 +1164,12 @@ def history(
return
start = addTzInfo(start)
stop = addTzInfo(stop)
if start is not None and not use_block_num and not isinstance(start, datetime):
if start is not None and not use_block_num and not isinstance(start, (datetime, date, time)):
start_index = start
elif start is not None and max_index > batch_size:
op_est = self.estimate_virtual_op_num(start, stop_diff=1)
est_diff = 0
if isinstance(start, datetime):
if isinstance(start, (datetime, date, time)):
for h in self.get_account_history(op_est, 0):
block_date = formatTimeString(h["timestamp"])
while(op_est > est_diff + batch_size and block_date > start):
Expand All @@ -1178,7 +1178,7 @@ def history(
est_diff = op_est
for h in self.get_account_history(op_est - est_diff, 0):
block_date = formatTimeString(h["timestamp"])
elif not isinstance(start, datetime):
elif not isinstance(start, (datetime, date, time)):
for h in self.get_account_history(op_est, 0):
block_num = h["block"]
while(op_est > est_diff + batch_size and block_num > start):
Expand Down Expand Up @@ -1209,15 +1209,15 @@ def history(
op_type = item['type']
timestamp = item["timestamp"]
block_num = item["block"]
if start and isinstance(start, datetime):
if start and isinstance(start, (datetime, date, time)):
timediff = start - formatTimeString(timestamp)
if timediff.total_seconds() > 0:
continue
elif start and use_block_num and block_num < start:
continue
elif start and not use_block_num and item_index < start:
continue
if stop and isinstance(stop, datetime):
if stop and isinstance(stop, (datetime, date, time)):
timediff = stop - formatTimeString(timestamp)
if timediff.total_seconds() < 0:
first = max_index + _limit
Expand Down Expand Up @@ -1329,7 +1329,7 @@ def history_reverse(
elif start is not None and first > batch_size:
op_est = self.estimate_virtual_op_num(start, stop_diff=1)
est_diff = 0
if isinstance(start, datetime):
if isinstance(start, (datetime, date, time)):
for h in self.get_account_history(op_est, 0):
block_date = h["timestamp"]
while(op_est + est_diff + batch_size < first and block_date < start):
Expand Down Expand Up @@ -1368,15 +1368,15 @@ def history_reverse(
op_type = item['type']
timestamp = item["timestamp"]
block_num = item["block"]
if start and isinstance(start, datetime):
if start and isinstance(start, (datetime, date, time)):
timediff = start - formatTimeString(timestamp)
if timediff.total_seconds() < 0:
continue
elif start and use_block_num and block_num > start:
continue
elif start and not use_block_num and item_index > start:
continue
if stop and isinstance(stop, datetime):
if stop and isinstance(stop, (datetime, date, time)):
timediff = stop - formatTimeString(timestamp)
if timediff.total_seconds() > 0:
first = 0
Expand Down
157 changes: 110 additions & 47 deletions beem/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1761,33 +1761,73 @@ def votes(account, direction, outgoing, incoming, days, export):
@click.argument('authorperm', nargs=1, required=False)
@click.option('--account', '-a', help='Show only curation for this account')
@click.option('--limit', '-l', help='Show only the first minutes')
@click.option('--payout', '-p', default=None, help="Show the curation for a potential payout in SBD as float")
@click.option('--payout', default=None, help="Show the curation for a potential payout in SBD as float")
@click.option('--export', '-e', default=None, help="Export results to HTML-file")
def curation(authorperm, account, limit, payout, export):
@click.option('--short', '-s', is_flag=True, default=False, help="Show only Curation without sum")
@click.option('--length', '-l', help='Limits the permlink character length', default=None)
@click.option('--permlink', '-p', help='Show the permlink for each entry', is_flag=True, default=False)
@click.option('--title', '-t', help='Show the title for each entry', is_flag=True, default=False)
@click.option('--days', '-d', default=7., help="Limit shown rewards by this amount of days (default: 7), max is 7 days.")
def curation(authorperm, account, limit, payout, export, short, length, permlink, title, days):
""" Lists curation rewards of all votes for authorperm
When authorperm is empty or "all", curation rewards
for all account votes is shown.
When authorperm is empty or "all", the curation rewards
for all account votes are shown.
authorperm can also be a number. e.g. 5 is equivalent to
the fifth account vote in the given time duration (default is 7 days)
"""
stm = shared_steem_instance()
if stm.rpc is not None:
stm.rpc.rpcconnect()
if authorperm == 'all' or authorperm is None:
if authorperm is None:
authorperm = 'all'
if account is None and authorperm is not 'all':
show_all_voter = True
else:
show_all_voter = False
if authorperm == 'all' or authorperm.isdigit():
if not account:
account = stm.config["default_account"]
utc = pytz.timezone('UTC')
limit_time = utc.localize(datetime.utcnow()) - timedelta(days=7)
limit_time = utc.localize(datetime.utcnow()) - timedelta(days=days)
votes = AccountVotes(account, start=limit_time, steem_instance=stm)
authorperm_list = [Comment(vote.authorperm, steem_instance=stm) for vote in votes]
if authorperm.isdigit():
if len(authorperm_list) < int(authorperm):
raise ValueError("Authorperm id must be lower than %d" % (len(authorperm_list) + 1))
authorperm_list = [authorperm_list[int(authorperm) - 1]["authorperm"]]
all_posts = False
else:
all_posts = True
else:
authorperm_list = [authorperm]
if export:
all_posts = False
if (all_posts) and permlink:
t = PrettyTable(["Author", "permlink", "Voting time", "Vote", "Early vote loss", "Curation", "Performance"])
t.align = "l"
elif (all_posts) and title:
t = PrettyTable(["Author", "permlink", "Voting time", "Vote", "Early vote loss", "Curation", "Performance"])
t.align = "l"
elif all_posts:
t = PrettyTable(["Author", "Voting time", "Vote", "Early vote loss", "Curation", "Performance"])
t.align = "l"
elif (export) and permlink:
t = PrettyTable(["Author", "permlink", "Voter", "Voting time", "Vote", "Early vote loss", "Curation", "Performance"])
t.align = "l"
elif (export) and title:
t = PrettyTable(["Author", "permlink", "Voter", "Voting time", "Vote", "Early vote loss", "Curation", "Performance"])
t.align = "l"
elif export:
t = PrettyTable(["Author", "Voter", "Voting time", "Vote", "Early vote loss", "Curation", "Performance"])
t.align = "l"
else:
t = PrettyTable(["Voter", "Voting time", "Vote", "Early vote loss", "Curation", "Performance"])
t.align = "l"
index = 0
for authorperm in authorperm_list:
index += 1
comment = Comment(authorperm, steem_instance=stm)
if payout is not None and comment.is_pending():
payout = float(payout)
Expand Down Expand Up @@ -1828,56 +1868,79 @@ def curation(authorperm, account, limit, payout, export):
sortedList = sorted(rows, key=lambda row: (row[1]), reverse=False)
new_row = []
new_row2 = []
if export:
new_row = [comment.author, comment.permlink]
voter = []
voter2 = []
if (all_posts or export) and permlink:
if length:
new_row = [comment.author, comment.permlink[:int(length)]]
else:
new_row = [comment.author, comment.permlink]
new_row2 = ["", ""]
elif (all_posts or export) and title:
if length:
new_row = [comment.author, comment.title[:int(length)]]
else:
new_row = [comment.author, comment.title]
new_row2 = ["", ""]
elif (all_posts or export):
new_row = [comment.author]
new_row2 = [""]
if not all_posts:
voter = [""]
voter2 = [""]

for row in sortedList:
if limit is not None and row[1] > float(limit):
continue
if account is None or account == row[0]:
t.add_row(new_row + [row[0],
"%.1f min" % row[1],
"%.3f SBD" % float(row[2]),
"%.3f SBD" % float(row[3]),
"%.3f SP" % (row[4]),
"%.1f %%" % (row[5])])
if show_all_voter or account == row[0]:
if not all_posts:
voter = [row[0]]
if all_posts:
new_row[0] = "%d. %s" % (index, comment.author)
t.add_row(new_row + voter + ["%.1f min" % row[1],
"%.3f SBD" % float(row[2]),
"%.3f SBD" % float(row[3]),
"%.3f SP" % (row[4]),
"%.1f %%" % (row[5])])
if len(authorperm_list) == 1:
new_row = new_row2
if export:
t.add_row(["", "", "", "", "", "", "", ""])
else:
t.add_row(["", "", "", "", "", ""])
if sum_curation[0] > 0:
curation_sum_percentage = sum_curation[3] / sum_curation[0] * 100
else:
curation_sum_percentage = 0

t.add_row(new_row2 + ["High. vote",
"%.1f min" % max_vote[1],
"%.3f SBD" % float(max_vote[2]),
"%.3f SBD" % float(max_vote[3]),
"%.3f SP" % (max_vote[4]),
"%.1f %%" % (max_vote[5])])
t.add_row(new_row2 + ["High. Cur.",
"%.1f min" % max_curation[1],
"%.3f SBD" % float(max_curation[2]),
"%.3f SBD" % float(max_curation[3]),
"%.3f SP" % (max_curation[4]),
"%.1f %%" % (max_curation[5])])
t.add_row(new_row2 + ["Sum",
"-",
"%.3f SBD" % (sum_curation[0]),
"%.3f SBD" % (sum_curation[1]),
"%.3f SP" % (sum_curation[2]),
"%.2f %%" % curation_sum_percentage])
if export:
t.add_row(["", "", "-", "-", "-", "-", "-", "-"])
else:
print("%s" % authorperm)
if not short:
t.add_row(new_row2 + voter2 + ["", "", "", "", ""])
if sum_curation[0] > 0:
curation_sum_percentage = sum_curation[3] / sum_curation[0] * 100
else:
curation_sum_percentage = 0
sum_line = new_row2 + voter2
sum_line[-1] = "High. vote"

t.add_row(sum_line + ["%.1f min" % max_vote[1],
"%.3f SBD" % float(max_vote[2]),
"%.3f SBD" % float(max_vote[3]),
"%.3f SP" % (max_vote[4]),
"%.1f %%" % (max_vote[5])])
sum_line[-1] = "High. Cur."
t.add_row(sum_line + ["%.1f min" % max_curation[1],
"%.3f SBD" % float(max_curation[2]),
"%.3f SBD" % float(max_curation[3]),
"%.3f SP" % (max_curation[4]),
"%.1f %%" % (max_curation[5])])
sum_line[-1] = "Sum"
t.add_row(sum_line + ["-",
"%.3f SBD" % (sum_curation[0]),
"%.3f SBD" % (sum_curation[1]),
"%.3f SP" % (sum_curation[2]),
"%.2f %%" % curation_sum_percentage])
if all_posts or export:
t.add_row(new_row2 + voter2 + ["-", "-", "-", "-", "-"])
if not (all_posts or export):
print("curation for %s" % (authorperm))
print(t)
if export:
with open(export, 'w') as w:
w.write(str(t.get_html_string()))
elif all_posts:
print("curation for @%s" % account)
print(t)


@cli.command()
Expand Down
11 changes: 7 additions & 4 deletions beem/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import logging
import pytz
import math
from datetime import datetime
from datetime import datetime, date, time
from .instance import shared_steem_instance
from .account import Account
from .amount import Amount
Expand Down Expand Up @@ -159,7 +159,7 @@ def json(self):
for p in parse_times:
if p in output:
date = output.get(p, datetime(1970, 1, 1, 0, 0))
if isinstance(date, datetime):
if isinstance(date, (datetime, date)):
output[p] = formatTimeString(date)
else:
output[p] = date
Expand Down Expand Up @@ -288,7 +288,7 @@ def get_curation_penalty(self, vote_time=None):
elapsed_seconds = self.time_elapsed().total_seconds()
elif isinstance(vote_time, str):
elapsed_seconds = (formatTimeString(vote_time) - self["created"]).total_seconds()
elif isinstance(vote_time, datetime):
elif isinstance(vote_time, (datetime, date)):
elapsed_seconds = (vote_time - self["created"]).total_seconds()
else:
raise ValueError("vote_time must be a string or a datetime")
Expand Down Expand Up @@ -471,7 +471,10 @@ def get_reblogged_by(self, identifier=None):
return self.steem.rpc.get_reblogged_by(post_author, post_permlink, api="follow")

def get_replies(self, raw_data=False, identifier=None):
"""Returns all content replies"""
""" Returns all content replies
:param bool raw_data: When set to False, the replies will be returned as Comment class objects
"""
if not identifier:
post_author = self["author"]
post_permlink = self["permlink"]
Expand Down

0 comments on commit 818c8f1

Please sign in to comment.