Skip to content

Instantly share code, notes, and snippets.

@Bluefissure
Created July 20, 2020 13:02
Show Gist options
  • Save Bluefissure/24aaa42823745de9fbb7347ebaf323b5 to your computer and use it in GitHub Desktop.
Save Bluefissure/24aaa42823745de9fbb7347ebaf323b5 to your computer and use it in GitHub Desktop.
add_cn_timeline
import argparse
import csv
import os
import requests
import codecs
import random
import re
import json
from collections import defaultdict
RAIDBOSS_DATA_PATH = "D:\\Code\\Git\\cactbot\\ui\\raidboss\\data"
class Mapper(object):
def __init__(self, verbose=False):
self.verbose = verbose
self.db_path = "../csv/"
self.required_csv = ["Action.csv", "BNpcName.csv"]
self.init_db()
self.id_to_cn = defaultdict(lambda: defaultdict(str))
self.id_to_en = defaultdict(lambda: defaultdict(str))
self.en_to_id = defaultdict(lambda: defaultdict(int))
self.build()
def init_db(self):
datamining_repo = (
"https://raw.githubusercontent.com/xivapi/ffxiv-datamining/master/csv/"
)
cn_repo = "https://raw.githubusercontent.com/thewakingsands/ffxiv-datamining-cn/master/"
for file in self.required_csv:
path = self.db_path + file
if not os.path.exists(path):
print("Dowloading {} in cn...".format(file))
r = requests.get(cn_repo + file)
with open(path, "wb") as f:
f.write(r.content)
for file in self.required_csv:
path = self.db_path + file.split(".")[0] + "_en.csv"
if not os.path.exists(path):
print("Dowloading {} in en...".format(file))
r = requests.get(datamining_repo + file)
with open(path, "wb") as f:
f.write(r.content)
def build(self):
for file in self.required_csv:
cat = file.split(".")[0]
path = self.db_path + file
with codecs.open(path, "r", "utf8") as csvfile:
f_csv = csv.reader(csvfile)
for row in f_csv:
if not row[0].isdigit():
continue
self.id_to_cn[cat][int(row[0])] = row[1]
en_path = self.db_path + cat + "_en.csv"
with codecs.open(en_path, "r", "utf8") as csvfile:
f_csv = csv.reader(csvfile)
for row in f_csv:
if not row[0].isdigit():
continue
self.en_to_id[cat][row[1].lower()] = int(row[0])
self.id_to_en[cat][int(row[0])] = row[1]
rand_en = random.choice(list(self.en_to_id[cat].keys()))
rand_idx = self.en_to_id[cat][rand_en]
rand_cn = self.id_to_cn[cat][rand_idx]
if self.verbose:
print("File {} build finished, ex:".format(cat))
print(" {} -- {} -- {}".format(rand_en, rand_idx, rand_cn))
def translate_en(self, cat, en_name):
en_name = en_name.lower()
idx = self.en_to_id[cat][en_name.lower()]
cn_name = self.id_to_cn[cat][idx]
return cn_name
def get_config():
parser = argparse.ArgumentParser(
description="Automatically add cn timelineReplace to cactbot raidboss js file."
)
parser.add_argument("-f", "--file", type=str, help="The target file name.")
parser.add_argument(
"-d",
"--data-path",
type=str,
default=RAIDBOSS_DATA_PATH,
help="The default path to locate the js files.",
)
# Parse args.
args = parser.parse_args()
return args
def extract_locale_from_timeline(timeline_file):
cn_locale = {"locale": "cn", "replaceSync": {}, "replaceText": {}}
ignore_entries = ["--reset--", "--sync--", "--untargetable--", "--targetable--"]
with codecs.open(timeline_file, "r", encoding="utf-8") as f:
for row in f:
pattern = r"^\d+(?:.\d+)?\s\"(.+)\"(?:.*sync\s\/:(.*?):(?:([0-9A-F]+):)?)?"
m = re.match(pattern, row)
if m:
if m.group(1):
en_name = m.group(1)
if en_name.lower() in ignore_entries:
continue
cn_locale["replaceText"][m.group(1)] = (
mapper.translate_en("Action", en_name)
if not m.group(3)
else mapper.id_to_cn["Action"][int(m.group(3), 16)]
)
if m.group(2):
en_name = m.group(2)
if en_name.lower() in ignore_entries:
continue
cn_locale["replaceSync"][m.group(2)] = mapper.translate_en(
"BNpcName", en_name
)
return cn_locale
def add_cn_timeline(trigger_file, mapper):
assert trigger_file.endswith(".js"), "Trigger file must end with .js"
timeline_file = trigger_file[:-3] + ".txt"
cn_locale = extract_locale_from_timeline(timeline_file)
print("=" * 24 + "\nCN locale :")
print(json.dumps(cn_locale, indent=4, ensure_ascii=False))
if __name__ == "__main__":
args = get_config()
mapper = Mapper()
assert args.file, "File must be specified."
found = False
for path, _, files in os.walk(args.data_path):
if args.file in files:
print("Updating {}".format(os.path.join(path, args.file)))
add_cn_timeline(os.path.join(path, args.file), mapper)
found = True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment