Skip to content

Commit

Permalink
[Migrated doloks update] Merged Doluks update and fixed the discord_b…
Browse files Browse the repository at this point in the history
…ot.py example
  • Loading branch information
majordoobie committed Aug 25, 2022
1 parent fe1865c commit e3d81b7
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 37 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ celerybeat-schedule
*.sage.py

# Environments
.env
examples/.env
.venv
env/
examples/.env/
venv/
ENV/
examples/.env/
env.bak/
venv.bak/

Expand Down
13 changes: 3 additions & 10 deletions coc/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from __future__ import annotations

import asyncio
import logging
Expand Down Expand Up @@ -242,7 +243,7 @@ def _create_holders(self):
if not self.load_game_data.never:
self._load_holders()

async def login(self, email: str, password: str) -> None:
async def login(self, email: str, password: str) -> Client:
"""Retrieves all keys and creates an HTTP connection ready for use.
Parameters
Expand Down Expand Up @@ -278,15 +279,7 @@ def login_with_keys(self, *keys: str) -> None:

LOG.debug("HTTP connection created. Client is ready for use.")

def close_loops(self) -> None:
"""Closes the HTTP connection
"""
LOG.info("Clash of Clans client logging out...")
self.dispatch("on_client_close")
self.loop.run_until_complete(self.http.close())
self.loop.close()

async def close_client(self) -> None:
async def close(self) -> None:
"""Closes the HTTP connection from within a loop function such as
async def main()"""
await self.http.close()
Expand Down
1 change: 0 additions & 1 deletion coc/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,6 @@ def close(self):
tasks = {t for t in asyncio.Task.all_tasks(loop=self.loop) if not t.done()}
for task in tasks:
task.cancel()
super().close_loops()

def dispatch(self, event_name: str, *args, **kwargs):
# pylint: disable=broad-except
Expand Down
113 changes: 90 additions & 23 deletions examples/discord_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,29 @@
# installed via `python -m pip install -U discord.py`
# for more info on using discord.py, see the docs at:
# https://discordpy.readthedocs.io/en/latest

import asyncio
import logging
import os
import traceback

import coc
import discord
from discord.ext import commands
from dotenv import load_dotenv

import coc
from coc import utils
from discord.ext import commands

INFO_CHANNEL_ID = 761848043242127370 # some discord channel ID
clan_tags = ["#20090C9PR", "#202GG92Q", "#20C8G0RPL"]

bot = commands.Bot(command_prefix="?", intents=discord.Intents.all())
coc_client = coc.login(
os.environ["DEV_SITE_EMAIL"],
os.environ["DEV_SITE_PASSWORD"],
key_names="coc.py tests",
client=coc.EventsClient,
)
logging.basicConfig(level=logging.ERROR)


@bot.event
async def on_ready():
print("Logged in!!")


@coc_client.event
@coc.ClanEvents.member_join(tags=clan_tags)
async def on_clan_member_join(member, clan):
await bot.get_channel(INFO_CHANNEL_ID).send(
Expand All @@ -40,7 +33,6 @@ async def on_clan_member_join(member, clan):
)


@coc_client.event
@coc.ClanEvents.member_name(tags=clan_tags)
async def member_name_change(old_player, new_player):
await bot.get_channel(INFO_CHANNEL_ID).send(
Expand All @@ -49,7 +41,6 @@ async def member_name_change(old_player, new_player):
)


@coc_client.event
@coc.ClientEvents.event_error()
async def on_event_error(exception):
if isinstance(exception, coc.PrivateWarLog):
Expand All @@ -65,7 +56,7 @@ async def player_heroes(ctx, player_tag):
return

try:
player = await coc_client.get_player(player_tag)
player = await ctx.bot.coc_client.get_player(player_tag)
except coc.NotFound:
await ctx.send("This player doesn't exist!")
return
Expand All @@ -80,7 +71,7 @@ async def player_heroes(ctx, player_tag):

@bot.command()
async def parse_army(ctx, army_link: str):
troops, spells = coc_client.parse_army_link(army_link)
troops, spells = ctx.bot.coc_client.parse_army_link(army_link)
print(troops, spells)
parsed_link_output = ''
if troops or spells: # checking if troops or spells is present in link
Expand All @@ -96,9 +87,10 @@ async def parse_army(ctx, army_link: str):
parsed_link_output += "Invalid Link!"
await ctx.send(parsed_link_output)


@bot.command()
async def create_army(ctx):
link = coc_client.create_army_link(
link = ctx.bot.coc_client.create_army_link(
barbarian=10,
archer=20,
hog_rider=30,
Expand All @@ -108,14 +100,50 @@ async def create_army(ctx):
)
await ctx.send(link)

@bot.command()
async def member_stat(ctx, player_tag):
if not utils.is_valid_tag(player_tag):
await ctx.send("You didn't give me a proper tag!")
return

try:
player = await ctx.bot.coc_client.get_player(player_tag)
except coc.NotFound:
await ctx.send("This clan doesn't exist!")
return

frame = ''
if player.town_hall > 11:
frame += f"`{'TH Weapon LvL:':<15}` `{player.town_hall_weapon:<15}`\n"
role = player.role if player.role else 'None'
clan = player.clan.name if player.clan else 'None'
frame += (
f"`{'Role:':<15}` `{role:<15}`\n"
f"`{'Player Tag:':<15}` `{player.tag:<15}`\n"
f"`{'Current Clan:':<15}` `{clan:<15.15}`\n"
f"`{'League:':<15}` `{player.league.name:<15.15}`\n"
f"`{'Trophies:':<15}` `{player.trophies:<15}`\n"
f"`{'Best Trophies:':<15}` `{player.best_trophies:<15}`\n"
f"`{'War Stars:':<15}` `{player.war_stars:<15}`\n"
f"`{'Attack Wins:':<15}` `{player.attack_wins:<15}`\n"
f"`{'Defense Wins:':<15}` `{player.defense_wins:<15}`\n"
f"`{'Castle Contrib':<15}` `{player.clan_capital_contributions:<15}`\n"
)
e = discord.Embed(colour=discord.Colour.green(),
description=frame)
e.set_thumbnail(url=player.clan.badge.url)
await ctx.send(embed=e)



@bot.command()
async def clan_info(ctx, clan_tag):
if not utils.is_valid_tag(clan_tag):
await ctx.send("You didn't give me a proper tag!")
return

try:
clan = await coc_client.get_clan(clan_tag)
clan = await ctx.bot.coc_client.get_clan(clan_tag)
except coc.NotFound:
await ctx.send("This clan doesn't exist!")
return
Expand All @@ -125,7 +153,10 @@ async def clan_info(ctx, clan_tag):
else:
log = "Public"



e = discord.Embed(colour=discord.Colour.green())

e.set_thumbnail(url=clan.badge.url)
e.add_field(name="Clan Name",
value=f"{clan.name}({clan.tag})\n[Open in game]({clan.share_link})", inline=False)
Expand Down Expand Up @@ -154,7 +185,14 @@ async def clan_info(ctx, clan_tag):
value=f"Won - {clan.war_wins}\nLost - {clan.war_losses}\n Draw - {clan.war_ties}",
inline=False
)
await ctx.send(embed=e)

frame = ""
for district in clan.capital_districts:
frame += (f"`{f'{district.name}:':<20}` `{district.hall_level:<15}`\n")

e2 = discord.Embed(colour=discord.Colour.green(), description=frame, title="Capital Distracts")

await ctx.send(embeds=[e, e2])


@bot.command()
Expand All @@ -164,14 +202,15 @@ async def clan_member(ctx, clan_tag):
return

try:
clan = await coc_client.get_clan(clan_tag)
clan = await ctx.bot.coc_client.get_clan(clan_tag)
except coc.NotFound:
await ctx.send("This clan does not exist!")
return

member = ""
for i, a in enumerate(clan.members, start=1):
member += f"`{i}.` {a.name}\n"

embed = discord.Embed(colour=discord.Colour.red(),
title=f"Members of {clan.name}", description=member)
embed.set_thumbnail(url=clan.badge.url)
Expand All @@ -188,7 +227,7 @@ async def current_war_status(ctx, clan_tag):
e = discord.Embed(colour=discord.Colour.blue())

try:
war = await coc_client.get_current_war(clan_tag)
war = await ctx.bot.coc_client.get_current_war(clan_tag)
except coc.PrivateWarLog:
return await ctx.send("Clan has a private war log!")

Expand Down Expand Up @@ -231,7 +270,35 @@ async def _mock_get_channel():

sys.exit(0)

if os.environ.get("RUNNING_TESTS"):
bot.loop.create_task(run_tests_and_quit())

bot.run(os.environ["DISCORD_BOT_TOKEN"])
def main():
load_dotenv()
logging.basicConfig(level=logging.ERROR)

# Instantiate the coc client used to log in
coc_client = coc.EventsClient(
key_names="coc.py bot example"
)

# Create an event loop
loop = asyncio.get_event_loop()

# Establish a connection with the coc API
loop.run_until_complete(
coc_client.login(os.environ.get("DEV_SITE_EMAIL"),
os.environ.get("DEV_SITE_PASSWORD")))

# Add the client session to the bot
bot.coc_client = coc_client

loop.run_until_complete(bot.start(os.environ.get("DISCORD_BOT_TOKEN")))


if __name__ == "__main__":
if os.environ.get("RUNNING_TESTS"):
bot.loop.create_task(run_tests_and_quit())

try:
main()
except KeyboardInterrupt:
pass

0 comments on commit e3d81b7

Please sign in to comment.