Пример #1
0
def networkUpdate(bot, ids, added):

    count = len(ids)

    logger.info("networkUpdate {}, {}".format(count, added))

    response = messages.markdown("<u><b>Network update<b><u>\n\n",
                                 bot.messenger)

    if added:
        response += "{} new node{} detected\n\n".format(
            count, "s" if count > 1 else "")
    else:
        response += "{} node{} left us!\n\n".format(abs(count),
                                                    "s" if count < 1 else "")

    with bot.nodeList as nodeList:

        response += messages.markdown(
            "We have <b>{}<b> created nodes now!\n\n".format(nodeList.count()),
            bot.messenger)
        response += messages.markdown(
            "<b>{}<b> of them are enabled.".format(nodeList.enabled()),
            bot.messenger)

    return response
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
def watchlist(bot, message):

    logger.info("watchlist")

    response = "<u><b>Your 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 += "<b>Unexpected error. Contact the team!<b>"
    else:

        watchlist = bot.database.getWatchlist(userId=userId)

        if not watchlist or not len(watchlist):
            logger.info("No watchlist entry!")
            response += messages.noWatchlistEntry(bot.messenger)
        else:

            proposalIds = list(map(lambda x: x['proposal_id'], watchlist))
            watchlist = bot.proposals.getProposals(proposalIds)

            response += proposalList(bot, watchlist)

    return messages.markdown(response, bot.messenger)
Пример #8
0
def detail(bot, args):

    logger.info("detail")

    response = messages.markdown("<u><b>Proposal detail<b><u>\n\n",
                                 bot.messenger)

    if len(args):
        proposalIds = []

        for arg in args:
            try:
                proposalIds.append(int(arg))
            except:
                response += "Invalid argument: {}\n\n".format(
                    messages.removeMarkdown(arg))

    for proposalId in proposalIds:
        proposal = bot.proposals.getProposal(proposalId)

        if proposal:
            response += messages.proposalDetail(bot.messenger, proposal)
        else:
            response += "There is no info about the ID {}!\n\n".format(
                proposalId)

    return response
Пример #9
0
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
Пример #10
0
def info(bot, update):

    logger.info("network")

    response = messages.markdown("<u><b>SmartNode Network<b><u>\n\n",
                                 bot.messenger)

    with bot.nodeList as nodeList:

        if nodeList.synced() and nodeList.enabled():

            lastBlock = nodeList.lastBlock
            created = nodeList.count()
            enabled = nodeList.enabled()
            preEnabled = nodeList.preEnabled
            expired = nodeList.expired
            newStartRequired = nodeList.newStartRequired
            qualifiedNormal = nodeList.qualifiedNormal
            qualifiedUpgrade = nodeList.qualifiedUpgrade
            upgradeModeDuration = nodeList.remainingUpgradeModeDuration
            protocolRequirement = nodeList.protocolRequirement()
            protocolOld = nodeList.count(nodeList.oldProtocol)
            protocolNew = nodeList.count(nodeList.newProtocol)
            initialWait = nodeList.minimumUptime()
            minPosition = int(enabled * 0.1)
            aberration = bot.aberration

            # Fallback if for whatever reason the top node could not filtered which
            # should actually not happen.
            top10Seconds = (int(
                (qualifiedNormal * 55) / 0.5) * (1 + bot.aberration))

            topNode = list(
                filter(lambda x: x.position == minPosition,
                       nodeList.nodes.values()))

            if len(topNode) and topNode[0].lastPaidTime:
                top10FromList = time.time() - topNode[0].lastPaidTime
                if top10FromList < 1.2 * top10Seconds:
                    top10Seconds = top10FromList

            top10Time = util.secondsToText(top10Seconds)

            if upgradeModeDuration:
                upgradeModeDuration = util.secondsToText(upgradeModeDuration)

            response += messages.networkState(
                bot.messenger, lastBlock, created, preEnabled, enabled,
                expired, newStartRequired, qualifiedNormal, qualifiedUpgrade,
                upgradeModeDuration, protocolRequirement, nodeList.oldProtocol,
                nodeList.newProtocol, protocolOld, protocolNew,
                util.secondsToText(initialWait), top10Time, aberration)

        else:
            response += messages.notSynced(bot.messenger)

    return response
Пример #11
0
def stats(bot):

    logger.info("stats")

    response = messages.markdown("<u><b>Statistics<b><u>\n\n", bot.messenger)

    response += "User: {}\n".format(len(bot.database.getUsers()))
    response += "Nodes: {}\n".format(len(bot.database.getAllNodes()))

    return response
Пример #12
0
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 isinstance(result.data,
                                      dict) or not "balance" in result.data:
                        response += "{} - Error: {}\n".format(
                            node['name'], "Could not fetch balance.")
                        logger.warning("Balance response error: {}".format(
                            result.data))

                    else:

                        try:
                            balance = float(result.data["balance"])
                            total += round(balance, 1)
                            response += "{} - {:,} SMART\n".format(
                                node['name'], balance)
                        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>{:,} SMART<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
Пример #13
0
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
Пример #14
0
def latest(bot):

    logger.info("latest")

    response = messages.markdown("<u><b>Latest proposal<b><u>\n\n",bot.messenger)

    proposal = bot.proposals.getLatestProposals()

    if proposal:
        response += messages.proposalDetail(bot.messenger, proposal)
    else:
        response += "No latest proposal available!"

    return response
Пример #15
0
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)
Пример #16
0
def stats(bot):

    logger.info("stats")

    response = messages.markdown("<u><b>Statistics<b><u>\n\n", bot.messenger)

    response += "User: {}\n".format(len(bot.database.getUsers()))
    response += "Nodes: {}\n".format(len(bot.database.getAllNodes()))

    response += "90024: {}\n".format(
        bot.nodeList.getNodeCountForProtocol(90024))
    response += "90025: {}\n".format(
        bot.nodeList.getNodeCountForProtocol(90025))

    return response
Пример #17
0
def stats(bot):

    logger.info("stats")

    response = messages.markdown("<u><b>Statistics<b><u>\n\n",bot.messenger)

    users = bot.database.getUsers()
    subscriptions = bot.database.getSubscriptions()
    watchlistEntries = bot.database.getWatchlist()

    response += "User: {}\n".format(len(users))
    response += "Subscriptions: {}\n".format(len(subscriptions))
    response += "Watchlist entires: {}\n".format(len(watchlistEntries))

    return response
Пример #18
0
def handleUpdatedProposal(bot, updated, proposal):

    # Create notification response messages!
    responses = {}
    changes = []

    if 'voteYes' in updated and updated['voteYes']:
        change = updated['voteYes']
        changes.append(
            "<b>YES<b> votes (SMART) changed from <b>{:,}<b> to <b>{:,}<b>\n".
            format(round(change['before'], 1), round(change['now'], 1)))

    if 'voteNo' in updated and updated['voteNo']:
        change = updated['voteNo']
        changes.append(
            "<b>NO<b> votes (SMART) changed from <b>{:,}<b> to <b>{:,}<b>\n".
            format(round(change['before'], 1), round(change['now'], 1)))

    if 'voteAbstain' in updated and updated['voteAbstain']:
        change = updated['voteAbstain']
        changes.append(
            "<b>ABSTAIN<b> votes (SMART) changed from <b>{:,}<b> to <b>{:,}<b>\n"
            .format(round(change['before'], 1), round(change['now'], 1)))

    if 'status' in updated and updated['status']:
        change = updated['status']
        changes.append(
            "<b>State<b> changed from <b>{}<b> to <b>{}<b>\n".format(
                change['before'], change['now']))

    if 'currentStatus' in updated and updated['currentStatus']:
        change = updated['currentStatus']
        changes.append(
            "<b>Current result<b> changed from <b>{}<b> to <b>{}<b>\n".format(
                change['before'], change['now']))

    for entry in bot.database.getWatchlist(proposalId=proposal.proposalId):

        message = "<u><b>Watchlist update!<b><u>\n\n"
        message += "The proposal <b>{}<b> obtained the following change{}\n\n".format(
            proposal.title, "s" if len(changes) > 1 else "")

        for change in changes:
            message += change

        responses[entry['user_id']] = messages.markdown(message, bot.messenger)

    return responses
Пример #19
0
def payouts(bot, args):

    logger.info("payouts")

    response = messages.markdown("<u><b>Payout statistics<b><u>\n\n",
                                 bot.messenger)

    if not bot.rewardList.running:
        response += "Not initialized yet. Wait a bit..."
        return response

    hours = 12

    if len(args):
        try:
            hours = float(args[0])
        except:
            pass

    start = time.time() - (hours * 3600)

    firstReward = bot.rewardList.getNextReward(start)
    lastReward = bot.rewardList.getLastReward()

    if not firstReward:
        response += "Could not fetch the rewards in the given time range!\n"
        response += "The last available is at block {} from {} ago.".format(
            lastReward.block,
            util.secondsToText(time.time() - lastReward.txtime))
        return response

    total = bot.rewardList.getRewardCount(start=start)
    vChain = bot.rewardList.getRewardCount(start=start, source=0, meta=0)
    iChain = bot.rewardList.getRewardCount(start=start, meta=1)
    nList = bot.rewardList.getRewardCount(start=start, source=1)
    err = bot.rewardList.getRewardCount(start=start, meta=-1)

    response += "Blocks: {}\n".format(lastReward.block - firstReward.block)
    response += "RT: {}\n".format(
        util.secondsToText(lastReward.txtime - firstReward.txtime))
    response += "P: {}\n".format(total)
    response += "V: {}\n".format(vChain)
    response += "I: {}\n".format(iChain)
    response += "NL: {}\n".format(nList)
    response += "ERR: {}\n".format(err)
    response += "E: {}%".format(round((1 - (nList / total)) * 100, 1))

    return response
Пример #20
0
def proposalList(bot, proposals, title = "", fallback = ""):
    logger.info("proposalList - " + title)

    response = ""

    if title != "":
        response = messages.markdown("<u><b>{}<b><u>\n\n".format(title),bot.messenger)

    if len(proposals):

        for proposal in proposals:
            response += messages.proposalShort(bot.messenger, proposal)
    else:
        response += fallback

    return response
Пример #21
0
def lookup(bot, userId, args):

    response = messages.markdown("<u><b>Node lookup<b><u>\n\n", bot.messenger)

    if bot.nodeList.synced() and bot.nodeList.lastBlock:

        if not len(args):
            response += messages.lookupArgumentRequiredError(bot.messenger)
        else:

            errors = []
            lookups = []

            for arg in args:

                ip = util.validateIp(arg)

                if not ip:
                    errors.append(messages.invalidIpError(bot.messenger, arg))
                else:

                    dbNode = bot.nodeList.getNodeByIp(ip)

                    if dbNode:

                        result = bot.nodeList.lookup(dbNode['collateral'])

                        if result:
                            lookups.append(
                                messages.lookupResult(bot.messenger, result))
                        else:
                            errors.append(
                                messages.lookupError(bot.messenger, ip))

                    else:
                        errors.append(
                            messages.nodeNotInListError(bot.messenger, ip))

            for e in errors:
                response += e

            for l in lookups:
                response += l
    else:
        response += "*Sorry, the bot is currently not synced with the network. Try it again in few minutes...*"

    return response
Пример #22
0
def lookup(bot, userId, args):

    response = messages.markdown("<u><b>Node lookup<b><u>\n\n", bot.messenger)

    with bot.nodeList as nodeList:

        if nodeList.synced() and nodeList.lastBlock:

            if not len(args):
                response += messages.lookupArgumentRequiredError(bot.messenger)
            else:

                errors = []
                lookups = []

                for arg in args:

                    ip = util.validateIp(arg)

                    if not ip:
                        errors.append(
                            messages.invalidIpError(bot.messenger, arg))
                    else:

                        result = nodeList.lookup(ip)

                        if result:
                            lookups.append(
                                messages.lookupResult(bot.messenger, result))
                        else:
                            errors.append(
                                messages.nodeNotInListError(bot.messenger, ip))

                for e in errors:
                    response += e

                for l in lookups:
                    response += l
        else:
            response += messages.notSynced(bot.messenger)

    return response
Пример #23
0
def parse(bot, args):

    message = help()

    if len(args):

        ask = " ".join(args)

        choices = fuzzy.extract(ask,faqs.keys(),limit=2)

        if choices[0][1] == choices[1][1] or choices[0][1] < 60:
            log.warning('Invalid fuzzy result {} - {}\n'.format(ask, choices))
            message = unknown(ask)
        else:

            topic = choices[0][0]

            message = "<b>" + faqs[topic].question + "<b>\n\n" + faqs[topic].answerCB(bot)

    return messages.markdown(header + message,bot.messenger)
Пример #24
0
    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)
Пример #25
0
def info(bot, update):

    logger.info("network")

    response = messages.markdown("<u><b>SmartNode Network<b><u>\n\n",
                                 bot.messenger)

    if bot.nodeList.synced() and bot.nodeList.lastBlock:

        bot.nodeList.acquire()

        lastBlock = bot.nodeList.lastBlock
        created = bot.nodeList.count()
        enabled = bot.nodeList.enabled()
        qualifiedNormal = bot.nodeList.qualifiedNormal
        qualifiedUpgrade = bot.nodeList.qualifiedUpgrade
        upgradeModeDuration = bot.nodeList.remainingUpgradeModeDuration
        protocolRequirement = bot.nodeList.protocolRequirement()
        protocol90024 = bot.nodeList.count(90024)
        protocol90025 = bot.nodeList.count(90025)
        initialWait = bot.nodeList.minimumUptime()

        if upgradeModeDuration:
            upgradeModeDuration = util.secondsToText(upgradeModeDuration)

        bot.nodeList.release()

        response += messages.networkState(bot.messenger, lastBlock, created,
                                          enabled, qualifiedNormal,
                                          qualifiedUpgrade,
                                          upgradeModeDuration,
                                          protocolRequirement, protocol90024,
                                          protocol90025,
                                          util.secondsToText(initialWait))

    else:
        response += "*Sorry, the bot is currently not synced with the network. Try it again in few minutes...*"

    return response
Пример #26
0
def new(bot):

    logger.info("new")

    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

    proposals = bot.proposals.getNotPublishedProposals(twitter=twitter,
                                                       reddit=reddit,
                                                       gab=gab,
                                                       discord=discord,
                                                       telegram=telegram)

    response = "<u><b>Unpublished proposals<b><u>\n\n"

    if len(proposals):

        for proposal in proposals:
            response += messages.proposalNew(bot.messenger,
                                             proposal,
                                             twitter=twitter,
                                             reddit=reddit,
                                             gab=gab,
                                             discord=discord,
                                             telegram=telegram)
    else:
        response += "Currently no proposal ready to publish!"

    return messages.markdown(response, bot.messenger)
Пример #27
0
def subscription(bot, message, state):

    logger.info("subscription")

    response = "<u><b>Subscription<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:
        logger.info("subscription - update {}".format(state))

        bot.database.updateSubscription(userId, state)

        response += "Succesfully <b>{}subscribed<b> new/ended proposals.".format("" if state else "un")

    return messages.markdown(response, bot.messenger)
Пример #28
0
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)
Пример #29
0
def nodeAdd(bot, update, args):

    userInfo = util.crossMessengerSplit(update)
    userId = userInfo['user'] if 'user' in userInfo else None
    userName = userInfo['name'] if 'name' in userInfo else None

    response = messages.markdown("<u><b>Add<b><u>\n\n", bot.messenger)

    logger.debug("add - " + " ".join(args))
    logger.debug("add - user: {}".format(userId))

    if len(args) == 0:

        response += messages.markdown((
            "<b>ERROR<b>: Arguments required: <b>IPAddress_0;name_0 ... IPAddress_n;name_n<b>\n\n"
            "Example: <cb>add<ca> 43.121.56.87;Node1 56.76.27.100;Node2\n"),
                                      bot.messenger)
        valid = False

    else:
        with bot.nodeList as nodeList:

            for arg in args:

                valid = True

                newNode = arg.split(";")

                if len(newNode) != 2:

                    response += messages.invalidParameterError(
                        bot.messenger, arg)
                    valid = False
                else:

                    ip = util.validateIp(newNode[0])
                    name = util.validateName(newNode[1])

                    if not ip:

                        response += messages.invalidIpError(
                            bot.messenger, newNode[0])
                        valid = False

                    if not name:

                        response += messages.invalidNameError(
                            bot.messenger, newNode[1])
                        valid = False

                if valid:

                    node = nodeList.getNodeByIp(ip)

                    if node == None:
                        response += messages.nodeNotInListError(
                            bot.messenger, ip)
                    else:

                        if bot.database.addNode(node.collateral, name, userId,
                                                userName):

                            response += "Added node {}!\n".format(ip)

                        else:

                            response += messages.nodeExistsError(
                                bot.messenger, ip)

    return response
Пример #30
0
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)