def nestedListToDictionary(nestedList): """Convert a nested list structure to a dictionary with a similar structure. The first element of each list is taken as key in the dictionary. Nested lists are converted to sub-dictionaries. Parameters nestedList ((nested) list) - structure to convert Returns dictionary representing the nestedList """ # strip empty lines d = [t for t in nestedList if t != []] # If argument is a sinlge entry, do not make a dictionary if len(d) == 1: if len(d[0]) == 1: d = d[0][0] return d # Else: convert to dictionary d = {k[0]: k[1:] for k in d} # convert types for i in d: if any(isinstance(j, list) for j in d[i]): # check if d[i] is a nested list d[i] = nestedListToDictionary(d[i][0]) else: for j in range(len(d[i])): if isInt(d[i][j]): #check if int d[i][j] = int(d[i][j]) elif isFloat(d[i][j]): #check if float d[i][j] = float(d[i][j]) if len(d[i]) == 1: #remove list if only one element d[i] = d[i][0] return d
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 publish(bot, message, args): logger.info("publish") result = {'fire': False} response = "<u><b>Publish proposal<b><u>\n\n" userInfo = util.crossMessengerSplit(message) userId = userInfo['user'] if 'user' in userInfo else None userName = userInfo['name'] if 'name' in userInfo else "Unknown" result['author'] = userName if len(args) != 1: response += messages.proposalIdRequired(bot.messenger, 'publish') elif not util.isInt(args[0].replace('#', '')): response += messages.invalidProposalId(bot.messenger, args[0]) else: proposal = bot.proposals.getProposal(int(args[0].replace('#', ''))) if not proposal: response += messages.proposalNotFound(bot.messenger, args[0]) else: result['proposal'] = proposal twitter = bot.tweeter != None reddit = bot.reddit != None gab = bot.gab != None discord = False telegram = False if 'discord' in bot.messenger: discord = True if 'telegram' in bot.messenger: telegram = True if proposal.published(twitter=twitter, reddit=reddit, gab=gab, discord=discord, telegram=telegram): response += messages.proposalAlreadyPublished( bot.messenger, args[0]) else: result['fire'] = True result['message'] = messages.markdown(response, bot.messenger) return result
def remove(bot, message, args): logger.info("remove") response = "<u><b>Remove from watchlist<b><u>\n\n" userInfo = util.crossMessengerSplit(message) userId = userInfo['user'] if 'user' in userInfo else None userName = userInfo['name'] if 'name' in userInfo else "Unknown" public = userInfo['public'] dbUser = bot.database.getUser(userId) if not dbUser: logger.error("User not in db?!") response += messages.unexpectedError(bot.messenger) else: if len(args) != 1: response += messages.proposalIdRequired(bot.messenger, 'remove') elif not util.isInt(args[0].replace('#', '')): response += messages.invalidProposalId(bot.messenger, args[0]) else: proposal = bot.proposals.getProposal(int(args[0].replace('#', ''))) if not proposal: response += messages.proposalNotFound(bot.messenger, args[0]) else: currentList = bot.database.getWatchlist(userId=userId) if currentList and len(currentList) and\ not proposal.proposalId in list(map(lambda x: x['proposal_id'],currentList)) or\ not currentList or not len(currentList): response += messages.proposalIsNotOnWatchlist( bot.messenger, proposal.title) else: if bot.database.removeFromWatchlist( userId, proposal.proposalId): response += "Succesfully removed the proposal <b>{}<b> from your watchlist.".format( proposal.title) else: logger.error("Could not remove watchlist entry?!") response += messages.unexpectedError(bot.messenger) return messages.markdown(response, bot.messenger)
def balances(bot, userId, results): response = messages.markdown("<u><b>Balances<b><u>\n\n", bot.messenger) if results != None: userNodes = bot.database.getAllNodes(userId) total = 0 error = False for result in results: for node in userNodes: if str(result.node.collateral) == node['collateral']: if not util.isInt(result.data) and "error" in result.data: response += "{} - Error: {}\n".format( node['name'], result.data["error"]) logger.warning("Balance response error: {}".format( result.data)) error = True else: try: total += round(result.data, 1) response += "{} - {} SMART\n".format( node['name'], result.data) except: error = True logger.warning( "Balance response invalid: {}".format( result.data)) response += "{} - Error: Could not fetch this balance.\n".format( node['name']) response += messages.markdown( "\nTotal: <b>{} SMART<b>".format(round(total, 1)), bot.messenger) # Only show the profit if there was no error since it would make not much sense otherwise. if not error: response += messages.markdown( "\nProfit: <b>{} SMART<b>".format( round(total - len(userNodes) * 10000, 1)), bot.messenger) else: response += "Sorry, could not check your balances! Looks like all explorers are down. Try it again later.\n\n" return response
def balances(bot, userId, results): response = messages.markdown("<u><b>Balances<b><u>\n\n", bot.messenger) if results != None: userNodes = bot.database.getAllNodes(userId) total = 0 for result in results: for node in userNodes: if str(result.node.collateral) == node['collateral']: if not util.isInt(result.data) and "error" in result.data: response += "{} - Error: {}\n".format( node['name'], result.data["error"]) logger.warning("Balance response error: {}".format( result.data)) else: try: total += round(result.data, 1) response += "{} - {:,} CRU\n".format( node['name'], result.data) except: logger.warning( "Balance response invalid: {}".format( result.data)) response += "{} - Error: Could not fetch this balance.\n".format( node['name']) response += messages.markdown( "\nTotal: <b>{:,} CRU<b>".format(round(total, 1)), bot.messenger) else: response += "Sorry, could not check your balances! Looks like all explorers are down. Try it again later.\n\n" return response
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)