Skip to content

Instantly share code, notes, and snippets.

@Aloxaf
Created November 26, 2019 05:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Aloxaf/3d4f9f8ea8fbcbb94d1a82569a6218d0 to your computer and use it in GitHub Desktop.
Save Aloxaf/3d4f9f8ea8fbcbb94d1a82569a6218d0 to your computer and use it in GitHub Desktop.
从 P 站下载图片元数据
#!/usr/bin/python
from pixivpy3 import *
from pathlib import Path
from typing import *
from concurrent import futures
from os import system
import json
def get_tags_from_pixiv():
"""
扫描本地图片, 获取图片信息并存储在 ./info.json 中
:return:
"""
# 登录 P 站
api = AppPixivAPI(proxies={"https": "socks5h://127.0.0.1:8877"})
api.set_accept_language("zh-cn")
api.login('username', 'password')
# 加载旧数据
data_path = Path('./info.json')
data = json.load(data_path.open('r'))
def dump_data():
json.dump(data, data_path.open('w'), ensure_ascii=False, indent=2)
# 获取本地 illust 列表, 去除已获取部分
illusts = Path("/home/aloxaf/Pictures/小萝莉").rglob("illust_*")
illusts = set(f.name.split('_')[1] for f in illusts)
illusts = filter(lambda x: data.get(x) is None, illusts)
for i, pid in enumerate(illusts):
print(f"\r{i}", end="")
info = api.illust_detail(pid)
# 作品可能被删除, 需要检查一下
if error := info.get('error'):
print(f'\n{error}')
else:
data[pid] = info['illust']
if i % 10 == 0:
dump_data()
dump_data()
def add_tags_for_local():
"""
使用 exiftool 为本地图片添加 metadata, 以供 digiKam 导入
:return:
"""
# 加载信息
data_path = Path('./info.json')
data = json.load(data_path.open('r'))
# 获取需要处理的图片列表
tagged_path = Path('./tagged.json')
tagged = set(json.load(tagged_path.open('r')))
illusts = Path("/home/aloxaf/Pictures/小萝莉").rglob("illust_*")
# exiftool 速度太慢, 开四线程
with futures.ThreadPoolExecutor(max_workers=4) as executor:
tasks = []
for file in illusts:
pid = file.name.split('_')[1]
# 过滤掉已经添加过的图片和没有信息可以添加的图片
if file.name in tagged or (info := data.get(pid)) is None:
continue
tagged.add(file.name)
tasks.append(executor.submit(add_tags_for_image, file, info))
futures.wait(tasks)
json.dump(list(tagged), tagged_path.open('w'), indent=2)
Json = Union[bool, float, str, int, Dict[str, 'Json'], List['Json']]
def add_tags_for_image(file: Path, info: Json):
"""
为图片添加 metada
:param file: 图片地址
:param info: 图片信息
:return:
"""
# 等待添加的 metadata
title = info['title']
author = info['user']['name']
caption = info['caption'] or ' ' # 如果没有描述, 添加一个空格, 否则作者不会被导入
tags = [tag.get('translated_name') or tag['name'] for tag in info['tags']]
tags = ', '.join(tags).replace('/', '\\')
attrs = ' '.join([
f'"-Title={title}"',
f'"-Description= "',
f'"-CaptionsAuthorNames={author}"',
f'"-TagsList={tags}"',
# f'"-Author="',
# f'"-CatalogSets="'
# f'"-Categories="',
# f'"-HierarchicalSubject="',
# f'"-LastKeywordXMP="',
# f'"-Subject="',
# f'"-Keywords="',
# f'"-Caption="',
# f'"-CatalogSets="',
# f'"-ObjectName="',
])
system(f'exiftool -sep ", " {attrs} {file} -overwrite_original')
def main():
get_tags_from_pixiv()
add_tags_for_local()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment