async def __login(self) -> None: utc_now = util.get_utcnow() if not self.__key: self.__key = create_device_key() if not self.__checksum: self.__checksum = create_device_checksum(self.__key) base_url = await core.get_base_url() url = f'{base_url}{self.__login_path}' utc_now = util.get_utcnow() async with aiohttp.ClientSession() as session: async with session.post(url) as response: data = await response.text(encoding='utf-8') result = core.convert_raw_xml_to_dict(data) self.__last_login = utc_now if 'UserService' in result.keys(): user = result['UserService']['UserLogin']['User'] if user.get('Name', None): self.__user = None self.__access_token = None raise DeviceInUseError('Cannot login. The device is already in use.') self.__user = user self.__access_token = result['UserService']['UserLogin']['accessToken'] self.__set_can_login_until(utc_now) else: self.__access_token = None self.__set_access_token_expiry()
def __login(self) -> None: utc_now = util.get_utcnow() if not self.__key: self.__key = create_device_key() if not self.__checksum: self.__checksum = create_device_checksum(self.__key) production_server = core.get_production_server() url = f'https://{production_server}/UserService/DeviceLogin8?deviceKey={self.__key}&isJailBroken=false&checksum={self.__checksum}&deviceType=DeviceTypeMac&languageKey=en&advertisingkey=%22%22' utc_now = util.get_utcnow() data = requests.post(url).content.decode('utf-8') result = core.convert_raw_xml_to_dict(data) self.__last_login = utc_now if 'UserService' in result.keys(): user = result['UserService']['UserLogin']['User'] if user.get('Name', None): self.__user = None self.__access_token = None raise DeviceInUseError( 'Cannot login. The device is already in use.') self.__user = user self.__access_token = result['UserService']['UserLogin'][ 'accessToken'] self.__set_can_login_until(utc_now) else: self.__access_token = None self.__set_access_token_expiry()
def get_data(self, year: int, month: int, initializing: bool = False) -> TourneyData: if year < self.from_year: raise ValueError( f'There\'s no data from {year}. Earliest data available is from {calendar.month_name[self.from_month]} {self.from_year}.' ) if year == self.from_year: if month < self.from_month: raise ValueError( f'There\'s no data from {calendar.month_name[month]} {year}. Earliest data available is from {calendar.month_name[self.from_month]} {self.from_year}.' ) if not initializing: if year > self.to_year or (year == self.to_year and month > self.to_month): utc_now = util.get_utcnow() if utc_now.year <= self.to_year and utc_now.month - 1 <= self.to_month: raise ValueError( f'There\'s no data from {calendar.month_name[month]} {year}. Most recent data available is from {calendar.month_name[self.to_month]} {self.to_year}.' ) result = self.__read_data(year, month) if result is None: result = self.__retrieve_data(year, month, initializing=initializing) self.__cache_data(result) return result
def can_login(self) -> bool: if self.__can_login_until is None: return True utc_now = util.get_utcnow() if self.__can_login_until <= utc_now and self.__can_login_until.day == utc_now.day: return False return True
async def post_raw_data(ctx: commands.Context, retriever: entity.EntityRetriever, entity_name: str, entity_id: str): if ctx.author.id in settings.RAW_COMMAND_USERS: retrieved_at = util.get_utcnow() mode = None if entity_id: if '--json' in entity_id: entity_id = entity_id.replace('--json', '').strip() mode = 'json' elif '--xml' in entity_id: entity_id = entity_id.replace('--xml', '').strip() mode = 'xml' if entity_id: try: entity_id = int(entity_id) except: raise ValueError( f'Invalid parameter specified: `{entity_id}` is not a valid entity id!' ) if entity_id: await __post_raw_entity(ctx, retriever, entity_name, str(entity_id), mode, retrieved_at) else: await __post_raw_file(ctx, retriever, entity_name, mode, retrieved_at) else: await ctx.send( 'You are not allowed to use this command. If you think this is an error, join the support server and contact the bot\'s author.' )
async def test(ctx, action, *, params): print(f'+ called command test(ctx, {action}, {params}) by {ctx.author}') if action == 'utcnow': utcnow = util.get_utcnow() txt = util.get_formatted_datetime(utcnow) await ctx.send(txt) elif action == 'init': core.init_db() await ctx.send('Initialized the database from scratch') await util.try_delete_original_message(ctx) elif (action == 'select' or action == 'selectall') and params: query = f'SELECT {params}' result, error = core.db_fetchall(query) if error: await ctx.send(error) elif result: await ctx.send(result) else: await ctx.send('The query didn\'t return any results.') elif action == 'query' and params: query = f'{params}' success, error = core.db_try_execute(query) if not success: await ctx.send(error) else: await ctx.send( f'The query \'{params}\' has been executed successfully.')
async def set_setting(setting_name: str, value: object, utc_now: datetime = None) -> bool: __log_db_function_enter('set_setting', setting_name=f'\'{setting_name}\'', value=value, utc_now=utc_now) column_name = None if isinstance(value, bool): column_name = 'settingboolean' elif isinstance(value, int): column_name = 'settingint' elif isinstance(value, float): column_name = 'settingfloat' elif isinstance(value, datetime): column_name = 'settingtimestamptz' else: column_name = 'settingtext' success = True setting, modify_date = await get_setting(setting_name) if utc_now is None: utc_now = util.get_utcnow() query = '' if setting is None and modify_date is None: query = f'INSERT INTO settings ({column_name}, modifydate, settingname) VALUES ($1, $2, $3)' elif setting != value: query = f'UPDATE settings SET {column_name} = $1, modifydate = $2 WHERE settingname = $3' success = not query or await try_execute(query, [value, utc_now, setting_name]) if success: __settings_cache[setting_name] = value return success
async def get_full_fleet_info_as_text(fleet_info: dict, fleet_data: dict = None, user_data: dict = None, data_date: datetime = None) -> (list, list): """Returns a list of lines for the post, as well as the path to the spreadsheet created""" fleet_name = fleet_info[FLEET_DESCRIPTION_PROPERTY_NAME] fleet_id = fleet_info[FLEET_KEY_NAME] retrieval_date = util.get_utcnow() fleet_users_infos = await _get_fleet_users_by_id(fleet_id) if fleet_users_infos: fleet_info = list(fleet_users_infos.values())[0]['Alliance'] else: fleet_info = await _get_fleet_info_by_name(fleet_name) post_content = await _get_fleet_details_by_info(fleet_info, fleet_users_infos) fleet_sheet_contents = _get_fleet_sheet_lines(fleet_users_infos, retrieval_date) fleet_sheet_path_current = excel.create_xl_from_data(fleet_sheet_contents, fleet_name, retrieval_date, FLEET_SHEET_COLUMN_TYPES) file_paths = [fleet_sheet_path_current] if fleet_data and fleet_id in fleet_data.keys() and user_data and data_date: fleet_info = fleet_data[fleet_id] fleet_name = fleet_info[fleet.FLEET_DESCRIPTION_PROPERTY_NAME] fleet_users_infos = dict({user_id: user_info for user_id, user_info in user_data.items() if user_info['AllianceId'] == fleet_id}) fleet_sheet_contents = _get_fleet_sheet_lines(fleet_users_infos, data_date, fleet_name) file_name = f'{fleet_name}_tournament-{data_date.year}-{util.get_month_short_name(data_date).lower()}.xlsx' fleet_sheet_path_past = excel.create_xl_from_data(fleet_sheet_contents, fleet_name, data_date, FLEET_SHEET_COLUMN_TYPES, file_name=file_name) file_paths.append(fleet_sheet_path_past) return post_content, file_paths
async def __post_raw_file(ctx: commands.Context, retriever: entity.EntityRetriever, entity_name: str, mode: str, retrieved_at: datetime.datetime): async with ctx.typing(): retrieved_at = retrieved_at or util.get_utcnow() entity_name = entity_name.replace(' ', '_') file_name_prefix = f'{entity_name}_designs' raw_data = await retriever.get_raw_data() raw_data_dict = core.xmltree_to_raw_dict(raw_data, fix_attributes=True) if mode == 'xml': file_path = __create_raw_file(raw_data, mode, file_name_prefix, retrieved_at) elif mode == 'json': data = json.dumps(raw_data_dict) file_path = __create_raw_file(data, mode, file_name_prefix, retrieved_at) else: #flattened_data = __flatten_raw_data(raw_data) start = time.perf_counter() flattened_data = __flatten_raw_dict_for_excel(raw_data_dict) time1 = time.perf_counter() - start file_path = excel.create_xl_from_raw_data_dict( flattened_data, retriever.key_name, file_name_prefix, retrieved_at) time2 = time.perf_counter() - start print(f'Flattening the data took {time1:.2f} seconds.') print(f'Creating the excel sheet took {time2:.2f} seconds.') await util.post_output_with_files(ctx, [], [file_path]) os.remove(file_path)
def is_tourney_running(start_date=None, utc_now=None): if not start_date: start_date = get_current_tourney_start() if not utc_now: utc_now = util.get_utcnow() return start_date < utc_now
def db_update_schema_v_1_2_4_0(): column_definitions = [('dailydeleteonchange', 'BOOLEAN', False, False, None)] schema_version = db_get_schema_version() if schema_version: compare_1240 = util.compare_versions(schema_version, '1.2.4.0') compare_1220 = util.compare_versions(schema_version, '1.2.2.0') if compare_1240 <= 0: return True elif compare_1220 > 0: return False query_lines = [] for (column_name, column_type, column_is_primary, column_not_null, column_default) in column_definitions: column_definition = util.db_get_column_definition( column_name, column_type, is_primary=column_is_primary, not_null=column_not_null, default=column_default) query_lines.append( f'ALTER TABLE serversettings ADD COLUMN IF NOT EXISTS {column_definition}' ) query = '\n'.join(query_lines) success = db_try_execute(query) if success: utc_now = util.get_utcnow() daily_info = daily.get_daily_info() success = daily.db_set_daily_info(daily_info, utc_now) if success: success = db_try_set_schema_version('1.2.4.0') return success
def create_xl_from_raw_data_dict(flattened_data: list, entity_key_name: str, file_prefix: str, data_retrieved_at: datetime.datetime = None) -> str: if data_retrieved_at is None: data_retrieved_at = util.get_utcnow() save_to = get_file_name(file_prefix, data_retrieved_at, FILE_ENDING.XL, consider_tourney=False) #wb = openpyxl.Workbook() #ws: openpyxl.worksheet.worksheet.Worksheet = wb.active wb = openpyxl.Workbook(write_only=True) ws: openpyxl.worksheet.worksheet.Worksheet = wb.create_sheet() df = pandas.DataFrame(flattened_data) for (columnName, columnData) in df.iteritems(): if 'datetime64' in columnData.dtype.name: df[columnName] = df[columnName].dt.tz_convert(None) for row in openpyxl.utils.dataframe.dataframe_to_rows(df, index=False, header=True): ws.append(row) table = openpyxl.worksheet.table.Table(displayName='tbl', ref=_get_ref_for_df(df)) table.tableStyleInfo = __BASE_TABLE_STYLE table._initialise_columns() for cell, col in zip(df.columns, table.tableColumns): col.name = str(cell) ws.add_table(table) wb.save(save_to) return save_to
def db_set_setting(setting_name: str, value: object, utc_now: datetime = None) -> bool: column_name = None if isinstance(value, bool): db_value = util.db_convert_boolean(value) column_name = 'settingboolean' elif isinstance(value, int): db_value = util.db_convert_to_int(value) column_name = 'settingint' elif isinstance(value, float): db_value = util.db_convert_to_float(value) column_name = 'settingfloat' elif isinstance(value, datetime): db_value = util.db_convert_to_datetime(value) column_name = 'settingtimestamptz' else: db_value = util.db_convert_text(value) column_name = 'settingtext' setting, modify_date = db_get_setting(setting_name) if utc_now is None: utc_now = util.get_utcnow() modify_date = util.db_convert_timestamp(utc_now) query = '' if setting is None and modify_date is None: query = f'INSERT INTO settings (settingname, modifydate, {column_name}) VALUES ({util.db_convert_text(setting_name)}, {modify_date}, {db_value})' elif setting != value: where_string = util.db_get_where_string('settingname', setting_name, is_text_type=True) query = f'UPDATE settings SET {column_name} = {db_value}, modifydate = {modify_date} WHERE {where_string}' success = not query or db_try_execute(query) return success
def create_xl_from_data(data: list, file_prefix: str, data_retrieval_date: datetime, column_formats: list, file_name: str = None) -> str: if data_retrieval_date is None: data_retrieval_date = util.get_utcnow() if file_name: save_to = file_name else: save_to = get_file_name(file_prefix, data_retrieval_date) wb = openpyxl.Workbook() ws = wb.active for item in data: ws.append(item) col_count = len(list(ws.columns)) + 1 row_count = len(list(ws.rows)) + 1 for i, col_no in enumerate(range(1, col_count)): column_format = column_formats[i] if column_format: for row_no in range(2, row_count): ws.cell(row_no, col_no).number_format = column_format wb.save(save_to) return save_to
def __update_data(self, initializing: bool = False) -> bool: if not initializing: self.__initialize() utc_now = util.get_utcnow() g_file_name = TourneyData.__get_latest_file_name(utc_now) g_file = self.__get_first_file(g_file_name) raw_data = g_file.GetContentString() data = json.loads(raw_data) new_fleet_data = TourneyData.__create_fleet_dict_from_data( data['fleets']) new_user_data = TourneyData.__create_user_dict_from_data( data['users'], data['data']) data_date = util.parse_formatted_datetime(data['meta']['timestamp'], include_tz=False, include_tz_brackets=False) self.__request_write() can_write = False while not can_write: can_write = self.__get_reader_count() == 0 if not can_write: time.sleep(random.random()) self.__write_data(new_fleet_data, new_user_data, utc_now, data_date) self.__finish_write() return True return False
def __write_data(self, data) -> None: self.__WRITE_LOCK.acquire() self.__data = data self.__modify_date = util.get_utcnow() util.dbg_prnt( f'[PssCache[{self.name}].__write_data] Stored {len(data)} bytes on {self.__modify_date}' ) self.__WRITE_LOCK.release()
def mock_get_daily_info(): utc_now = util.get_utcnow() if utc_now.hour < 1: if utc_now.minute < 20: return __mock_get_daily_info_1() else: return __mock_get_daily_info_2() else: return __mock_get_daily_info_1()
async def db_try_set_schema_version(version: str) -> bool: prior_version = await db_get_schema_version() utc_now = util.get_utcnow() if not prior_version: query = f'INSERT INTO settings (modifydate, settingtext, settingname) VALUES ($1, $2, $3)' else: query = f'UPDATE settings SET modifydate = $1, settingtext = $2 WHERE settingname = $3' success = await db_try_execute(query, [utc_now, version, 'schema_version']) return success
async def tournament_next(ctx): """Get information about the time of next month's tournament.""" async with ctx.typing(): utc_now = util.get_utcnow() start_of_tourney = tourney.get_next_tourney_start() embed_colour = util.get_bot_member_colour(bot, ctx.guild) embed = tourney.embed_tourney_start(start_of_tourney, utc_now, embed_colour) await ctx.send(embed=embed)
def __get_is_data_outdated(self) -> bool: if self.__UPDATE_INTERVAL_ORIG == 0: return True utc_now = util.get_utcnow() self.__WRITE_LOCK.acquire() modify_date = self.__modify_date self.__WRITE_LOCK.release() result = modify_date is None or utc_now - modify_date > self.__UPDATE_INTERVAL return result
def get_latest_data(self, initializing: bool = False) -> TourneyData: utc_now = util.get_utcnow() year, month = TourneyDataClient.__get_tourney_year_and_month(utc_now) while year > self.from_year or month >= self.from_month: result = self.get_data(year, month, initializing=initializing) if result: break month -= 1 if month == 0: year -= 1 month = 12 return result
def is_old_file(filename, max_days=0, max_seconds=3600, verbose=True): """Returns true if the file modification date > max_days / max_seconds ago or if the file does not exist""" if not os.path.isfile(filename): return True file_stats = os.stat(filename) modify_date = file_stats.st_mtime utc_now = util.get_utcnow() time_diff = utc_now - datetime.fromtimestamp(modify_date) if verbose: print('Time since file {} creation: {}'.format(filename, time_diff)) return (time_diff.days > max_days) or time_diff.seconds > max_seconds
async def get_user_details_by_info(user_info: dict, max_tourney_battle_attempts: int = None, retrieved_at: datetime = None, past_fleet_infos: entity.EntitiesData = None) -> list: is_past_data = past_fleet_infos is not None and past_fleet_infos user_id = user_info[USER_KEY_NAME] retrieved_at = retrieved_at or util.get_utcnow() tourney_running = tourney.is_tourney_running(utc_now=retrieved_at) if past_fleet_infos: ship_info = {} fleet_info = past_fleet_infos.get(user_info.get(fleet.FLEET_KEY_NAME)) else: _, ship_info = await ship.get_inspect_ship_for_user(user_id) fleet_info = await __get_fleet_info_by_user_info(user_info) user_name = __get_user_name_as_text(user_info) is_in_tourney_fleet = fleet.is_tournament_fleet(fleet_info) and tourney_running attempts = __get_tourney_battle_attempts(user_info, retrieved_at) if attempts and max_tourney_battle_attempts: attempts_left = max_tourney_battle_attempts - int(attempts) else: attempts_left = None details = { 'Account created': __get_timestamp_as_text(user_info, 'CreationDate', retrieved_at), 'Last login': __get_timestamp_as_text(user_info, 'LastLoginDate', retrieved_at), 'Fleet': __get_fleet_name_and_rank_as_text(user_info, fleet_info), 'Division': fleet.get_division_name_as_text(fleet_info), 'Joined fleet': __get_fleet_joined_at_as_text(user_info, fleet_info, retrieved_at), 'Trophies': __get_trophies_as_text(user_info), 'League': __get_league_as_text(user_info), 'Stars': __get_stars_as_text(user_info, is_in_tourney_fleet, attempts_left), 'Crew donated': __get_crew_donated_as_text(user_info, fleet_info), 'Crew borrowed': __get_crew_borrowed_as_text(user_info, fleet_info), 'PVP win/lose/draw': __get_pvp_attack_stats_as_text(user_info), 'Defense win/lose/draw': __get_pvp_defense_stats_as_text(user_info), 'Level': await __get_level_as_text(ship_info), 'Status': __get_ship_status_as_text(ship_info), 'User type': __get_user_type_as_text(user_info) } lines = [f'**```{user_name}```**```'] for detail_name, detail_value in details.items(): if detail_value is not None: lines.append(f'{detail_name} - {detail_value}') if is_past_data: lines.append(f'``````{util.get_historic_data_note(retrieved_at)}```') else: lines[-1] += '```' return lines
async def update(self, channel: discord.TextChannel = None, can_post: bool = None, latest_message: discord.Message = None, change_mode: AutoDailyChangeMode = None, store_now_as_created_at: bool = False) -> bool: settings: Dict[str, object] = {} update_channel = channel is not None and channel != self.channel update_can_post = can_post is not None and can_post != self.can_post update_latest_message = ( latest_message is None and store_now_as_created_at) or ( latest_message is not None and latest_message.id != self.latest_message_id and (latest_message.edited_at or latest_message.created_at) != self.latest_message_modified_at) update_change_mode = change_mode is not None and change_mode != self.change_mode if update_channel: settings[_COLUMN_NAME_DAILY_CHANNEL_ID] = channel.id if update_can_post: settings[_COLUMN_NAME_DAILY_CAN_POST] = can_post if update_latest_message: if store_now_as_created_at: settings[ _COLUMN_NAME_DAILY_LATEST_MESSAGE_CREATED_AT] = util.get_utcnow( ) else: settings[ _COLUMN_NAME_DAILY_LATEST_MESSAGE_ID] = latest_message.id settings[ _COLUMN_NAME_DAILY_LATEST_MESSAGE_CREATED_AT] = latest_message.created_at settings[ _COLUMN_NAME_DAILY_LATEST_MESSAGE_MODIFIED_AT] = latest_message.edited_at or latest_message.created_at if update_change_mode: settings[_COLUMN_NAME_DAILY_CHANGE_MODE] = change_mode success = await _db_update_server_settings(self.guild_id, settings) if success: if update_channel: self.__channel = channel if update_can_post: self.__can_post = settings.get(_COLUMN_NAME_DAILY_CAN_POST) if update_latest_message: self.__latest_message_id = settings.get( _COLUMN_NAME_DAILY_LATEST_MESSAGE_ID) self.__latest_message_created_at = settings.get( _COLUMN_NAME_DAILY_LATEST_MESSAGE_CREATED_AT) self.__latest_message_modified_at = settings.get( _COLUMN_NAME_DAILY_LATEST_MESSAGE_MODIFIED_AT) if update_change_mode: self.__delete_on_change = settings[ _COLUMN_NAME_DAILY_CHANGE_MODE] return success
def db_try_set_schema_version(version: str) -> bool: prior_version = db_get_schema_version() utc_now = util.get_utcnow() modify_date_for_db = util.db_convert_timestamp(utc_now) version_for_db = util.db_convert_text(version) if prior_version == '': query = f'INSERT INTO settings (settingname, modifydate, settingtext) VALUES (\'schema_version\', {modify_date_for_db}, {version_for_db})' else: where_string = util.db_get_where_string('settingname', 'schema_version', is_text_type=True) query = f'UPDATE settings SET settingtext = {version_for_db}, modifydate = {modify_date_for_db} WHERE {where_string}' success = db_try_execute(query) return success
def get_data(self) -> (dict, dict, datetime): utc_now = util.get_utcnow() if self.__is_data_outdated(utc_now): self.__update_data() can_read = False while not can_read: can_read = not self.__get_write_requested() if not can_read: time.sleep(random.random()) self.__add_reader() result = self.__read_data() self.__remove_reader() return result
async def get_full_fleet_info_as_text( fleet_info: dict, past_fleets_data: dict = None, past_users_data: dict = None, past_retrieved_at: datetime = None) -> (list, list): """Returns a list of lines for the post, as well as the paths to the spreadsheet created""" fleet_id = fleet_info[FLEET_KEY_NAME] fleet_name = fleet_info[FLEET_DESCRIPTION_PROPERTY_NAME] is_past_data = past_fleets_data and past_users_data and past_retrieved_at if is_past_data: retrieved_at = past_retrieved_at if fleet_info.get('CurrentAllianceName') is None: current_fleet_info = await _get_fleet_info_by_id(fleet_id) if current_fleet_info[ FLEET_DESCRIPTION_PROPERTY_NAME] != fleet_info[ FLEET_DESCRIPTION_PROPERTY_NAME]: fleet_info['CurrentAllianceName'] = current_fleet_info[ FLEET_DESCRIPTION_PROPERTY_NAME] fleet_users_infos = { user_id: user_info for user_id, user_info in past_users_data.items() if user_info.get(FLEET_KEY_NAME) == fleet_id } else: retrieved_at = util.get_utcnow() fleet_info = await _get_fleet_info_by_id(fleet_id) fleet_users_infos = await _get_fleet_users_by_id(fleet_id) post_content = await _get_fleet_details_by_info(fleet_info, fleet_users_infos, retrieved_at=retrieved_at, is_past_data=is_past_data) fleet_sheet_contents = _get_fleet_sheet_lines(fleet_users_infos, retrieved_at) fleet_sheet_file_name = excel.get_file_name(fleet_name, retrieved_at, consider_tourney=False) fleet_sheet_path_current = excel.create_xl_from_data( fleet_sheet_contents, fleet_name, retrieved_at, FLEET_SHEET_COLUMN_TYPES, file_name=fleet_sheet_file_name) file_paths = [fleet_sheet_path_current] return post_content, file_paths
async def get_autodaily_settings( bot: discord.ext.commands.Bot, guild_id: int = None, can_post: bool = None, no_post_yet: bool = False) -> List[AutoDailySettings]: utc_now = util.get_utcnow() if guild_id: autodaily_settings_collection = [(await GUILD_SETTINGS.get(bot, guild_id))] else: autodaily_settings_collection = [ settings for settings in GUILD_SETTINGS.autodaily_settings if settings.channel is not None ] result = [] for autodaily_settings in autodaily_settings_collection: if not (no_post_yet and autodaily_settings.latest_message_created_at): result.append(autodaily_settings) return result
async def set_settings(settings: Dict[str, Tuple[object, datetime]]) -> bool: __log_db_function_enter('set_settings', settings=settings) utc_now = util.get_utcnow() if settings: query_lines = [] args = [] success = True current_settings = await get_settings(settings.keys()) for setting_name, (value, modified_at) in settings.items(): query = '' column_name = None if isinstance(value, bool): column_name = 'settingboolean' value = util.db_convert_boolean(value) elif isinstance(value, int): column_name = 'settingint' elif isinstance(value, float): column_name = 'settingfloat' elif isinstance(value, datetime): column_name = 'settingtimestamptz' value = util.db_convert_timestamp(value) else: column_name = 'settingtext' value = util.db_convert_text(value) current_value, db_modify_date = current_settings[setting_name] modify_date = db_modify_date or utc_now setting_name = util.db_convert_text(setting_name) if current_value is None and db_modify_date is None: query = f'INSERT INTO settings ({column_name}, modifydate, settingname) VALUES ({value}, \'{modified_at}\', {setting_name});' elif current_value != value: query = f'UPDATE settings SET {column_name} = {value}, modifydate = \'{modified_at}\' WHERE settingname = {setting_name};' if query: query_lines.append(query) args.extend([value, modified_at, setting_name]) success = not query_lines or await try_execute('\n'.join(query_lines)) if success: __settings_cache.update(settings) return success else: return True
async def get_dropship_text(bot: commands.Bot = None, guild: discord.Guild = None, daily_info: dict = None, utc_now: datetime = None, language_key: str = 'en') -> Tuple[List[str], List[discord.Embed], bool]: utc_now = utc_now or util.get_utcnow() if not daily_info: daily_info = await core.get_latest_settings(language_key=language_key) collections_designs_data = await crew.collections_designs_retriever.get_data_dict3() chars_designs_data = await crew.characters_designs_retriever.get_data_dict3() items_designs_data = await item.items_designs_retriever.get_data_dict3() rooms_designs_data = await room.rooms_designs_retriever.get_data_dict3() trainings_designs_data = await training.trainings_designs_retriever.get_data_dict3() try: daily_msg = _get_daily_news_from_data_as_text(daily_info) dropship_msg = await _get_dropship_msg_from_data_as_text(daily_info, chars_designs_data, collections_designs_data) merchantship_msg = await _get_merchantship_msg_from_data_as_text(daily_info, items_designs_data, trainings_designs_data) shop_msg = await _get_shop_msg_from_data_as_text(daily_info, chars_designs_data, collections_designs_data, items_designs_data, rooms_designs_data, trainings_designs_data) sale_msg = await _get_sale_msg_from_data_as_text(daily_info, chars_designs_data, collections_designs_data, items_designs_data, rooms_designs_data, trainings_designs_data) daily_reward_msg = await _get_daily_reward_from_data_as_text(daily_info, items_designs_data, trainings_designs_data) except Exception as e: pp = pprint.PrettyPrinter(indent=4) pp.pprint(daily_info) print(e) return [], False parts = [dropship_msg, merchantship_msg, shop_msg, sale_msg, daily_reward_msg] lines = list(daily_msg) for part in parts: lines.append(settings.EMPTY_LINE) lines.extend(part) title = 'Pixel Starships Dropships' footer = f'Star date {util.get_star_date(utc_now)}' description = ''.join(daily_msg) fields = [(part[0], '\n'.join(part[1:]), False) for part in parts] sprite_url = await sprites.get_download_sprite_link(daily_info['NewsSpriteId']) colour = util.get_bot_member_colour(bot, guild) embed = util.create_embed(title, description=description, fields=fields, image_url=sprite_url, colour=colour, footer=footer) return lines, [embed], True