Esempio n. 1
0
 def __init__(self, bot):
     super().__init__(bot)
     self.logger = self.logger.getChild('cogs')
     self.path = 'data/downloader/'
     self.file_path = 'data/downloader/repos.json'
     # {name:{url,cog1:{installed},cog1:{installed}}}
     self.repos = dataIO.load_json(self.file_path)
     self.executor = ThreadPoolExecutor(NUM_THREADS)
     self._do_first_run()
Esempio n. 2
0
 def get_info_data(self, repo_name, cog=None):
     if cog is not None:
         cogs = self.list_cogs(repo_name)
         if cog in cogs:
             info_file = os.path.join(cogs[cog].get('folder'), 'info.json')
             if os.path.isfile(info_file):
                 try:
                     data = dataIO.load_json(info_file)
                 except:
                     return None
                 return data
     else:
         repo_info = os.path.join(self.path, repo_name, 'info.json')
         if os.path.isfile(repo_info):
             try:
                 data = dataIO.load_json(repo_info)
                 return data
             except:
                 return None
     return None
Esempio n. 3
0
def set_cog(cog, value):  # TODO: move this out of core.py
    data = dataIO.load_json("data/cogs.json")
    data[cog] = value
    dataIO.save_json("data/cogs.json", data)
Esempio n. 4
0
    async def update(self, ctx):
        """Updates cogs."""

        tasknum = 0
        num_repos = len(self.repos)

        min_dt = 0.5
        burst_inc = 0.1 / (NUM_THREADS)
        touch_n = tasknum
        touch_t = time()

        def regulate(touch_t, touch_n):
            dt = time() - touch_t
            if dt + burst_inc * (touch_n) > min_dt:
                touch_n = 0
                touch_t = time()
                return True, touch_t, touch_n
            return False, touch_t, touch_n + 1

        tasks = []
        for r in self.repos:
            task = partial(self.update_repo, r)
            task = self.bot.loop.run_in_executor(self.executor, task)
            tasks.append(task)

        base_msg = 'Downloading updated cogs, please wait... '
        status = f' {task_num}/{num_repos} repos updated'
        msg = await ctx.send(base_msg + status)

        updated_cogs = []
        new_cogs = []
        deleted_cogs = []
        error_repos = {}
        installed_updated_cogs = []

        for f in as_completed(tasks):
            tasknum += 1
            try:
                name, updates, oldhash = await f
                if updates:
                    if type(updates) is dict:
                        for k, l in updates.items():
                            tl = [(name, c, oldhash) for c in l]
                            if k == 'A':
                                new_cogs.extend(tl)
                            elif k == 'D':
                                deleted_cogs.extend(tl)
                            elif k == 'M':
                                updated_cogs.extend(tl)
            except UpdateError as e:
                name, what = e.args
                error_repos[name] = what
            edit, touch_t, touch_n = regulate(touch_t, touch_n)
            if edit:
                status = f' {task_num}/{num_repos} repos updated'
                msg = await self._robust_edit(msg, base_msg + status)
        status = 'done. '

        if not any(self.repos[repo][cog]['INSTALLED']
                   for repo, cog, _ in updated_cogs):
            status += ' No updates to apply. '

        if new_cogs:
            status += '\nNew cogs: ' \
                   + ', '.join('%s/%s' % c[:2] for c in new_cogs) + '.'
        if deleted_cogs:
            status += '\nDeleted cogs: ' \
                   + ', '.join('%s/%s' % c[:2] for c in deleted_cogs) + '.'
        if updated_cogs:
            status += '\nUpdated cogs: ' \
                   + ', '.join('%s/%s' % c[:2] for c in updated_cogs) + '.'
        if error_repos:
            status += '\nThe following repos failed to update: '
            for n, what in error_repos.items():
                status += '\n%s: %s' % (n, what)

        msg = await self._robust_edit(msg, base_msg + status)

        registry = dataIO.load_json("data/cogs.json")

        for t in updated_cogs:
            repo, cog, _ = t
            if (self.repos[repo][cog]['INSTALLED']
                    and registry.get('cogs.' + cog, False)):
                installed_updated_cogs.append(t)
                self.install(repo, cog)

        if not installed_updated_cogs:
            return

        patchnote_lang = 'Prolog'
        shorten_by = 8 + len(patchnote_lang)
        for note in self.patch_notes_handler(installed_updated_cogs):
            if note is None:
                continue
            for page in pagify(note, delims=['\n'], shorten_by=shorten_by):
                await ctx.send(box(page, patchnote_lang))

        await ctx.send("Cogs updated. Reload updated cogs? (yes/no)")
        answer = await self.bot.wait_for(
            'message', timeout=15, check=lambda m: m.author == ctx.author)
        if answer is None:
            await ctx.send("Ok then, you can reload cogs with"
                           " `{}reload <cog_name>`".format(ctx.prefix))
        elif answer.content.lower().strip() == "yes":
            update_list = []
            fail_list = []
            for repo, cog, _ in installed_updated_cogs:
                try:
                    self.bot.unload_extension("cogs." + cog)
                    self.bot.load_extension("cogs." + cog)
                    update_list.append(cog)
                except:
                    fail_list.append(cog)
            msg = 'Done.'
            if update_list:
                msg += " The following cogs were reloaded: "\
                    + ', '.join(update_list) + "\n"
            if fail_list:
                msg += " The following cogs failed to reload: "\
                    + ', '.join(fail_list)
            await ctx.send(msg)

        else:
            await ctx.send("Ok then, you can reload cogs with"
                           " `{}reload <cog_name>`".format(ctx.prefix))