War Logs

This is an example of how to handle war logs.

  1import asyncio
  2import os
  3
  4import coc
  5from coc.raid import RaidLogEntry
  6
  7
  8async def get_war_log_for_clans(client: coc.Client, clan_tags: list):
  9    war_logs = {}
 10    for tag in clan_tags:
 11        # if we're not allowed to view war_log (private in game),
 12        # this will raise an exception
 13        try:
 14            war_log = await client.get_war_log(tag)
 15        except coc.PrivateWarLog:
 16            war_log = []
 17
 18        war_logs[tag] = war_log
 19
 20    return war_logs
 21
 22
 23async def test_raid_log(client: coc.Client, clan_tag: str):
 24    # Limit is set to None retrieving all values
 25    raid_no_page = await client.get_raid_log(clan_tag)
 26    limit = len(raid_no_page)
 27    page_limit = 30
 28
 29    # Enable pagination, by default it will only cache 10 logs using limit
 30    # once you iterate beyond the cached amount, it will fetch the next set
 31    raid_with_page = await client.get_raid_log(clan_tag, page=True, limit=page_limit)
 32
 33    # Iterate over war_logs like the current version of coc.py
 34    for i, e in enumerate(raid_no_page):
 35        e: RaidLogEntry
 36        # print(f"[{i}]-sync limit: {limit} page: False {e.start_time.time}")
 37
 38    # Option to async for loop a non paginated object
 39    count = 0
 40    async for i in raid_no_page:
 41        # print(f"[{count}]-async limit: {limit} page: False")
 42        count += 1
 43
 44    # for i, e in enumerate(raid_with_page):
 45    #     print(f"[{i}]-sync limit: {page_limit} page: True")
 46
 47    # Set `paginate=True` to enable fetching beyond the limit value until
 48    # there are more values to fetch
 49    count = 0
 50    async for i in raid_with_page:
 51        # print(f"[{count}]-async limit: {page_limit} page: True {i.start_time.time}")
 52        count += 1
 53
 54    # Simple test comparing the two data sets
 55    count = 0
 56    async for async_log in raid_with_page:
 57        if async_log != raid_no_page[count]:
 58            raise AssertionError(f"{id(async_log)} does not match {id(raid_no_page[count])} at index {count}")
 59        count += 1
 60
 61
 62async def test_war_log(client: coc.Client, clan_tag: str):
 63    # Limit is set to None retrieving all values
 64    war_logs_no_page = await client.get_war_log(clan_tag)
 65    limit = len(war_logs_no_page)
 66    pagination_limit = 11
 67
 68    # Enable pagination, by default it will only cache 10 logs using limit
 69    # once you iterate beyond the cached amount, it will fetch the next set
 70    war_logs_with_page = await client.get_war_log(clan_tag, page=True, limit=pagination_limit)
 71
 72    # # Iterate over war_logs like the current version of coc.py
 73    # for i, e in enumerate(war_logs_no_page):
 74    #     print(f"[{i}]-sync limit: {limit} page: False")
 75
 76    # Option to async for loop a non paginated object
 77    count = 0
 78    async for i in war_logs_no_page:
 79        # print(f"[{count}]-async limit: {limit} page: False")
 80        count += 1
 81
 82    # for i, e in enumerate(war_logs_with_page):
 83    #     print(f"[{i}]-sync limit: {pagination_limit} page: True")
 84
 85    # Set `paginate=True` to enable fetching beyond the limit value until
 86    # there are more values to fetch
 87    count = 0
 88    async for i in war_logs_with_page:
 89        # print(f"[{count}]-async limit: {pagination_limit} page: True {i.end_time.time}")
 90        count += 1
 91
 92    # Simple test comparing the two data sets
 93    count = 0
 94    async for async_log in war_logs_with_page:
 95        if async_log != war_logs_no_page[count]:
 96            raise AssertionError(f"{id(async_log)} does not match {id(war_logs_no_page[count])} at index {count}")
 97        count += 1
 98    print(count)
 99
100
101async def get_clan_tags_names(client: coc.Client, name: str, limit: int):
102    clans = await client.search_clans(name=name, limit=limit)
103    # return a list of tuples of name/tag pair ie.
104    # [(name, tag), (another name, another tag)]
105    return [(n.name, n.tag) for n in clans]
106
107
108async def get_war_log_opponents_from_clan_name(client: coc.Client, name: str, no_of_clans: int):
109    clan_tags_names = await get_clan_tags_names(client, name, no_of_clans)
110
111    # search for war logs with clan tags found
112    war_logs = await get_war_log_for_clans(client, [n[1] for n in clan_tags_names])
113
114    for name, tag in clan_tags_names:
115        # iterate over the wars
116        for war_log in war_logs[tag]:
117            # if it is a league war we will error below because it does not
118            # return a WarLog object, and thus no opponent
119            if war_log.is_league_entry:
120                print("League War Season - No opponent info available")
121            else:
122                print(f"War: {war_log.clan.name} vs {war_log.opponent.name}")
123
124
125async def main():
126    async with coc.Client() as coc_client:
127        try:
128            await coc_client.login(os.environ.get("DEV_SITE_EMAIL"),
129                                   os.environ.get("DEV_SITE_PASSWORD"))
130        except coc.InvalidCredentials as error:
131            exit(error)
132
133        await get_war_log_opponents_from_clan_name(coc_client, "Reddit Zulu", 5)
134        await test_war_log(coc_client, "#2Y28CGP8")
135        await test_raid_log(coc_client, "#2Y28CGP8")
136
137
138if __name__ == "__main__":
139    asyncio.run(main())