Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
620054e
Lots of Changes:
mathsman5133 May 19, 2019
03bad77
Add `EqualityComparable` to compare if 2 objects are equal.
mathsman5133 May 19, 2019
a9d8b49
New Error: `GatewayError`
mathsman5133 May 19, 2019
85a5a18
Update iterators for use with new parameter `update_cache`
mathsman5133 May 19, 2019
1dd5937
Use new `GatewayError` exception, use `_ready.set()` to indicate http…
mathsman5133 May 19, 2019
ae421b5
New Extension: `events`
mathsman5133 May 19, 2019
36fd792
Bump version to v0.2.0a
mathsman5133 May 19, 2019
3920d6e
Bump version to v0.2.0a
mathsman5133 May 19, 2019
81432e6
Stop git/pypi from freaking out
mathsman5133 May 19, 2019
0b12b33
Document all events.
mathsman5133 May 21, 2019
3c6b953
Organise models into different files according to groups:
mathsman5133 May 21, 2019
4c47b34
Add all new data models to respective imports etc.
mathsman5133 May 21, 2019
e3c45d0
Document `update_cache` parameter
mathsman5133 May 21, 2019
bb8ba2e
Changes to how things work:
mathsman5133 May 21, 2019
afa4b15
Document `start_updates` and `stop_updates` methods
mathsman5133 May 21, 2019
ff1b430
Forgot to add couple classes to __init__
mathsman5133 May 21, 2019
2da3110
Add EventsClient to docs
mathsman5133 May 21, 2019
3a1a576
Add a better `client.close()` function, and helper `client.run_foreve…
mathsman5133 May 21, 2019
8efe443
Add events example.
mathsman5133 May 21, 2019
111cc02
Remove debug loop setting
mathsman5133 May 22, 2019
b907248
Fix bad `@client.event` example (from .event())
mathsman5133 May 22, 2019
1ce1523
Update examples to work
mathsman5133 May 22, 2019
93c7fac
Utilise `._ready.clear()` and `set()` properly
mathsman5133 May 22, 2019
9818207
Remove the ext/events file and move into `coc.client.py`
mathsman5133 May 22, 2019
dee16a8
Update docs and examples with file paths changing
mathsman5133 May 22, 2019
8052b3c
Stop pip from whinging
mathsman5133 May 22, 2019
d4bb56e
BugFix: functions_dict is default None in `eventsclient.add_events`
mathsman5133 May 22, 2019
9773343
BugFix: pass http into wars
mathsman5133 May 22, 2019
a3a2881
Cache Updates:
mathsman5133 May 25, 2019
57f209c
BugFix: try_enum needs http parameter passed for `Clan` objects.
mathsman5133 May 25, 2019
bd9ad93
Override `EventsClient.default_cache` to not expire as won't work wit…
mathsman5133 May 25, 2019
c890ebd
BugFixes with using itertools.chain in wrong spots.
mathsman5133 May 25, 2019
2d0e8bd
Only log requests throttled as debug.
mathsman5133 May 25, 2019
7335ff1
Re-fix update cache stuff from ages ago
mathsman5133 May 25, 2019
a61359b
Bugfixes:
mathsman5133 May 26, 2019
044db01
Add enum `ACHIEVEMENT_ORDER` which is achievemts in order as API returns
mathsman5133 May 26, 2019
cc66df6
Bugfix: stop trying to find length of itertools chain
mathsman5133 May 26, 2019
6d06425
BugFixes: check to see if any war attacks to prevent type error
mathsman5133 May 28, 2019
f7da072
New Events:
mathsman5133 May 28, 2019
f14e422
BugFix: Handle case for when war has just started and cached attacks …
mathsman5133 May 29, 2019
7af3b36
Catch ValueError rather than KeyError
mathsman5133 May 29, 2019
87974ab
New Attribute: `type` for `CurrentWar` and `LeagueWar`
mathsman5133 May 29, 2019
04c5fb3
New Methods, Iterators and Classes.
mathsman5133 May 29, 2019
96b8b11
Utilise __slots__ wherever possible to speed up attribute access.
mathsman5133 May 30, 2019
95720fd
Timestamp: `time` has been renamed to `raw_time`, with `utc_timestamp…
mathsman5133 May 30, 2019
eba880f
BugFix: Client.loop needed to be ran through `nest_asyncio`
mathsman5133 May 31, 2019
ae33267
New Events: `on_clan_batch_updates`, same for `war`, `player`.
mathsman5133 Jun 1, 2019
2110c59
BugFix: resetting keys while using iterators.
mathsman5133 Jun 1, 2019
482d37a
Change `utc_timestamp` --> `time` in War.type
mathsman5133 Jun 2, 2019
586be7d
Add `ClanWar.status` property: status of war, ie. winning, losing, ti…
mathsman5133 Jun 2, 2019
1462718
Reverse order of `functions_dict` in `EventsClient.add_events` becaus…
mathsman5133 Jun 2, 2019
07f0f76
BugFix: forgot `EventsClient` is first arg
mathsman5133 Jun 2, 2019
b6893fa
Ditch asyncio events for now since impl. is confusing
mathsman5133 Jun 2, 2019
7d306e4
Add try block for deleting key as it sometimes unexpectedly dies.
mathsman5133 Jun 2, 2019
7f6009f
Return `ClanWar` if `league_group` is in `preparation` in `Client.get…
mathsman5133 Jun 2, 2019
bdd9a44
Try and debug batch updates
mathsman5133 Jun 2, 2019
a07eff8
BugFixes: Batch updates, passing player to achievement update, proper…
mathsman5133 Jun 2, 2019
8d5a8ae
BugFix: `cache.pop()` threw a KeyError here
mathsman5133 Jun 3, 2019
8215759
Encountered `ServerDisconnect` and other errors, so instead restart f…
mathsman5133 Jun 4, 2019
93c139b
BugFix: Stop Timestamp.time from throwing RecursionError.
mathsman5133 Jun 12, 2019
1e6ed01
Change how default cache works for EventsClient
mathsman5133 Jun 14, 2019
4827ee5
New Events: `on_clan_member_donation` and `on_clan_member_donation_re…
mathsman5133 Jun 14, 2019
55b45c9
Add a huge number of new events. Find them in :ref:`EventReference` i…
mathsman5133 Jun 17, 2019
83a67d6
Final fixes and version bump to v0.2.0
mathsman5133 Jun 17, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Quick Example
import coc
import asyncio

client = coc.Client('email', 'password')
client = coc.login('email', 'password')

async def get_some_player(tag):
player = await client.get_player(tag)
Expand Down
84 changes: 53 additions & 31 deletions coc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,22 @@
# -*- coding: utf-8 -*-

__version__ = '0.1.3'
__version__ = '0.2.0'

from .client import Client
from .dataclasses import (
from .clans import (
Clan,
BasicClan,
SearchClan,
BasicClan,
WarClan,
Player,
BasicPlayer,
WarMember,
SearchPlayer,
BaseWar,
WarLog,
CurrentWar,
Achievement,
Troop,
Hero,
Spell,
WarAttack,
Location,
League,
LeagueRankedPlayer,
Season,
LegendStatistics,
Badge,
Timestamp,
LeaguePlayer,
LeagueClan,
LeagueGroup,
LeagueWar,
LeagueWarLogEntry
LeagueClan
)
from .client import Client, EventsClient, login
from .enums import (
CacheType,
HOME_TROOP_ORDER,
BUILDER_TROOPS_ORDER,
SPELL_ORDER,
HERO_ORDER,
SIEGE_MACHINE_ORDER
)
from .errors import (
ClashOfClansException,
Expand All @@ -40,10 +25,47 @@
InvalidArgument,
InvalidCredentials,
Forbidden,
Maitenance
Maitenance,
GatewayError
)
from .http import HTTPClient
from .iterators import (
ClanIterator,
PlayerIterator,
ClanWarIterator,
LeagueWarIterator,
CurrentWarIterator
)
from .miscmodels import (
Achievement,
Badge,
EqualityComparable,
Hero,
League,
LegendStatistics,
Location,
Spell,
Troop,
Timestamp,

from .enums import (
CacheType
)
from .players import (
Player,
BasicPlayer,
SearchPlayer,
LeaguePlayer,
LeagueRankedPlayer,
WarMember
)
from .wars import (
BaseWar,
WarLog,
ClanWar,
WarAttack,
LeagueGroup,
LeagueWar,
LeagueWarLogEntry
)



58 changes: 50 additions & 8 deletions coc/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,31 @@ async def new_coro():
return new_coro()


def _wrap_store_coro(cache, key, coro):
def _wrap_store_coro(cache, key, coro, update_cache):
async def fctn():
value = await coro
cache[key] = value
if update_cache:
cache[key] = value

return value
return fctn()


def _try_wrap_store_coro(cache, key, data):
def _try_wrap_store_coro(cache, key, data, update_cache):
if inspect.isawaitable(data):
return _wrap_store_coro(cache, key, data)
return _wrap_store_coro(cache, key, data, update_cache)
if inspect.isasyncgen(data):
return data

cache[key] = data
if update_cache:
cache[key] = data

return data


class LRU(OrderedDict):
__slots__ = ('max_size', 'ttl')

def __init__(self, max_size, ttl):
self.max_size = max_size
self.ttl = ttl
Expand All @@ -79,7 +85,12 @@ def __getitem__(self, key):
self.check_expiry()

value = super().__getitem__(key)
self.move_to_end(key)

try:
self.move_to_end(key)
except KeyError:
pass

return value[1]

def __setitem__(self, key, value):
Expand Down Expand Up @@ -108,12 +119,20 @@ def check_max_size(self):


class Cache:
__slots__ = ('cache', 'ttl', 'max_size', 'fully_populated',
'_is_clan', '_is_player', '_is_war', '_is_static')

def __init__(self, max_size=128, ttl=None):
self.cache = LRU(max_size, ttl)
self.ttl = self.cache.ttl
self.max_size = self.cache.max_size
self.fully_populated = False

self._is_clan = False
self._is_player = False
self._is_war = False
self._is_static = False

def __call__(self, *args, **kwargs):
self.cache.check_expiry()

Expand All @@ -124,6 +143,7 @@ def wrapper(*args, **kwargs):
key = find_key(args, kwargs)
cache = kwargs.pop('cache', False)
fetch = kwargs.pop('fetch', True)
update_cache = kwargs.pop('update_cache', True)

if not key:
return func(*args, **kwargs)
Expand All @@ -133,7 +153,7 @@ def wrapper(*args, **kwargs):
else:
if fetch:
data = func(*args, **kwargs)
return _try_wrap_store_coro(self.cache, key, data)
return _try_wrap_store_coro(self.cache, key, data, update_cache)

else:
return None
Expand All @@ -144,7 +164,7 @@ def wrapper(*args, **kwargs):
else:
return None

return _try_wrap_store_coro(self.cache, key, data)
return _try_wrap_store_coro(self.cache, key, data, update_cache)

else:
log.debug('Using cached object with KEY: %s and VALUE: %s', key, data)
Expand Down Expand Up @@ -184,3 +204,25 @@ def get_limit(self, limit: int=None):
return self.get_all_values()

return self.get_all_values()[:limit]

def events_cache(self):
def deco(func):
@wraps(func)
def wrapper(*args, **kwargs):
event_name = args[1]
if event_name.endswith('batch_updates'):
return func(*args, **kwargs)

event_args = [n for n in args[1:]]
event_args.extend(kwargs.values())

key = f'{event_name}.{time.monotonic()}'

self.add(key, event_args)

return func(*args, **kwargs)
return wrapper
return deco



Loading