From 536171d044da47f6b7ce0ee48881886a695b0cbc Mon Sep 17 00:00:00 2001
From: "@top_left" <gisilfrid@protonmail.com>
Date: Wed, 8 Dec 2021 19:38:38 +0100
Subject: [PATCH] [somebot] DialogManagedFSInfCoin + /send-inf-coin-to
 <username> <amount>

---
 modules/CommandSendInfCoinTo.py |  50 +++++++++++
 modules/DialogManagedInfCoin.py | 148 ++++++++++++++++++++++++++++++++
 2 files changed, 198 insertions(+)
 create mode 100644 modules/CommandSendInfCoinTo.py
 create mode 100644 modules/DialogManagedInfCoin.py

diff --git a/modules/CommandSendInfCoinTo.py b/modules/CommandSendInfCoinTo.py
new file mode 100644
index 0000000..3287c72
--- /dev/null
+++ b/modules/CommandSendInfCoinTo.py
@@ -0,0 +1,50 @@
+# Mattermost Bot module.
+#  Copyright (c) 2016-2021 by Someone <someone@somenet.org> (aka. Jan Vales <jan@jvales.net>)
+#  published under MIT-License
+
+import json
+import os
+import requests
+
+
+from AbstractCommand import AbstractCommand
+class CommandSendInfCoinTo(AbstractCommand):
+    TRIGGER = "send-inf-coin-to"
+    CONFIG = {"display_name": "somebot-command", "auto_complete": True,
+              "auto_complete_hint": "<username> <amount>",
+             }
+    USEINFO = CONFIG["auto_complete_desc"] = CONFIG["description"] = "Helper to send Inf-Coins to somebody."
+
+
+    def __init__(self, team_id, datadir, infcoin_req_url):
+        super().__init__(team_id)
+
+        self.datadir = datadir
+        self.infcoin_req_url = infcoin_req_url
+
+
+    def on_POST(self, request, data):
+        msg_text = data['text'].strip().split(" ")
+
+        if len(msg_text) != 2:
+            request.cmd_respond_text_temp("``/send-inf-coin-to`` failed: The arguments are: <username> <amount>. :(")
+            return
+
+        user = self.bot.api.get_user_by_username(msg_text[0].replace("@","").strip(), exc=False)
+        infcoin_wallet = json.loads(self._wallet_load(self.datadir+"wallet-"+user["id"], ".json", '{"wallet":""}'))
+        if infcoin_wallet["wallet"] != "":
+            msg = "### [Complete the transaction with neoline via webbrowser]("+self.infcoin_req_url+"?addr="+infcoin_wallet["wallet"]+"&amount="+msg_text[1]+")"
+        else:
+            msg = "### ``/send-inf-coin-to`` failed: @"+msg_text[0].replace("@","").strip()+" hasnt told @bot their wallet address yet (by using ``/inf-coin``)"
+
+        request.cmd_respond_text_temp(msg)
+
+
+
+    def _wallet_load(self, path, filename, default=""):
+        path = path+filename
+        ret = default
+        if os.path.isfile(path):
+            with open(path, "r") as f:
+                ret = f.read()
+        return ret
diff --git a/modules/DialogManagedInfCoin.py b/modules/DialogManagedInfCoin.py
new file mode 100644
index 0000000..cae7775
--- /dev/null
+++ b/modules/DialogManagedInfCoin.py
@@ -0,0 +1,148 @@
+# Mattermost Bot module.
+#  Copyright (c) 2016-2021 by Someone <someone@somenet.org> (aka. Jan Vales <jan@jvales.net>)
+#  published under MIT-License
+
+from inspect import cleandoc
+import json
+import os
+import requests
+
+
+from AbstractCommand import *
+class DialogManagedInfCoin(AbstractCommand):
+    TRIGGER = "inf-coin"
+    CONFIG = {"display_name": "somebot-command", "auto_complete": True,
+#              "auto_complete_hint": "Manage your Inf-Coins",
+             }
+    USEINFO = CONFIG["auto_complete_desc"] = CONFIG["description"] = "Will make @bot send you a Inf-Coin managing post."
+
+
+    def __init__(self, team_id, datadir, infcoin_req_url, infcoin_req_user, infcoin_req_pw, infcoin_req_amount=100):
+        super().__init__(team_id)
+
+        self.datadir = datadir
+        self.infcoin_req_url = infcoin_req_url
+        self.infcoin_req_user = infcoin_req_user
+        self.infcoin_req_pw = infcoin_req_pw
+        self.infcoin_req_amount = infcoin_req_amount
+
+
+    def on_POST(self, request, data):
+#        self._require_bot_admin(data) # will throw an exception if not. (Dont try-except: Its handled up the stack.)
+
+        msg = cleandoc("""
+            ``AUTODELETE-DAY``
+            ## ``(FS)Inf``:coin: ``Management`` :rocket:
+            **Inf-Coins, previously FSInf-Coins are tokens of gratitude and appreciation without any inherent value.**
+            For more details about Inf-Coin, [visit its professional website!](https://infcoin.jvales.net)
+
+            You will be rewarded 1 Inf-Coin for setting your wallet address for the first time. :rocket:
+
+            To send Inf-Coins to somebody, use the command ``/send-inf-coin @<ACCOUNTNAME>``
+
+            #### How to proceed
+            + Get yourself a NEO wallet which supports NEO2-Testnet. At least these should do:
+              + https://testnet.neotracker.io/wallet (Web)
+              + https://neoline.io/en/ (Extension)
+
+            + Once setup, start tracking the [$Inf (f26c60f640091e2fa8cd15b30bb5f51cd4d2048b) asset on NEO2-testnet](https://testnet.neotube.io/nep5/f26c60f640091e2fa8cd15b30bb5f51cd4d2048b/page/1) in your wallet.
+            + As soon as you get Inf-Coins your wallet should display them to you and you should be able to transfer them.
+
+            :information_source: *Coin minting cannot be done automatically is a secure manner so it might take a while for you to receive your Inf-Coins.*
+            :warning:**If you need to update your addess, because you gave a wrong one, contact @someone so your coins dont get send on the old address. Once sent, there is no undo.**
+            """)
+
+        att = [{
+            "text": "Self-Management",
+            "actions": [
+                {"name": ":pencil: Set your Inf-Coin wallet address", "integration": {"url": self.URL+"/interactive"}},
+                #{"name": ":rocket: Claim newly received Inf-Coins", "integration": {"url": self.URL+"/interactive"}}
+            ]
+            #},{
+            #"text": "Off-Chain",
+            #"actions": [{"name": ":package: Send unclaimed coins to somebody", "integration": {"url": self.URL+"/interactive"}}]
+            }]
+
+        c = self.bot.api.create_dm_channel_with(data['user_id'])
+        p = self.bot.api.create_post(c['id'], msg, props={"from_webhook":"true", "attachments":att})
+        request.cmd_respond_text_temp("@bot has written you a direct message.\n:arrow_right: https://mattermost.fsinf.at/"+data["team_domain"]+"/pl/"+p["id"])
+
+
+    def on_POST_interactive(self, request, data):
+        #import pprint
+        #print("on_POST_interactive")
+        #pprint.pprint(data)
+
+        callback_id = "wallet-"+data["user_id"]
+        infcoin_wallet = json.loads(self._wallet_load(self.datadir+callback_id, ".json", '{"wallet":""}'))
+
+        dialog = {
+            "callback_id": callback_id,
+            "title": "Set your Inf-Coin/NEO2-Testnet wallet address",
+            "submit_label":"Submit",
+            "elements":[{
+                "display_name": "Your Inf-Coin/NEO2-Testnet wallet address",
+                "placeholder": "Paste here.",
+                "name": "infcoin_wallet",
+                "type": "text",
+                "help_text": "The wallet address is alphanumeric and 34 characters long.",
+                "optional": True,
+                "default": infcoin_wallet['wallet']
+            }]
+        }
+
+        self.bot.api.open_dialog(data["trigger_id"], self.URL+"/dialog", dialog)
+        request.respond(200, {})
+
+
+
+    def on_POST_dialog(self, request, data):
+        #import pprint
+        #print("on_POST_dialog")
+        #pprint.pprint(data)
+
+        # Validate address.
+        if data["submission"]["infcoin_wallet"] == "":
+            data["submission"]["infcoin_wallet"] = None
+        if data["submission"]["infcoin_wallet"] is not None and not (data["submission"]["infcoin_wallet"].isascii() and data["submission"]["infcoin_wallet"].isalnum() and len(data["submission"]["infcoin_wallet"]) == 34):
+            request.respond(200, {"errors": {"infcoin_wallet": "This doesnt seem like a valid address."}})
+        else:
+            c = self.bot.api.create_dm_channel_with(data['user_id'])
+            existed = self._wallet_store(self.datadir+data["callback_id"], ".json", json.dumps({"wallet":data["submission"]["infcoin_wallet"]}))
+            if not existed and data["submission"]["infcoin_wallet"] is not None:
+                self.award_infcoins(data["user_id"], self.infcoin_req_amount, "wallet-set")
+                p = self.bot.api.create_post(c['id'], "``AUTODELETE-DAY`` Wallet address set. Inf-Coins requested.", props={"from_webhook":"true"})
+            elif not existed:
+                p = self.bot.api.create_post(c['id'], "``AUTODELETE-DAY`` Did nothing.", props={"from_webhook":"true"})
+            else:
+                p = self.bot.api.create_post(c['id'], "``AUTODELETE-DAY`` Wallet address updated. No Inf-Coins requested.", props={"from_webhook":"true"})
+
+
+
+    def award_infcoins(self, user_id, amount, reason_part):
+        infcoin_wallet = json.loads(self._wallet_load(self.datadir+"wallet-"+user_id, ".json", '{"wallet":""}'))
+        if infcoin_wallet["wallet"] != "":
+            r = requests.get(self.infcoin_req_url, {"auth_name":self.infcoin_req_user, "auth_secret":self.infcoin_req_pw, "addr":infcoin_wallet["wallet"], "amount":amount, "reason_uniq":"mm-"+reason_part+", uid="+user_id})
+            return True
+        return False
+
+
+
+    def _wallet_load(self, path, filename, default=""):
+        path = path+filename
+        ret = default
+        if os.path.isfile(path):
+            with open(path, "r") as f:
+                ret = f.read()
+        return ret
+
+
+    def _wallet_store(self, path, filename, data):
+        path = path+filename
+        data = str(data).strip()
+        existed = os.path.isfile(path)
+        if not (not existed and data == json.dumps({"wallet":None})):
+            with open(path, "w") as f:
+                f.write(data)
+        return existed
+
-- 
2.43.0