RPGs3_card_insanity/sync.py

164 lines
5.8 KiB
Python
Executable File

#!/usr/bin/env python3
from pprint import pprint
from requests.auth import HTTPBasicAuth
import concurrent.futures
import json
import os
import requests
import requests.packages.urllib3.util.connection as urllib3_cn
import socket
import xmltodict
MY_COLLECTIONS = {
"26" : "Fjompens fjomperi",
"48" : "Fjompens Fjomperi - not in deck",
}
AUTH = None
CARD_STYLE = 6 # Fjompens's card style
##FORCE_IPV4 = False
##def allowed_gai_family(): # used to force either ipv4 or ipv6
## family = socket.AF_INET
## if not FORCE_IPV4 and urllib3_cn.HAS_IPV6:
## family = socket.AF_INET6 # force ipv6 only if it is available
## return family
##urllib3_cn.allowed_gai_family = allowed_gai_family
def get_card_ids(): # generator
resp = requests.get("https://www.pvv.ntnu.no/~andreasd/cards/command.php?cmd=get_all_cards", auth=AUTH)
for collection in resp.json():
if MY_COLLECTIONS.get(collection["id"]) == collection["name"]:
yield from collection["cards"]
def get_card_xml(card_id:int):
resp = requests.get(f"https://www.pvv.ntnu.no/~andreasd/cards/command.php?cmd=get_card_xml&id={card_id}", auth=AUTH)
return resp.text
def get_card_style_id(card_id:int):
resp = requests.get(f"https://www.pvv.ntnu.no/~andreasd/cards/command.php?cmd=get_card_style&id={card_id}", auth=AUTH)
return resp.text
def set_card_xml(card_id:int, xml_data):
resp = requests.post(f"https://www.pvv.ntnu.no/~andreasd/cards/command.php", auth=AUTH, data={
"cmd" : "update_card_text",
"id" : str(card_id),
"data" :xml_data,
})
if resp.ok and resp.text == "<span class='ui success'>Card Updated</span>":
return True
else:
print(resp.text)
return False
def set_card_style_id(card_id:int, style_id:int):
resp = requests.post(f"http://pvv.org/~andreasd/cards/command.php", auth=AUTH, data={
"cmd" : "update_card_style",
"id" : str(card_id),
"style" : str(style_id),
})
if resp.ok and resp.text == "<span class='ui success'>Card Updated</span>": # lol
return True
else:
print(resp.text)
return False
def list_collections():
with concurrent.futures.ThreadPoolExecutor(max_workers=50) as e:
resp = requests.get("https://www.pvv.ntnu.no/~andreasd/cards/command.php?cmd=get_all_cards", auth=AUTH)
print("== All collections: ==\n")
for i in resp.json():
print("collection_id: ", i["id"])
print("collection_name: ", i["name"])
print("cards: ", i["cards"])
print("card styles: ", sorted(set(map(int, e.map(get_card_style_id, i["cards"])))))
print()
def pull_all():
card_ids = get_card_ids()
for card_id in card_ids:
print(f"pulling card {card_id}... ", end="")
data = get_card_xml(card_id)
style_id = get_card_style_id(card_id)
if style_id not in map(str, (0, CARD_STYLE)):
print("Error! style id was",style_id)
continue
try:
xml = xmltodict.parse(data)
except:
xml = None
#if xml and "ability_card" in xml:
# if "yaml_data" in xml["ability_card"]:
# if len(xml["ability_card"].keys()) == 1:
# yaml_data = xml["ability_card"]["yaml_data"]
# with open(f"cards/{card_id}.yaml", "w") as f:
# f.write(yaml_data + "\n")
# print(f"./cards/{card_id}.yaml written!")
# continue
ftype = "xml" if data.strip() else "yaml"
with open(f"cards/{card_id}.{ftype}", "w") as f:
f.write(data + "\n")
print(f"./cards/{card_id}.{ftype} written!")
def push_all():
existing_card_ids = get_card_ids()
for card_id in existing_card_ids:
if os.path.isfile(f"cards/{card_id}.yaml"): # deprecated, will no be written anymore
fname = f"cards/{card_id}.yaml"
with open(fname) as f:
yaml_data = f.read()
xml_data = f"<ability_card><yaml_data>\n{yaml_data.strip()}\n</yaml_data></ability_card>"
elif os.path.isfile(f"cards/{card_id}.xml"):
fname = f"cards/{card_id}.xml"
with open(fname) as f:
xml_data = f.read()
else:
continue
if xml_data:
print(f"POSTing {fname} to site... ", end="")
if set_card_xml(card_id, xml_data) == True:
print("OK!")
else:
print("FAILED!")
style_id = get_card_style_id(card_id)
if style_id == "0":
print("Setting card", card_id, "style to", CARD_STYLE, "...", end=" ")
if set_card_style_id(card_id, CARD_STYLE):
print("OK!")
else:
print("FAILED!")
def push_style():
print(f"POSTing build/style.xsl to site... ", end="")
with open("build/style.xsl") as f:
xsl_data = f.read()
resp = requests.post(f"http://pvv.org/~andreasd/cards/command.php", auth=AUTH, data={
"cmd" : "update_style_xsl",
"id" : str(CARD_STYLE),
"xsl" : str(xsl_data),
})
if resp.ok and resp.text == "<span class='ui success'>XSL Updated</span>":
print("Success!")
else:
print("Failed:")
print(resp.text)
if __name__ == "__main__":
import sys
if len(sys.argv) < 4:
print(__file__, "<action> <uname> <passwd>\n\n\taction: either 'list', 'push', 'push_style' or 'pull'\n")
else:
AUTH = HTTPBasicAuth(sys.argv[2], sys.argv[3])
action = sys.argv[1].strip().lower()
if action == "list": list_collections()
if action == "pull": pull_all()
if action == "push": push_all()
if action == "push_style": push_style()