Files
2025-03-22 12:35:29 +11:00

189 lines
6.0 KiB
Python

import requests
import json
import time
import os
# Constants
OUTPUT_DIR = "tag_lists"
CATEGORY_FILES = {
0: "general.txt", # General tags
1: "artist.txt", # Artist tags
3: "copyright.txt", # Copyright tags
4: "character.txt", # Character tags
5: "meta.txt", # Meta tags
'all': "all_tags.txt" # All tags combined
}
BASE_URL = "https://danbooru.donmai.us/tags.json"
LIMIT = 200 # Maximum limit per request
MIN_COUNT = 100 # Minimum post count
def ensure_output_dir():
"""Create output directory if it doesn't exist"""
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
def get_output_path(filename):
"""Get full path for output file"""
return os.path.join(OUTPUT_DIR, filename)
def get_tags_with_count_over(min_count):
"""
Retrieve all tags that have a post count higher than min_count
"""
all_tags = []
page = 1
more_results = True
print(f"Fetching tags with count over {min_count}...")
while more_results:
# Parameters for the API request
params = {
"search[post_count]": f">{min_count}",
"search[order]": "count", # Order by post count (highest first)
"limit": LIMIT,
"page": page
}
try:
print(f"Fetching page {page}...")
response = requests.get(BASE_URL, params=params)
response.raise_for_status() # Raise an exception for HTTP errors
tags = response.json()
if not tags:
more_results = False
else:
all_tags.extend(tags)
page += 1
# Be nice to the API and avoid rate limiting
time.sleep(1)
except requests.exceptions.RequestException as e:
print(f"Error fetching data: {e}")
break
return all_tags
def save_tags_to_files(tags, append=False):
"""
Save the tags to separate files based on their category and to all_tags.txt
append: If True, append to files; if False, overwrite files
"""
try:
# Group tags by category
categorized_tags = {}
for tag in tags:
category = tag['category']
if category in CATEGORY_FILES:
if category not in categorized_tags:
categorized_tags[category] = []
categorized_tags[category].append(tag)
# Save each category to its respective file
for category, category_tags in categorized_tags.items():
filename = get_output_path(CATEGORY_FILES[category])
mode = 'a' if append else 'w'
with open(filename, mode, encoding='utf-8') as f:
# Sort by post_count in descending order
sorted_tags = sorted(category_tags, key=lambda x: x['post_count'], reverse=True)
for tag in sorted_tags:
f.write(f"{tag['name']}, {tag['post_count']}\n")
print(f"Saved {len(category_tags)} {CATEGORY_FILES[category]} tags")
# Save to all_tags.txt
filename = get_output_path(CATEGORY_FILES['all'])
mode = 'a' if append else 'w'
with open(filename, mode, encoding='utf-8') as f:
# Sort all tags by post_count
sorted_tags = sorted(tags, key=lambda x: x['post_count'], reverse=True)
for tag in sorted_tags:
f.write(f"{tag['name']}, {tag['post_count']}\n")
print(f"Saved {len(tags)} tags to {CATEGORY_FILES['all']}")
except IOError as e:
print(f"Error saving to files: {e}")
def get_last_saved_page():
"""
Determine the last page that was processed by counting lines in all_tags.txt
"""
try:
filepath = get_output_path(CATEGORY_FILES['all'])
try:
with open(filepath, 'r', encoding='utf-8') as f:
total_lines = sum(1 for _ in f)
# Calculate the last completed page based on LIMIT tags per page
last_page = (total_lines + LIMIT - 1) // LIMIT
return last_page
except FileNotFoundError:
return 0
except Exception as e:
print(f"Error reading files: {e}")
return 0
def clear_output_files():
"""Clear all category files"""
for filename in CATEGORY_FILES.values():
filepath = get_output_path(filename)
open(filepath, 'w').close()
def main():
ensure_output_dir()
# Get the last processed page
start_page = get_last_saved_page()
page = start_page + 1 if start_page > 0 else 1
more_results = True
total_tags = 0
print(f"Fetching tags with count over {MIN_COUNT}...")
print(f"Resuming from page {page}...")
# Clear files if starting from beginning
if page == 1:
clear_output_files()
while more_results:
# Parameters for the API request
params = {
"search[post_count]": f">{MIN_COUNT}",
"search[order]": "count", # Order by post count (highest first)
"limit": LIMIT,
"page": page
}
try:
print(f"Fetching page {page}...")
response = requests.get(BASE_URL, params=params)
response.raise_for_status()
tags = response.json()
if not tags:
more_results = False
else:
# Save this batch immediately
save_tags_to_files(tags, append=(page != 1))
total_tags += len(tags)
page += 1
# Be nice to the API and avoid rate limiting
time.sleep(1)
except requests.exceptions.RequestException as e:
print(f"Error fetching data: {e}")
break
print(f"Finished! Found {total_tags} tags with count over {MIN_COUNT}")
if __name__ == "__main__":
main()