diff --git a/Pipfile.lock b/Pipfile.lock index f7da62f..7b1840e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -23,6 +23,13 @@ ], "version": "==0.5.14" }, + "appdirs": { + "hashes": [ + "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", + "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + ], + "version": "==1.4.3" + }, "asyncio": { "hashes": [ "sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41", @@ -32,6 +39,20 @@ ], "version": "==3.4.3" }, + "beautifulsoup4": { + "hashes": [ + "sha256:194ec62a25438adcb3fdb06378b26559eda1ea8a747367d34c33cef9c7f48d57", + "sha256:90f8e61121d6ae58362ce3bed8cd997efb00c914eae0ff3d363c32f9a9822d10", + "sha256:f0abd31228055d698bb392a826528ea08ebb9959e6bea17c606fd9c9009db938" + ], + "version": "==4.6.3" + }, + "bs4": { + "hashes": [ + "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a" + ], + "version": "==0.0.1" + }, "certifi": { "hashes": [ "sha256:376690d6f16d32f9d1fe8932551d80b23e9d393a8578c5633a2ed39a64861638", @@ -91,10 +112,24 @@ ], "version": "==10.0" }, + "cssselect": { + "hashes": [ + "sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204", + "sha256:3b5103e8789da9e936a68d993b70df732d06b8bb9a337a05ed4eb52c17ef7206" + ], + "markers": "python_version != '3.3.*' and python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.0.*'", + "version": "==1.0.3" + }, "e1839a8": { "editable": true, "path": "." }, + "fake-useragent": { + "hashes": [ + "sha256:c104998b750eb097eefc28ae28e92d66397598d2cf41a31aa45d5559ef1adf35" + ], + "version": "==0.1.11" + }, "geojson": { "hashes": [ "sha256:8831556d1ac18805c4955aa881e022e6ddcef44020b315200680eec6dd209e40", @@ -116,6 +151,53 @@ ], "version": "==2.7" }, + "lxml": { + "hashes": [ + "sha256:02bc220d61f46e9b9d5a53c361ef95e9f5e1d27171cd461dddb17677ae2289a5", + "sha256:22f253b542a342755f6cfc047fe4d3a296515cf9b542bc6e261af45a80b8caf6", + "sha256:2f31145c7ff665b330919bfa44aacd3a0211a76ca7e7b441039d2a0b0451e415", + "sha256:36720698c29e7a9626a0dc802ef8885f8f0239bfd1689628ecd459a061f2807f", + "sha256:438a1b0203545521f6616132bfe0f4bca86f8a401364008b30e2b26ec408ce85", + "sha256:4815892904c336bbaf73dafd54f45f69f4021c22b5bad7332176bbf4fb830568", + "sha256:5be031b0f15ad63910d8e5038b489d95a79929513b3634ad4babf77100602588", + "sha256:5c93ae37c3c588e829b037fdfbd64a6e40c901d3f93f7beed6d724c44829a3ad", + "sha256:60842230678674cdac4a1cf0f707ef12d75b9a4fc4a565add4f710b5fcf185d5", + "sha256:62939a8bb6758d1bf923aa1c13f0bcfa9bf5b2fc0f5fa917a6e25db5fe0cfa4e", + "sha256:75830c06a62fe7b8fe3bbb5f269f0b308f19f3949ac81cfd40062f47c1455faf", + "sha256:81992565b74332c7c1aff6a913a3e906771aa81c9d0c68c68113cffcae45bc53", + "sha256:8c892fb0ee52c594d9a7751c7d7356056a9682674b92cc1c4dc968ff0f30c52f", + "sha256:9d862e3cf4fc1f2837dedce9c42269c8c76d027e49820a548ac89fdcee1e361f", + "sha256:a623965c086a6e91bb703d4da62dabe59fe88888e82c4117d544e11fd74835d6", + "sha256:a7783ab7f6a508b0510490cef9f857b763d796ba7476d9703f89722928d1e113", + "sha256:aab09fbe8abfa3b9ce62aaf45aca2d28726b1b9ee44871dbe644050a2fff4940", + "sha256:abf181934ac3ef193832fb973fd7f6149b5c531903c2ec0f1220941d73eee601", + "sha256:ae07fa0c115733fce1e9da96a3ac3fa24801742ca17e917e0c79d63a01eeb843", + "sha256:b9c78242219f674ab645ec571c9a95d70f381319a23911941cd2358a8e0521cf", + "sha256:bccb267678b870d9782c3b44d0cefe3ba0e329f9af8c946d32bf3778e7a4f271", + "sha256:c4df4d27f4c93b2cef74579f00b1d3a31a929c7d8023f870c4b476f03a274db4", + "sha256:caf0e50b546bb60dfa99bb18dfa6748458a83131ecdceaf5c071d74907e7e78a", + "sha256:d3266bd3ac59ac4edcd5fa75165dee80b94a3e5c91049df5f7c057ccf097551c", + "sha256:db0d213987bcd4e6d41710fb4532b22315b0d8fb439ff901782234456556aed1", + "sha256:dbbd5cf7690a40a9f0a9325ab480d0fccf46d16b378eefc08e195d84299bfae1", + "sha256:e16e07a0ec3a75b5ee61f2b1003c35696738f937dc8148fbda9fe2147ccb6e61", + "sha256:e175a006725c7faadbe69e791877d09936c0ef2cf49d01b60a6c1efcb0e8be6f", + "sha256:edd9c13a97f6550f9da2236126bb51c092b3b1ce6187f2bd966533ad794bbb5e", + "sha256:fa39ea60d527fbdd94215b5e5552f1c6a912624521093f1384a491a8ad89ad8b" + ], + "version": "==4.2.5" + }, + "over-stats": { + "hashes": [ + "sha256:47aa9d5fda0a06a48ba8199e312d6b543753ca3ddf1581f69db0f0726a135301" + ], + "version": "==0.3.1" + }, + "parse": { + "hashes": [ + "sha256:9dd6048ea212cd032a342f9f6aa2b7bc222f7407c7e37bdc2777fecd36897437" + ], + "version": "==1.9.0" + }, "pycparser": { "hashes": [ "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3" @@ -123,6 +205,13 @@ "markers": "python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.1.*' and python_version >= '2.7'", "version": "==2.19" }, + "pyee": { + "hashes": [ + "sha256:47f8fa96d6dee61c82001831e1fbba55f3f808003a322d0e6653aa01c59f6b9e", + "sha256:4ec22817297b7024f89721cc34f790ee2767c5b5ca44284c565ee643abafbe32" + ], + "version": "==5.0.0" + }, "pynacl": { "hashes": [ "sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255", @@ -156,6 +245,20 @@ ], "version": "==2.9.0" }, + "pyppeteer": { + "hashes": [ + "sha256:51fe769b722a1718043b74d12c20420f29e0dd9eeea2b66652b7f93a9ad465dd" + ], + "markers": "python_version >= '2.6' and python_version != '3.1.*' and python_version != '3.0.*'", + "version": "==0.0.25" + }, + "pyquery": { + "hashes": [ + "sha256:07987c2ed2aed5cba29ff18af95e56e9eb04a2249f42ce47bddfb37f487229a3", + "sha256:4771db76bd14352eba006463656aef990a0147a0eeaf094725097acfa90442bf" + ], + "version": "==1.4.0" + }, "requests": { "hashes": [ "sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1", @@ -163,6 +266,13 @@ ], "version": "==2.19.1" }, + "requests-html": { + "hashes": [ + "sha256:34257d5249b20b8ed14573eba910f48032a61205e70d11ce8a3ef6abf8edc50b", + "sha256:9686f21c5753ba6c025c6ba223a8329c7b149a935a73055097faf8999eee85b1" + ], + "version": "==0.9.0" + }, "six": { "hashes": [ "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", @@ -170,6 +280,14 @@ ], "version": "==1.11.0" }, + "tqdm": { + "hashes": [ + "sha256:18f1818ce951aeb9ea162ae1098b43f583f7d057b34d706f66939353d1208889", + "sha256:df02c0650160986bac0218bb07952245fc6960d23654648b5d5526ad5a4128c9" + ], + "markers": "python_version >= '2.6' and python_version != '3.1.*' and python_version != '3.0.*'", + "version": "==4.26.0" + }, "urllib3": { "hashes": [ "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", @@ -178,6 +296,40 @@ "markers": "python_version < '4' and python_version >= '2.6' and python_version != '3.2.*' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.1.*'", "version": "==1.23" }, + "w3lib": { + "hashes": [ + "sha256:55994787e93b411c2d659068b51b9998d9d0c05e0df188e6daf8f45836e1ea38", + "sha256:aaf7362464532b1036ab0092e2eee78e8fd7b56787baa9ed4967457b083d011b" + ], + "version": "==1.19.0" + }, + "websockets": { + "hashes": [ + "sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136", + "sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6", + "sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1", + "sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538", + "sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4", + "sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908", + "sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0", + "sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d", + "sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c", + "sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d", + "sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c", + "sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb", + "sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf", + "sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e", + "sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96", + "sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584", + "sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484", + "sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d", + "sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559", + "sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff", + "sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454" + ], + "markers": "python_version >= '3.4'", + "version": "==6.0" + }, "youtube-dl": { "hashes": [ "sha256:17b03b94031efc28457ef0808ea2c750012aa38007b2980f93a9c9b1d7387363", diff --git a/demo.py b/demo.py new file mode 100644 index 0000000..74214f9 --- /dev/null +++ b/demo.py @@ -0,0 +1,61 @@ +import json +import over_stats + +# Initialize a player profile by providing the player tag and the platform. +# the platform is optional and by default it is 'pc'. Other valid values are +# 'xbl' and 'psn' +player_data = over_stats.PlayerProfile('Cyrus#1852') +# or +# player_data = over_stats.PlayerProfile('acesarramsan', over_stats.PLAT_PSN) + +# Ther is a bug in the boto3 library that causes it not to be able to handle +# floats. To get around this issue there is flag that you can use to wrap floats +# into a Decimal. Be careful that Decimals cannot be dumped to json. +# player_data = over_stats.PlayerProfile('acesarramsan', over_stats.PLAT_PSN, True) + +# Download and parse the profile's data +player_data.load_data() + +# Print the entire profile's data in JSON format +# print (json.dumps(player_data.raw_data, indent=4)) + +# You can also use the helper methods to access the data you want +for mode in over_stats.MODES: + # mode will be 'quickplay' or 'competitive' + # print (f"Game Mode: {mode}") + # print ("Comparison Types Available: " + str(player_data.comparison_types(mode))) + # for comparison_type in player_data.comparison_types(mode): + # # A comparison type will be one of the options in the 'Top Heroes' section, 'Times Played', 'Games Won', + # # 'Weapon Accuracy', etc + # print (f" - Comparison Type: {comparison_type}") + # print (" - Heroes available to compare: " + str(player_data.comparison_heroes(mode, comparison_type))) + # for comparison_hero in player_data.comparison_heroes(mode, comparison_type): + # # The comparison_hero be each hero in this list. The comparisons() method will return the value linked to each hero + # print (" - " + comparison_hero + ": " + str(player_data.comparisons(mode, comparison_type, comparison_hero))) + + # This data belongs to the 'career_stats'. The values for hero will be 'All Heroes', 'Reaper', 'Tracer', etc. + print ("Heroes with Stats Available: " + str(player_data.stat_heroes(mode))) + for hero in player_data.stat_heroes(mode): + print (f" - Hero: {hero}") + # The category represents each card in for the selected hero, for example 'Combat', 'Assists', etc. + print (" - Categories available for stats " + str(player_data.stat_categories(mode, hero))) + for category in player_data.stat_categories(mode, hero): + print (f" - Category: {category}") + print (" - Stats available: " + str(player_data.stat_names(mode, hero, category))) + # for stat_name in player_data.stat_names(mode, hero, category): + # # This will print each stat from each category along with it's value + # print (" - " + stat_name + ": " + str(player_data.stats(mode, hero, category, stat_name))) + +# # Achievements do not depend on game mode and instead they use categories like 'General', 'Offence', 'Defense', etc +# print ("Achievemet Types Available: " + str(player_data.achievement_types())) +# for achievement_type in player_data.achievement_types(): +# print (f"Achievement Type: {achievement_type}") +# # Each achievement category contains two lists, one with acquired achievements and one for missing achievements. +# print (f" - {over_stats.ACH_EARNED}") +# for achievement in player_data.achievements(achievement_type, over_stats.ACH_EARNED): +# # Print each earned achievements +# print (f" - {achievement}") +# print (f" - {over_stats.ACH_MISSING}") +# for achievement in player_data.achievements(achievement_type, over_stats.ACH_MISSING): +# # Print each achievement that this player does not yet have +# print (f" - {achievement}") diff --git a/kwargs_test.py b/kwargs_test.py new file mode 100644 index 0000000..ecd3e9f --- /dev/null +++ b/kwargs_test.py @@ -0,0 +1,35 @@ +KWARGS = { 'pc': 'platform', + 'psn': 'platform', + 'xbox': 'platform', + 'comp': 'mode', + 'competitive': 'mode', + 'qp': 'mode', + 'quickplay': 'mode', +} + +KWARGS_DEFAULT = + +def kwarg_generator(kwargs_map, args): + kwargs = {} + for arg in args: + if arg in kwargs_map: + kwargs[kwargs_map[arg]] = arg + if arg.isdigit() + kwargs['top'] = arg + + if 'top' not in kwargs: + kwargs['top'] = + return kwargs + + +def test_kwargs(kwargs): + print(kwargs['mode']) + print(kwargs['platform']) + + + +test_args=['qp', 'pc',] + +kwargs = kwarg_generator(KWARGS, test_args) + +test_kwargs(kwargs) diff --git a/setup.py b/setup.py index 0158b84..440fc23 100644 --- a/setup.py +++ b/setup.py @@ -9,8 +9,11 @@ 'aiomeasures', 'coloredlogs', 'over_stats', + 'oyaml', 'PyNaCl', 'pyowm', + 'python-overwatch', + 'pyyaml', 'youtube_dl' ] diff --git a/tamago/__init__.py b/tamago/__init__.py index cf5366a..9f2c736 100644 --- a/tamago/__init__.py +++ b/tamago/__init__.py @@ -1,5 +1,5 @@ """ init - version info """ -VERSION_INFO = (0, 1, 0) +VERSION_INFO = (0, 1, 1) VERSION = '.'.join(str(c) for c in VERSION_INFO) diff --git a/tamago/lib/plugins/fun.py b/tamago/lib/plugins/fun.py index d58156e..ff19dbc 100644 --- a/tamago/lib/plugins/fun.py +++ b/tamago/lib/plugins/fun.py @@ -24,8 +24,8 @@ async def eight_ball(self, ctx): 'It is quite possible', 'Definitely', ] - await self.tamago.say('{}, {}'.format(random.choice(possible_responses), - ctx.message.author.mention)) + await ctx.send('{}, {}'.format(random.choice(possible_responses), + ctx.message.author.mention)) @commands.command(pass_context=True) async def hello(self, ctx): diff --git a/tamago/lib/plugins/mod_tools.py b/tamago/lib/plugins/mod_tools.py index 692797e..0431eae 100644 --- a/tamago/lib/plugins/mod_tools.py +++ b/tamago/lib/plugins/mod_tools.py @@ -1,6 +1,7 @@ import discord import logging from discord.ext import commands +from tamago.lib import utils LOG = logging.getLogger(__name__) @@ -11,12 +12,26 @@ def __init__(self, client): @commands.command(pass_context=True) @commands.has_permissions(manage_messages=True, administrator=True) async def clear(self, ctx, amount=5): + """ + Clears messages by !clear #ofmessages [@user] + :param class self: tamago bot client + :param context ctx: context of the message sent + """ channel = ctx.message.channel messages = [] - async for message in channel.history(limit=int(amount) + 1): - messages.append(message) + if ctx.message.mentions: + mentions = [] + for member in ctx.message.mentions: + mentions.append(member.id) + async for message in channel.history(limit=int(amount) + 1): + if message.author.id in mentions: + messages.append(message) + else: + async for message in channel.history(limit=int(amount) + 1): + messages.append(message) + await channel.delete_messages(messages) - await ctx.send('%s messages purged' % amount) + await ctx.send('{} messages purged'.format(len(messages))) @commands.command(name='getid', aliases=['id'], pass_context=True) @commands.has_permissions(manage_messages=True, administrator=True) diff --git a/tamago/lib/plugins/music.py b/tamago/lib/plugins/music.py index 1180a59..3051918 100644 --- a/tamago/lib/plugins/music.py +++ b/tamago/lib/plugins/music.py @@ -24,8 +24,8 @@ 'source_address': '0.0.0.0' # ipv6 addresses cause issues sometimes } -ffmpegopts = { - 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', +ffmpeg_options = { + 'before_options': '-nostdin -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn' } @@ -92,7 +92,7 @@ async def create_source(cls, ctx, search: str, *, loop, download=False): else: return {'webpage_url': data['webpage_url'], 'requester': ctx.author, 'title': data['title']} - return cls(discord.FFmpegPCMAudio(source), data=data, requester=ctx.author) + return cls(discord.FFmpegPCMAudio(source, **ffmpeg_options), data=data, requester=ctx.author) @classmethod async def regather_stream(cls, data, *, loop): @@ -105,7 +105,7 @@ async def regather_stream(cls, data, *, loop): to_run = partial(ytdl.extract_info, url=data['webpage_url'], download=False) data = await loop.run_in_executor(None, to_run) - return cls(discord.FFmpegPCMAudio(data['url']), data=data, requester=requester) + return cls(discord.FFmpegPCMAudio(data['url'], **ffmpeg_options), data=data, requester=requester) class MusicPlayer: diff --git a/tamago/lib/plugins/server.py b/tamago/lib/plugins/server.py index 86a55ba..dba2ba3 100644 --- a/tamago/lib/plugins/server.py +++ b/tamago/lib/plugins/server.py @@ -26,6 +26,12 @@ async def on_command_error(self, ctx, error): msg = '{} the command you ran does not exist please use !help for assistance'.format(ctx.message.author.mention) if isinstance(error, commands.CheckFailure): msg = ':octagonal_sign: you do not have permission to run this command, {}'.format(ctx.message.author.mention) + if isinstance(error, commands.MissingRequiredArgument): + msg = 'Missing required argument: ```{}```'.format(error) + + if not msg: + msg = 'Oh no, I have no idea what I am doing! {}'.format(error) + await ctx.send('{}'.format(msg)) diff --git a/tamago/lib/plugins/stats_overwatch.py b/tamago/lib/plugins/stats_overwatch.py new file mode 100644 index 0000000..f67abdc --- /dev/null +++ b/tamago/lib/plugins/stats_overwatch.py @@ -0,0 +1,184 @@ +import discord +import logging +import over_stats +import oyaml as yaml +from discord.ext import commands +from tamago.lib import utils + +LOG = logging.getLogger(__name__) + +KWARGS = { 'pc': {'kwarg': 'platform', + 'value': 'pc'}, + 'psn': {'kwarg': 'platform', + 'value': 'psn'}, + 'xbox': {'kwarg': 'platform', + 'value': 'xbox'}, + 'comp': {'kwarg': 'mode', + 'value': 'competitive'}, + 'competitive': {'kwarg': 'mode', + 'value': 'competitive'}, + 'kd': {'kwarg': 'comparison_type', + 'value': 'Eliminations per Life'}, + 'qp': {'kwarg': 'mode', + 'value': 'quickplay'}, + 'qpc': {'kwarg': 'mode', + 'value': 'quickplay,competitive'}, + 'quickplay': {'kwarg': 'mode', + 'value': 'quickplay'}, + 'time': {'kwarg': 'comparison_type', + 'value': 'Time Played'}, + 'wins': {'kwarg': 'comparison_type', + 'value': 'Games Won'}, + 'winrate': {'kwarg': 'comparison_type', + 'value': 'Win Percentage'}, +} +KWARGS_DEFAULT = { + 'platform': 'pc', + 'mode': 'competitive', + 'comparison_type': None, + 'top': 5, + } + +class StatsOverwatch: + def __init__(self, client): + self.client = client + + @commands.command() + @utils.block_check() + async def ow(self, ctx, player, *args ): + kwargs = kwarg_generator(args) + LOG.info(kwargs) + ow_data = await ow_load_data(player, + platform=kwargs['platform'], + comparison_type=kwargs['comparison_type'], + top=kwargs['top'], + modes=kwargs['mode'].split(',')) + if ow_data: + embed = await stat_embed(ow_data) + await ctx.send(embed=embed) + else: + await ctx.send(':information_source: Did not pass in a search paramater use !owhelp') + + @ow.error + async def ow_error(self, ctx, error): + if isinstance(error, commands.CommandInvokeError): + if 'PlayerNotFound' in str(error): + msg = ':mag: player not found check your user name' + if not msg: + msg = 'overwatch data overflow! Please reduce the query amount!' + + await ctx.send(msg) + + @commands.command() + @utils.block_check() + async def owhelp(self, ctx): + help_dict = {} + for arg in KWARGS: + kwarg = '**{}**'.format(KWARGS[arg]['kwarg']) + if kwarg not in help_dict: + help_dict[kwarg] = [] + help_dict[kwarg].append(arg) + + embed = discord.Embed( + title = ':information_source: Overwatch command help!', + colour = discord.Colour.purple() + ) + for kwarg in help_dict: + embed.add_field(name=kwarg.upper(), + value=yaml.dump(help_dict[kwarg], + default_flow_style=False, + allow_unicode=True, indent=8), + inline=False) + + await ctx.send(embed=embed) + +def kwarg_generator(args, kwargs_map=KWARGS, kwargs_default=KWARGS_DEFAULT): + kwargs = {} + for arg in args: + if arg in kwargs_map: + kwargs[kwargs_map[arg]['kwarg']] = kwargs_map[arg]['value'] + if arg.isdigit(): + kwargs['top'] = arg + + for k_default in kwargs_default: + if k_default not in kwargs: + kwargs[k_default] = kwargs_default[k_default] + + if kwargs['comparison_type'] == 'Win Percentage': + kwargs['mode'] = 'competitive' + + return kwargs + +def ow_data_formatter(data, comparison_type): + if comparison_type == 'Time Played': + data = data.replace('[','').replace(']','').replace("'", "").split() + data = ''.join(data).replace(',', ' ') + if comparison_type == 'Win Percentage': + data = '{}%'.format(float(data) * 100) + if comparison_type == 'Eliminations per Life': + data = '{} k/d'.format(float(data)) + return data + +async def stat_embed(data_dict): + + embed = discord.Embed( + title = list(data_dict.keys())[0], + colour = discord.Colour.red(), + ) + + for user in data_dict: + for mode in data_dict[user]: + stat_values = [] + for stat in data_dict[user][mode]: + stat_values.append('{} : {}'.format(stat, data_dict[user][mode][stat])) + embed.add_field(name=mode, value=yaml.dump(stat_values, + default_flow_style=False, + allow_unicode=True, indent=8).replace("'", ""), + inline=False) + + return embed + + +async def ow_load_data2(player, modes=['quickplay', 'competitive'], + platform='pc', comparison_type=None, top=5 ): + ow_data = {} + ow_stats = {} + player_data = over_stats.PlayerProfile(player, platform) + + player_data.load_data() + for mode in modes: + ow_data[mode] = {} + if comparison_type: + for comparison_hero in player_data.comparison_heroes(mode, comparison_type): + ow_data[mode][comparison_hero] = str(player_data.comparisons(mode, comparison_type, comparison_hero)) + stat = '**{} - {}**'.format(player, comparison_type) + ow_stats[stat] = {} + for mode in ow_data: + ow_stats[stat]['**{}**'.format(mode.upper())] = {} + for hero in utils.take(int(top), ow_data[mode]): + ow_stats[stat]['**{}**'.format(mode.upper())]['**{}**'.format(hero)] = ow_data_formatter(ow_data[mode][hero], comparison_type) + + return ow_stats + +async def ow_load_data(player, modes=['quickplay', 'competitive'], + platform='pc', comparison_type=None, top=5 ): + ow_data = {} + ow_stats = {} + player_data = over_stats.PlayerProfile(player, platform) + player_data.load_data() + for mode in modes: + ow_data[mode] = {} + if comparison_type: + for comparison_hero in player_data.comparison_heroes(mode, comparison_type): + ow_data[mode][comparison_hero] = str(player_data.comparisons(mode, comparison_type, comparison_hero)) + stat = '**{} - {}**'.format(player, comparison_type) + ow_stats[stat] = {} + for mode in ow_data: + ow_stats[stat]['**{}**'.format(mode.upper())] = {} + for hero in utils.take(int(top), ow_data[mode]): + ow_stats[stat]['**{}**'.format(mode.upper())]['{}'.format(hero)] = ow_data_formatter(ow_data[mode][hero], comparison_type) + + return ow_stats + +def setup(client): + client.add_cog(StatsOverwatch(client)) diff --git a/tamago/lib/plugins/weather.py b/tamago/lib/plugins/weather.py index 62a6416..9abf571 100644 --- a/tamago/lib/plugins/weather.py +++ b/tamago/lib/plugins/weather.py @@ -15,13 +15,13 @@ def get_emoji(status): """ emoji_status = { 'broken clouds': ':cloud:', - 'Clear': ':sunny:', - 'Clouds': ':cloud:', + 'clear': ':sunny:', + 'clouds': ':cloud:', 'light rain': ':cloud_rain:', 'mist': ':cloud_rain:', - 'Rain': ':cloud_rain:', + 'rain': ':cloud_rain:', 'scattered clouds': ':cloud:', - 'Thunderstorm': ':cloud_lightning:', + 'thunderstorm': ':cloud_lightning:', } if status in emoji_status: @@ -47,7 +47,7 @@ def get_weather(location, owm_api_key): weather['ERROR'] = {'value': 'Unable to find location, try another', 'inline': True } return weather - weather['Status'] = {'value': get_emoji(w.get_status()), 'inline': True } + weather['Status'] = {'value': get_emoji(w.get_status().lower()), 'inline': True } weather['Cloud Coverage'] = {'value': '{}%'.format(w.get_clouds()), 'inline': True } weather['Wind'] = {'value': '{} mph'.format(round(w.get_wind(unit='miles_hour')['speed'], 2)), 'inline': True } diff --git a/tamago/lib/utils.py b/tamago/lib/utils.py index 8f96ee5..4a3cae6 100644 --- a/tamago/lib/utils.py +++ b/tamago/lib/utils.py @@ -4,7 +4,7 @@ import logging import os from discord import Game -from itertools import cycle +from itertools import cycle, islice from tamago import VERSION from discord.ext import commands @@ -24,6 +24,10 @@ def parse_arguments(): return parser.parse_args() +def take(n, iterable): + "Return first n items of the iterable as a list" + return list(islice(iterable, n)) + def friendly_time(seconds): minutes, seconds = divmod(seconds, 60) hours, minutes = divmod(minutes, 60) @@ -35,6 +39,8 @@ def friendly_time(seconds): return '{}'.format(time_string) +def message_check(message, mentions): + return message.author.id in mentions def block_check(): def predicate(ctx): @@ -55,9 +61,9 @@ async def change_status(client): async def list_servers(client): await client.wait_until_ready() - while not client.is_closed: + while not client.is_closed(): server_list = [] - for server in client.servers: + for server in client.guilds: server_list.append(server.name) LOG.info('Current servers: {}'.format(server_list)) await asyncio.sleep(600) diff --git a/tamago/tamago_bot.py b/tamago/tamago_bot.py index 1250532..bc8f67a 100644 --- a/tamago/tamago_bot.py +++ b/tamago/tamago_bot.py @@ -16,16 +16,16 @@ from tamago.lib import plugin, utils from tamago.tamago import Tamago - EXTENSIONS = [ - 'tamago.lib.plugins.crypto', - 'tamago.lib.plugins.fun', - 'tamago.lib.plugins.mod_tools', - 'tamago.lib.plugins.music', - 'tamago.lib.plugins.ping', - 'tamago.lib.plugins.server', - 'tamago.lib.plugins.weather', - ] + 'crypto', + 'fun', + 'mod_tools', + 'music', + 'ping', + 'server', + 'stats_overwatch', + 'weather', + ] LOG = logging.getLogger(__name__) @@ -37,6 +37,7 @@ SHARD_COUNT = os.getenv('SHARD_COUNT') or 1 TOKEN = os.getenv('TOKEN') + def main(): """Entrypoint if called as an executable.""" args = utils.parse_arguments() @@ -59,7 +60,7 @@ def main(): dd_agent_url=DD_AGENT_URL, owm_api_key=OWM_API_KEY, command_prefix=BOT_PREFIX) for extension in EXTENSIONS: - plugin.load(extension, tamago) + plugin.load('tamago.lib.plugins.{}'.format(extension), tamago) tamago.run(TOKEN)