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.")
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())
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)
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())