From bd2de72746d9cec57f94954e18d9f6dfff259024 Mon Sep 17 00:00:00 2001
From: holgern <holgernahrstaedt@gmx.de>
Date: Tue, 27 Aug 2019 23:48:29 +0200
Subject: [PATCH] Prepare changes for HF21

* operations for account_update2, create_proposal, update_proposal_votes and remove_proposal were added
* update_proposal_votes was added to steem
* update_account_jsonmetadata was added to account
* new beempy delete were added
---
 beem/account.py             |  24 ++++++++
 beem/cli.py                 |  27 +++++++++
 beem/steem.py               |  27 +++++++++
 beem/utils.py               |   9 +++
 beem/version.py             |   2 +-
 beemapi/version.py          |   2 +-
 beembase/operationids.py    |  10 +++
 beembase/operations.py      | 117 ++++++++++++++++++++++++++++++++++++
 beembase/version.py         |   2 +-
 beemgraphenebase/version.py |   2 +-
 setup.py                    |   2 +-
 11 files changed, 219 insertions(+), 5 deletions(-)

diff --git a/beem/account.py b/beem/account.py
index 26a20dc2..54b3b2dc 100644
--- a/beem/account.py
+++ b/beem/account.py
@@ -2208,6 +2208,30 @@ class Account(BlockchainObject):
             })
         return self.steem.finalizeOp(op, account, "active", **kwargs)
 
+    def update_account_jsonmetadata(self, metadata, account=None, **kwargs):
+        """ Update an account's profile in json_metadata using the posting key
+
+            :param dict metadata: The new metadata to use
+            :param str account: (optional) the account to allow access
+                to (defaults to ``default_account``)
+
+        """
+        if account is None:
+            account = self
+        else:
+            account = Account(account, steem_instance=self.steem)
+        if isinstance(metadata, dict):
+            metadata = json.dumps(metadata)
+        elif not isinstance(metadata, str):
+            raise ValueError("Profile must be a dict or string!")
+        op = operations.Account_update(
+            **{
+                "account": account["name"],
+                "posting_json_metadata": metadata,
+                "prefix": self.steem.prefix,
+            })
+        return self.steem.finalizeOp(op, account, "posting", **kwargs)
+
     # -------------------------------------------------------------------------
     #  Approval and Disapproval of witnesses
     # -------------------------------------------------------------------------
diff --git a/beem/cli.py b/beem/cli.py
index 87d073ee..6f23e29a 100644
--- a/beem/cli.py
+++ b/beem/cli.py
@@ -754,6 +754,33 @@ def upvote(post, account, weight):
     tx = json.dumps(tx, indent=4)
     print(tx)
 
+@cli.command()
+@click.argument('post', nargs=1)
+@click.option('--account', '-a', help='Voter account name')
+def delete(post, account):
+    """delete a post/comment
+
+        POST is @author/permlink
+    """
+    stm = shared_steem_instance()
+    if stm.rpc is not None:
+        stm.rpc.rpcconnect()
+
+    if not account:
+        account = stm.config["default_account"]
+    if not unlock_wallet(stm):
+        return
+    try:
+        post = Comment(post, steem_instance=stm)
+        tx = post.delete(account=account)
+        if stm.unsigned and stm.nobroadcast and stm.steemconnect is not None:
+            tx = stm.steemconnect.url_from_tx(tx)
+    except exceptions.VotingInvalidOnArchivedPost:
+        print("Could not delete post.")
+        tx = {}
+    tx = json.dumps(tx, indent=4)
+    print(tx)
+
 
 @cli.command()
 @click.argument('post', nargs=1)
diff --git a/beem/steem.py b/beem/steem.py
index ea2196eb..7106a5e2 100644
--- a/beem/steem.py
+++ b/beem/steem.py
@@ -1550,6 +1550,33 @@ class Steem(object):
             })
         return self.finalizeOp(op, account, "active", **kwargs)
 
+    def update_proposal_votes(self, proposal_ids, approve, account=None, **kwargs):
+        """ Update proposal votes
+
+            :param list proposal_ids: list of proposal ids
+            :param bool approve: True/False
+            :param str account: (optional) witness account name
+
+
+        """
+        if not account and config["default_account"]:
+            account = config["default_account"]
+        if not account:
+            raise ValueError("You need to provide an account")
+
+        account = Account(account, steem_instance=self)
+        if not isinstance(proposal_ids, list):
+            proposal_ids = [proposal_ids]
+
+        op = operations.Update_proposal_votes(
+            **{
+                "voter": account["name"],
+                "proposal_ids": proposal_ids,
+                "approve": approve,
+                "prefix": self.prefix,
+            })
+        return self.finalizeOp(op, account, "active", **kwargs)
+
     def _test_weights_treshold(self, authority):
         """ This method raises an error if the threshold of an authority cannot
             be reached by the weights.
diff --git a/beem/utils.py b/beem/utils.py
index 57a2856f..777c7216 100644
--- a/beem/utils.py
+++ b/beem/utils.py
@@ -5,6 +5,7 @@ from __future__ import print_function
 from __future__ import unicode_literals
 from builtins import next
 import re
+import json
 import time as timenow
 import math
 from datetime import datetime, tzinfo, timedelta, date, time
@@ -361,3 +362,11 @@ def seperate_yaml_dict_from_body(content):
     else:
         body = content
     return body, parameter
+
+    
+def load_dirty_json(dirty_json):
+    regex_replace = [(r"([ \{,:\[])(u)?'([^']+)'", r'\1"\3"'), (r" False([, \}\]])", r' false\1'), (r" True([, \}\]])", r' true\1')]
+    for r, s in regex_replace:
+        dirty_json = re.sub(r, s, dirty_json)
+    clean_json = json.loads(dirty_json)
+    return clean_json    
diff --git a/beem/version.py b/beem/version.py
index a9481d2f..4f660c52 100644
--- a/beem/version.py
+++ b/beem/version.py
@@ -1,2 +1,2 @@
 """THIS FILE IS GENERATED FROM beem SETUP.PY."""
-version = '0.20.24'
+version = '0.21.0'
diff --git a/beemapi/version.py b/beemapi/version.py
index a9481d2f..4f660c52 100644
--- a/beemapi/version.py
+++ b/beemapi/version.py
@@ -1,2 +1,2 @@
 """THIS FILE IS GENERATED FROM beem SETUP.PY."""
-version = '0.20.24'
+version = '0.21.0'
diff --git a/beembase/operationids.py b/beembase/operationids.py
index 69c9b2e7..b3700bde 100644
--- a/beembase/operationids.py
+++ b/beembase/operationids.py
@@ -47,6 +47,10 @@ ops = [
     'delegate_vesting_shares',
     'account_create_with_delegation',
     'witness_set_properties',
+    'account_update2',
+    'create_proposal',
+    'update_proposal_votes',
+    'remove_proposal',    
     'fill_convert_request',
     'author_reward',
     'curation_reward',
@@ -62,6 +66,12 @@ ops = [
     'comment_payout_update',
     'return_vesting_delegation',
     'comment_benefactor_reward',
+    'return_vesting_delegation',
+    'comment_benefactor_reward',
+    'producer_reward',
+    'clear_null_account_balance',
+    'proposal_pay',
+    'sps_fund'
 ]
 operations = {o: ops.index(o) for o in ops}
 
diff --git a/beembase/operations.py b/beembase/operations.py
index ca3d1fd4..c941dd44 100644
--- a/beembase/operations.py
+++ b/beembase/operations.py
@@ -278,6 +278,123 @@ class Account_update(GrapheneObject):
         ]))
 
 
+class Account_update2(GrapheneObject):
+    def __init__(self, *args, **kwargs):
+        if check_for_class(self, args):
+            return
+        if len(args) == 1 and len(kwargs) == 0:
+            kwargs = args[0]
+        prefix = kwargs.get("prefix", default_prefix)
+
+        if "owner" in kwargs:
+            owner = Optional(Permission(kwargs["owner"], prefix=prefix))
+        else:
+            owner = Optional(None)
+
+        if "active" in kwargs:
+            active = Optional(Permission(kwargs["active"], prefix=prefix))
+        else:
+            active = Optional(None)
+
+        if "posting" in kwargs:
+            posting = Optional(Permission(kwargs["posting"], prefix=prefix))
+        else:
+            posting = Optional(None)
+            
+    
+        if "memo_key" in kwargs:
+            memo_key = Optional(Permission(kwargs["memo_key"], prefix=prefix))
+        else:
+            memo_key = Optional(None)        
+
+        meta = ""
+        if "json_metadata" in kwargs and kwargs["json_metadata"]:
+            if isinstance(kwargs["json_metadata"], dict):
+                meta = json.dumps(kwargs["json_metadata"])
+            else:
+                meta = kwargs["json_metadata"]
+        posting_meta = ""
+        if "posting_json_metadata" in kwargs and kwargs["posting_json_metadata"]:
+            if isinstance(kwargs["posting_json_metadata"], dict):
+                posting_meta = json.dumps(kwargs["posting_json_metadata"])
+            else:
+                posting_meta = kwargs["posting_json_metadata"]        
+
+        super(Account_update2, self).__init__(OrderedDict([
+            ('account', String(kwargs["account"])),
+            ('owner', owner),
+            ('active', active),
+            ('posting', posting),
+            ('memo_key', memo_key),
+            ('json_metadata', String(meta)),
+            ('posting_json_metadata', String(posting_meta)),
+        ]))
+
+
+
+class Create_proposal(GrapheneObject):
+    def __init__(self, *args, **kwargs):
+        if check_for_class(self, args):
+            return
+        if len(args) == 1 and len(kwargs) == 0:
+            kwargs = args[0]
+        prefix = kwargs.get("prefix", default_prefix)
+        extensions = Array([])
+
+        super(Create_proposal, self).__init__(
+            OrderedDict([
+                ('creator', String(kwargs["creator"])),
+                ('receiver', String(kwargs["receiver"])),
+                ('start_date', PointInTime(kwargs["start_date"])),
+                ('end_date', PointInTime(kwargs["end_date"])),
+                ('daily_pay', Amount(kwargs["daily_pay"], prefix=prefix)),
+                ('subject', String(kwargs["subject"])),
+                ('permlink', String(kwargs["permlink"])),
+                ('extensions', extensions)
+            ]))
+
+
+class Update_proposal_votes(GrapheneObject):
+    def __init__(self, *args, **kwargs):
+        if check_for_class(self, args):
+            return
+        if len(args) == 1 and len(kwargs) == 0:
+            kwargs = args[0]
+        prefix = kwargs.get("prefix", default_prefix)
+        extensions = Array([])
+        proposal_ids = []
+        for e in kwargs["proposal_ids"]:
+            proposal_ids.append(Uint64(e))
+
+        super(Update_proposal_votes, self).__init__(
+            OrderedDict([
+                ('voter', String(kwargs["voter"])),
+                ('proposal_ids', Array(proposal_ids)),          
+                ('approve', Bool(kwargs["approve"])),
+                ('extensions', extensions)
+            ]))
+
+
+class Remove_proposal(GrapheneObject):
+    def __init__(self, *args, **kwargs):
+        if check_for_class(self, args):
+            return
+        if len(args) == 1 and len(kwargs) == 0:
+            kwargs = args[0]
+        prefix = kwargs.get("prefix", default_prefix)
+        extensions = Array([])
+        proposal_ids = []
+        for e in kwargs["proposal_ids"]:
+            proposal_ids.append(Uint64(e))        
+
+        super(Remove_proposal, self).__init__(
+            OrderedDict([
+                ('proposal_owner', String(kwargs["voter"])),
+                ('proposal_ids', Array(proposal_ids)),
+                ('extensions', extensions)
+            ]))
+
+
 class Witness_set_properties(GrapheneObject):
     def __init__(self, *args, **kwargs):
         if check_for_class(self, args):
diff --git a/beembase/version.py b/beembase/version.py
index a9481d2f..4f660c52 100644
--- a/beembase/version.py
+++ b/beembase/version.py
@@ -1,2 +1,2 @@
 """THIS FILE IS GENERATED FROM beem SETUP.PY."""
-version = '0.20.24'
+version = '0.21.0'
diff --git a/beemgraphenebase/version.py b/beemgraphenebase/version.py
index a9481d2f..4f660c52 100644
--- a/beemgraphenebase/version.py
+++ b/beemgraphenebase/version.py
@@ -1,2 +1,2 @@
 """THIS FILE IS GENERATED FROM beem SETUP.PY."""
-version = '0.20.24'
+version = '0.21.0'
diff --git a/setup.py b/setup.py
index 27e632b8..b98cd309 100755
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@ except LookupError:
     ascii = codecs.lookup('ascii')
     codecs.register(lambda name, enc=ascii: {True: enc}.get(name == 'mbcs'))
 
-VERSION = '0.20.24'
+VERSION = '0.21.0'
 
 tests_require = ['mock >= 2.0.0', 'pytest', 'pytest-mock', 'parameterized']
 
-- 
GitLab