def username(bot, update, args): response = messages.markdown("<u><b>Change username<b><u>\n\n", bot.messenger) userInfo = util.crossMessengerSplit(update) userId = userInfo['user'] if 'user' in userInfo else None #Get the user entry from the user which fired the command user = bot.database.getUser(userId) if user == None: response += messages.nodesRequired(bot.messenger) elif len(args) != 1: response += messages.userNameRequiredError(bot.messenger) elif not util.validateName(args[0]): response += messages.invalidNameError.format(args[0]) else: old = user['name'] bot.database.updateUsername(args[0], user['id']) response += "Username updated from {} to {}".format( messages.removeMarkdown(old), messages.removeMarkdown(args[0])) return response
def me(bot, update): response = messages.markdown("<u><b>User info<b><u>\n\n", bot.messenger) userInfo = util.crossMessengerSplit(update) userId = userInfo['user'] if 'user' in userInfo else None #Get the user entry from the user which fired the command user = bot.database.getUser(userId) if user == None: response += messages.nodesRequired(bot.messenger) else: response += "You are {}\n\n".format( messages.removeMarkdown(user['name'])) response += "Status Notifications " + messages.notificationState( bot.messenger, user['status_n']) response += "\nReward Notifications " + messages.notificationState( bot.messenger, user['reward_n']) response += "\nTimeout Notifications " + messages.notificationState( bot.messenger, user['timeout_n']) response += "\nNetwork Notifications " + messages.notificationState( bot.messenger, user['network_n']) return response
def changeState(bot, update, args, action, description): response = messages.markdown( "<b>{} notifications<b>\n\n".format(description), bot.messenger) userInfo = util.crossMessengerSplit(update) userId = userInfo['user'] if 'user' in userInfo else None #Get the user entry from the user which fired the command user = bot.database.getUser(userId) if user == None: response += messages.nodesRequired(bot.messenger) elif len(args) != 1: response += messages.notificationArgumentRequiredError(bot.messenger) elif not util.isInt(args[0]) or int(args[0]) < 0 or int(args[0]) > 1: response += messages.notificationArgumentInvalidError(bot.messenger) else: action(user['id'], args[0]) response += messages.notificationResponse(bot.messenger, description.lower(), int(args[0])) return response
def detail(bot, update): response = messages.markdown("<u><b>Detail<b><u>\n\n", bot.messenger) userInfo = util.crossMessengerSplit(update) userId = userInfo['user'] if 'user' in userInfo else None userName = userInfo[ 'name'] if 'name' in userInfo else update.message.from_user.name logger.debug("detail - user: {}".format(userId)) nodesFound = False user = bot.database.getUser(userId) userNodes = bot.database.getAllNodes(userId) if user == None or userNodes == None or len(userNodes) == 0: response += messages.nodesRequired(bot.messenger) else: with bot.nodeList as nodeList: minimumUptime = nodeList.minimumUptime() top10 = nodeList.enabledWithMinProtocol() * 0.1 for userNode in userNodes: masternode = nodeList.getNodes([userNode['collateral']])[0] response += messages.markdown( ("<b>" + userNode['name'] + " - " + masternode.ip + "<b>"), bot.messenger) response += "\n `Status` " + masternode.status response += "\n `Position` " + messages.markdown( masternode.positionString(minimumUptime, top10), bot.messenger) response += "\n `Payee` " + masternode.payee response += "\n `Active since` " + util.secondsToText( masternode.activeSeconds) response += "\n `Last seen` " + util.secondsToText( int(time.time()) - masternode.lastSeen) response += "\n `Last payout (Block)` " + masternode.payoutBlockString( ) response += "\n `Last payout (Time)` " + masternode.payoutTimeString( ) response += "\n `Protocol` {}".format(masternode.protocol) #response += "\n `Rank` {}".format(masternode.rank) response += "\n " + messages.link( bot.messenger, 'https://explorer3.curium.cc/address/{}'.format( masternode.payee), 'Open the explorer!') response += "\n\n" return response
def nodes(bot, update): response = messages.markdown("<u><b>Nodes<b><u>\n\n", bot.messenger) userInfo = util.crossMessengerSplit(update) userId = userInfo['user'] if 'user' in userInfo else None userName = userInfo['name'] if 'name' in userInfo else None logger.debug("nodes - user: {}".format(userId)) nodesFound = False user = bot.database.getUser(userId) userNodes = bot.database.getAllNodes(userId) if user == None or userNodes == None or len(userNodes) == 0: response += messages.nodesRequired(bot.messenger) else: with bot.nodeList as nodeList: collaterals = list(map(lambda x: x['collateral'], userNodes)) nodes = nodeList.getNodes(collaterals) minimumUptime = nodeList.minimumUptime() top10 = nodeList.enabledWithMinProtocol() * 0.1 for masternode in sorted(nodes, key=lambda x: x.position if x.position > 0 else 100000): userNode = bot.database.getNodes(masternode.collateral, user['id']) payoutText = util.secondsToText(masternode.lastPaidTime) response += messages.markdown( "<b>" + userNode['name'] + "<b> - `" + masternode.status + "`", bot.messenger) response += "\nPosition " + messages.markdown( masternode.positionString(minimumUptime, top10), bot.messenger) response += "\nLast seen " + util.secondsToText( int(time.time()) - masternode.lastSeen) response += "\nLast payout " + masternode.payoutTimeString() response += "\n" + messages.link( bot.messenger, 'https://explorer3.curium.cc/address/{}'.format( masternode.payee), 'Open the explorer!') response += "\n\n" return response
def balance(self, bot, update): if not self.isGroup(update): failed = None nodes = [] dbUser = self.database.getUser(update.message.chat_id) userNodes = self.database.getAllNodes(update.message.chat_id) if dbUser == None or userNodes == None or len(userNodes) == 0: response = messages.markdown("<u><b>Balances<b><u>\n\n", self.messenger) response += messages.nodesRequired(self.messenger) self.sendMessage(update.message.chat_id, response) return collaterals = list(map(lambda x: x['collateral'], userNodes)) nodes = self.nodeList.getNodes(collaterals) check = self.explorer.balances(nodes) # Needed cause the balanceChecks dict also gets modified from other # threads. self.balanceSem.acquire() if check: self.balanceChecks[check] = update.message.chat_id else: logger.info("Balance check failed instant.") failed = uuid.uuid4() self.balanceChecks[failed] = update.message.chat_id # Needed cause the balanceChecks dict also gets modified from other # threads. self.balanceSem.release() if failed: self.balancesCB(failed, None)
def top(bot, update, args): response = "<u><b>Top nodes<b><u>\n\n" userInfo = util.crossMessengerSplit(update) userId = userInfo['user'] if 'user' in userInfo else None userName = userInfo['name'] if 'name' in userInfo else None logger.debug("nodes - user: {}".format(userId)) nodesFound = False user = bot.database.getUser(userId) userNodes = bot.database.getAllNodes(userId) if user == None or userNodes == None or len(userNodes) == 0: response += messages.nodesRequired(bot.messenger) else: invalidFilterValueMsg = "<b>ERROR<b>: Invalid filter value: <b>{}<b>! Valid range: 10 - 100\n\n" topPercent = 10 if len(args) >= 1: if util.isInt(args[0]) and\ int(args[0]) >= 10 and int(args[0]) <= 100: topPercent = int(args[0]) else: response += invalidFilterValueMsg.format( messages.removeMarkdown(args[0])) response += "<b>Filter<b> {}%\n\n".format(topPercent) with bot.nodeList as nodeList: topX = nodeList.enabledWithMinProtocol() * (topPercent / 100) collaterals = list(map(lambda x: x['collateral'], userNodes)) nodes = nodeList.getNodes(collaterals) topNodes = list( filter(lambda x: x.position <= topX and x.position > 0, nodes)) minimumUptime = nodeList.minimumUptime() if len(topNodes): for masternode in sorted(topNodes, key=lambda x: x.position if x.position > 0 else 100000): userNode = bot.database.getNodes(masternode.collateral, user['id']) response += "<b>" + userNode['name'] + "<b>" response += "\nPosition " + messages.markdown( masternode.positionString(minimumUptime), bot.messenger) response += "\n" + messages.link( bot.messenger, 'https://explorer3.curium.cc/address/{}'.format( masternode.payee), 'Open the explorer!') response += "\n\n" else: response += "<b>You have currently no nodes in the top {}% of the queue.<b>\n\n".format( topPercent) return messages.markdown(response, bot.messenger)
def history(bot, update): response = "<u><b>History<b><u>\n\n" userInfo = util.crossMessengerSplit(update) userId = userInfo['user'] if 'user' in userInfo else None userName = userInfo['name'] if 'name' in userInfo else None logger.debug("history - user: {}".format(userId)) nodesFound = False user = bot.database.getUser(userId) userNodes = bot.database.getAllNodes(userId) if user == None or userNodes == None or len(userNodes) == 0: response += messages.nodesRequired(bot.messenger) else: with bot.nodeList as nodeList: collaterals = list(map(lambda x: x['collateral'], userNodes)) nodes = nodeList.getNodes(collaterals) time30Days = time.time() - (2592000) # now - 30d * 24h * 60m * 60s totalInvest = len(nodes) * 10000 totalProfit = 0 totalAvgInterval = 0 totalFirst = 0 countMultiplePayouts = 0 totalProfit30Days = 0 for masternode in nodes: userNode = bot.database.getNodes(masternode.collateral, user['id']) rewards = bot.rewardList.getRewardsForPayee(masternode.payee) profit = sum(map(lambda x: x.amount, rewards)) profit30Days = sum( map(lambda x: x.amount if x.txtime > time30Days else 0, rewards)) totalProfit30Days += profit30Days totalProfit += round(profit, 1) avgInterval = 0 masterPerDay = 0 first = 0 last = 0 if len(rewards) == 1: first = rewards[0].txtime if len(rewards) > 1: countMultiplePayouts += 1 payoutTimes = list(map(lambda x: x.txtime, rewards)) first = min(payoutTimes) last = max(payoutTimes) if not totalFirst or first and totalFirst > first: totalFirst = first if last: avgInterval = (last - first) / len(rewards) totalAvgInterval += avgInterval masterPerDay = round( profit / ((time.time() - first) / 86400), 1) response += "<u><b>Node - " + userNode['name'] + "<b><u>\n\n" response += "<b>Payouts<b> {}\n".format(len(rewards)) response += "<b>Profit<b> {:,} CRU\n".format(round(profit, 1)) response += "<b>Profit (30 days)<b> {:,} CRU\n".format( round(profit30Days, 1)) if avgInterval: response += "\n<b>Payout interval<b> " + util.secondsToText( avgInterval) if masterPerDay: response += "\n<b>CRU/day<b> {:,} CRU".format(masterPerDay) response += "\n<b>ROI (CRU)<b> {}%".format( round((profit / 10000.0) * 100.0, 1)) response += "\n\n" response += "<u><b>Total stats<b><u>\n\n" if totalFirst: response += "<b>First payout<b> {} ago\n\n".format( util.secondsToText(time.time() - totalFirst)) response += "<b>Profit (30 days)<b> {:,} CRU\n".format( round(totalProfit30Days, 1)) response += "<b>CRU/day (30 days)<b> {:,} CRU\n\n".format( round(totalProfit30Days / 30, 1)) if totalAvgInterval: totalAvgInterval = totalAvgInterval / countMultiplePayouts response += "<b>Total payout interval<b> {}\n".format( util.secondsToText(totalAvgInterval)) response += "<b>Total CRU/day<b> {:,} CRU\n\n".format( round(totalProfit / ((time.time() - totalFirst) / 86400), 1)) response += "<b>Total profit<b> {:,} CRU\n".format( round(totalProfit, 1)) response += "<b>Total ROI (CRU)<b> {}%\n\n".format( round((totalProfit / totalInvest) * 100, 1)) return messages.markdown(response, bot.messenger)
async def commandHandler(self, message, command, args): logger.info("commandHandler - {}, command: {}, args: {}".format(message.author, command, args)) # Check if the user is already in the databse result = common.checkUser(self, message) if result['response']: await self.sendMessage(message.author, result['response']) if result['added'] and not isinstance(message.author, discord.Member): return # per default assume the message gets back from where it came receiver = message.author #### # List of available commands # Public = 0 # DM-Only = 1 # Admin only = 2 #### commands = { # Common commands 'help':0, 'info':0, 'faq':0, # User commmands 'me':1,'status':1,'reward':1,'network':1, 'timeout':1, # Node commands 'add':1,'update':1,'remove':1,'nodes':1, 'detail':1,'history':1, 'balance':1, 'lookup':1, 'top':1, # Admin commands 'stats':2, 'broadcast':2, 'payouts':2 } choices = fuzzy.extract(command,commands.keys(),limit=2) if choices[0][1] == choices[1][1] or choices[0][1] < 60: logger.debug('Invalid fuzzy result {}'.format(choices)) command = 'unknown' else: command = choices[0][0] # If the command is DM only if command in commands and commands[command] == 1: if isinstance(message.author, discord.Member): await self.client.send_message(message.channel,\ message.author.mention + ', the command `{}` is only available in private chat with me!'.format(command)) await self.client.send_message(message.author, messages.markdown('<b>Try it here!<b>\n', self.messenger)) return else: receiver = message.channel # If the command is admin only if command in commands and commands[command] == 2: # Admin command got fired in a public chat if isinstance(message.author, discord.Member): # Just send the unknown command message and jump out await self.sendMessage(receiver, (message.author.mention + ", " + commandhandler.unknown(self))) logger.info("Admin only, public") return def tryAdmin(message, args): if message.author.id in self.admins: if self.password: if len(args) >= 1 and args[0] == self.password: return True else: return True return False # Admin command got fired from an unauthorized user if tryAdmin(message, args): receiver = message.author else: logger.info("Admin only, other") # Just send the unknown command message and jump out await self.sendMessage(receiver, (message.author.mention + ", " + common.unknown(self))) return ### Common command handler ### if command == 'info': response = common.info(self,message) await self.sendMessage(receiver, response) elif command == 'faq': response = faq.parse(self, args) await self.sendMessage(receiver, response) ### Node command handler ### elif command == 'add': response = node.nodeAdd(self,message,args) await self.sendMessage(receiver, response) elif command == 'update': response = node.nodeUpdate(self,message,args) await self.sendMessage(receiver, response) elif command == 'remove': response = node.nodeRemove(self,message,args) await self.sendMessage(receiver, response) elif command == 'nodes': response = node.nodes(self,message) await self.sendMessage(receiver, response) elif command == 'detail': response = node.detail(self,message) await self.sendMessage(receiver, response) elif command == 'history': response = node.history(self,message) await self.sendMessage(receiver, response) elif command == 'top': response = node.top(self,message, args) await self.sendMessage(receiver, response) elif command == 'balance': failed = None nodes = [] dbUser = self.database.getUser(message.author.id) userNodes = self.database.getAllNodes(message.author.id) # If there is no nodes added yet send an error and return if dbUser == None or userNodes == None or len(userNodes) == 0: response = messages.markdown("<u><b>Balances<b><u>\n\n",self.messenger) response += messages.nodesRequired(self.messenger) await self.sendMessage(message.author, response) return collaterals = list(map(lambda x: x['collateral'],userNodes)) nodes = self.nodeList.getNodes(collaterals) check = self.explorer.balances(nodes) # Needed cause the balanceChecks dict also gets modified from other # threads. self.balanceSem.acquire() if check: self.balanceChecks[check] = message.author.id else: logger.info("Balance check failed instant.") failed = uuid.uuid4() self.balanceChecks[failed] = message.author.id # Needed cause the balanceChecks dict also gets modified from other # threads. self.balanceSem.release() if failed: self.balancesCB(failed,None) elif command == 'lookup': response = messages.markdown(node.lookup(self,message, args),self.messenger) await self.sendMessage(receiver, response) ### User command handler ### elif command == 'me': response = user.me(self,message) await self.sendMessage(receiver, response) elif command == 'status': response = user.status(self,message, args) await self.sendMessage(receiver, response) elif command == 'reward': response = user.reward(self,message, args) await self.sendMessage(receiver, response) elif command == 'timeout': response = user.timeout(self,message, args) await self.sendMessage(receiver, response) elif command == 'network': response = user.network(self,message, args) await self.sendMessage(receiver, response) ### Admin command handler ### elif command == 'stats': response = common.stats(self) await self.sendMessage(receiver, response) elif command == 'payouts': response = common.payouts(self,args[1:]) await self.sendMessage(receiver, response) elif command == 'broadcast': response = " ".join(args[1:]) for dbUser in self.database.getUsers(): member = self.findMember(dbUser['id']) if member: await self.sendMessage(member, response) # Help message elif command == 'help': await self.sendMessage(receiver, messages.help(self.messenger)) # Could not match any command. Send the unknwon command message. else: await self.sendMessage(receiver, (message.author.mention + ", " + common.unknown(self)))