使用脚本生成,作者Neitsa。-- Pokewiz(讨论) 2017年10月17日 (二) 11:15 (CST)
Python 3 code for creating the page at Event IDs. This code is GPLv3.
#!/usr/bin/env python3
'''
Created on 2014/05/14
@author: Neitsa
Usage:
euiv_event_ids.py -o output.txt <main_euiv_path>
The main EUIV path should be something like:
C:\Steam\steamapps\common\Europa Universalis IV
If it contains spaces, just surround the path with double quotes:
euiv_event_ids.py -o output.txt "C:\Steam\steamapps\common\Europa Universalis IV"
'''
import sys
import argparse
import os.path
import glob
import re
REOBJ_ID = re.compile(r"id\s*=\s*(?P<id>[a-z_\.]*\d+)", re.MULTILINE)
REOBJ_TITLE = re.compile(r'title\s*=\s*"*(?P<title>[\w\.]+)"*', re.MULTILINE)
REOBJ_DESC = re.compile(r'desc\s*=\s*"*(?P<desc>[\w\.]+)"*', re.MULTILINE)
class Event(object):
# event types
COUNTRY_EVENT = 1
PROVINCE_EVENT = 2
EVENT_MAP = {1: 'Country', 2: 'Province'}
def __init__(self, file_name):
'''
constructor
'''
self._file_name = file_name
self._type = None
self._id = None
self._title = None
self._desc = None
self._comment = None
self._namespace = None
def __str__(self):
return ("fname: {}; type: {}; namespace: {}; id: {}; title: {};"
" desc: {}; comment: {}".format(self._file_name, self._type,
self._namespace, self._id,
self._title, self._desc,
self._comment))
@property
def filename(self):
return self._file_name
@filename.setter
def filename(self, v):
self._file_name = v
@property
def type(self):
return self._type
@type.setter
def type(self, v):
self._type = v
@property
def id(self):
return self._id
@id.setter
def id(self, v):
self._id = v
@property
def title(self):
return self._title
@title.setter
def title(self, v):
self._title = v
@property
def desc(self):
return self._desc
@desc.setter
def desc(self, v):
self._desc = v
@property
def comment(self):
return self._comment
@comment.setter
def comment(self, v):
self._comment = v
@property
def namespace(self):
return self._namespace
@namespace.setter
def namespace(self, v):
self._namespace = v
def check_euiv_installation(path):
'''
Check that the argument 'path' really is the EUIV installation path.
'''
if not os.path.isdir(path):
print("[-] Error: the path '{}' doesn't exists or is not a directory".
format(path))
return False
main_prog = os.path.join(path, 'eu4.exe')
if not os.path.isfile(main_prog):
print("[-] Error: the main program couldn't be found at '{}'. Is this "
"really the installation path for EUIV?".format(main_prog))
return False
events_dir = os.path.join(path, "events")
if not os.path.isdir(events_dir):
print("[-] Error: the '\\events' directory path '{}' doesn't exists or"
" is not a directory.".format(events_dir))
return False
return True
def parse_event_file(file_path):
data = None
with open(file_path, 'r', errors='replace') as f:
data = f.readlines()
if not data:
return None
filename = os.path.split(file_path)[1]
events = list()
current_event = None
comment_line = None
for line in data:
if line.startswith('#'):
if line.startswith('##'):
continue
comment_line = line[1:].strip(" #\t\n")
continue
if line.startswith('country_event'):
current_event = Event(filename)
current_event.type = Event.COUNTRY_EVENT
current_event.comment = comment_line
comment_line = None
continue
elif line.startswith('province_event'):
current_event = Event(filename)
current_event.type = Event.PROVINCE_EVENT
current_event.comment = comment_line
comment_line = None
continue
elif line.startswith('}'):
events.append(current_event)
# current_event = None
continue
match = REOBJ_ID.search(line)
if match:
event_id = match.group("id")
namespace_id = event_id.split('.')
if len(namespace_id) == 2:
current_event.namespace = namespace_id[0]
current_event.id = namespace_id[1]
else:
current_event.id = namespace_id[0]
continue
match = REOBJ_TITLE.search(line)
if match:
current_event.title = match.group("title")
continue
match = REOBJ_DESC.search(line)
if match:
current_event.desc = match.group("desc")
continue
return events
def produce_wiki_table(all_events, output_file_name):
# "wikitable sortable mw-collapsible mw-collapsed"
head = ("""
{|class = "wikitable sortable"
|-
! Event file name !! Event type !! Namespace !! Event id !! Title !! Description !! class="unsortable"|Comment (as in file)
|-""")
f = open(output_file_name, 'w', encoding='utf-8')
f.write(head)
for file_events in all_events:
for event in file_events:
namespace = event.namespace if event.namespace is not None else "n/a"
event_type = Event.EVENT_MAP[event.type]
s = "\n| {} || {} || {} || {} || {} || {} || {}\n|-".format(
event.filename,
event_type,
namespace,
event.id,
event.title,
event.desc,
event.comment
)
# s.encode('utf-8', errors= 'surrogateescape')
try:
f.write(s)
except UnicodeEncodeError as ueerr:
print(s.encode('utf-8', errors='replace'))
raise ueerr
f.write("|}")
def main(args):
if not check_euiv_installation(args.euiv_path):
return
events_path = os.path.join(args.euiv_path, "events")
event_files = glob.glob(os.path.join(events_path, "*.txt"))
if not event_files:
print("[-] Error: couldn't find any file in the events directory...")
all_events = list()
for file_path in event_files:
print("[*] Parsing {}".format(os.path.split(file_path)[1]))
file_events = parse_event_file(file_path)
if not file_events:
# some event files are empty or contains only comments...
print("[-] Warning: no file events for {}".
format(os.path.split(file_path)[1]))
else:
all_events.append(file_events)
produce_wiki_table(all_events, args.output)
if __name__ == '__main__':
print('start')
parser = argparse.ArgumentParser()
parser.add_argument('euiv_path', action='store',
help='Europa Universalis IV directory path')
parser.add_argument('--output', '-o', action='store', default='output.txt',
help='output file path')
parser.add_argument('--version', action='version', version='%(prog)s 1.1')
args = parser.parse_args(sys.argv[1:])
main(args)