mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-28 10:45:19 +00:00
110 lines
3.1 KiB
Python
110 lines
3.1 KiB
Python
import os
|
|
import re
|
|
import sys
|
|
|
|
from module.base.decorator import cached_property
|
|
from module.logger import logger
|
|
|
|
"""
|
|
Importing pkg_resources is so slow, like 0.4 ~ 1.0s, just google it you will find it indeed really slow.
|
|
Since it was some kind of standard library there is no way to modify it or speed it up.
|
|
So here's a poor but fast implementation of pkg_resources returning the things in need.
|
|
|
|
To patch:
|
|
```
|
|
# Patch pkg_resources before importing adbutils and uiautomator2
|
|
from module.device.pkg_resources import get_distribution
|
|
# Just avoid being removed by import optimization
|
|
_ = get_distribution
|
|
```
|
|
"""
|
|
# Inject sys.modules, pretend we have pkg_resources imported
|
|
try:
|
|
sys.modules['pkg_resources'] = sys.modules['module.device.pkg_resources']
|
|
except KeyError:
|
|
logger.error('Patch pkg_resources failed, patch module does not exists')
|
|
|
|
|
|
def remove_suffix(s, suffix):
|
|
"""
|
|
Remove suffix of a string or bytes like `string.removesuffix(suffix)`, which is on Python3.9+
|
|
|
|
Args:
|
|
s (str, bytes):
|
|
suffix (str, bytes):
|
|
|
|
Returns:
|
|
str, bytes:
|
|
"""
|
|
return s[:-len(suffix)] if s.endswith(suffix) else s
|
|
|
|
|
|
class FakeDistributionObject:
|
|
def __init__(self, dist, version):
|
|
self.dist = dist
|
|
self.version = version
|
|
|
|
def __str__(self):
|
|
return f'{self.__class__.__name__}({self.dist}={self.version})'
|
|
|
|
__repr__ = __str__
|
|
|
|
|
|
class PackageCache:
|
|
@cached_property
|
|
def site_packages(self):
|
|
# Just whatever library to locate the `site-packages` directory
|
|
import requests
|
|
path = os.path.abspath(os.path.join(requests.__file__, '../../'))
|
|
return path
|
|
|
|
@cached_property
|
|
def dict_installed_packages(self):
|
|
"""
|
|
Returns:
|
|
dict: Key: str, package name
|
|
Value: FakeDistributionObject
|
|
"""
|
|
dic = {}
|
|
for file in os.listdir(self.site_packages):
|
|
# mxnet_cu101-1.6.0.dist-info
|
|
# adbutils-0.11.0-py3.7.egg-info
|
|
res = re.match(r'^([a-zA-Z0-9._]+)-([a-zA-Z0-9._]+)-', file)
|
|
if res:
|
|
version = remove_suffix(res.group(2), '.dist')
|
|
# version = res.group(2)
|
|
obj = FakeDistributionObject(
|
|
dist=res.group(1),
|
|
version=version,
|
|
)
|
|
dic[obj.dist] = obj
|
|
|
|
return dic
|
|
|
|
|
|
PACKAGE_CACHE = PackageCache()
|
|
|
|
|
|
def resource_filename(*args):
|
|
if args == ("adbutils", "binaries"):
|
|
path = os.path.abspath(os.path.join(PACKAGE_CACHE.site_packages, *args))
|
|
return path
|
|
|
|
|
|
def get_distribution(dist):
|
|
"""Return a current distribution object for a Requirement or string"""
|
|
if dist == 'adbutils':
|
|
return PACKAGE_CACHE.dict_installed_packages.get(
|
|
'adbutils',
|
|
FakeDistributionObject('adbutils', '0.11.0'),
|
|
)
|
|
if dist == 'uiautomator2':
|
|
return PACKAGE_CACHE.dict_installed_packages.get(
|
|
'uiautomator2',
|
|
FakeDistributionObject('uiautomator2', '2.16.17'),
|
|
)
|
|
|
|
|
|
class DistributionNotFound(Exception):
|
|
pass
|