Skip to content

Commit

Permalink
Upgrade EnkaNetwork.py
Browse files Browse the repository at this point in the history
- add http client
- update example

- add aenter, aexit for auto close client
  • Loading branch information
staciax committed Aug 4, 2022
1 parent cae329d commit 3ec03d9
Show file tree
Hide file tree
Showing 25 changed files with 475 additions and 232 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ build
enkanetwork.py.egg-info
dist
test/*.test.py
.pytest_cache
.pytest_cache
.idea
17 changes: 9 additions & 8 deletions enkanetwork/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from .client import * # noqa: F403
from .exception import * # noqa: F403
from .model import * # noqa: F403
from .utils import * # noqa: F403
from .info import * # noqa: F403
from .cache import * # noqa: F403
from .client import *
from .exception import *
from .model import *
from .utils import *
from .info import *
from .cache import *
from .enum import *

__VERSION__ = VERSION # noqa: F405
__AUTHOR__ = AUTHOR # noqa: F405
__VERSION__ = VERSION
__AUTHOR__ = AUTHOR
11 changes: 7 additions & 4 deletions enkanetwork/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
import os
import logging

from typing import Dict, Union, List
from io import TextIOWrapper
from typing import Dict, List, TextIO

from .enum import Language
from .model import assets
from .utils import create_ui_path

from typing import Union

PATH = os.path.dirname(os.path.abspath(__file__))

LOGGER = logging.getLogger(__name__)
Expand All @@ -19,7 +20,7 @@ class Assets:
HASH_MAP: Dict[str, dict] = {}
LANGS: Language = Language.EN

def __init__(self, lang: Language = Language.EN) -> None:
def __init__(self, lang: Union[str, Language] = Language.EN) -> None:
# Set language
self._set_language(lang)
self.reload_assets()
Expand Down Expand Up @@ -180,7 +181,9 @@ def __load_assets_data(cls) -> None:
FILE_DATA = os.listdir(_PATH)
for FILENAME in FILE_DATA:
LOGGER.debug(f"Loading data file {FILENAME}...")

cls.DATA[FILENAME.split(".")[0]] = json.load(cls.__load(os.path.join(_PATH, FILENAME))) # noqa: E501

def __load(path: str) -> TextIOWrapper:
@staticmethod
def __load(path: str) -> TextIO:
return open(path, "r", encoding="utf-8")
1 change: 1 addition & 0 deletions enkanetwork/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from cachetools import TTLCache

__all__ = ('Cache',)

class Cache:
def __init__(self, maxsize, ttl):
Expand Down
94 changes: 43 additions & 51 deletions enkanetwork/client.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import logging
import os
import json

from typing import Union
from __future__ import annotations

import logging
from .http import HTTPClient
from .model import EnkaNetworkResponse
from .exception import VaildateUIDError, UIDNotFounded
from .assets import Assets
from .utils import create_path, validate_uid, request
from .enum import Language
from .cache import Cache

from typing import Union, Optional, Type, TYPE_CHECKING

if TYPE_CHECKING:
from typing_extensions import Self
from types import TracebackType

__all__ = ("EnkaNetworkAPI",)

class EnkaNetworkAPI:

LOGGER = logging.getLogger(__name__)
RAWDATA = "https://raw.githubusercontent.com/mrwan200/enkanetwork.py-data/{PATH}" # noqa: E501

def __init__(self, lang: str = "en", debug: bool = False, key: str = "", cache: bool = True, agent: str = "") -> None: # noqa: E501
def __init__(self, lang: str = "en", *, debug: bool = False, key: str = "", cache: bool = True, agent: str = "") -> None: # noqa: E501
# Logging
logging.basicConfig()
logging.getLogger("enkanetwork").setLevel(logging.DEBUG if debug else logging.ERROR) # noqa: E501
Expand All @@ -28,11 +31,25 @@ def __init__(self, lang: str = "en", debug: bool = False, key: str = "", cache:
self._enable_cache = cache
self.cache = Cache(1024, 60 * 3)

# Custom User-Agent
self.__agent = agent
# http client
self.__http = HTTPClient(key=key, agent=agent)
self._closed = False

# Key
self.__key = key
async def __aenter__(self) -> Self:
return self

async def __aexit__(
self,
exc_type: Optional[Type[BaseException]],
exc_value: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
self._close = True
if self._close:
await self.__http.close()

def is_closed(self) -> bool:
return self._closed

@property
def lang(self) -> Language:
Expand All @@ -50,60 +67,35 @@ async def set_language(self, lang: Language) -> None:

async def fetch_user(self, uid: Union[str, int]) -> EnkaNetworkResponse:
self.LOGGER.debug(f"Validating with UID {uid}...")
if not validate_uid(str(uid)):
raise VaildateUIDError("Validate UID failed. Please check your UID.") # noqa: E501

user = await self.__http.fetch_user(uid)

data = user["content"]

self.LOGGER.debug(f"Fetching user with UID {uid}...")

if self._enable_cache:
self.LOGGER.warn("Getting data from cache...")
data = await self.cache.get(uid)
self.LOGGER.debug("Caching data...")
await self.cache.set(uid, data)

if data is not None:
# Return data
self.LOGGER.debug("Parsing data...")
return EnkaNetworkResponse.parse_obj(data)

headers = {}
if self.__agent != "":
headers["User-Agent"] = self.__agent

resp = await request(url=create_path(f"u/{uid}/__data.json" + ("?key={key}" if self.__key else "")), headers=headers) # noqa: E501

# Check if status code is not 200 (Ex. 500)
if resp["status"] != 200:
raise UIDNotFounded(f"UID {uid} not found.")

# Parse JSON data
data = resp["content"]

if not data:
raise UIDNotFounded(f"UID {uid} not found.")

self.LOGGER.debug("Got data from EnkaNetwork.")
self.LOGGER.debug(f"Raw data: {data}")

if self._enable_cache:
self.LOGGER.debug("Caching data...")
await self.cache.set(uid, data)

# Return data
self.LOGGER.debug("Parsing data...")
return EnkaNetworkResponse.parse_obj(data)

async def update_assets(self) -> None:
print("Updating assets...")
self.LOGGER.debug("Downloading new content...")
_PATH = Assets._get_path_assets()
for folder in _PATH:
for filename in os.listdir(_PATH[folder]):
self.LOGGER.debug(f"Downloading {folder} file {filename}...")
_json = await request(
url=self.RAWDATA.format(PATH=f"master/exports/{folder}/{filename}") # noqa: E501
)

self.LOGGER.debug(f"Writing {folder} file {filename}...")
with open(os.path.join(_PATH[folder], filename), "w", encoding="utf-8") as f: # noqa: E501
json.dump(_json["content"], f, ensure_ascii=False, indent=4) # noqa: E501

# get path
path = Assets._get_path_assets()

# update assets
await self.__http.update_asset(path)

# Reload config
self.assets.reload_assets()
7 changes: 7 additions & 0 deletions enkanetwork/enum.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
from enum import Enum

__all__ = (
'Language',
'EquipmentsType',
'DigitType',
'ElementType',
'EquipType'
)

class Language(str, Enum):
EN = "en"
Expand Down
15 changes: 14 additions & 1 deletion enkanetwork/exception.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
class VaildateUIDError(Exception):
""" Raised when the UID is not valid. """
pass


class UIDNotFounded(Exception):
""" Raised when the UID is not found. """
pass

class HTTPException(Exception):
""" Exception that's raised when an HTTP request operation fails. """
pass

class Forbidden(HTTPException):
""" Exception that's raised for when status code 403 occurs."""
pass

class EnkaServerError(HTTPException):
""" Exception that's raised for when status code 500 occurs."""
pass
Loading

0 comments on commit 3ec03d9

Please sign in to comment.