def __init__(self, account_name, comments_only=False, steemd_instance=None): self.steem = steemd_instance or shared_steemd_instance() self.comments_only = comments_only self.account = Account(account_name, steemd_instance=steemd_instance) self.history = self.account.history_reverse(filter_by='comment') self.seen_items = set()
def appendSigner(self, account, permission): assert permission in ["active", "owner", "posting"], "Invalid permission" account = Account(account, steemd_instance=self.steemd) required_treshold = account[permission]["weight_threshold"] def fetchkeys(account, level=0): if level > 2: return [] r = [] for authority in account[permission]["key_auths"]: wif = self.wallet.getPrivateKeyForPublicKey(authority[0]) if wif: r.append([wif, authority[1]]) if sum([x[1] for x in r]) < required_treshold: # go one level deeper for authority in account[permission]["account_auths"]: auth_account = Account(authority[0], steemd_instance=self.steemd) r.extend(fetchkeys(auth_account, level + 1)) return r keys = fetchkeys(account) self.wifs.extend([x[0] for x in keys])
def addSigningInformation(self, account, permission): """ This is a private method that adds side information to a unsigned/partial transaction in order to simplify later signing (e.g. for multisig or coldstorage) """ account_obj = Account(account, steemd_instance=self.steemd) authority = account_obj[permission] # We add a required_authorities to be able to identify # how to sign later. This is an array, because we # may later want to allow multiple operations per tx self.update({"required_authorities": { account: authority }}) for account_auth in authority["account_auths"]: account_auth_account = Account(account_auth[0], steemd_instance=self.steemd) self["required_authorities"].update({ account_auth[0]: account_auth_account.get(permission) }) # Try to resolve required signatures for offline signing self["missing_signatures"] = [x[0] for x in authority['key_auths']] # Add one recursion of keys from account_auths: for account_auth in authority["account_auths"]: account_auth_account = Account(account_auth[0], steemd_instance=self.steemd) self["missing_signatures"].extend( [x[0] for x in account_auth_account[permission]["key_auths"]] ) self["blockchain"] = self.steemd.chain_params
def fetchkeys(account, level=0): if level > 2: return [] r = [] for authority in account[permission]["key_auths"]: wif = self.wallet.getPrivateKeyForPublicKey(authority[0]) if wif: r.append([wif, authority[1]]) if sum([x[1] for x in r]) < required_treshold: # go one level deeper for authority in account[permission]["account_auths"]: auth_account = Account(authority[0], steemd_instance=self.steemd) r.extend(fetchkeys(auth_account, level + 1)) return r
def getAccount(self, pub): """ Get the account data for a public key """ name = self.getAccountFromPublicKey(pub) if not name: return {"name": None, "type": None, "pubkey": pub} else: try: account = Account(name) except: return keyType = self.getKeyType(account, pub) return { "name": name, "account": account, "type": keyType, "pubkey": pub }
def test_history(): # TODO 1: test is disabled because api.steemit.com account history # pruning is temporarily in place, breaking assumptions. # TODO 2: in addition, the current pruning implementation fails # to remove the very first operation, revealing a bug in # history_reverse() which causes it to be included once # on every page, causing an item count mismatch. return a = Account('barbara2') h1 = [x['index'] for x in list(a.history())] h2 = [x['index'] for x in list(a.history_reverse())] # pprint(list(zip(h1, h2[::-1]))) # various tests of equality should pass assert len(h1) == len(h2) assert set(h1) == set(h2) == set(range(a.virtual_op_count() + 1)) assert h1 == h2[::-1] == list(range(a.virtual_op_count() + 1))
def logout(user: User): a = Account(user.name, steemd_instance=steem_obj) posting_ppk = a['posting']['key_auths'][0][0] steem_obj.commit.wallet.keys.pop(posting_ppk, None) user.delete_instance()
def account_exists(username: str) -> bool: try: Account(username, steemd_instance=steem_obj) return True except AccountDoesNotExistsException as e: return False
class Blog: """ Obtain a list of blog posts for an account Args: account_name (str): Name of the account comments_only (bool): (Default False). Toggle between posts and comments. steemd_instance (Steemd): Steemd instance overload Returns: Generator with Post objects in reverse chronological order. Example: To get all posts, you can use either generator: :: gen1 = Blog('furion') gen2 = b.all() next(gen1) next(gen2) To get some posts, you can call `take()`: :: b = Blog('furion') posts = b.take(5) """ def __init__(self, account_name, comments_only=False, steemd_instance=None): self.steem = steemd_instance or shared_steemd_instance() self.comments_only = comments_only self.account = Account(account_name, steemd_instance=steemd_instance) self.history = self.account.history_reverse(filter_by='comment') self.seen_items = set() def take(self, limit=5): """ Take up to n (n = limit) posts/comments at a time. You can call this method as many times as you want. Once there are no more posts to take, it will return []. Returns: List of posts/comments in a batch of size up to `limit`. """ # get main posts only comment_filter = is_comment if self.comments_only else complement( is_comment) hist = filter(comment_filter, self.history) # filter out reblogs def match_author(x): return x['author'] == self.account.name hist2 = filter(match_author, hist) # post edits will re-appear in history # we should therefore filter out already seen posts def ensure_unique(post): if post['permlink'] not in self.seen_items: self.seen_items.add(post['permlink']) return True unique = filter(ensure_unique, hist2) serialized = filter(bool, map(silent(Post), unique)) batch = take(limit, serialized) return batch def all(self): """ A generator that will return ALL of account history. """ while True: chunk = self.take(10) if chunk: for little_chunk in iter(chunk): yield little_chunk else: break def __iter__(self): return self def __next__(self): next_item = first(self.take(1)) if not next_item: raise StopIteration return next_item