Пример #1
0
    async def update(self, ctx, *args):
        """
        Updates the current character sheet, preserving all settings.
        __Valid Arguments__
        `-v` - Shows character sheet after update is complete.
        `-nocc` - Do not automatically create or update custom counters for class resources and features.
        `-noprep` - Import all known spells as prepared.
        """
        old_character: Character = await Character.from_ctx(ctx)
        url = old_character.upstream
        args = argparse(args)

        prefixes = 'dicecloud-', 'google-', 'beyond-'
        _id = url[:]
        for p in prefixes:
            if url.startswith(p):
                _id = url[len(p):]
                break
        sheet_type = old_character.sheet_type
        if sheet_type == 'dicecloud':
            parser = DicecloudParser(_id)
            loading = await ctx.send('Updating character data from Dicecloud...')
        elif sheet_type == 'google':
            parser = GoogleSheet(_id)
            loading = await ctx.send('Updating character data from Google...')
        elif sheet_type == 'beyond':
            parser = BeyondSheetParser(_id)
            loading = await ctx.send('Updating character data from Beyond...')
        else:
            return await ctx.send(f"Error: Unknown sheet type {sheet_type}.")

        try:
            character = await parser.load_character(ctx, args)
        except ExternalImportError as eep:
            return await loading.edit(content=f"Error loading character: {eep}")
        except Exception as eep:
            log.warning(f"Error importing character {old_character.upstream}")
            log.warning(traceback.format_exc())
            return await loading.edit(content=f"Error loading character: {eep}")

        character.update(old_character)
        
        # keeps an old check if the old character was active on the current server
        was_server_active = old_character.is_active_server(ctx)
        
        await character.commit(ctx)
        
        # overwrites the old_character's server active state
        # since character._active_guilds is old_character._active_guilds here
        if old_character.is_active_global():
            await character.set_active(ctx)
        if was_server_active:
            await character.set_server_active(ctx)
        
        await loading.edit(content=f"Updated and saved data for {character.name}!")
        if args.last('v'):
            await ctx.send(embed=character.get_sheet_embed())
        if sheet_type == 'beyond':
            await send_ddb_ctas(ctx, character)
    async def gsheet(self, ctx, url: str):
        """Loads a character sheet from [GSheet v2.0](http://gsheet2.avrae.io) (auto) or [GSheet v1.3](http://gsheet.avrae.io) (manual), resetting all settings.
        The sheet must be shared with Avrae for this to work.
        Avrae's google account is `[email protected]`."""

        loading = await ctx.send('Loading character data from Google... (This usually takes ~30 sec)')
        try:
            url = extract_gsheet_id_from_url(url)
        except NoValidUrlKeyFound:
            return await loading.edit(content="This is not a Google Sheets link.")

        override = await self._confirm_overwrite(ctx, f"google-{url}")
        if not override: return await ctx.send("Character overwrite unconfirmed. Aborting.")

        try:
            parser = GoogleSheet(url, self.gsheet_client)
        except AssertionError:
            await self.init_gsheet_client()  # hmm.
            return await loading.edit(content="I am still connecting to Google. Try again in 15-30 seconds.")

        try:
            await parser.get_character()
        except (KeyError, SpreadsheetNotFound):
            return await loading.edit(content=
                                      "Invalid character sheet. Make sure you've shared it with me at "
                                      "`[email protected]`!")
        except HttpError:
            return await loading.edit(content=
                                      "Error: Google returned an error. Please ensure your sheet is shared with "
                                      "`[email protected]` and try again in a few minutes.")
        except Exception as e:
            return await loading.edit(content='Error: Could not load character sheet.\n' + str(e))

        try:
            sheet = await parser.get_sheet()
        except Exception as e:
            traceback.print_exception(type(e), e, e.__traceback__, file=sys.stderr)
            return await loading.edit(content='Error: Invalid character sheet.\n' + str(e))

        try:
            await loading.edit(content=
                               'Loaded and saved data for {}!'.format(sheet['sheet']['stats']['name']))
        except TypeError as e:
            traceback.print_exception(type(e), e, e.__traceback__, file=sys.stderr)
            return await loading.edit(content=
                                      'Invalid character sheet. Make sure you have shared the sheet so that anyone with the link can view.')

        char = Character(sheet['sheet'], f"google-{url}").initialize_consumables()
        await char.commit(ctx)
        await char.set_active(ctx)

        try:
            await ctx.send(embed=char.get_sheet_embed())
        except:
            await ctx.send(
                "...something went wrong generating your character sheet. Don't worry, your character has been saved. "
                "This is usually due to an invalid image.")
Пример #3
0
    async def update(self, ctx, *args):
        """Updates the current character sheet, preserving all settings.
        __Valid Arguments__
        `-v` - Shows character sheet after update is complete.
        `-cc` - Updates custom counters from Dicecloud."""
        old_character: Character = await Character.from_ctx(ctx)
        url = old_character.upstream
        args = argparse(args)

        prefixes = 'dicecloud-', 'pdf-', 'google-', 'beyond-'
        _id = url[:]
        for p in prefixes:
            if url.startswith(p):
                _id = url[len(p):]
                break
        sheet_type = old_character.sheet_type
        if sheet_type == 'dicecloud':
            parser = DicecloudParser(_id)
            loading = await ctx.send(
                'Updating character data from Dicecloud...')
        elif sheet_type == 'google':
            parser = GoogleSheet(_id)
            loading = await ctx.send('Updating character data from Google...')
        elif sheet_type == 'beyond':
            parser = BeyondSheetParser(_id)
            loading = await ctx.send('Updating character data from Beyond...')
        else:
            return await ctx.send(f"Error: Unknown sheet type {sheet_type}.")

        try:
            character = await parser.load_character(str(ctx.author.id), args)
        except ExternalImportError as eep:
            return await loading.edit(content=f"Error loading character: {eep}"
                                      )
        except Exception as eep:
            log.warning(f"Error importing character {old_character.upstream}")
            log.warning(traceback.format_exc())
            return await loading.edit(content=f"Error loading character: {eep}"
                                      )

        character.update(old_character)

        await character.commit(ctx)
        await character.set_active(ctx)
        await loading.edit(
            content=f"Updated and saved data for {character.name}!")
        if args.last('v'):
            await ctx.send(embed=character.get_sheet_embed())
Пример #4
0
    async def gsheet(self, ctx, url: str, *args):
        """Loads a character sheet from [GSheet v2.0](http://gsheet2.avrae.io) (auto) or [GSheet v1.4](http://gsheet.avrae.io) (manual), resetting all settings.
        The sheet must be shared with Avrae for this to work.
        Avrae's google account is `[email protected]`."""

        loading = await ctx.send('Loading character data from Google... (This usually takes ~30 sec)')
        try:
            url = extract_gsheet_id_from_url(url)
        except ExternalImportError:
            return await loading.edit(content="This is not a Google Sheets link.")

        override = await self._confirm_overwrite(ctx, f"google-{url}")
        if not override: return await ctx.send("Character overwrite unconfirmed. Aborting.")

        parser = GoogleSheet(url)
        await self._load_sheet(ctx, parser, args, loading)
Пример #5
0
            prefix = 'beyond'
            url = beyond_match.group(1)
            parser = BeyondSheetParser(url)
        elif dicecloud_match := DICECLOUD_URL_RE.match(url):
            loading = await ctx.send('Loading character data from Dicecloud...')
            url = dicecloud_match.group(1)
            prefix = 'dicecloud'
            parser = DicecloudParser(url)
        else:
            try:
                url = extract_gsheet_id_from_url(url)
            except ExternalImportError:
                return await ctx.send("Sheet type did not match accepted formats.")
            loading = await ctx.send('Loading character data from Google...')
            prefix = 'google'
            parser = GoogleSheet(url)

        override = await self._confirm_overwrite(ctx, f"{prefix}-{url}")
        if not override:
            return await ctx.send("Character overwrite unconfirmed. Aborting.")

        # Load the parsed sheet
        character = await self._load_sheet(ctx, parser, args, loading)
        if character and beyond_match:
            await send_ddb_ctas(ctx, character)

    @commands.command(hidden=True, aliases=['gsheet', 'dicecloud'])
    @commands.max_concurrency(1, BucketType.user)
    async def beyond(self, ctx, url: str, *args):
        """
        This is an old command and has been replaced. Use `!import` instead!
    async def update(self, ctx, *, args=''):
        """Updates the current character sheet, preserving all settings.
        Valid Arguments: `-v` - Shows character sheet after update is complete.
        `-cc` - Updates custom counters from Dicecloud."""
        char = await Character.from_ctx(ctx)
        url = char.id
        old_character = char.character

        prefixes = 'dicecloud-', 'pdf-', 'google-', 'beyond-'
        _id = copy.copy(url)
        for p in prefixes:
            if url.startswith(p):
                _id = url[len(p):]
                break
        sheet_type = old_character.get('type', 'dicecloud')
        if sheet_type == 'dicecloud':
            parser = DicecloudParser(_id)
            loading = await ctx.send('Updating character data from Dicecloud...')
        elif sheet_type == 'google':
            try:
                parser = GoogleSheet(_id, self.gsheet_client)
            except AssertionError:
                await self.init_gsheet_client()  # attempt reconnection
                return await ctx.send("I am still connecting to Google. Try again in 15-30 seconds.")
            loading = await ctx.send('Updating character data from Google...')
        elif sheet_type == 'beyond':
            loading = await ctx.send('Updating character data from Beyond...')
            parser = BeyondSheetParser(_id)
        else:
            return await ctx.send("Error: Unknown sheet type.")
        try:
            await parser.get_character()
        except (timeout, aiohttp.ClientResponseError) as e:
            log.warning(
                f"Response error importing char:\n{''.join(traceback.format_exception(type(e), e, e.__traceback__))}")
            return await loading.edit(content=
                                      "I'm having some issues connecting to Dicecloud or Google right now. "
                                      "Please try again in a few minutes.")
        except HttpError:
            return await loading.edit(content=
                                      "Google returned an error trying to access your sheet. "
                                      "Please ensure your sheet is shared and try again in a few minutes.")
        except Exception as e:
            log.warning(
                f"Failed to import character\n{''.join(traceback.format_exception(type(e), e, e.__traceback__))}")
            return await loading.edit(content='Error: Invalid character sheet.\n' + str(e))

        try:
            if sheet_type == 'dicecloud':
                sheet = parser.get_sheet()
            elif sheet_type == 'pdf':
                sheet = parser.get_sheet()
            elif sheet_type == 'google':
                sheet = await parser.get_sheet()
            elif sheet_type == 'beyond':
                sheet = parser.get_sheet()
            else:
                return await ctx.send("Error: Unknown sheet type.")
            await loading.edit(content=
                               'Updated and saved data for {}!'.format(sheet['sheet']['stats']['name']))
        except TypeError as e:
            del parser
            log.info(f"Exception in parser.get_sheet: {e}")
            log.debug('\n'.join(traceback.format_exception(type(e), e, e.__traceback__)))
            return await loading.edit(content=
                                      'Invalid character sheet. '
                                      'If you are using a dicecloud sheet, '
                                      'make sure you have shared the sheet so that anyone with the '
                                      'link can view.')
        except Exception as e:
            del parser
            return await loading.edit(content='Error: Invalid character sheet.\n' + str(e))

        sheet = sheet['sheet']
        sheet['settings'] = old_character.get('settings', {})
        sheet['overrides'] = old_character.get('overrides', {})
        sheet['cvars'] = old_character.get('cvars', {})
        sheet['consumables'] = old_character.get('consumables', {})

        overrides = old_character.get('overrides', {})
        sheet['stats']['description'] = overrides.get('desc') or sheet.get('stats', {}).get("description",
                                                                                            "No description available.")
        sheet['stats']['image'] = overrides.get('image') or sheet.get('stats', {}).get('image', '')
        override_spells = []
        for s in overrides.get('spells', []):
            if isinstance(s, str):
                override_spells.append({'name': s, 'strict': True})
            else:
                override_spells.append(s)
        sheet['spellbook']['spells'].extend(override_spells)

        c = Character(sheet, url).initialize_consumables()

        if '-cc' in args and sheet_type == 'dicecloud':
            counters = parser.get_custom_counters()
            for counter in counters:
                displayType = 'bubble' if c.evaluate_cvar(counter['max']) < 6 else None
                try:
                    c.create_consumable(counter['name'], maxValue=str(counter['max']),
                                        minValue=str(counter['min']),
                                        reset=counter['reset'], displayType=displayType, live=counter['live'])
                except InvalidArgument:
                    pass

        # if c.get_combat_id() and not self.bot.rdb.exists(c.get_combat_id()):
        #     c.leave_combat()
        # reimplement this later

        await c.commit(ctx)
        await c.set_active(ctx)
        del parser, old_character  # pls don't freak out avrae
        if '-v' in args:
            await ctx.send(embed=c.get_sheet_embed())