Skip to content

Commit

Permalink
2.2.0
Browse files Browse the repository at this point in the history
This update takes Star Rail Card to the next level!!


Added support:

* EnkaNetwork Build - Allows you to get all your assemblies from the EnkaNetwork website
* HoYoLab API - Gives you the opportunity to get ALL your characters

* Added the ability to set a custom image for each build.
* Added the ability to work with all currently available APIs
* The result of the work received new arguments
* Added additional main class.
* Added new function for getting assemblies.
* Improved work with API - Now this is not only the best module for generating cards, but also an excellent wrapper for all APIs
* Added a dependency on genshin.py if you want to use the HoYoLab API


At the moment the code looks a little terrible and there is also a lack of documentation, but this will be fixed soon

Signed-off-by: Deviant <112615715+DEViantUA@users.noreply.github.com>
  • Loading branch information
DEViantUA authored May 22, 2024
1 parent c8822ff commit 43ee000
Show file tree
Hide file tree
Showing 14 changed files with 1,474 additions and 60 deletions.
2 changes: 1 addition & 1 deletion starrailcard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

__title__ = 'StarRailCard.py'
__author__ = 'DeviantUa'
__version__ = '2.1.9'
__version__ = '2.2.0'
__license__ = 'MIT'
__copyright__ = 'Copyright 2024-present DeviantUa'

Expand Down
288 changes: 283 additions & 5 deletions starrailcard/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,193 @@

import anyio
from typing import Union
#import asyncio
import asyncio

from .src.tools import cache, http, ukrainization, options, translator, git
from .src.generator import style_relict_score, style_ticket, style_profile_phone, style_card
from .src.api import api, enka
from .src.api import api, enka, error, hoyolab
from .src.model import StarRailCard,api_mihomo
from .src.tools.pill import image_control


class HoYoCard:
def __init__(self, cookie: dict, lang: str = "en", character_art = None, character_id = None, seeleland: bool = False,
user_font = None, save: bool = False, asset_save: bool = False, boost_speed: bool = False, remove_logo: bool = False,
cache = {"maxsize": 150, "ttl": 300}, proxy: str = None, color: dict = None):

self.lang = lang
self.character_art = character_art
self.character_id = character_id
self.seeleland = seeleland
self.user_font = user_font
self.save = save
self.asset_save = asset_save
self.remove_logo = remove_logo
self.cache = cache
self.boost_speed = boost_speed
self.proxy = proxy
self.color = color
self.cookie = cookie

async def __aenter__(self):
cache.Cache.get_cache(maxsize = self.cache.get("maxsize", 150), ttl = self.cache.get("ttl", 300))
await http.AioSession.enter(self.proxy)

await git.ImageCache.set_assets_download(self.asset_save)

if self.character_id:
self.character_id = await options.get_charter_id(self.character_id)

if self.character_art:
if not isinstance(self.character_art, dict):
raise TypeError(4,"The character_art parameter must be a dictionary, where the key is the name of the character, and the parameter is an image.\nExample: character_art = {'1235': 'img.png', '1235': ['img.png','http.../img2.png']} or {'123596': 'img.png', '123854': 'http.../img2.png', ...}")
else:
self.character_art = await options.get_character_art(self.character_art)

if not self.lang in translator.SUPPORTED_LANGUAGES:
self.lang = "en"

if self.lang == "ua":
await ukrainization.TranslateDataManager().check_update()

self.translateLang = translator.Translator(self.lang)

if self.user_font:
await git.change_font(font_path = self.user_font)

image_control._boost_speed = self.boost_speed


if isinstance(self.color, dict):
self.color = await options.get_color_user(self.color)

if self.remove_logo:
print("""
Thank you for using our StarRailCard!
By removing the GitHub logo from the generated results, you acknowledge supporting the author through one of the following links:
- Patreon: https://www.patreon.com/deviantapi/membership
- Ko-fi: https://ko-fi.com/dezzso
Failure to contribute to the project may lead to the author discontinuing updates in the future.
""")
return self

async def __aexit__(self, exc_type, exc, tb):
await http.AioSession.exit(exc_type, exc, tb)

async def set_lang(self, lang):
"""Sets the language
Args:
lang (str): lang (str): Language in which generation will take place, supported languages: cht, cn, de, en, es, fr, id, jp, kr, pt, ru, th, vi, ua . Defaults to "en".
"""
if not lang in translator.SUPPORTED_LANGUAGES:
lang = "en"
self.lang = "en"
else:
self.lang = lang

if lang == "ua":
await ukrainization.TranslateDataManager().check_update()

self.translateLang = translator.Translator(lang)

async def set_user_font(self, user_font: str):
"""Will install a custom font
Args:
user_font (srt): Font path or font name.
"""
await git.change_font(font_path = user_font)

async def create(self, uid: Union[int,str], style: int = 1, hide_uid: bool = False):
"""Function for generating character cards
Args:
uid (int): UID of the user in the game
style (int, optional): Card style. Defaults to 1.
hide_uid (bool, optional): Hide UID. Defaults to False.
Returns:
StarRail: A class object containing profile information and a character cards
"""
try:
data = await hoyolab.HoYoLabApi(uid, lang= self.lang).get(self.cookie)
except Exception as e:
print(e)
raise error.StarRailCardError(8, "To use the HoYoLab API you need to download/update the asset")

result = []
style, style_settings = await options.style_setting(style, None)

try:
player = data.player.model_dump()
except:
player = data.player

response = {
"settings": {
"uid": int(uid),
"lang": self.lang,
"hide_uid": hide_uid,
"save": self.save,
"force_update": False,
"style": int(style)
},
"player": player,
"card": None,
"character_name": [],
"character_id": [],
}

async with anyio.create_task_group() as tasks:

for key in data.characters:
async def get_result(key):
try:
response["character_id"].append(key.id)
response["character_name"].append(key.name)

if self.character_id:
if not str(key.id) in self.character_id:
return

if self.color:
color = self.color.get(str(key.id))
else:
color = None

art = None
if self.character_art:
if str(key.id) in self.character_art:
art = self.character_art[str(key.id)]
if style == 1:
result.append(await style_relict_score.Create(key,self.translateLang,art,hide_uid,uid, self.seeleland,self.remove_logo, color).start(True))
elif style == 2:
result.append(await style_ticket.Create(key,self.translateLang,art,hide_uid,uid, self.seeleland,self.remove_logo, color).start(True))
elif style == 3:
result.append(await style_card.Create(key,self.translateLang,art,hide_uid,uid, self.seeleland,self.remove_logo, color).start(True))
except Exception as e:
print(f"Error in get_result for character {key.id}: {e}")

tasks.start_soon(get_result, key)

response["card"] = result

if self.lang == "ua":
StarRailCard.UA_LANG = True
else:
StarRailCard.UA_LANG = False

if self.save:
async with anyio.create_task_group() as tasks:
for key in response["card"]:
if key["animation"]:
continue
tasks.start_soon(options.save_card,uid,key["card"],key["id"])

return StarRailCard.StarRail(**response)


class Card:
def __init__(self, lang: str = "en", character_art = None, character_id = None, seeleland: bool = False,
Expand Down Expand Up @@ -123,7 +301,7 @@ async def set_user_font(self, user_font: str):
user_font (srt): Font path or font name.
"""
await git.change_font(font_path = user_font)

async def create_profile(self, uid: Union[int,str], style: bool = 1, hide_uid: bool = False, background = None, force_update: bool = False):
"""Function for generating a user profile card
Expand Down Expand Up @@ -185,7 +363,7 @@ async def create_profile(self, uid: Union[int,str], style: bool = 1, hide_uid: b

return StarRailCard.StarRail(**response)

async def create(self, uid: Union[int,str], style: int = 1, hide_uid: bool = False, force_update: bool = False, style_settings = None, log: bool = False):
async def create(self, uid: Union[int,str], style: int = 1, hide_uid: bool = False, force_update: bool = False, style_settings = None):
"""Function for generating character cards
Args:
Expand Down Expand Up @@ -235,7 +413,7 @@ async def create(self, uid: Union[int,str], style: int = 1, hide_uid: bool = Fal
"character_name": [],
"character_id": [],
}

async with anyio.create_task_group() as tasks:

for key in data.characters:
Expand Down Expand Up @@ -282,4 +460,104 @@ async def get_result(key):
continue
tasks.start_soon(options.save_card,uid,key["card"],key["id"])

return StarRailCard.StarRail(**response)


async def create_build(self, uid: Union[int,str], name: str, hash: str, style: int = 1, hide_uid: bool = False):
"""Function for generating character cards
Args:
uid (int): UID of the user in the game
name (str): NickName EnkaNetwork
hash (str): hash obtained using the method: get_hash()
style (int, optional): Card style. Defaults to 1.
hide_uid (bool, optional): Hide UID. Defaults to False.
style_settings (dict, optional): not implemented yet. Defaults to None.
Returns:
StarRail: A class object containing profile information and a character cards
"""

if self.api_data is None:
try:
data = await enka.ApiEnkaNetwork().get_build(name, hash, uid)
except Exception as e:
print(e)
raise error.StarRailCardError(8, "To use the HoYoLab API you need to download/update the asset")
else:
data = self.api_data

result = []

style, style_settings = await options.style_setting(style, None)

try:
player = data.player.model_dump()
except:
player = data.player

response = {
"settings": {
"uid": int(uid),
"lang": self.lang,
"hide_uid": hide_uid,
"save": self.save,
"force_update": False,
"style": int(style)
},
"player": player,
"card": None,
"character_name": [],
"character_id": [],
}

async with anyio.create_task_group() as tasks:

for key in data.characters:
async def get_result(key):
try:
response["character_id"].append(key.id)
response["character_name"].append(key.name)

if self.character_id:
if not str(key.id) in self.character_id:
return

if self.color:
color = self.color.get(str(key.id))
else:
color = None

art = None
if self.character_art:
if str(key.id) in self.character_art:
art = self.character_art[str(key.id)]
if str(key.build["id"]) in self.character_art:
art = self.character_art[str(key.build["id"])]
if style == 1:
result.append(await style_relict_score.Create(key,self.translateLang,art,hide_uid,uid, self.seeleland,self.remove_logo, color).start(build= key.build))
elif style == 2:
result.append(await style_ticket.Create(key,self.translateLang,art,hide_uid,uid, self.seeleland,self.remove_logo, color).start(build= key.build))
elif style == 3:
result.append(await style_card.Create(key,self.translateLang,art,hide_uid,uid, self.seeleland,self.remove_logo, color).start(build= key.build))
except Exception as e:
print(f"Error in get_result for character {key.id}: {e}")

tasks.start_soon(get_result, key)

response["card"] = result

if self.lang == "ua":
StarRailCard.UA_LANG = True
else:
StarRailCard.UA_LANG = False

if self.save:
async with anyio.create_task_group() as tasks:
for key in response["card"]:
print(key)
if key["animation"]:
continue
tasks.start_soon(options.save_card,uid,key["card"],f'{key["id"]}_{key["build"]["name_build"]}')

return StarRailCard.StarRail(**response)
11 changes: 5 additions & 6 deletions starrailcard/src/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,8 @@ def __init__(self, uid: str, lang: str = "en", v: int = 2, force_update: bool =
api_mihomo.UA_LANG = True

self.v = v

async def recollect(self, data):

pass

async def get(self) -> Optional[api_mihomo.MiHoMoApi]:
async def get(self, parse: bool = True) -> Optional[api_mihomo.MiHoMoApi]:
"""Get data from the MiHoMo API."""
try:
params = {
Expand Down Expand Up @@ -72,7 +68,10 @@ async def get(self) -> Optional[api_mihomo.MiHoMoApi]:
if self.ua_lang:
await ukrainization.TranslateDataManager().load_translate_data()

return api_mihomo.MiHoMoApi(player=data["player"], characters=data["characters"], dont_update_link= False)
if parse:
return api_mihomo.MiHoMoApi(player=data["player"], characters=data["characters"], dont_update_link= False)
else:
return data

async def add_info(self, data):
info = self.dop_info["detailInfo"]["recordInfo"]
Expand Down
Loading

0 comments on commit 43ee000

Please sign in to comment.