Long chains are quite annoying to fix, so I decided to create a simple tool to do it.
I don't want to associate my Github with e621, so I'll just post the code here:
Code
import json
import os.path
import requests as requests
from ratelimit import limits, sleep_and_retry
@sleep_and_retry
@limits(calls=1, period=1)
def api_limit():
pass
def get_login() -> tuple[str, str]:
if os.path.isfile("login.json"):
with open("login.json", "r") as file:
data = json.load(file)
return data["username"], data["key"]
username = input("Username: ")
key = input("API key: ")
if input("Save login (y/n): ") == "y":
with open("login.json", "w") as file:
json.dump({"username": username, "key": key}, file)
return username, key
def get_page(session: requests.Session, post_id: str) -> dict:
api_limit()
response = session.get(f"https://e621.net/posts/{post_id}.json")
if not response:
print(f"Unable to get {post_id}: Status {response.status_code}, response {response.text}")
exit(1)
post = response.json()["post"]
return {"id": post_id, "parent": post["relationships"]["parent_id"], "pools": post["pools"]}
def get_chain(session: requests.Session, start: str) -> list:
print("Getting posts")
post_id = start
result = []
while post_id is not None:
result.append(get_page(session, post_id))
print(f"Got {post_id}, pools: {result[-1]['pools']}")
post_id = result[-1]["parent"]
result.reverse()
return result
def get_category():
while True:
response = input("category (series/collection): ")
if response == "series" or response == "s":
return "series"
if response == "collection" or response == "c":
return "collection"
print("Invalid response")
def create_pool(session: requests.Session, chain: list):
payload = dict()
payload["pool[name]"] = input("name: ")
payload["pool[description]"] = input("description: ")
payload["pool[category]"] = get_category()
payload["pool[is_active]"] = "true"
payload["pool[post_ids]"] = " ".join([str(post["id"]) for post in chain])
api_limit()
response = session.post("https://e621.net/pools.json", data=payload)
if response:
print(f"Created pool: https://e621.net/pools/{response.json()['id']}")
else:
print(f"Failed to create pool: Status {response.status_code}, response {response.text}")
def remove_parents(session: requests.Session, chain: list):
for post in chain[1:]:
payload = dict()
payload["post[parent_id]"] = ""
payload["post[old_parent_id]"] = str(post["parent"])
payload["post[edit_reason]"] = "Convert chain to pool (automatic update)"
api_limit()
response = session.patch(f"https://e621.net/posts/{post['id']}.json", data=payload)
if response:
print(f"Removed parent from post {post['id']}")
else:
print(f"Failed to remove parent from post {post['id']}: Status {response.status_code}, response {response.text}")
def main():
login = get_login()
start = input("ID of last post in chain: ")
with requests.Session() as session:
session.auth = login
session.headers.update({"User-Agent": "ChainToPool/1.0 (by SCTH)"})
chain = get_chain(session, start)
if input("Create pool (y/n): ") == "y":
create_pool(session, chain)
if input("Remove parents from chain (y/n): ") == "y":
remove_parents(session, chain)
if __name__ == '__main__':
main()
I don't use Python much, but it is quite convenient for small things like this.