Skip to content

Commit

Permalink
Tracemoe格式化
Browse files Browse the repository at this point in the history
  • Loading branch information
kitUIN committed Nov 20, 2020
1 parent 09e66ea commit 8057d77
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 160 deletions.
24 changes: 9 additions & 15 deletions PicImageSearch/saucenao.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,6 @@ def __init__(self, resp):
self.minimum_similarity: float = resp_header['minimum_similarity']
self.results_returned: int = resp_header['results_returned']

@staticmethod
def _sort(data):
if data is None:
return []
sorts = sorted(data, key=lambda r: float(r['header']['similarity']), reverse=True)
return sorts

def __repr__(self):
return (f'<SauceResponse(count={repr(len(self.raw))}, long_remaining={repr(self.long_remaining)}, '
f'short_remaining={repr(self.short_remaining)})>')
Expand All @@ -124,14 +117,14 @@ def __init__(self,
db: int = 999,
) -> None:
"""
:param api_key:(str)用于SauceNAO的访问密钥 默认=None
:param api_key:(str)用于SauceNAO的访问密钥 (默认=None)
:param output_type:(int) 0=正常(默认) html 1=xml api(未实现) 2=json api 默认=2
:param testmode:(int) 测试模式 0=正常 1=测试 默认=0
:param numres:(int)输出数量 默认=5
:param dbmask:(int)用于选择要启用的特定索引的掩码 默认=None
:param dbmaski:(int)用于选择要禁用的特定索引的掩码 默认=None
:param db:(int)搜索特定的索引号或全部索引 默认=999,索引见https://saucenao.com/tools/examples/api/index_details.txt
:param minsim:(int)控制最小相似度 默认=30
:param testmode:(int) 测试模式 0=正常 1=测试 (默认=0)
:param numres:(int)输出数量 (默认=5)
:param dbmask:(int)用于选择要启用的特定索引的掩码 (默认=None)
:param dbmaski:(int)用于选择要禁用的特定索引的掩码 (默认=None)
:param db:(int)搜索特定的索引号或全部索引 (默认=999),索引见https://saucenao.com/tools/examples/api/index_details.txt
:param minsim:(int)控制最小相似度 (默认=30)
:param hide:(int)结果隐藏控制,无=0,明确返回值(默认)=1,怀疑返回值=2,全部返回值=3
"""
# minsim 控制最小相似度
Expand All @@ -148,7 +141,8 @@ def __init__(self,
params['hide'] = hide
params['db'] = db
params['minsim'] = minsim
params['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36 Edg/86.0.622.63'
params[
'User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36 Edg/86.0.622.63'
self.params = params

def search(self, url: str, files=None):
Expand Down
211 changes: 112 additions & 99 deletions PicImageSearch/tracemoe.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,85 @@
from loguru import logger


# todo 完善注释
class TraceMoeNorm:
def __init__(self, data, mute=False):
self.origin: dict = data
self.From: int = data['from'] # 匹配场景的开始时间
self.To: int = data['to'] # 匹配场景的结束时间
self.anilist_id: int = data['anilist_id'] # 匹配的Anilist ID见https://anilist.co/
self.at: int = data['at'] # 匹配场景的确切时间
self.season: str = data['season'] # 发布时间
self.anime: str = data['anime'] # 番剧名字
self.filename: str = data['filename'] # 找到匹配项的文件名
self.episode: int = data['episode'] # 估计的匹配的番剧的集数
self.tokenthumb: str = data['tokenthumb'] # 用于生成预览的token
self.similarity: float = float(data['similarity']) # 相似度,相似性低于 87% 的搜索结果可能是不正确的结果
self.title: str = data['title'] # 番剧名字
self.title_native: str = data['title_native'] # 番剧世界命名
self.title_chinese: str = data['title_chinese'] # 番剧中文命名
self.title_english: str = data['title_english'] # 番剧英文命名
self.title_romaji: str = data['title_romaji'] # 番剧罗马命名
self.mal_id: int = data['mal_id'] # 匹配的MyAnimelist ID见https://myanimelist.net/
self.synonyms: list = data['synonyms'] # 备用英文标题
self.synonyms_chinese: list = data['synonyms_chinese'] # 备用中文标题
self.is_adult: bool = data['is_adult'] # 是否R18
self.thumbnail: str = self._preview_image()
self.video_thumbnail: str = self._preview_video(mute)

def _preview_image(self): # 图片预览图
# parse.quote()用于网页转码
url = "https://trace.moe/thumbnail.php" \
"?anilist_id={}&file={}&t={}&token={}".format(self.anilist_id, parse.quote(self.filename), self.at,
self.tokenthumb)
return url

def _preview_video(self, mute=False):
"""
创建预览视频
:param mute:预览视频是否静音,True为静音
:return: 预览视频url地址
"""
url = "https://media.trace.moe/video/" \
"{}/{}?t={}&token={}".format(self.anilist_id, parse.quote(self.filename), self.at,
self.tokenthumb)
if mute:
url = url + '&mute'
return url

def __repr__(self):
return f'<NormTraceMoe(title={repr(self.title_chinese)}, similarity={self.similarity:.2f})>'


class TraceMoeResponse:
def __init__(self, resp,mute):
self.raw: list = []
resp_docs = resp['docs']
for i in resp_docs:
self.raw.append(TraceMoeNorm(i,mute=mute))
self.origin: dict = resp
self.RawDocsCount: int = resp['RawDocsCount'] # 搜索的帧总数
self.RawDocsSearchTime: int = resp['RawDocsSearchTime'] # 从数据库检索帧所用的时间
self.ReRankSearchTime: int = resp['ReRankSearchTime'] # 比较帧所用的时间
self.CacheHit: bool = resp['CacheHit'] # 是否缓存搜索结果
self.trial: int = resp['trial'] # 搜索时间
self.limit: int = resp['limit'] # 剩余搜索限制数
self.limit_ttl: int = resp['limit_ttl'] # 限制重置之前的时间(秒)
self.quota: int = resp['quota'] # 剩余搜索配额数
self.quota_ttl: int = resp['quota_ttl'] # 配额重置之前的时间(秒)

def __repr__(self):
return (f'<TraceMoeResponse(count={repr(len(self.raw))}, RawDocsCount={repr(self.RawDocsCount)}, '
f'RawDocsSearchTime={repr(self.RawDocsSearchTime)},trial={repr(self.trial)})>')


class TraceMoe:
def __init__(self):
self.Url = 'https://trace.moe/api/search' # 按图像 URL 搜索
self.img = '' # 本地图片base64转码结果
self.raws = []
TraceMoeURL = 'https://trace.moe/api/search'

def __init__(self, mute=False):
"""
:param mute: 预览视频是否静音(默认不静音)
"""
self.mute: bool = mute

@staticmethod
def _base_64(filename):
Expand All @@ -19,12 +92,9 @@ def _base_64(filename):
# print('本地base64转码~')
return coding.decode()

'''
def errors(self,code):
if code == 200:
response = 'trace.moe访问正常。'
return response
elif code == 413:
@staticmethod
def _errors(code):
if code == 413:
response = '图片体积太大。'
return response
elif code == 400:
Expand All @@ -38,115 +108,58 @@ def errors(self,code):
return response
elif code == 500 or code == 503:
response = '服务器错误 或者 你传错了图片格式。'
return response
return response
else:
response = '未知错误'
return
'''

def arrange(self, data): # todo 更新成class形式
self.raw_all = data # 总返回
self.RawDocsCount = data['RawDocsCount'] # 搜索的帧总数
self.RawDocsSearchTime = data['RawDocsSearchTime'] # 从数据库检索帧所用的时间
self.ReRankSearchTime = data['ReRankSearchTime'] # 比较帧所用的时间
self.CacheHit = data['CacheHit'] # 是否缓存搜索结果
self.trial = data['trial'] # 搜索时间
self.limit = data['limit'] # 剩余搜索限制数
self.limit_ttl = data['limit_ttl'] # 限制重置之前的时间(秒)
self.quota = data['quota'] # 剩余搜索配额数
self.quota_ttl = data['quota_ttl'] # 配额重置之前的时间(秒)
docs = data['docs'][0]
self.raw = docs # 最匹配项总结果
self.From = docs['from'] # 匹配场景的开始时间
self.to = docs['to'] # 匹配场景的结束时间
self.anilist_id = docs['anilist_id'] # 匹配的Anilist IDhttps://anilist.co/
self.at = docs['at'] # 匹配场景的确切时间
self.season = docs['season'] # 发布时间
self.anime = docs['anime'] # 番剧名字
self.filename = docs['filename'] # 找到匹配项的文件名
self.episode = docs['episode'] # 估计的匹配的番剧的集数
self.tokenthumb = docs['tokenthumb'] # 用于生成预览的token
self.similarity = docs['similarity'] # 相似度,相似性低于 87% 的搜索结果可能是不正确的结果
self.title = docs['title'] # 番剧名字
self.title_native = docs['title_native'] # 番剧世界命名
self.title_chinese = docs['title_chinese'] # 番剧中文命名
self.title_english = docs['title_english'] # 番剧英文命名
self.title_romaji = docs['title_romaji'] # 番剧罗马命名
self.mal_id = docs['mal_id'] # 匹配的MyAnimelist IDhttps://myanimelist.net/
self.synonyms = docs['synonyms'] # 备用英文标题
self.synonyms_chinese = docs['synonyms_chinese'] # 备用中文标题
self.is_adult = docs['is_adult'] # 是否R18
self.thumbnail = self.preview_image() # 缩略图预览地址
self.viedo = self.preview_video() # 视频预览地址
for i in range(len(data['docs'])):
self.raws.append(data['docs'][i]) # 分开搜索结果

def preview_image(self): # 预览

anilist_id = self.anilist_id
filename = parse.quote(self.filename)
at = self.at
tokenthumb = self.tokenthumb
url = "https://trace.moe/thumbnail.php?anilist_id={}&file={}&t={}&token={}".format(anilist_id, filename, at,
tokenthumb)
return url

def preview_video(self, mute=False):
"""
创建预览视频
:param mute:预览视频是否静音,True为静音
:return: 预览视频url地址
"""
anilist_id = self.anilist_id
filename = parse.quote(self.filename)
at = self.at
tokenthumb = self.tokenthumb
url = 'https://media.trace.moe/video/{}/{}?t={}&token={}'.format(anilist_id, filename, at, tokenthumb)
if mute:
url = url + '&mute'
return url
response = '未知错误,请联系开发者或者TraceMoe'
return response

def search(self, url, file=False, Filter=0):
def search(self, url, Filter=0):
"""
搜索
:param url:网络地址或本地
:param file: 是否是本地文件(默认否)
:param Filter: 搜索限制为特定的 Anilist ID(默认无)
:return:
"""
try:
if file: # 是否是本地文件
URl = self.Url
self.img = self._base_64(url)
res = requests.post(URl, json={"image": self.img, "filter": Filter})
self.code = res.status_code
data = res.json()
self.arrange(data)
elif not file: # 网络url
URl = self.Url + '?url=' + url
res = requests.get(URl)
self.code = res.status_code
data = res.json()
self.arrange(data)
params = dict()
if url[:4] == 'http': # 网络url
params['url'] = url
res = requests.get(self.TraceMoeURL, params=params)
if res.status_code == 200:
data = res.json()
return TraceMoeResponse(data,self.mute)
else:
logger.error(self._errors(res.status_code))
else: # 是否是本地文件
img = self._base_64(url)
res = requests.post(self.TraceMoeURL, json={"image": img, "filter": Filter})
if res.status_code == 200:
data = res.json()
return TraceMoeResponse(data,self.mute)
else:
logger.error(self._errors(res.status_code))
except Exception as e:
logger.info(e)

def download_image(self, thumbnail):
@staticmethod
def download_image(thumbnail, filename='image.png'):
"""
下载缩略图
:param thumbnail:缩略图地址
:param filename: 重命名文件
:param thumbnail:缩略图地址 见返回值中的thumbnail
"""
with requests.get(thumbnail, stream=True) as resp:
with open('image.png', 'wb') as fd:
with open(filename, 'wb') as fd:
for chunk in resp.iter_content():
fd.write(chunk)

def download_video(self, video):
@staticmethod
def download_video(video, filename='video.mp4'):
"""
下载预览视频
:param video :缩略图地址
:param filename: 重命名文件
:param video :缩略图地址 见返回值中的video_thumbnail
"""
with requests.get(video, stream=True) as resp:
with open('video.mp4', 'wb') as fd:
with open(filename, 'wb') as fd:
for chunk in resp.iter_content():
fd.write(chunk)
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
- [ ] [iqdb]
- [ ] [ascii2d]
## TODO
- TraceMoe
- 完善注释
- 更新成class形式
- iqdb
- ascii2d
### 安装
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

setuptools.setup(
name="PicImageSearch",
version="0.6.3",
version="0.6.4",
author="kitUIN",
author_email="[email protected]",
description="PicImageSearch APIs for Python 3.x 适用于 Python 3 以图搜源整合API",
Expand Down
Loading

0 comments on commit 8057d77

Please sign in to comment.