def __init__(self, bot): self.wowsnews_jp = WowsNewsJP() self.bot = bot statuses = self.wowsnews_jp.get_latest_statuses() self.latest_id = statuses[0].id self.logger = Logger(__name__) self.check_task.start()
def __init__(self, db_path): self.database = Database(db_path) self.logger = Logger(self.__class__.__name__) # if db file not found or empty, create file try: with open(db_path, 'rb') as f: if f.read() == b'': self._create_table() except Exception as e: self.logger.info('Database not found.') self._create_table()
class Weather(commands.Cog): __slots__ = ('bot', 'logger', 'last_sent_date') def __init__(self, bot, logger=None): self.bot = bot self.logger = Logger(__name__) if logger is None else logger self.last_sent_date = None self.weather_task.start() @commands.command() async def weather(self, ctx): """ 天気を教えるよ! """ self.logger.debug('Creating weather embed.') scraper = Scrape_weather() e, c = scraper.embed_builder() self.logger.debug('Created weather embed.') await ctx.send('```' + c + '```', embed=e) del scraper, e, c @tasks.loop(seconds=50) async def weather_task(self): now = datetime.datetime.now(tz=tz) if not (now.hour == 6 and now.minute == 30): return if self.last_sent_date == now.date(): return else: self.last_sent_date = now.date() scraper = Scrape_weather() e, c = scraper.embed_builder() for guild in self.bot.guilds: for channel in guild.channels: if channel.name == 'main': await channel.send('```' + c + '```', embed=e) del scraper, e, c
class Listener(commands.Cog): __slots__ = ('bot', 'logger') def __init__(self, bot, logger=None): self.bot = bot self.logger = Logger(__name__) if logger is None else logger @commands.Cog.listener() async def on_ready(self): print('----------') print('Logged in as') print('name:\t' + self.bot.user.name) print('id:\t' + str(self.bot.user.id)) print('----------') @commands.Cog.listener() async def on_message(self, mes): self.logger.info( f'Message:{mes.content} author:{mes.author.name} id:{mes.author.id}' ) # if mes.attachments: # for attachment in mes.attachments: # try: # await attachment.save(attachmentpath + str(attachment.id) + attachment.filename, seek_begin=True, use_cached=True) # except: # continue @commands.Cog.listener() async def on_command_error(self, ctx, error): pass @commands.Cog.listener() async def on_member_remove(self, member): self.logger.info(f'Member removed:{member.name} id:{member.id}') @commands.Cog.listener() async def on_raw_message_delete(self, payload): message = payload.cached_message if message: self.logger.info( f'Message deleted:{message.content} author:{message.author.id}' ) else: self.logger.info('Message deleted. No content found.')
class Twitter_manager(commands.Cog): """ twitter_manager class. Responsible for interactions with twitter. """ def __init__(self, bot): self.wowsnews_jp = WowsNewsJP() self.bot = bot statuses = self.wowsnews_jp.get_latest_statuses() self.latest_id = statuses[0].id self.logger = Logger(__name__) self.check_task.start() @tasks.loop(seconds=30) async def check_task(self): self.logger.debug('Checking for latest tweets.') statuses = self.wowsnews_jp.get_latest_statuses() # return if up to date if self.latest_id == statuses[0].id: self.logger.debug('Twitter_manager is up to date.') return to_send = [] for status in statuses: # stop if id is the one saved if status.id == self.latest_id: self.logger.debug('This tweet has already been sent.') break to_send.insert(0, status) for guild in self.bot.guilds: for channel in guild.channels: if channel.name == 'wows-news': for status in to_send: await channel.send( f'{status.text}\n{_create_url(status)}') self.latest_id = statuses[0].id self.logger.debug('Finished sending.') @check_task.before_loop async def before_check(self): await self.bot.wait_until_ready() await asyncio.sleep(1)
class WowsApi: def __init__(self, application_id): self.application_id = application_id self.logger = Logger(self.__class__.__name__) def get_warships_count(self): """ Get the number of warships registered in wows API. """ self.logger.debug('Counting warships.') response = requests.get('https://api.worldofwarships.asia/wows/encyclopedia/ships/?' \ f'application_id={self.application_id}&limit=1') if response.status_code != 200: self.logger.critical('Invalid status code.') return text = response.text text_json = json.loads(text) if text_json['status'] != 'ok': self.logger.critical('Invalid status.') return warships_count = text_json['meta']['total'] self.logger.debug(f'Found {warships_count} ships.') return warships_count def get_warships(self, pages): """ Get list of warships as list of Warship instance. """ self.logger.debug(f'Getting warships for {pages} pages.') warship_list = [] for i in range(pages): response = requests.get('https://api.worldofwarships.asia/wows/encyclopedia/ships/?' \ f'application_id={self.application_id}&page_no={i+1}&language=ja') if response.status_code != 200: self.logger.critical('Invalid status code.') return text = response.text text_json = json.loads(text) if text_json['status'] != 'ok': self.logger.critical('Invalid status code.') return values = text_json['data'].values() for v in values: temp = Warship.warship_from_dict(v) warship_list.append(temp) self.logger.debug(f'Created {len(warship_list)} warships.') return warship_list def get_ship_profile(self, ship_id): """ Get ShipParam instance of given ship id. """ response = requests.get('https://api.worldofwarships.asia/wows/encyclopedia/shipprofile/?' \ f'application_id={self.application_id}&ship_id={ship_id}') if response.status_code != 200: self.logger.critical('Invalid status code.') return text = response.text text_json = json.loads(text) if text_json['status'] != 'ok': self.logger.debug('Invalid status code.') return param = text_json['data'][str(ship_id)] shipparam = ShipParam.shipparam_from_dict(param) return shipparam def information_about_encyclopedia(self): """ Get when encyclopedia was last updated. """ self.logger.debug('Fetching last ships_updated_at.') response = requests.get('https://api.worldofwarships.asia/wows/encyclopedia/info/?' \ f'application_id={self.application_id}&fields=ships_updated_at') if response.status_code != 200: self.logger.critical('Invalid status code.') return text = response.text text_json = json.loads(text) if text_json['status'] != 'ok': self.logger.debug('Invalid status code.') return version = text_json['data']['ships_updated_at'] self.logger.debug(f'Encyclopedia was last updated at {version}.') return version
class Database: """ Database class. """ def __init__(self, db_path: str, logger=None): self.db_path = db_path self.logger = Logger(__name__) if logger is None else logger def fetchone(self, command: str, values=()): """ Get one result from database. """ self.logger.debug(f'Executing script on {self.db_path}.') # connect and execute script try: conn = self._create_connection() cursor = conn.cursor() cursor.execute(command, values) result = cursor.fetchone() # sql errors except Exception as e: self.logger.critical(e) self.logger.critical(traceback.format_exc()) result = None # close connection finally: self._close_connection(conn) self.logger.debug(f'Executing script finished on {self.db_path}.') return result def execute(self, command: str, values=()): """ Get one result from database. """ self.logger.debug(f'Executing script on {self.db_path}.') # connect and execute script try: conn = self._create_connection() cursor = conn.cursor() cursor.execute(command, values) # sql errors except Exception as e: self.logger.critical(e) self.logger.critical(traceback.format_exc()) result = None # close connection finally: self._close_connection(conn) self.logger.debug(f'Executing script finish on {self.db_path}.') def executescript(self, command: str): """ Execute script on database. """ self.logger.debug(f'Executing script on {self.db_path}.') # connect and execute script try: conn = self._create_connection() cursor = conn.cursor() cursor.executescript(command) # sql errors except Exception as e: self.logger.critical(e) self.logger.critical(traceback.format_exc()) result = None # close connection finally: self._close_connection(conn) self.logger.debug(f'Executing script finished on {self.db_path}.') def _create_connection(self) -> Connection: self.logger.debug('Connecting to database.') conn = sqlite3.connect(self.db_path) self.logger.debug('Connected to database.') return conn def _close_connection(self, conn): self.logger.debug('Closing connection to database.') conn.commit() conn.close() self.logger.debug('Closed connection to database.')
def __init__(self, db_path: str, logger=None): self.db_path = db_path self.logger = Logger(__name__) if logger is None else logger
class Roles(commands.Cog): __slots__ = ('bot', 'logger') def __init__(self, bot): self.bot = bot self.logger = Logger(__name__) @commands.group() async def roles(self, ctx): """ 役職をいじれるよ! """ if ctx.invoked_subcommand is None: await ctx.send('コマンドも教えてね!') @roles.command() async def create(self, ctx, name, color='red'): """ 役職を作るよ! roles create '役職の名前' '色(英語で教えてね!)' """ try: color = matplotlib.colors.cnames.get(color) except IndexError: await ctx.send('名前と色も教えてね!') return color = discord.Colour(int(str(color)[1:], 16)) await ctx.guild.create_role(name=name, colour=color) await ctx.send(name + ', いっちょあがり!') # @roles.command() # async def random(self, ctx, target=None): # if target is None: # await ctx.send('役職誰にあげるのかわかんないよ〜') # return # elif not check_user(target): # await ctx.send('誰この人!') # return # user = get_user(name=target) # give_role(user, role) # await ctx.send('じゃーん!何あげたでしょー') @roles.command() async def listnotused(self, ctx): """ 使ってない役職の一覧を貼るよ! """ self.logger.debug('Processing listnotused.') b = False for role in ctx.guild.roles: if role.is_default(): continue for member in ctx.guild.members: if role in member.roles: b = True if not (b): await ctx.send(role.name + ',\t誰も使ってないよ!') b = False await ctx.send('はい、終わり!') @roles.command() async def deletenotused(self, ctx): """ 使ってない役職をすべて削除するよ! """ self.logger.debug('Processing deletenotused.') b = False for role in ctx.guild.roles: if role.is_default(): continue for member in ctx.guild.members: if role in member.roles: b = True if not (b): self.logger.debug('Deleting role.') await ctx.send(role.name + ', バーン!') await role.delete() self.logger.debug('Deleted role.') b = False self.logger.debug('Processed deletenotused.') await ctx.send('はい、終わり!') # @roles.command() # async def hoist(self, ctx): # """ 全ての役職をオンラインメンバーとは別に役職メンバーを表示するよ! """ # for role in ctx.guild.roles: # if not role.hoist: # await role.edit(hoist=True) # await ctx.send(':thumbsup:') @roles.command() async def mentionoff(self, ctx): """ 全ての役職をメンション不可能にするよ! """ for role in ctx.guild.roles: if role.mentionable: await role.edit(mentionable=False) await ctx.send(':thumbsup:')
def __init__(self, key): self.logger = Logger(self.__class__.__name__) self.api = WowsApi(key)
class WowsCog(commands.Cog): def __init__(self, bot): self.bot = bot self.logger = Logger(self.__class__.__name__) self.wowsdb = Wows_database(db_path) @commands.command() async def param(self, ctx, *, name): """ そのぽふねのデータ教えてあげる! """ self.logger.info('Recieved param command.') if name is None: await ctx.send('どのぽふねのデータがほしいの?\n日本艦は漢字で登録されてるから気を付けて!') return result = self.wowsdb.get_warship(name) # exact match if isinstance(result, Warship): self.logger.info('Found exact match for a warship.') embed = self.embed_builder(result) await ctx.send(embed=embed) #another exact match elif len(result) == 1: self.logger.info('Found exact match for a warship.') embed = self.embed_builder(result[0]) await ctx.send(embed=embed) elif not result: self.logger.debug('No result found.') await ctx.send('そんなもんねーよ!あ、日本艦は漢字で書いてね♡') return else: self.logger.info('Found multiple matches.') name_list = map(lambda ship: ship.name, result) mes = 'いっぱいヒットしちゃったよ~\n' \ '```' + ', '.join(name_list) + '```' await ctx.send(mes) def embed_builder(self, warship: Warship): self.logger.debug('Creating embed.') d = warship.to_dict() name = d['name'] tier = d['tier'] nation = d['nation'][:2] shiptype = d['shiptype'] embed = Embed(colour=0x793DB6, title=d['name'], description=f'T{tier} {nation.upper()} {shiptype}') a = embed.add_field s = self.wowsdb.get_shipparam(warship.ship_id) s = s.to_dict() mobility = ast.literal_eval(s['mobility']) if mobility is not None: rudder_time = mobility['rudder_time'] turning_radius = mobility['turning_radius'] max_speed = mobility['max_speed'] a(name='機動性', value=f'{max_speed}kts 転舵時間{rudder_time}s 転舵半径{turning_radius}m', inline=False) hull = ast.literal_eval(s['hull']) if hull is not None: torp_barrels = hull['torpedoes_barrels'] health = hull['health'] artillery_barrels = hull['artillery_barrels'] if torp_barrels == 0: a(name='船体性能', value=f'体力{health}({health+tier*350}) 主砲{artillery_barrels}基', inline=False) else: a(name='船体性能', value= f'体力{health}({health+tier*350}) 主砲{artillery_barrels}基 魚雷{torp_barrels}基', inline=False) artillery = ast.literal_eval(s['artillery']) if artillery is not None: max_dispersion = artillery['max_dispersion'] shot_delay = artillery['shot_delay'] shells = artillery['shells'] for key, shell in shells.items(): if key == 'HE': a(name=f'{key}', value= f'{shell["bullet_speed"]}ms^-1 最大{shell["damage"]} 装填{shot_delay}s 発火率{shell["burn_probability"]}%', inline=False) else: a(name=f'{key}', value= f'{shell["bullet_speed"]}ms^-1 最大{shell["damage"]} 装填{shot_delay}s', inline=False) torpedoes = ast.literal_eval(s['torpedoes']) if torpedoes is not None: visibility_dist = torpedoes['visibility_dist'] distance = torpedoes['distance'] reload_time = torpedoes['reload_time'] torp_speed = torpedoes['torpedo_speed'] max_damage = torpedoes['max_damage'] a(name='魚雷性能', value= f'被発見{visibility_dist}km 装填{reload_time}s 雷速{torp_speed}kts^-1 最大{max_damage}', inline=False) fire_control = ast.literal_eval(s['fire_control']) if fire_control is not None: distance = fire_control['distance'] distance_increase = fire_control['distance_increase'] a(name='射程', value=f'{distance}km', inline=False) concealment = ast.literal_eval(s['concealment']) if concealment is not None: detect_dist_plane = concealment['detect_distance_by_plane'] detect_dist_ship = concealment['detect_distance_by_ship'] if tier < 8: best_concealment = detect_dist_ship * 0.9 * 0.97 else: best_concealment = detect_dist_ship * 0.9 * 0.9 * 0.97 best_concealment = round(best_concealment, 2) a(name='隠蔽性', value= f'航空発見{detect_dist_plane}km 艦艇発見{detect_dist_ship}km 最良{best_concealment}km(誤差有)', inline=False) del a return embed
class Wows_database: """ Scrapes and registers data into database. """ __slots__ = ('database', 'logger') def __init__(self, db_path): self.database = Database(db_path) self.logger = Logger(__name__) # if db file not found or empty, create file try: with open(db_path, 'rb') as f: if f.read() == b'': self._create_table() except Exception as e: self.logger.info('Database not found.') self._create_table() async def update(self): """ Update database. """ self.logger.info('Update started.') try: # await self._update_medium() # await self._update_facebook() await self._update_hp() except Exception: self.logger.critical(f'Exception while updating: {traceback.format_exc()}') self.logger.info('Update finished.') def _create_table(self): self.logger.debug('Creating wows database table.') self.database.executescript(""" CREATE TABLE wowsnews( id INTEGER PRIMARY KEY AUTOINCREMENT, source TEXT, title TEXT, description TEXT, url TEXT, img TEXT ); """) self.logger.debug('Created wows database table.') def _get_latest(self, source:str): """ Get latest news stored in database. Returns ------- res : tuple, None """ self.logger.debug(f'Starting _get_latest source: {source}') res = self.database.fetchone('SELECT * FROM wowsnews WHERE source==? ORDER BY id DESC', (source,)) self.logger.debug(f'_get_latest result: {res}') return res async def _update_hp(self): """ Check for new articles, if found update db. """ self.logger.info('Updating wows hp.') # get data and data from db. try: data = get_hp_articles() except ScrapingException: self.logger.critical('Scraping failed.') return data_db = self._get_latest('wowshomepage') # if database is up to date return if _is_same_data(data_db, data[0]): self.logger.info('Wows hp is up to date.') return # if same url already exists in database, return elif self._url_exists(data[0][3]): self.logger.info('Article with same url exists.') return # update db self.logger.info('Saving data.') try: self.database.execute('INSERT INTO wowsnews(source, title, description, url, img) VALUES(?, ?, ?, ?, ?)', data[0]) except Exception as e: self.logger.critical(f'Inserting into database failed: {e}') return self.logger.info('Updated wows hp.') async def _update_facebook(self): """ Check for new articles, if found update db. """ self.logger.info('Updating facebook.') try: data = get_facebook_articles() except ScrapingException: self.logger.critical('Scraping failed.') return data_db = self._get_latest('facebook') # if up to date, return if _has_same_url(data_db, data[0]): self.logger.info('Facebook is up to date.') return # counter shows how many articles to update counter = 0 for d in data: # if data is most recent in db if d == data_db: break counter += 1 # data.reverse() not working, so using temp.reverse() temp = data temp.reverse() news = temp[:counter] # update db try: for new in news: # continue if url already exists in database if self._url_exists(new[3]): self.logger.info('Article with same url exists.') continue self.database.execute('INSERT INTO wowsnews(source, title, description, url, img) VALUES(?, ?, ?, ?, ?)', new) except Exception as e: self.logger.critical(f'Inserting into database failed: {e}') return self.logger.info('Updated facebook.') async def _update_medium(self): """ Check for new articles, if found update db. """ self.logger.info('Updating medium.') try: data = get_medium_articles() except ScrapingException: self.logger.critical('Scraping failed.') return # get latest data in database data_db = self._get_latest('medium') # if up to date, return if _is_same_data(data_db, data[0]): self.logger.info('Medium is up to date.') return # counter shows how many articles to update counter = 0 for d in data: # if url is most recent in db if d == data_db: break counter += 1 # data.reverse() not working, so using temp reverse() temp = data temp.reverse() news = temp[:counter] try: for new in news: self.database.execute('INSERT INTO wowsnews(source, title, description, url, img) VALUES(?, ?, ?, ?, ?)', new) except Exception as e: self.logger.critical(f'Inserting into database failed: {e}') return self.logger.info('Updated medium.') def _url_exists(self, url:str): self.logger.debug('Checking if url already exists in database.') self.logger.debug(f'url is {url[10:]}') try: res = self.database.fetchone(f'SELECT * FROM wowsnews WHERE url==?', (url,)) except Exception as e: self.logger.critical(f'Fetching datbase failed: {e}') res = None self.logger.debug(f'Result: {res}') if not res: return False return True
def __init__(self, key, db_path): self.logger = Logger(self.__class__.__name__) self.logger.debug('Initializing wows class.') self.wowsapi = WowsApi(key) self.wowsdb = Wows_database(db_path)
class WorldofWarships: def __init__(self, key, db_path): self.logger = Logger(self.__class__.__name__) self.logger.debug('Initializing wows class.') self.wowsapi = WowsApi(key) self.wowsdb = Wows_database(db_path) def update(self): # check version version_db = self.wowsdb.get_db_version() version_api = self.wowsapi.get_api_version() # return if version is up to date. if version_db == version_api: self.logger.debug( f'Returning as database has latest version {version_db}.') return self.update_warships() self.update_shipparams() # finally update version self.wowsdb.update_version(version_api) def update_warships(self): """ Update warships table in database. """ self.logger.debug('Updating warships in database.') warships_count = self.wowsapi.get_warships_count() pages = math.ceil(warships_count / 100) warships_api = self.wowsapi.get_warships(pages) warships_db = self.wowsdb.get_warships() warships_db_ids = list( map(lambda warship: warship.ship_id, warships_db)) for warship in warships_api: # if warship not found in db, register if warship.ship_id not in warships_db_ids: self.wowsdb.register_ship(warship) else: index = warships_db_ids.index(warship.ship_id) warship_db = warships_db[index] assert warship.ship_id == warship_db.ship_id # if warship from api differes from warship in db, update if warship != warship_db: self.wowsdb.update_warship(warship) self.logger.debug('Warships updated.') def update_shipparams(self): """ Update shipparameters table in database. """ self.logger.debug('Updating shipparams in database.') ship_ids = self.wowsdb.get_ship_ids() for ship_id in ship_ids: param = self.wowsapi.get_ship_profile(ship_id[0]) self.wowsdb.update_shipparam(param) self.logger.debug('Ship parameters updated.')
def __init__(self, application_id): self.application_id = application_id self.logger = Logger(self.__class__.__name__)
def __init__(self, bot): self.bot = bot self.logger = Logger(self.__class__.__name__) self.wowsdb = Wows_database(db_path)
def __init__(self, bot, logger=None): self.bot = bot self.logger = Logger(__name__) if logger is None else logger
class NewRoles(commands.Cog): def __init__(self, bot): self.bot = bot self.logger = Logger(__name__) @commands.command() async def dl(self, ctx): """ Temporal command for deleting guild activity roles. """ ceiling = ctx.guild.get_role(632304461087506442) roles = ctx.guild.roles # for role in roles: # if role.position is not 0 and \ # role < ceiling: # self.logger.debug(f'deleting {role}') # await role.delete() # self.logger.debug('done.') roles = await self._get_guild_activity_roles() for role in roles: self.logger.debug(f'deleting {role}') await role.delete() self.logger.debug('done.') @commands.command() async def role_task(self, ctx): self.logger.debug('starting role_task.') members = ctx.guild.members self.logger.debug(f'found {len(members)} members.') guild_activity_roles = await self._get_guild_activity_roles() self.logger.debug('got guild activity roles.') # give or remove roles for member in members: await self._configure_roles(member) # remove unused roles await self._remove_unused_activity_roles(guild_activity_roles) # # configure hierarchy # guild_activity_roles = await self._get_guild_activity_roles() # await self._configure_hierarchy(guild_activity_roles) self.logger.debug('finished role_task.') async def _configure_roles(self, member): """ Give or remove activity roles of the member. """ self.logger.debug('configuring roles.') activities = member.activities # member's activities anames = [a.name for a in activities] activity_roles = await self._get_activity_roles( member) # member's activity roles given rnames = [r.name for r in activity_roles] self.logger.debug( f'{len(anames)} activity names and {len(rnames)} role names found.' ) # removing process for rname in rnames: self.logger.debug(f'processing role name {rname}.') # if member has a role which the member does not play, remove if rname not in anames: self.logger.debug('removing role.') role = self._get_role(activity_roles, rname) if not role: self.logger.critical('role not found.') return await member.remove_role(role) # else, member has a role which the member plays, so pass # giving process for aname in anames: # if it was Custom status, you can't fetch the status name # thus skip giving process if aname == 'Custom Status': continue self.logger.debug(f'giving role named {aname}.') # if member has activity which the member does not have a role of, give that if aname not in rnames: self.logger.debug('giving role.') role = await self._get_opt_role(aname) self.logger.debug('adding role.') await member.add_roles(role) self.logger.debug('added role.') # else, member has activity and has role of, pass async def _get_opt_role(self, aname): """ Get a role where name is aname. If that role exists, return that. If it does not exist, create one and return that. """ self.logger.debug('finding for optimum role.') roles = await self._get_guild_activity_roles() for role in roles: if role.name == aname: return role role = await self._create_role(aname) return role async def _create_role(self, aname): """ Return role with given name aname and position where one larger than role_floor. """ self.logger.debug('creating role.') guild = get_guild(self.bot) self.logger.debug('found guild.') role = await guild.create_role(name=aname, hoist=True) self.logger.debug(f'created role {aname}.') floor_role = get_guild(self.bot).get_role(_activity_role_floor) self.logger.debug('found floor_role.') self.logger.debug(f'floor position is {floor_role.position}.') position = floor_role.position # role.edit does not work sometimes while position is not role.position: self.logger.debug( f'position is {position} and role.position is {role.position}') await role.edit(position=position) self.logger.debug('returning role.') return role def _get_role(self, activity_roles, rname): """ Get role where name is rname in activity_roles. Returns None if no role found. """ for arole in activity_roles: if arole.name == rname: return arole return None # merge _get_guild_activity_roles() and _get_activity_roles() later async def _get_guild_activity_roles(self): """ Return list of activity roles of a given guild. """ self.logger.debug('finding for guild activity roles.') guild = get_guild(self.bot) roles = guild.roles floor = guild.get_role(_activity_role_floor) ceiling = guild.get_role(_activity_role_ceiling) self.logger.debug(f'{len(roles)} roles found.') activity_roles = [] self.logger.debug( f'floor position is {floor.position} and ceiling position is {ceiling.position}.' ) for role in roles: if role < ceiling \ and floor < role: activity_roles.append(role) self.logger.debug( f'returning roles list with {len(activity_roles)} items.') return activity_roles async def _get_activity_roles(self, member): """ Return list of activity roles of a given member. """ roles = member.roles guild = get_guild(self.bot) floor = guild.get_role(_activity_role_floor) ceiling = guild.get_role(_activity_role_ceiling) activity_roles = [] for role in roles: if role < ceiling \ and floor < role: activity_roles.append(role) return activity_roles async def _remove_unused_activity_roles(self, guild_activity_roles): """ Removes all unused activity roles. """ for role in guild_activity_roles: if not role.members: await role.delete() async def _configure_hierarchy(self, guild_activity_roles): """ Configures hierarchy of guild's activity roles. Hirarchy will be configured by its number of players. """ self.logger.debug('Configuring hierarchy.') new_pos = get_guild(self.bot).get_role(_activity_role_floor).position # sort roles in order of members roles = sorted(guild_activity_roles, key=lambda role: len(role.members)) roles.reverse() for role in roles: # edit role if needed self.logger.debug( f'{role} is at {role.position} and new position is {new_pos}') if not role.position == new_pos: await role.edit(position=new_pos) pos = +1
def __init__(self, bot, logger=None): self.bot = bot self.logger = Logger(__name__) if logger is None else logger self.last_sent_date = None self.weather_task.start()
def __init__(self, bot): self.bot = bot self.logger = Logger(__name__)
class Wows_database: """ Wows_database class. Responsible for interactions with database. """ __slots__ = ('database', 'logger') def __init__(self, db_path): self.database = Database(db_path) self.logger = Logger(self.__class__.__name__) # if db file not found or empty, create file try: with open(db_path, 'rb') as f: if f.read() == b'': self._create_table() except Exception as e: self.logger.info('Database not found.') self._create_table() def _create_table(self): self.logger.debug('Creating wows database table.') self.database.executescript(""" CREATE TABLE players( discord_id INTEGER PRIMARY KEY AUTOINCREMENT, wows_id INTEGER, in_game_name TEXT, clan TEXT ); CREATE TABLE version ( version_id INTEGER PRIMARY KEY AUTOINCREMENT, ships_updated_at INTGER ); CREATE TABLE updates( id INTEGER PRIMARY KEY AUTOINCREMENT, ship_id INTEGER, diff TEXT ); CREATE TABLE warships( price_gold INTEGER, ship_id_str TEXT, has_demo_profile INTEGER, images TEXT, modules TEXT, modules_tree TEXT, nation TEXT, is_premium INTEGER, ship_id INTEGER PRIMARY KEY, price_credit INTEGER, default_profile TEXT, upgrades TEXT, tier INTEGER, next_ships TEXT, mod_slots INTEGER, type TEXT, is_special INTEGER, name TEXT ); CREATE TABLE shipparams( engine TEXT, anti_aircraft TEXT, mobility TEXT, hull TEXT, atbas TEXT, artillery TEXT, torpedoes TEXT, fighters TEXT, ship_id INTEGER PRIMARY KEY, fire_control TEXT, weaponry TEXT, flight_control TEXT, concealment REAL, armour TEXT, dive_bomber TEXT ); INSERT INTO version(ships_updated_at) VALUES('initial value'); """) self.logger.debug('Created wows database table.') def get_db_version(self): """ Get the version of database. """ command = 'SELECT ships_updated_at from version ORDER BY version_id desc' result = self.database.fetch(command) version = result[0] self.logger.debug('Returning database version.') return version def update_version(self, version): """ Update version to given version. """ command = 'INSERT INTO version(ships_updated_at) VALUES(?)' self.database.execute(command, (version, )) self.logger.debug('Database updated.') def get_warship(self, name) -> Warship: """ Get information of a warship of given name. If many data match, returns as list of Warship instance. """ self.logger.debug(f'Searching for a warship with {name=}.') # exact match result = self.database.fetch('SELECT * FROM warships WHERE name=?', (name, )) if result: self.logger.debug('Found exact match.') warship = Warship.warship_from_tuple(result) return warship results = self.database.fetch( f'SELECT * FROM warships WHERE name LIKE ?', (f'{name}%', ), count=10) self.logger.debug('Found close match.') warships = list( map(lambda result: Warship.warship_from_tuple(result), results)) return warships def get_warships(self) -> list: """ Get list of warships as list of Warship instance. """ results = self.database.fetch('SELECT * FROM warships', count=-1) warships = list( map(lambda result: Warship.warship_from_tuple(result), results)) return warships def get_ship_ids(self) -> list: """ Get ship ids stored in database as a list. """ result = self.database.fetch('SELECT ship_id from warships', count=-1) return result def get_shipparam(self, ship_id) -> ShipParam: """ Get ship parameters of given ship_id. """ result = self.database.fetch( 'SELECT * FROM shipparams WHERE ship_id=?', (ship_id, )) if not result: return None param = ShipParam.shipparam_from_tuple(result) return param def update_warship(self, warship): """ Update database with given warship. """ self.deregister_ship(warship.ship_id) self.register_ship(warship) def update_shipparam(self, param: ShipParam): self.deregister_shipparam(param.ship_id) self.register_shipparam(param) def register_shipparam(self, param: ShipParam): command = 'INSERT INTO shipparams VALUES (?,?,?,?,?,?,?,' \ '?,?,?,?,?,?,?,?)' values = param.to_tuple() self.database.execute(command, values) def deregister_shipparam(self, ship_id: int): command = 'DELETE FROM shipparams WHERE ship_id=?' values = (ship_id, ) self.database.execute(command, values) def register_ship(self, warship: Warship): """ Register ship into database. """ command = 'INSERT INTO warships VALUES(?,?,?,?,?,?,?,?,?,?,' \ '?,?,?,?,?,?,?,?)' values = warship.to_tuple() self.database.execute(command, values) def deregister_ship(self, ship_id: int): """ Deregister warship from database. """ command = 'DELETE FROM warships WHERE ship_id=?' values = (ship_id, ) self.database.execute(command, values) def register_user(self, player, discord_id): """ Register discord user into database. """ self.logger.debug(f'Registering {player["nickname"]}.') self.database.execute( 'INSERT INTO players VALUES(?, ?, ?, ?) ', (discord_id, player['account_id'], player['nickname'], '')) self.logger.debug('Registered player.') def deregister_user(self, discord_id): """ Deregister discord user from database. """ self.logger.debug('Deregistering user.') self.database.execute('DELETE FROM players WHERE discord_id = ?', (discord_id, )) self.logger.debug('Deregistered user.') def is_user_registered(self, discord_id): """ Checks is given discord_id is registered. """ result = self.database.fetch( 'SELECT discord_id from players WHERE discord_id = ?', (discord_id, )) self.logger.debug(f'{result=}') return result is not None
class ApiManager: def __init__(self, key): self.logger = Logger(self.__class__.__name__) self.api = WowsApi(key) def get_player_info(self, player_name): self.logger.debug(f'Creating player info for {player_name}.') player = self.api.players(Region.AS, player_name) if not player: return elif player['status'] != 'ok': return player_id = player['data'][0]['account_id'] player_data = self.api.player_personal_data(Region.AS, player_id) if not player_data: return elif player_data['status'] != 'ok': return player_data = player_data['data'][str(player_id)] self.logger.debug('Created player_data successfully.') return player_data def get_api_version(self): """ Get api's version. """ self.logger.debug('Fetching version for api.') version = self.api.information_about_encyclopedia() self.logger.debug('Returning api version.') return version def get_warships(self): """ Get warships fetched from wows api. """ self.logger.debug('Fetching for warships api.') warships = [] warships_count = self.api.get_warships_count() pages = math.ceil(warships_count/100) warships = self.api.get_warships(pages) self.logger.debug('Created warships.') return warships