Spaces:
Running
Running
File size: 5,190 Bytes
aeae670 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | """
cli.py
โโโโโโ
ๅฝไปค่ก้้
ๅฑ๏ผๅฏ้๏ผใ
ๅญๅฝไปค๏ผ
search ่ฏญไนๆ็ดขๆ ็ญพ
related ๅบไบๅ
ฑ็ฐ่กจๆฅๅ
ณ่ๆจ่
็จๆณ๏ผ
python cli.py search "็ฝ่ฒๆฐดๆๆ็ๅฅณๅญฉ" --limit 10 --no-nsfw
python cli.py related "white_serafuku,sailor_collar" --limit 20
python cli.py related "white_serafuku,sailor_collar" --no-nsfw --show-sources
"""
import argparse
import asyncio
from core.engine import DanbooruTagger
from core.models import SearchRequest
# โโ search โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
async def cmd_search(args):
tagger = await DanbooruTagger.get_instance()
request = SearchRequest(
query=args.query,
top_k=args.top_k,
limit=args.limit,
popularity_weight=args.weight,
show_nsfw=not args.no_nsfw,
use_segmentation=not args.no_seg,
)
resp = await asyncio.to_thread(tagger.search, request)
print(f"\n{'='*60}")
print(f"ๆฅ่ฏข๏ผ{args.query} | ๅ
ฑ {len(resp.results)} ๆก็ปๆ")
print(f"{'='*60}")
print(f"ๆจ่ Prompt๏ผ\n {resp.tags_sfw if args.no_nsfw else resp.tags_all}\n")
for r in resp.results:
nsfw_mark = "๐ด" if r.nsfw == '1' else "๐ข"
print(f" {nsfw_mark} [{r.final_score:.3f}] {r.tag:<30} {r.cn_name[:20]:<20} {r.category}")
# โโ related โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
async def cmd_related(args):
seed_tags = [t.strip() for t in args.tags.split(',') if t.strip()]
if not seed_tags:
print("้่ฏฏ๏ผ่ฏทๆไพ่ณๅฐไธไธช็งๅญๆ ็ญพ๏ผๅคไธชๆ ็ญพไปฅ้ๅทๅ้ใ")
return
tagger = await DanbooruTagger.get_instance()
results = await asyncio.to_thread(
tagger.get_related,
seed_tags,
set(seed_tags), # exclude ็งๅญๆ ็ญพ่ช่บซ
args.limit,
not args.no_nsfw,
)
if not results:
print("ๆชๆพๅฐๅ
ณ่ๆจ่๏ผๅ
ฑ็ฐ่กจๅฏ่ฝๆชๅ ่ฝฝ๏ผๆ็งๅญๆ ็ญพไธๅจๅบไธญ๏ผใ")
return
print(f"\n{'='*60}")
print(f"็งๅญๆ ็ญพ๏ผ{', '.join(seed_tags)} | ๅ
ฑ {len(results)} ๆกๆจ่")
print(f"{'='*60}")
# ่พๅบ้ๅทๅ้็ๆ ็ญพไธฒ๏ผๆนไพฟ็ดๆฅๅคๅถไฝฟ็จ๏ผ
tag_list = [r.tag for r in results if not (r.nsfw == '1' and args.no_nsfw)]
print(f"ๆจ่ๆ ็ญพ๏ผ\n {', '.join(tag_list)}\n")
# ๆ็ป่กจ
for r in results:
if r.nsfw == '1' and args.no_nsfw:
continue
nsfw_mark = "๐ด" if r.nsfw == '1' else "๐ข"
sources_str = f" โ {', '.join(r.sources)}" if args.show_sources else ""
print(
f" {nsfw_mark} [{r.cooc_score:.3f}] {r.tag:<30}"
f" {r.cn_name[:20]:<20} {r.category}"
f" (ๅ
ฑ็ฐ:{r.cooc_count:,}){sources_str}"
)
# โโ ๅ
ฅๅฃ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
async def main():
parser = argparse.ArgumentParser(
description="Danbooru Tag CLI Searcher",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
็คบไพ๏ผ
python cli.py search "็ฝ่ฒๆฐดๆๆ็ๅฅณๅญฉ" --limit 10
python cli.py related "white_serafuku,sailor_collar"
python cli.py related "white_serafuku" --limit 30 --no-nsfw --show-sources
""",
)
sub = parser.add_subparsers(dest='cmd', required=True)
# โโ search ๅญๅฝไปค โโ
p_search = sub.add_parser('search', help='่ฏญไนๆ็ดขๆ ็ญพ')
p_search.add_argument('query', help='ๆ็ดข่ฏ๏ผๆฏๆไธญ่ฑๆ่ช็ถ่ฏญ่จ๏ผ')
p_search.add_argument('--top-k', type=int, default=5, help='ๆฏๅฑ่ฟๅๆฐ้๏ผ้ป่ฎค 5๏ผ')
p_search.add_argument('--limit', type=int, default=20, help='็ปๆไธ้๏ผ้ป่ฎค 20๏ผ')
p_search.add_argument('--weight', type=float, default=0.15, help='็ญๅบฆๆ้๏ผ้ป่ฎค 0.15๏ผ')
p_search.add_argument('--no-nsfw', action='store_true', help='่ฟๆปค NSFW ๅ
ๅฎน')
p_search.add_argument('--no-seg', action='store_true', help='็ฆ็จๆบ่ฝๅ่ฏ')
# โโ related ๅญๅฝไปค โโ
p_related = sub.add_parser('related', help='ๅบไบๅ
ฑ็ฐ่กจๆฅๅ
ณ่ๆจ่')
p_related.add_argument('tags', help='็งๅญๆ ็ญพ๏ผไปฅ่ฑๆ้ๅทๅ้๏ผๅฆ white_serafuku,sailor_collar๏ผ')
p_related.add_argument('--limit', type=int, default=50, help='ๆจ่็ปๆไธ้๏ผ้ป่ฎค 50๏ผ')
p_related.add_argument('--no-nsfw', action='store_true', help='่ฟๆปค NSFW ๅ
ๅฎน')
p_related.add_argument('--show-sources', action='store_true', help='ๆพ็คบๆฏๆกๆจ่็ฑๅชไธช็งๅญ่งฆๅ')
args = parser.parse_args()
if args.cmd == 'search':
await cmd_search(args)
elif args.cmd == 'related':
await cmd_related(args)
if __name__ == "__main__":
asyncio.run(main())
|