wmlxgettext: Support extracting all textdomains at once (#7624)

* wmlxgettext: Support extracting all textdomains at once

- -o now expects a folder.
- --domain is now treated as an optional filter.

* wmltools/gui/wmlxgettext: Update input handling

- Fix --initialdomain
- Textdomain is no longer mandatory.
- Accept output dir rather than output file.
This commit is contained in:
Slayer95 2023-05-24 15:08:18 -05:00 committed by GitHub
parent ed45fcae67
commit be991e027d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 178 additions and 118 deletions

View file

@ -444,8 +444,8 @@ It comes complete with a context menu and a directory selection screen"""
def on_clear(self):
self.textvariable.set("")
class SelectSaveFile(Frame):
def __init__(self, parent, textvariable, **kwargs):
class SelectOutputPath(Frame):
def __init__(self, parent, textvariable, filetypes=None, **kwargs):
"""A subclass of Frame with a readonly Entry and a Button with a browse icon.
It has a context menu and a save file selection dialog."""
super().__init__(parent,**kwargs)
@ -469,19 +469,33 @@ It has a context menu and a save file selection dialog."""
text="Clear",
command=self.on_clear)
self.clear_button.pack(side=LEFT)
def on_browse(self):
self.filetypes = filetypes
def on_browse_file(self):
# if the user already selected a file, try to use its directory
current_dir,current_file=os.path.split(self.textvariable.get())
if os.path.exists(current_dir):
directory=asksaveasfilename(filetypes=[("POT File", "*.pot"),("All Files", "*")],
return asksaveasfilename(filetypes=self.filetypes,
initialdir=current_dir,
initialfile=current_file,
confirmoverwrite=False) # the GUI will ask later if the file should be overwritten, so disable it for now
# otherwise attempt to detect the user's userdata folder
else:
directory=asksaveasfilename(filetypes=[("POT File", "*.pot"),("All Files", "*")],
return asksaveasfilename(filetypes=self.filetypes,
initialdir=get_addons_directory(),
confirmoverwrite=False)
def on_browse_dir(self):
current_dir=self.textvariable.get()
if os.path.exists(current_dir):
return askdirectory(initialdir=current_dir)
# otherwise attempt to detect the user's userdata folder
else:
return askdirectory(initialdir=get_addons_directory())
def on_browse(self):
if self.filetypes is None:
directory = self.on_browse_dir()
else:
directory = self.on_browse_file(self)
if directory:
# use os.path.normpath, so on Windows the usual backwards slashes are correctly shown
self.textvariable.set(os.path.normpath(directory))
@ -956,24 +970,17 @@ class WmlindentTab(Frame):
class WmlxgettextTab(Frame):
def __init__(self,parent):
super().__init__(parent)
self.domain_and_output_frame=Frame(self)
self.domain_and_output_frame.grid(row=0,column=0,columnspan=2,sticky=N+E+S+W)
self.domain_label=Label(self.domain_and_output_frame,
text="Textdomain:")
self.domain_label.grid(row=0,column=0,sticky=W)
self.domain_variable=StringVar()
self.domain_entry=Entry(self.domain_and_output_frame,
textvariable=self.domain_variable)
self.domain_entry.grid(row=0,column=1,sticky=N+E+S+W)
self.output_label=Label(self.domain_and_output_frame,
text="Output file:")
self.output_label.grid(row=1,column=0,sticky=W)
self.output_wrapper_frame=Frame(self)
self.output_wrapper_frame.grid(row=0,column=0,columnspan=2,sticky=N+E+S+W)
self.output_label=Label(self.output_wrapper_frame,
text="Output dir:")
self.output_label.grid(row=0,column=0,sticky=W)
self.output_variable=StringVar()
self.output_frame=SelectSaveFile(self.domain_and_output_frame,self.output_variable)
self.output_frame.grid(row=1,column=1,sticky=N+E+S+W)
self.output_frame=SelectOutputPath(self.output_wrapper_frame,textvariable=self.output_variable)
self.output_frame.grid(row=0,column=1,sticky=N+E+S+W)
self.options_labelframe=LabelFrame(self,
text="Options")
self.options_labelframe.grid(row=2,column=0,sticky=N+E+S+W)
self.options_labelframe.grid(row=1,column=0,sticky=N+E+S+W)
self.recursive_variable=BooleanVar()
self.recursive_variable.set(True)
self.recursive_check=Checkbutton(self.options_labelframe,
@ -992,30 +999,47 @@ class WmlxgettextTab(Frame):
self.fuzzy_check.grid(row=2,column=0,sticky=W)
self.advanced_labelframe=LabelFrame(self,
text="Advanced options")
self.advanced_labelframe.grid(row=2,column=1,sticky=N+E+S+W)
self.advanced_labelframe.grid(row=1,column=1,sticky=N+E+S+W)
self.package_version_variable=BooleanVar()
self.package_version_check=Checkbutton(self.advanced_labelframe,
text="Package version",
variable=self.package_version_variable)
self.package_version_check.grid(row=0,column=0,sticky=W)
self.initialdomain_variable=BooleanVar()
self.textdomain_variable=BooleanVar()
self.textdomain_check=Checkbutton(self.advanced_labelframe,
text="Filter textdomains:",
variable=self.textdomain_variable,
command=self.textdomain_callback)
self.textdomain_check.grid(row=1,column=0,sticky=W)
self.textdomain_name=StringVar()
self.textdomain_entry=Entry(self.advanced_labelframe,
state=DISABLED,
width=40,
textvariable=self.textdomain_name)
self.textdomain_entry.grid(row=1,column=1,sticky=E+W)
self.initialdomain_check=Checkbutton(self.advanced_labelframe,
text="Initial textdomain",
text="Initial textdomain:",
variable=self.initialdomain_variable,
command=self.initialdomain_callback)
self.initialdomain_check.grid(row=1,column=0,sticky=W)
self.initialdomain_check.grid(row=2,column=0,sticky=W)
self.initialdomain_name=StringVar()
self.initialdomain_entry=Entry(self.advanced_labelframe,
state=DISABLED,
width=0,
width=40,
textvariable=self.initialdomain_name)
self.initialdomain_entry.grid(row=1,column=1,sticky=E+W)
self.domain_and_output_frame.columnconfigure(1,weight=1)
self.domain_and_output_frame.rowconfigure(0,uniform="group")
self.domain_and_output_frame.rowconfigure(1,uniform="group")
self.initialdomain_entry.grid(row=2,column=1,sticky=E+W)
self.output_wrapper_frame.columnconfigure(1,weight=1)
self.output_wrapper_frame.rowconfigure(0,uniform="group")
self.advanced_labelframe.columnconfigure(1,weight=1)
self.advanced_labelframe.columnconfigure(2,weight=1)
self.columnconfigure(0,weight=2)
self.columnconfigure(1,weight=1)
def textdomain_callback(self, event=None):
if self.textdomain_variable.get():
self.textdomain_entry.configure(state=NORMAL)
else:
self.textdomain_entry.configure(state=DISABLED)
def initialdomain_callback(self, event=None):
if self.initialdomain_variable.get():
self.initialdomain_entry.configure(state=NORMAL)
@ -1322,12 +1346,8 @@ wmlindent will be run on the Wesnoth core directory""")
# build the command line and add the path of the Python interpreter
wmlxgettext_command_string=[sys.executable]
wmlxgettext_command_string.append(os.path.join(APP_DIR,"wmlxgettext"))
textdomain=self.wmlxgettext_tab.domain_variable.get()
if textdomain:
wmlxgettext_command_string.extend(["--domain",textdomain])
else:
showerror("Error","""No textdomain specified""")
return
if self.wmlxgettext_tab.textdomain_variable.get():
wmlxgettext_command_string.extend(["--domain",self.wmlxgettext_tab.textdomain_entry.get()])
wmlxgettext_command_string.append("--directory")
umc_dir=self.dir_variable.get()
if os.path.exists(umc_dir): # add-on exists
@ -1362,9 +1382,8 @@ wmlxgettext won't be run""")
if self.wmlxgettext_tab.package_version_variable.get():
wmlxgettext_command_string.append("--package-version")
wmlxgettext_command_string.append("--no-text-colors")
initialdomain=self.wmlxgettext_tab.initialdomain_variable.get()
if initialdomain:
wmlxgettext_command_string.extend(["--initialdomain",initialdomain])
if self.wmlxgettext_tab.initialdomain_variable.get():
wmlxgettext_command_string.extend(["--initialdomain",self.wmlxgettext_tab.initialdomain_entry.get()])
# start thread and wmlxgettext subprocess
wmlxgettext_thread=ToolThread("wmlxgettext",self.queue,wmlxgettext_command_string)
wmlxgettext_thread.start()

View file

@ -23,9 +23,14 @@ def _closenode_update_dict(podict):
# be ignored, then wrong context info would be attached to these sentences,
# or to an undetermined future sentence.
wmlerr(*unbalanced_wml)
posentence = podict.get(i.sentence)
if i.domain in podict:
d = podict[i.domain]
else:
podict[i.domain] = dict()
d = podict[i.domain]
posentence = d.get(i.sentence)
if posentence is None:
podict[i.sentence] = (
d[i.sentence] = (
nodes[-1].nodesentence_to_posentence(i) )
else:
posentence.update_with_commented_string(
@ -114,13 +119,13 @@ def closenode(closetag, mydict, lineno):
nodes = None
def addNodeSentence(sentence, *, ismultiline, lineno, lineno_sub,
def addNodeSentence(sentence, *, domain, ismultiline, lineno, lineno_sub,
override, addition, plural=None):
global nodes
if nodes is None:
nodes = [pos.WmlNode(fileref=fileref, fileno=fileno,
tagname="", autowml=False)]
nodes[-1].add_sentence(sentence, ismultiline=ismultiline,
nodes[-1].add_sentence(sentence, domain=domain, ismultiline=ismultiline,
lineno=lineno, lineno_sub=lineno_sub,
override=override, addition=addition,
plural=plural)

View file

@ -14,9 +14,10 @@ class PoCommentedStringPL:
class PoCommentedString:
def __init__(self, sentence, *, orderid, ismultiline,
def __init__(self, sentence, domain, *, orderid, ismultiline,
wmlinfos, finfos, addedinfos, plural=None):
self.sentence = sentence
self.domain = domain
self.wmlinfos = wmlinfos
self.addedinfos = addedinfos
self.finfos = finfos
@ -79,9 +80,10 @@ class PoCommentedString:
# WmlNodeSentence use PoCommentedStringPL for 'plural' parameter
class WmlNodeSentence:
def __init__(self, sentence, *, ismultiline, lineno, lineno_sub=0,
def __init__(self, sentence, *, domain, ismultiline, lineno, lineno_sub=0,
plural=None, override=None, addition=None):
self.sentence = sentence
self.domain = domain
# Say if it is multiline or not.
self.ismultiline = ismultiline
self.lineno = lineno
@ -126,7 +128,7 @@ class WmlNode:
self.wmlinfos = None
self.autowml = autowml
def add_sentence(self, sentence, *, ismultiline, lineno,
def add_sentence(self, sentence, *, domain, ismultiline, lineno,
lineno_sub=0, plural=None, override=None, addition=None):
if self.sentences is None:
self.sentences = []
@ -154,6 +156,7 @@ class WmlNode:
plural_value = plural
plural = None
self.sentences.append( WmlNodeSentence(sentence,
domain=domain,
ismultiline=ismultiline,
lineno=lineno,
lineno_sub=lineno_sub,
@ -199,6 +202,7 @@ class WmlNode:
if(nodesentence.addedinfo is not None and
nodesentence.addedinfo != ""):
return PoCommentedString(nodesentence.sentence,
nodesentence.domain,
ismultiline=nodesentence.ismultiline,
orderid=self.assemble_orderid(nodesentence),
wmlinfos=[],
@ -208,6 +212,7 @@ class WmlNode:
plural=nodesentence.plural )
else:
return PoCommentedString(nodesentence.sentence,
nodesentence.domain,
ismultiline=nodesentence.ismultiline,
orderid=self.assemble_orderid(nodesentence),
wmlinfos=[],
@ -219,6 +224,7 @@ class WmlNode:
if(nodesentence.addedinfo is not None and
nodesentence.addedinfo != ""):
return PoCommentedString(nodesentence.sentence,
nodesentence.domain,
ismultiline=nodesentence.ismultiline,
orderid=self.assemble_orderid(nodesentence),
wmlinfos=[nodesentence.overrideinfo],
@ -228,6 +234,7 @@ class WmlNode:
plural=nodesentence.plural )
else:
return PoCommentedString(nodesentence.sentence,
nodesentence.domain,
ismultiline=nodesentence.ismultiline,
orderid=self.assemble_orderid(nodesentence),
wmlinfos=[nodesentence.overrideinfo],
@ -241,6 +248,7 @@ class WmlNode:
if(nodesentence.addedinfo is not None and
nodesentence.addedinfo != ""):
return PoCommentedString(nodesentence.sentence,
nodesentence.domain,
ismultiline=nodesentence.ismultiline,
orderid=self.assemble_orderid(nodesentence),
wmlinfos=[self.assemble_wmlinfo()],
@ -250,6 +258,7 @@ class WmlNode:
plural=nodesentence.plural )
else:
return PoCommentedString(nodesentence.sentence,
nodesentence.domain,
ismultiline=nodesentence.ismultiline,
orderid=self.assemble_orderid(nodesentence),
wmlinfos=[self.assemble_wmlinfo()],
@ -263,6 +272,7 @@ class WmlNode:
if(nodesentence.addedinfo is not None and
nodesentence.addedinfo != ""):
return PoCommentedString(nodesentence.sentence,
nodesentence.domain,
ismultiline=nodesentence.ismultiline,
orderid=self.assemble_orderid(nodesentence),
wmlinfos=[],
@ -272,6 +282,7 @@ class WmlNode:
plural=nodesentence.plural )
else:
return PoCommentedString(nodesentence.sentence,
nodesentence.domain,
ismultiline=nodesentence.ismultiline,
orderid=self.assemble_orderid(nodesentence),
wml_infos=[],

View file

@ -32,8 +32,7 @@ class LuaCheckdomState:
self.iffail = 'lua_checkpo'
def run(self, xline, lineno, match):
pywmlx.state.machine._currentdomain = match.group(3)
pywmlx.state.machine.checkdomain(lineno)
pywmlx.state.machine.switchdomain(lineno, match.group(3))
xline = None
if match.group(1) is None and pywmlx.state.machine._warnall:
finfo = pywmlx.nodemanip.fileref + ":" + str(lineno)

View file

@ -13,7 +13,14 @@ from pywmlx.state.wml_states import setup_wmlstates
import pywmlx.nodemanip
import pdb
# Universe - convenient singleton for which
# `x in Universe` is always True
# Passing it to a filter is equivalent to not filtering.
class UniversalSet:
def __contains__(self, any):
return True
Universe = UniversalSet()
# --------------------------------------------------------------------
# PART 1: machine.py global variables
@ -30,12 +37,12 @@ _fdebug = None
_dictionary = None
# dictionary containing lua and WML states
_states = None
# initialdomain value (setted with --initialdomain command line option)
# initialdomain value (set with --initialdomain command line option)
_initialdomain = None
# the current domain value when parsing file (changed by #textdomain text)
_currentdomain = None
# the domain value (setted with --domain command line option)
_domain = None
# the domain value (set with --domain command line option)
_domains = Universe
# this boolean value will be usually:
# True (when the file is a WML .cfg file)
# False (when the file is a .lua file)
@ -100,14 +107,20 @@ def clear_pending_infos(lineno, error=False):
def checkdomain(lineno):
global _currentdomain
global _domain
if _currentdomain == _domain:
global _domains
if _currentdomain in _domains:
return True
else:
clear_pending_infos(lineno, error=True)
return False
def switchdomain(lineno, domain):
global _currentdomain
if _currentdomain != domain:
clear_pending_infos(lineno, error=True)
_currentdomain = domain
def checksentence(mystring, finfo, *, islua=False):
m = re.match(r'\s*$', mystring)
@ -233,10 +246,13 @@ class PendingLuaString:
loc_addedinfos = []
if _pending_addedinfo is not None:
loc_addedinfos = _pending_addedinfo
loc_posentence = _dictionary.get(self.luastring)
if not _currentdomain in _dictionary:
_dictionary[_currentdomain] = dict()
loc_posentence = _dictionary[_currentdomain].get(self.luastring)
if loc_posentence is None:
_dictionary[self.luastring] = PoCommentedString(
_dictionary[_currentdomain][self.luastring] = PoCommentedString(
self.luastring,
_currentdomain,
orderid=(fileno, self.lineno, _linenosub),
ismultiline=self.ismultiline,
wmlinfos=loc_wmlinfos, finfos=[finfo],
@ -246,6 +262,7 @@ class PendingLuaString:
loc_posentence.update_with_commented_string(
PoCommentedString(
self.luastring,
_currentdomain,
orderid=(fileno, self.lineno, _linenosub),
ismultiline=self.ismultiline,
wmlinfos=loc_wmlinfos, finfos=[finfo],
@ -295,6 +312,7 @@ class PendingWmlString:
else:
self.wmlstring = re.sub('""', r'\"', self.wmlstring)
pywmlx.nodemanip.addNodeSentence(self.wmlstring,
domain=_currentdomain,
ismultiline=self.ismultiline,
lineno=self.lineno,
lineno_sub=_linenosub,
@ -312,16 +330,17 @@ def addstate(name, value):
def setup(dictionary, initialdomain, domain, wall, fdebug):
def setup(dictionary, initialdomain, domains, wall, fdebug):
global _dictionary
global _initialdomain
global _domain
global _domains
global _warnall
global _debugmode
global _fdebug
_dictionary = dictionary
_initialdomain = initialdomain
_domain = domain
if domains is not None:
_domains = set(domains)
_warnall = wall
_fdebug = fdebug
if fdebug is None:

View file

@ -66,8 +66,7 @@ class WmlCheckdomState:
self.iffail = 'wml_checkpo'
def run(self, xline, lineno, match):
pywmlx.state.machine._currentdomain = match.group(1)
pywmlx.state.machine.checkdomain(lineno)
pywmlx.state.machine.switchdomain(lineno, match.group(1))
xline = None
return (xline, 'wml_idle')

View file

@ -44,8 +44,9 @@ import pywmlx
def commandline(args):
parser = argparse.ArgumentParser(
description='Generate .po from WML/lua file list.',
usage='''wmlxgettext --domain=DOMAIN -o OUTPUT_FILE
description='Generate .pot from WML/Lua file list.',
usage='''wmlxgettext -o OUTPUT_DIR
[--domain=DOMAIN]
[--directory=START_PATH]
[--recursive] [--initialdomain=INITIAL_DOMAIN]
[--package-version=PACKAGE_VERSION]
@ -55,28 +56,26 @@ def commandline(args):
parser.add_argument(
'--version',
action='version',
version='wmlxgettext 2019.09.03.py3'
version='wmlxgettext 2023.05.17.py3'
)
parser.add_argument(
'-o',
required=True,
default=None,
dest='outfile',
help= ('Destination file. In some special situations you might want '
dest='folder',
help= ('Destination folder. In some special situations you might want '
'to write the output to STDOUT instead of writing '
'an actual file (using "-o -"). On a standard usage, however, '
'you should avoid to write the output to STDOUT (or you can '
'an actual file (using "-o -"). On standard usage, however, '
'you should avoid to write the output to STDOUT (or you may '
'face some issues related to text encoding). '
'[**REQUIRED ARGUMENT**]')
)
parser.add_argument(
'--domain',
default='wmlxgettext',
required=True,
nargs='*',
dest='domain',
help= ('The textdomain (on WML/lua file) wich contains the '
'strings that will be actually translated. '
'[**REQUIRED ARGUMENT**]')
help= ('One or more textdomain values (on WML/Lua file) associated to the '
'strings that will be actually translated. ')
)
parser.add_argument(
'--directory',
@ -84,14 +83,14 @@ def commandline(args):
dest='start_path',
help=('Complete path of your "start directory". '
'(Default: current directory). The (relative) path to '
'every WML/lua file should start from this directory.')
'every WML/Lua file should start from this directory.')
)
parser.add_argument(
'--initialdomain',
default='wesnoth',
dest='initdom',
help=('Initial domain value on WML/lua file when no textdomain '
'set in that WML/lua file.\nBy default it is equal to '
help=('Initial domain value on WML/Lua file when no textdomain '
'set in that WML/Lua file.\nBy default, it is equal to '
'"wesnoth" and usually you don\'t need to change this value.')
)
parser.add_argument(
@ -107,7 +106,7 @@ def commandline(args):
action='store_false',
default=True,
dest='sort_by_file',
help=("By default the list of input files is sorted so that they "
help=("By default, the list of input files is sorted so that they "
"are processed in a deterministic order. Use this flag to "
"process the files in the order that they're named on the "
"command line.")
@ -117,7 +116,7 @@ def commandline(args):
action='store_false',
default=True,
dest='text_col',
help=("By default warnings are displayed with colored text. You can "
help=("By default, warnings are displayed with colored text. You can "
"disable this feature using this flag.")
)
parser.add_argument(
@ -125,15 +124,15 @@ def commandline(args):
action='store_true',
default=False,
dest='warnall',
help="Show all warnings. By default some warnings are hidden."
help="Show all warnings. By default, some warnings are hidden."
)
parser.add_argument(
'--fuzzy',
action='store_true',
default=False,
dest='fuzzy',
help=("If you specify this flag, all sentences contained on the POT "
"file created by wmlxgettext will be set as fuzzy.\n"
help=("If you specify this flag, all sentences in the POT "
"files created by wmlxgettext will be set as fuzzy.\n"
"By default sentences are NOT set as fuzzy.")
)
parser.add_argument(
@ -141,14 +140,14 @@ def commandline(args):
action='store_true',
default=False,
help=("If this option is used, wmlxgettext will scan recursively the "
"directory set on the '--directory' parameter and checks "
"itself every WML/lua file. "
"directory set by the '--directory' parameter, and check "
"every WML/Lua file. "
"If this option is used, EXPLICIT LIST of files will be "
"ignored.")
)
parser.add_argument(
'filelist',
help='List of WML/lua files of your UMC (source files).',
help='List of WML/Lua files of your UMC (source files).',
nargs='*'
)
@ -157,7 +156,7 @@ def commandline(args):
--DMode is a reserved flag used to verify how wmlxgettext is internally
working. When this flag is used (set to ON), an extra
file (debug.txt) will be created. debug.txt will contain
useful informations to check if wmlxgettext is working as expected
useful information to check if wmlxgettext is working as expected
(but make sense only for wmlxgettext developers/contributors)
'''
parser.add_argument(
@ -182,8 +181,8 @@ def main():
sentlist = dict()
fileno = 0
fdebug = None
if args.outfile == '-':
args.outfile = None
if args.folder == '-':
args.folder = None
if args.debugmode:
fdebug = open('debug.txt', 'w', encoding='utf-8')
pywmlx.statemachine.setup(sentlist, args.initdom, args.domain,
@ -240,41 +239,50 @@ def main():
pywmlx.statemachine.run(filebuf=infile, fileref=fx,
fileno=fileno, startstate='lua_idle', waitwml=False)
infile.close()
outfile = None
if args.outfile is None:
outfile = sys.stdout
else:
outfile_name = os.path.realpath(os.path.normpath(args.outfile))
try:
outfile = open(outfile_name, 'w', encoding="utf-8")
except OSError as e:
errmsg = 'cannot write file: ' + e.args[1]
pywmlx.wmlerr(e.filename, errmsg, OSError)
pkgversion = args.package_version + '\\n"'
print('msgid ""\nmsgstr ""', file=outfile)
print('"Project-Id-Version:', pkgversion, file=outfile)
print('"Report-Msgid-Bugs-To: https://bugs.wesnoth.org/\\n"', file=outfile)
now = datetime.utcnow()
cdate = '{:04d}-{:02d}-{:02d} {:02d}:{:02d} UTC\\n"'.format(now.year,
now.month,
now.day,
now.hour,
now.minute)
print('"POT-Creation-Date:', cdate, file=outfile)
print('"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"', file=outfile)
print('"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"', file=outfile)
print('"Language-Team: LANGUAGE <LL@li.org>\\n"', file=outfile)
print('"MIME-Version: 1.0\\n"', file=outfile)
print('"Content-Type: text/plain; charset=UTF-8\\n"', file=outfile)
print('"Content-Transfer-Encoding: 8bit\\n"\n', file=outfile)
for posentence in sorted(sentlist.values(), key=lambda x: x.orderid):
posentence.write(outfile, args.fuzzy)
print('', file=outfile)
if args.outfile is not None:
outfile.close()
if args.debugmode:
fdebug.close()
folder = None
filename = None
outfile = sys.stdout
now = datetime.utcnow()
if args.folder is not None:
folder = os.path.realpath(os.path.normpath(args.folder))
if not os.path.isdir(folder) and "." in os.path.basename(folder):
# Back-compat
folder, filename = os.path.split(folder)
os.makedirs(folder, exist_ok=True)
for domain, d in sentlist.items():
if folder is not None:
try:
outfile = open(os.path.join(folder, "{}.pot".format(domain) if filename is None else filename), 'w', encoding="utf-8")
except OSError as e:
errmsg = 'cannot write file: ' + e.args[1]
pywmlx.wmlerr(e.filename, errmsg, OSError)
pkgversion = args.package_version + '\\n"'
print('msgid ""\nmsgstr ""', file=outfile)
print('"Project-Id-Version:', pkgversion, file=outfile)
print('"Report-Msgid-Bugs-To: https://bugs.wesnoth.org/\\n"', file=outfile)
cdate = '{:04d}-{:02d}-{:02d} {:02d}:{:02d} UTC\\n"'.format(now.year,
now.month,
now.day,
now.hour,
now.minute)
print('"POT-Creation-Date:', cdate, file=outfile)
print('"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"', file=outfile)
print('"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"', file=outfile)
print('"Language-Team: LANGUAGE <LL@li.org>\\n"', file=outfile)
print('"MIME-Version: 1.0\\n"', file=outfile)
print('"Content-Type: text/plain; charset=UTF-8\\n"', file=outfile)
print('"Content-Transfer-Encoding: 8bit\\n"\n', file=outfile)
for posentence in sorted(d.values(), key=lambda x: x.orderid):
posentence.write(outfile, args.fuzzy)
print('', file=outfile)
if args.folder is not None:
outfile.close()
if args.debugmode:
fdebug.close()