189 lines
6.0 KiB
Python
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()
|