Spaces:
Running
Running
| """ | |
| 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()) | |