Module genshinstats.daily

Automatic sign-in for hoyolab's daily rewards.

Automatically claims the next daily reward in the daily check-in rewards.

Expand source code Browse git
"""Automatic sign-in for hoyolab's daily rewards.

Automatically claims the next daily reward in the daily check-in rewards.
"""
from typing import Any, Dict, Iterator, List, Mapping, NamedTuple, Optional
from urllib.parse import urljoin

from .caching import permanent_cache
from .genshinstats import fetch_endpoint
from .hoyolab import get_game_accounts
from .utils import recognize_server

__all__ = [
    "fetch_daily_endpoint",
    "get_daily_reward_info",
    "get_claimed_rewards",
    "get_monthly_rewards",
    "claim_daily_reward",
]

OS_URL = "https://hk4e-api-os.hoyoverse.com/event/sol/"  # overseas
OS_ACT_ID = "e202102251931481"
CN_URL = "https://api-takumi.mihoyo.com/event/bbs_sign_reward/"  # chinese
CN_ACT_ID = "e202009291139501"


class DailyRewardInfo(NamedTuple):
    signed_in: bool
    claimed_rewards: int


def fetch_daily_endpoint(endpoint: str, chinese: bool = False, **kwargs) -> Dict[str, Any]:
    """Fetch an enpoint for daily rewards"""
    url, act_id = (CN_URL, CN_ACT_ID) if chinese else (OS_URL, OS_ACT_ID)
    kwargs.setdefault("params", {})["act_id"] = act_id
    url = urljoin(url, endpoint)

    return fetch_endpoint(url, **kwargs)


def get_daily_reward_info(
    chinese: bool = False, cookie: Mapping[str, Any] = None
) -> DailyRewardInfo:
    """Fetches daily award info for the currently logged-in user.

    Returns a tuple - whether the user is logged in, how many total rewards the user has claimed so far
    """
    data = fetch_daily_endpoint("info", chinese, cookie=cookie)
    return DailyRewardInfo(data["is_sign"], data["total_sign_day"])


@permanent_cache("chinese", "lang")
def get_monthly_rewards(
    chinese: bool = False, lang: str = "en-us", cookie: Mapping[str, Any] = None
) -> List[Dict[str, Any]]:
    """Gets a list of avalible rewards for the current month"""
    return fetch_daily_endpoint("home", chinese, cookie=cookie, params=dict(lang=lang))["awards"]


def get_claimed_rewards(
    chinese: bool = False, cookie: Mapping[str, Any] = None
) -> Iterator[Dict[str, Any]]:
    """Gets all claimed awards for the currently logged-in user"""
    current_page = 1
    while True:
        data = fetch_daily_endpoint(
            "award", chinese, cookie=cookie, params=dict(current_page=current_page)
        )["list"]
        yield from data
        if len(data) < 10:
            break
        current_page += 1


def claim_daily_reward(
    uid: int = None, chinese: bool = False, lang: str = "en-us", cookie: Mapping[str, Any] = None
) -> Optional[Dict[str, Any]]:
    """Signs into hoyolab and claims the daily rewards.

    Chinese and overseas servers work a bit differently,
    so you must specify whether you want to claim rewards for chinese accounts.

    When claiming rewards for other users you may add a cookie argument.

    Returns the claimed reward or None if the reward cannot be claimed yet.
    """
    signed_in, claimed_rewards = get_daily_reward_info(chinese, cookie)
    if signed_in:
        return None

    params = {}

    if chinese:
        if uid is None:
            accounts = get_game_accounts(chinese=True, cookie=cookie)
            params["game_uid"] = accounts[0]["game_uid"]
            params["region"] = accounts[0]["region"]
        else:
            params["game_uid"] = uid
            params["region"] = recognize_server(uid)

    params["lang"] = lang

    fetch_daily_endpoint("sign", chinese, cookie=cookie, method="POST", params=params)
    rewards = get_monthly_rewards(chinese, lang, cookie)
    return rewards[claimed_rewards]

Functions

def claim_daily_reward(uid: int = None, chinese: bool = False, lang: str = 'en-us', cookie: Mapping[str, Any] = None) ‑> Optional[Dict[str, Any]]

Signs into hoyolab and claims the daily rewards.

Chinese and overseas servers work a bit differently, so you must specify whether you want to claim rewards for chinese accounts.

When claiming rewards for other users you may add a cookie argument.

Returns the claimed reward or None if the reward cannot be claimed yet.

Expand source code Browse git
def claim_daily_reward(
    uid: int = None, chinese: bool = False, lang: str = "en-us", cookie: Mapping[str, Any] = None
) -> Optional[Dict[str, Any]]:
    """Signs into hoyolab and claims the daily rewards.

    Chinese and overseas servers work a bit differently,
    so you must specify whether you want to claim rewards for chinese accounts.

    When claiming rewards for other users you may add a cookie argument.

    Returns the claimed reward or None if the reward cannot be claimed yet.
    """
    signed_in, claimed_rewards = get_daily_reward_info(chinese, cookie)
    if signed_in:
        return None

    params = {}

    if chinese:
        if uid is None:
            accounts = get_game_accounts(chinese=True, cookie=cookie)
            params["game_uid"] = accounts[0]["game_uid"]
            params["region"] = accounts[0]["region"]
        else:
            params["game_uid"] = uid
            params["region"] = recognize_server(uid)

    params["lang"] = lang

    fetch_daily_endpoint("sign", chinese, cookie=cookie, method="POST", params=params)
    rewards = get_monthly_rewards(chinese, lang, cookie)
    return rewards[claimed_rewards]
def fetch_daily_endpoint(endpoint: str, chinese: bool = False, **kwargs) ‑> Dict[str, Any]

Fetch an enpoint for daily rewards

Expand source code Browse git
def fetch_daily_endpoint(endpoint: str, chinese: bool = False, **kwargs) -> Dict[str, Any]:
    """Fetch an enpoint for daily rewards"""
    url, act_id = (CN_URL, CN_ACT_ID) if chinese else (OS_URL, OS_ACT_ID)
    kwargs.setdefault("params", {})["act_id"] = act_id
    url = urljoin(url, endpoint)

    return fetch_endpoint(url, **kwargs)
def get_claimed_rewards(chinese: bool = False, cookie: Mapping[str, Any] = None) ‑> Iterator[Dict[str, Any]]

Gets all claimed awards for the currently logged-in user

Expand source code Browse git
def get_claimed_rewards(
    chinese: bool = False, cookie: Mapping[str, Any] = None
) -> Iterator[Dict[str, Any]]:
    """Gets all claimed awards for the currently logged-in user"""
    current_page = 1
    while True:
        data = fetch_daily_endpoint(
            "award", chinese, cookie=cookie, params=dict(current_page=current_page)
        )["list"]
        yield from data
        if len(data) < 10:
            break
        current_page += 1
def get_daily_reward_info(chinese: bool = False, cookie: Mapping[str, Any] = None) ‑> genshinstats.daily.DailyRewardInfo

Fetches daily award info for the currently logged-in user.

Returns a tuple - whether the user is logged in, how many total rewards the user has claimed so far

Expand source code Browse git
def get_daily_reward_info(
    chinese: bool = False, cookie: Mapping[str, Any] = None
) -> DailyRewardInfo:
    """Fetches daily award info for the currently logged-in user.

    Returns a tuple - whether the user is logged in, how many total rewards the user has claimed so far
    """
    data = fetch_daily_endpoint("info", chinese, cookie=cookie)
    return DailyRewardInfo(data["is_sign"], data["total_sign_day"])
def get_monthly_rewards(chinese: bool = False, lang: str = 'en-us', cookie: Mapping[str, Any] = None) ‑> List[Dict[str, Any]]

Gets a list of avalible rewards for the current month

Expand source code Browse git
@permanent_cache("chinese", "lang")
def get_monthly_rewards(
    chinese: bool = False, lang: str = "en-us", cookie: Mapping[str, Any] = None
) -> List[Dict[str, Any]]:
    """Gets a list of avalible rewards for the current month"""
    return fetch_daily_endpoint("home", chinese, cookie=cookie, params=dict(lang=lang))["awards"]