def __init__(self, bot):
     with open('config.json') as config:
         self.config_data = json.load(config)
     self.bot = bot
     self.started = False
     self.market_list = None
     self.market_stats = None
     self.acronym_list = None
     self.top_five = []
     self.top_five_gains = []
     self.top_five_losses = []
     self.coin_market = CoinMarket(self.config_data["cmc_api_key"])
     self.server_data = self._check_server_file()
     self.cmc = CoinMarketFunctionality(bot,
                                        self.coin_market,
                                        self.server_data)
     self.alert = AlertFunctionality(bot,
                                     self.coin_market,
                                     self.config_data["alert_capacity"],
                                     self.server_data)
     self.subscriber = SubscriberFunctionality(bot,
                                               self.coin_market,
                                               self.config_data["subscriber_capacity"],
                                               self.server_data)
     # self.cal = CalFunctionality(bot,
     #                             self.config_data,
     #                             self.server_data)
     self.misc = MiscFunctionality(bot, self.server_data)
     self._save_server_file(self.server_data, backup=True)
     self.bot.loop.create_task(self._continuous_updates())
예제 #2
0
class CoreFunctionality:
    """Handles Core functionality"""
    def __init__(self, bot):
        with open('config.json') as config:
            self.config_data = json.load(config)
        self.bot = bot
        self.started = False
        self.market_list = None
        self.market_stats = None
        self.acronym_list = None
        self.coin_market = CoinMarket()
        self.server_data = self._check_server_file()
        self.cmc = CoinMarketFunctionality(bot, self.coin_market,
                                           self.server_data)
        self.alert = AlertFunctionality(bot, self.coin_market,
                                        self.config_data["alert_capacity"],
                                        self.server_data)
        self.subscriber = SubscriberFunctionality(
            bot, self.coin_market, self.config_data["subscriber_capacity"],
            self.server_data)
        self.misc = MiscFunctionality(bot, self.server_data)
        self._save_server_file(self.server_data, backup=True)
        self.bot.loop.create_task(self._continuous_updates())

    def _check_server_file(self):
        """
        Checks to see if there's a valid server_settings.json file
        """
        try:
            with open('server_settings.json') as settings:
                return json.load(settings)
        except FileNotFoundError:
            self._save_server_file()
            return json.loads('{}')
        except Exception as e:
            print("Unable to load server file. See error.log.")
            logger.error("Exception: {}".format(str(e)))

    def _save_server_file(self, server_data={}, backup=False):
        """
        Saves server_settings.json file
        """
        if backup:
            server_settings_filename = "server_settings_backup.json"
        else:
            server_settings_filename = "server_settings.json"
        with open(server_settings_filename, 'w') as outfile:
            json.dump(server_data, outfile, indent=4)

    def _update_server_data(self):
        try:
            self.cmc.update(server_data=self.server_data)
            self.alert.update(server_data=self.server_data)
            self.subscriber.update(server_data=self.server_data)
            self.misc.update(server_data=self.server_data)
        except Exception as e:
            print("Failed to update server data. See error.log.")
            logger.error("Exception: {}".format(str(e)))

    async def _update_data(self, minute=0):
        try:
            await self._update_market()
            self._load_acronyms()
            self.cmc.update(self.market_list, self.acronym_list,
                            self.market_stats)
            self.alert.update(self.market_list, self.acronym_list)
            self.subscriber.update(self.market_list, self.acronym_list)
            await self._update_game_status()
            await self.alert.alert_user()
            if self.started:
                await self.subscriber.display_live_data(minute)
        except Exception as e:
            print("Failed to update data. See error.log.")
            logger.error("Exception: {}".format(str(e)))

    async def _update_game_status(self):
        """
        Updates the game status of the bot
        """
        try:
            game_status = discord.Game(name="$updates to see log")
            await self.bot.change_presence(game=game_status)
        except Exception as e:
            print("Failed to update game status. See error.log.")
            logger.error("Exception: {}".format(str(e)))

    async def _continuous_updates(self):
        await self._update_data()
        self.started = True
        print('CoinMarketDiscordBot is online.')
        logger.info('Bot is online.')
        while True:
            time = datetime.datetime.now()
            if time.minute % 5 == 0:
                await self._update_data(time.minute)
                await asyncio.sleep(60)
            else:
                await asyncio.sleep(20)

    async def _update_market(self):
        """
        Loads all the cryptocurrencies that exist in the market

        @return - list of crypto-currencies
        """
        try:
            retry_count = 0
            market_stats = self.coin_market.fetch_coinmarket_stats()
            currency_data = self.coin_market.fetch_currency_data(load_all=True)
            while market_stats is None or currency_data is None:
                if retry_count >= 10:
                    msg = ("Max retry attempts reached. Please make "
                           "sure you're able to access coinmarketcap "
                           "through their website, check if the coinmarketapi "
                           "is down, and check if "
                           "anything is blocking you from requesting "
                           "data.")
                    raise CoreFunctionalityException(msg)
                logger.warning("Retrying to get data..")
                if market_stats is None:
                    market_stats = self.coin_market.fetch_coinmarket_stats()
                if currency_data is None:
                    currency_data = self.coin_market.fetch_currency_data(
                        load_all=True)
                retry_count += 1
                await asyncio.sleep(5)
            market_dict = {}
            for currency in currency_data:
                market_dict[currency['id']] = currency
            self.market_stats = market_stats
            self.market_list = market_dict
        except CoreFunctionalityException as e:
            logger.error(str(e))
        except Exception as e:
            print("Failed to update market. See error.log.")
            logger.error("Exception: {}".format(str(e)))

    def _load_acronyms(self):
        """
        Loads all acronyms of existing crypto-coins out there

        @return - list of crypto-acronyms
        """
        try:
            if self.market_list is None:
                raise Exception("Market list was not loaded.")
            acronym_list = {}
            duplicate_list = {}
            for currency, data in self.market_list.items():
                if data['symbol'] in acronym_list:
                    if data['symbol'] not in duplicate_list:
                        duplicate_list[data['symbol']] = 1
                    duplicate_list[data['symbol']] += 1
                    if data['symbol'] not in acronym_list[data['symbol']]:
                        acronym_list[data['symbol'] +
                                     '1'] = acronym_list[data['symbol']]
                        acronym_list[data['symbol']] = (
                            "Duplicate acronyms "
                            "found. Possible "
                            "searches are:\n"
                            "{}1 ({})\n".format(data['symbol'],
                                                acronym_list[data['symbol']]))
                    dupe_key = data['symbol'] + str(
                        duplicate_list[data['symbol']])
                    acronym_list[dupe_key] = currency
                    acronym_list[data['symbol']] = (
                        acronym_list[data['symbol']] +
                        "{} ({})\n".format(dupe_key, currency))
                else:
                    acronym_list[data['symbol']] = currency
            self.acronym_list = acronym_list
        except Exception as e:
            print("Failed to load cryptocurrency acronyms. See error.log.")
            logger.error("Exception: {}".format(str(e)))

    async def _say_msg(self, msg=None, channel=None, emb=None):
        """
        Bot will say msg if given correct permissions

        @param msg - msg to say
        @param channel - channel to send msg to
        @param emb - embedded msg to say
        """
        try:
            if channel:
                if emb:
                    await self.bot.send_message(channel, embed=emb)
                else:
                    await self.bot.send_message(channel, msg)
            else:
                if emb:
                    await self.bot.say(embed=emb)
                else:
                    await self.bot.say(msg)
        except:
            pass

    async def display_server_settings(self, ctx):
        """
        Displays server settings of cmds the admins have enabled
        """
        try:
            try:
                ctx.message.channel.server
            except:
                await self._say_msg("Not a valid server to retrieve settings.")
                return
            msg = ''
            server_id = ctx.message.server.id
            if server_id not in self.server_data:
                await self._say_msg("No settings to display.")
                return
            elif len(self.server_data[server_id]) == 0:
                await self._say_msg("No settings to display.")
                return
            for setting in self.server_data[server_id]:
                setting_line = "{}\n".format(setting)
                msg += setting_line
            em = discord.Embed(title="Server Settings",
                               description=msg,
                               colour=0xFFFFFF)
            await self._say_msg(emb=em)
        except Exception as e:
            print("Failed to display server settings. See error.log.")
            logger.error("Exception: {}".format(str(e)))

    async def toggle_commands(self, ctx, mode):
        """
        Toggles the command mode on/off
        """
        try:
            try:
                user_roles = ctx.message.author.roles
            except:
                await self._say_msg("Command must be used in a server.")
                return
            if CMB_ADMIN not in [role.name for role in user_roles]:
                await self._say_msg("Admin role '{}' is required for "
                                    "this command.".format(CMB_ADMIN))
                return
            channel = ctx.message.channel.id
            try:
                server = self.bot.get_channel(
                    channel).server  # validate channel
            except:
                await self._say_msg("Not a valid server to toggle mode.")
                return
            if server.id not in self.server_data:
                self.server_data[server.id] = [mode]
                await self._say_msg("Server set '{}'.".format(mode))
            elif mode in self.server_data[server.id]:
                self.server_data[server.id].remove(mode)
                await self._say_msg("'{}' has been taken off.".format(mode))
            elif mode not in self.server_data[server.id]:
                self.server_data[server.id].append(mode)
                await self._say_msg("Server set '{}'.".format(mode))
            self._save_server_file(self.server_data)
            self._update_server_data()
        except Exception as e:
            print("Failed to toggle {}. See error.log.".format(mode))
            logger.error("Exception: {}".format(str(e)))
예제 #3
0
def setup(bot):
    cmd_function = CommandFunctionality(bot)
    bot.add_cog(CoinMarketCommands(cmd_function))
    bot.add_cog(SubscriberCommands(cmd_function))
    bot.add_cog(AlertCommands(cmd_function))
    bot.add_cog(MiscCommands(MiscFunctionality(bot)))