From 3e88744e3b4fd62325ebb1b2aed63a10c06ee5c9 Mon Sep 17 00:00:00 2001 From: moneromooo Date: Fri, 6 Feb 2015 19:36:58 +0000 Subject: [PATCH] Accounts can now be linked --- tipbot.py | 37 +++++++++++++++++++++++++++++++++++++ tipbot/utils.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/tipbot.py b/tipbot.py index 285a8a8..60bb3f8 100644 --- a/tipbot.py +++ b/tipbot.py @@ -158,6 +158,41 @@ def AddBalance(link,cmd): return link.send("%s's balance is now %s" % (aidentity,AmountToString(balance))) +def LinkAccount(link,cmd): + linked_identity=GetParam(cmd,1) + if linked_identity == None: + link.send('usage: !link_account [:]') + return + linked_identity=IdentityFromString(link,linked_identity) + ok,reason=LinkCore(link,linked_identity) + if not ok: + link.send('An error occured') + return + + if reason=='same-identity': + link.send('An account is already implicitly linked to itself') + elif reason=='already' or reason=='ok': + link.send('%s now needs to link to %s too' % (linked_identity,link.identity())) + elif reason=='same-account': + link.send('%s and %s are already linked' % (link.identity(),linked_identity)) + elif reason=='linked': + link.send('Accounts linked') + +def LinkingAccounts(link,cmd): + link.send_private('If you have several accounts with %s, you can link them together' % config.tipbot_name) + link.send_private('This will merge those accounts\' balances, so you can use your balance') + link.send_private('from any of these accounts. Similarly, payments made to any of your accounts') + link.send_private('will be available to all accounts. In order to link accounts A and B,') + link.send_private('both need to link to the other account: A to B, and B to A') + link.send_private('When logged in as A, use the command: !link_account B') + link.send_private('When logged in as B, use the command: !link_account A') + link.send_private('When both are done, the accounts will be linked, and you will be able to use') + link.send_private('any account interchangeably. If the accounts are on different networks') + link.send_private('(eg, IRC and Reddit), the user names need to be prefixed with the network\'s') + link.send_private('name (irc: for IRC, reddit:), like this: !link_account reddit:myredditname') + link.send_private('Linking accounts is irreversible, so make sure you only link to accounts') + link.send_private('under your control') + def ScanWho(link,cmd): link.network.update_users_list(link.group.name if link.group else None) @@ -351,6 +386,8 @@ def RegisterCommands(): RegisterCommand({'module': 'builtin', 'name': 'commands', 'parms': '[module]', 'function': Commands, 'help': "Displays list of commands"}) RegisterCommand({'module': 'builtin', 'name': 'isregistered', 'function': IsRegistered, 'help': "show whether you are currently registered with freenode"}) RegisterCommand({'module': 'builtin', 'name': 'balance', 'function': GetBalance, 'registered': True, 'help': "show your current balance"}) + RegisterCommand({'module': 'builtin', 'name': 'link_account', 'function': LinkAccount, 'registered': True, 'help': "Link your account to another - see !linking_accounts"}) + RegisterCommand({'module': 'builtin', 'name': 'linking_accounts', 'function': LinkingAccounts, 'registered': True, 'help': "Help about linking accounts"}) RegisterCommand({'module': 'builtin', 'name': 'info', 'function': Info, 'help': "infornmation about %s" % config.tipbot_name}) RegisterCommand({'module': 'builtin', 'name': 'height', 'function': GetHeight, 'admin': True, 'help': "Get current blockchain height"}) diff --git a/tipbot/utils.py b/tipbot/utils.py index 3f28aeb..cd7adee 100644 --- a/tipbot/utils.py +++ b/tipbot/utils.py @@ -331,6 +331,48 @@ def RetrieveBalance(link): log_error('RetrieveBalance: exception: %s' % str(e)) raise +def LinkCore(link,other_identity): + try: + identity=link.identity() + if identity==other_identity: + return True, "same-identity" + links=redis_hget('links',identity) + if links: + if other_identity in links.split(chr(0)): + return True, "already" + links=links+chr(0)+other_identity + else: + links=other_identity + redis_hset('links',identity,links) + + links=redis_hget('links',other_identity) + if links: + if identity in links.split(chr(0)): + # we have both + account=redis_hget('accounts',identity) + other_account=redis_hget('accounts',other_identity) + if account==other_account: + log_info('%s and %s already have the same account: %s' % (identity,other_identity,account)) + return True, "same-account" + + balance=long(redis_hget('balances',account)) + log_info('Linking accounts %s (%s) and %s (%s)' % (account,identity,other_account,other_identity)) + p=redis_pipeline() + p.hincrby('balances',other_account,balance) + p.hincrby('balances',account,-balance) + accounts=redis_hgetall('accounts') + for a in accounts: + if accounts[a]==account: + log_info('Changing %s\'s account from %s to %s' % (a,account,other_account)) + p.hset('accounts',a,other_account) + p.execute() + return True, "linked" + except Exception,e: + log_error('Error linking %s and %s: %s' % (identity,other_identity,str(e))) + return False, "error" + + return True, "ok" + def IdentityFromString(link,s): if s.find(':') == -1: network = link.network