Issue 4274, Gramps cli commands for user with non latin characters in names. Mostly Windows.
svn: r15983
This commit is contained in:
parent
dd1f244d24
commit
174886e40a
@ -371,21 +371,26 @@ class CommandLineReport(object):
|
|||||||
opt = self.options_help[key]
|
opt = self.options_help[key]
|
||||||
# Make the output nicer to read, assume that tab has 8 spaces
|
# Make the output nicer to read, assume that tab has 8 spaces
|
||||||
tabs = '\t' if len(key) < 10 else '\t'*2
|
tabs = '\t' if len(key) < 10 else '\t'*2
|
||||||
print " %s%s%s (%s)" % (key, tabs, opt[1], opt[0])
|
optmsg = " %s%s%s (%s)" % (key, tabs, opt[1], opt[0])
|
||||||
|
print optmsg.encode(sys.getfilesystemencoding())
|
||||||
else:
|
else:
|
||||||
print " %s" % key
|
optmsg = " %s" % key
|
||||||
|
print optmsg.encode(sys.getfilesystemencoding())
|
||||||
print " Use 'show=option' to see description and acceptable values"
|
print " Use 'show=option' to see description and acceptable values"
|
||||||
elif self.show in self.options_help:
|
elif self.show in self.options_help:
|
||||||
opt = self.options_help[self.show]
|
opt = self.options_help[self.show]
|
||||||
tabs = '\t' if len(self.show) < 10 else '\t'*2
|
tabs = '\t' if len(self.show) < 10 else '\t'*2
|
||||||
print ' %s%s%s%s' % (self.show, tabs, opt[0], opt[1])
|
optmsg = ' %s%s%s%s' % (self.show, tabs, opt[0], opt[1])
|
||||||
|
print optmsg.encode(sys.getfilesystemencoding())
|
||||||
print " Available values are:"
|
print " Available values are:"
|
||||||
vals = opt[2]
|
vals = opt[2]
|
||||||
if isinstance(vals, (list, tuple)):
|
if isinstance(vals, (list, tuple)):
|
||||||
for val in vals:
|
for val in vals:
|
||||||
print " %s" % val
|
optmsg = " %s" % val
|
||||||
|
print optmsg.encode(sys.getfilesystemencoding())
|
||||||
else:
|
else:
|
||||||
print " %s" % opt[2]
|
optmsg = " %s" % opt[2]
|
||||||
|
print optmsg.encode(sys.getfilesystemencoding())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
#there was a show option given, but the option is invalid
|
#there was a show option given, but the option is invalid
|
||||||
|
@ -94,7 +94,9 @@ class ArgHandler(object):
|
|||||||
if self.errorfunc:
|
if self.errorfunc:
|
||||||
self.errorfunc(string)
|
self.errorfunc(string)
|
||||||
else:
|
else:
|
||||||
print string
|
# Need to convert to str before printing
|
||||||
|
# For non latin characters in Windows path/file/user names
|
||||||
|
print string.encode(sys.getfilesystemencoding())
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# Argument parser: sorts out given arguments
|
# Argument parser: sorts out given arguments
|
||||||
@ -115,8 +117,8 @@ class ArgHandler(object):
|
|||||||
"""
|
"""
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
|
value = Utils.get_unicode_path_from_env_var(value)
|
||||||
db_path = self.__deduce_db_path(value)
|
db_path = self.__deduce_db_path(value)
|
||||||
|
|
||||||
if db_path:
|
if db_path:
|
||||||
# We have a potential database path.
|
# We have a potential database path.
|
||||||
# Check if it is good.
|
# Check if it is good.
|
||||||
@ -134,6 +136,9 @@ class ArgHandler(object):
|
|||||||
Handle the "-i" or "--import" option.
|
Handle the "-i" or "--import" option.
|
||||||
Only Files supported by a plugin can be imported, so not Family Trees.
|
Only Files supported by a plugin can be imported, so not Family Trees.
|
||||||
"""
|
"""
|
||||||
|
# Need to convert path/filename to unicode before openingh
|
||||||
|
# For non latin characters in Windows path/file/user names
|
||||||
|
value = Utils.get_unicode_path_from_env_var(value)
|
||||||
fname = value
|
fname = value
|
||||||
fullpath = os.path.abspath(os.path.expanduser(fname))
|
fullpath = os.path.abspath(os.path.expanduser(fname))
|
||||||
if not os.path.exists(fullpath):
|
if not os.path.exists(fullpath):
|
||||||
@ -168,6 +173,9 @@ class ArgHandler(object):
|
|||||||
"""
|
"""
|
||||||
if self.gui:
|
if self.gui:
|
||||||
return
|
return
|
||||||
|
# Need to covert path/filename to unicode before openingh
|
||||||
|
# For non latin characters in Windows path/file/user names
|
||||||
|
value = Utils.get_unicode_path_from_env_var(value)
|
||||||
fname = value
|
fname = value
|
||||||
fullpath = os.path.abspath(os.path.expanduser(fname))
|
fullpath = os.path.abspath(os.path.expanduser(fname))
|
||||||
if os.path.exists(fullpath):
|
if os.path.exists(fullpath):
|
||||||
@ -176,8 +184,9 @@ class ArgHandler(object):
|
|||||||
{'name' : fullpath})
|
{'name' : fullpath})
|
||||||
answer = None
|
answer = None
|
||||||
while not answer:
|
while not answer:
|
||||||
answer = raw_input(_('OK to overwrite? (yes/no) '))
|
answer = raw_input(_('OK to overwrite? (yes/no) ') \
|
||||||
if answer.upper() in ('Y', 'YES', _('YES')):
|
.encode(sys.getfilesystemencoding()))
|
||||||
|
if answer.upper() in ('Y', 'YES', _('YES').upper()):
|
||||||
self.__error( _("Will overwrite the existing file: %s")
|
self.__error( _("Will overwrite the existing file: %s")
|
||||||
% fullpath)
|
% fullpath)
|
||||||
else:
|
else:
|
||||||
@ -310,7 +319,11 @@ class ArgHandler(object):
|
|||||||
self.cl_action(action, options_str)
|
self.cl_action(action, options_str)
|
||||||
|
|
||||||
for expt in self.exports:
|
for expt in self.exports:
|
||||||
print "Exporting: file %s, format %s." % expt
|
# Need to convert path/filename to str before printing
|
||||||
|
# For non latin characters in Windows path/file/user names
|
||||||
|
fn = expt[0].encode(sys.getfilesystemencoding())
|
||||||
|
fmt = str(expt[1])
|
||||||
|
print "Exporting: file %s, format %s." % (fn, fmt)
|
||||||
self.cl_export(expt[0], expt[1])
|
self.cl_export(expt[0], expt[1])
|
||||||
|
|
||||||
if cleanup:
|
if cleanup:
|
||||||
@ -356,7 +369,11 @@ class ArgHandler(object):
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
for imp in self.imports:
|
for imp in self.imports:
|
||||||
print "Importing: file %s, format %s." % imp
|
# Need to covert path/filename to str before printing
|
||||||
|
# For non latin characters in Windows path/file/user names
|
||||||
|
fn = imp[0].encode(sys.getfilesystemencoding())
|
||||||
|
fmt = str(imp[1])
|
||||||
|
print "Importing: file %s, format %s." % (fn , fmt)
|
||||||
self.cl_import(imp[0], imp[1])
|
self.cl_import(imp[0], imp[1])
|
||||||
|
|
||||||
def __open_action(self):
|
def __open_action(self):
|
||||||
@ -480,9 +497,9 @@ class ArgHandler(object):
|
|||||||
if len(pdata.id) <= 25:
|
if len(pdata.id) <= 25:
|
||||||
print " %s%s- %s" % ( pdata.id,
|
print " %s%s- %s" % ( pdata.id,
|
||||||
" " * (26 - len(pdata.id)),
|
" " * (26 - len(pdata.id)),
|
||||||
pdata.name)
|
pdata.name.encode(sys.getfilesystemencoding()))
|
||||||
else:
|
else:
|
||||||
print " %s\t- %s" % (pdata.id, pdata.name)
|
print " %s\t- %s" % (pdata.id, pdata.name.encode(sys.getfilesystemencoding()) )
|
||||||
|
|
||||||
elif action == "tool":
|
elif action == "tool":
|
||||||
try:
|
try:
|
||||||
@ -517,9 +534,9 @@ class ArgHandler(object):
|
|||||||
if len(pdata.id) <= 25:
|
if len(pdata.id) <= 25:
|
||||||
print " %s%s- %s" % ( pdata.id,
|
print " %s%s- %s" % ( pdata.id,
|
||||||
" " * (26 - len(pdata.id)),
|
" " * (26 - len(pdata.id)),
|
||||||
pdata.name)
|
pdata.name.encode(sys.getfilesystemencoding()))
|
||||||
else:
|
else:
|
||||||
print " %s\t- %s" % (pdata.id, pdata.name)
|
print " %s\t- %s" % (pdata.id, pdata.name.encode(sys.getfilesystemencoding()))
|
||||||
else:
|
else:
|
||||||
print "Unknown action: %s." % action
|
print "Unknown action: %s." % action
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Gramps - a GTK+/GNOME based genealogy program
|
# Gramps - a GTK+/GNOME based genealogy program
|
||||||
#
|
#
|
||||||
@ -44,6 +45,7 @@ import logging
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
import const
|
import const
|
||||||
|
import Utils
|
||||||
|
|
||||||
|
|
||||||
# Note: Make sure to edit const.py POPT_TABLE too!
|
# Note: Make sure to edit const.py POPT_TABLE too!
|
||||||
@ -68,6 +70,51 @@ Application options
|
|||||||
-u, --force-unlock Force unlock of family tree
|
-u, --force-unlock Force unlock of family tree
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
_USAGE = _("""
|
||||||
|
Example of usage of Gramps command line interface
|
||||||
|
|
||||||
|
1. To import four databases (whose formats can be determined from their names)
|
||||||
|
and then check the resulting database for errors, one may type:
|
||||||
|
gramps -i file1.ged -i file2.gpkg -i ~/db3.gramps -i file4.wft -a check
|
||||||
|
|
||||||
|
2. To explicitly specify the formats in the above example, append filenames with appropriate -f options:
|
||||||
|
gramps -i file1.ged -f gedcom -i file2.gpkg -f gramps-pkg -i ~/db3.gramps -f gramps-xml -i file4.wft -f wft -a check
|
||||||
|
|
||||||
|
3. To record the database resulting from all imports, supply -e flag
|
||||||
|
(use -f if the filename does not allow GRAMPS to guess the format):
|
||||||
|
gramps -i file1.ged -i file2.gpkg -e ~/new-package -f gramps-pkg
|
||||||
|
|
||||||
|
4. To save any error messages of the above example into files outfile and errfile, run:
|
||||||
|
gramps -i file1.ged -i file2.dpkg -e ~/new-package -f gramps-pkg >outfile 2>errfile
|
||||||
|
|
||||||
|
5. To import three databases and start interactive GRAMPS session with the result:
|
||||||
|
gramps -i file1.ged -i file2.gpkg -i ~/db3.gramps
|
||||||
|
|
||||||
|
6. To open a database and, based on that data, generate timeline report in PDF format
|
||||||
|
putting the output into the my_timeline.pdf file:
|
||||||
|
gramps -O 'Family Tree 1' -a report -p name=timeline,off=pdf,of=my_timeline.pdf
|
||||||
|
|
||||||
|
7. To generate a summary of a database:
|
||||||
|
gramps -O 'Family Tree 1' -a report -p name=summary
|
||||||
|
|
||||||
|
8. Listing report options
|
||||||
|
Use the name=timeline,show=all to find out about all available options for the timeline report.
|
||||||
|
To find out details of a particular option, use show=option_name , e.g. name=timeline,show=off string.
|
||||||
|
To learn about available report names, use name=show string.
|
||||||
|
|
||||||
|
9. To convert a family tree on the fly to a .gramps xml file:
|
||||||
|
gramps -O 'Family Tree 1' -e output.gramps -f gramps-xml
|
||||||
|
|
||||||
|
10. To generate a web site into an other locale (in german):
|
||||||
|
LANGUAGE=de_DE; LANG=de_DE.UTF-8 gramps -O 'Family Tree 1' -a report -p name=navwebpage,target=/../de
|
||||||
|
|
||||||
|
11. Finally, to start normal interactive session type:
|
||||||
|
gramps
|
||||||
|
|
||||||
|
Note: These examples are for bash shell.
|
||||||
|
Syntax may be different for other shells and for Windows.
|
||||||
|
""")
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# ArgParser
|
# ArgParser
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
@ -121,6 +168,7 @@ class ArgParser(object):
|
|||||||
self.list = False
|
self.list = False
|
||||||
self.list_more = False
|
self.list_more = False
|
||||||
self.help = False
|
self.help = False
|
||||||
|
self.usage = False
|
||||||
self.force_unlock = False
|
self.force_unlock = False
|
||||||
|
|
||||||
self.errors = []
|
self.errors = []
|
||||||
@ -150,14 +198,30 @@ class ArgParser(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# Convert arguments to unicode, otherwise getopt will not work
|
||||||
|
# if a non latin character is used as an option (by mistake).
|
||||||
|
# getopt will try to treat the first char in an utf-8 sequence. Example:
|
||||||
|
# -Ärik is '-\xc3\x84rik' and getopt will respond :
|
||||||
|
# option -\xc3 not recognized
|
||||||
|
for arg in range(len(self.args) - 1):
|
||||||
|
self.args[arg+1] = Utils.get_unicode_path_from_env_var(self.args[arg + 1])
|
||||||
options, leftargs = getopt.getopt(self.args[1:],
|
options, leftargs = getopt.getopt(self.args[1:],
|
||||||
const.SHORTOPTS, const.LONGOPTS)
|
const.SHORTOPTS, const.LONGOPTS)
|
||||||
except getopt.GetoptError, msg:
|
except getopt.GetoptError, msg:
|
||||||
|
# Extract the arguments in the list.
|
||||||
|
# The % operator replaces the list elements with repr() of the list elemements
|
||||||
|
# which is OK for latin characters, but not for non latin characters in list elements
|
||||||
|
cliargs = "[ "
|
||||||
|
for arg in range(len(self.args) - 1):
|
||||||
|
cliargs += self.args[arg + 1] + " "
|
||||||
|
cliargs += "]"
|
||||||
|
# Must first do str() of the msg object.
|
||||||
|
msg = unicode(str(msg))
|
||||||
self.errors += [(_('Error parsing the arguments'),
|
self.errors += [(_('Error parsing the arguments'),
|
||||||
str(msg) + '\n' +
|
msg + '\n' +
|
||||||
_("Error parsing the arguments: %s \n"
|
_("Error parsing the arguments: %s \n"
|
||||||
"Type gramps --help for an overview of commands, or "
|
"Type gramps --help for an overview of commands, or "
|
||||||
"read the manual pages.") % self.args[1:])]
|
"read the manual pages.") % cliargs)]
|
||||||
return
|
return
|
||||||
|
|
||||||
if leftargs:
|
if leftargs:
|
||||||
@ -214,6 +278,8 @@ class ArgParser(object):
|
|||||||
self.help = True
|
self.help = True
|
||||||
elif option in ('-u', '--force-unlock'):
|
elif option in ('-u', '--force-unlock'):
|
||||||
self.force_unlock = True
|
self.force_unlock = True
|
||||||
|
elif option in ('--usage'):
|
||||||
|
self.usage = True
|
||||||
|
|
||||||
#clean options list
|
#clean options list
|
||||||
cleandbg.reverse()
|
cleandbg.reverse()
|
||||||
@ -222,10 +288,17 @@ class ArgParser(object):
|
|||||||
|
|
||||||
if len(options) > 0 and self.open is None and self.imports == [] \
|
if len(options) > 0 and self.open is None and self.imports == [] \
|
||||||
and not (self.list or self.list_more or self.help):
|
and not (self.list or self.list_more or self.help):
|
||||||
|
# Extract and convert to unicode the arguments in the list.
|
||||||
|
# The % operator replaces the list elements with repr() of the list elemements
|
||||||
|
# which is OK for latin characters, but not for non latin characters in list elements
|
||||||
|
cliargs = "[ "
|
||||||
|
for arg in range(len(self.args) - 1):
|
||||||
|
cliargs += Utils.get_unicode_path_from_env_var(self.args[arg + 1]) + " "
|
||||||
|
cliargs += "]"
|
||||||
self.errors += [(_('Error parsing the arguments'),
|
self.errors += [(_('Error parsing the arguments'),
|
||||||
_("Error parsing the arguments: %s \n"
|
_("Error parsing the arguments: %s \n"
|
||||||
"To use in the command-line mode," \
|
"To use in the command-line mode," \
|
||||||
"supply at least one input file to process.") % self.args[1:])]
|
"supply at least one input file to process.") % cliargs)]
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# Determine the need for GUI
|
# Determine the need for GUI
|
||||||
@ -262,6 +335,15 @@ class ArgParser(object):
|
|||||||
If the user gives the --help or -h option, print the output to terminal.
|
If the user gives the --help or -h option, print the output to terminal.
|
||||||
"""
|
"""
|
||||||
if self.help:
|
if self.help:
|
||||||
print _HELP
|
# Convert Help messages to file system encoding before printing
|
||||||
|
print _HELP.encode(sys.getfilesystemencoding())
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
def print_usage(self):
|
||||||
|
"""
|
||||||
|
If the user gives the --usage print the output to terminal.
|
||||||
|
"""
|
||||||
|
if self.usage:
|
||||||
|
# Convert Help messages to file system encoding before printing
|
||||||
|
print _USAGE.encode(sys.getfilesystemencoding())
|
||||||
|
sys.exit(0)
|
||||||
|
@ -297,14 +297,24 @@ def startcli(errors, argparser):
|
|||||||
"""
|
"""
|
||||||
if errors:
|
if errors:
|
||||||
#already errors encountered. Show first one on terminal and exit
|
#already errors encountered. Show first one on terminal and exit
|
||||||
print _('Error encountered: %s') % errors[0][0]
|
# Convert error message to file system encoding before print
|
||||||
print _(' Details: %s') % errors[0][1]
|
errmsg = _('Error encountered: %s') % errors[0][0]
|
||||||
|
errmsg = errmsg.encode(sys.getfilesystemencoding())
|
||||||
|
print errmsg
|
||||||
|
errmsg = _(' Details: %s') % errors[0][1]
|
||||||
|
errmsg = errmsg.encode(sys.getfilesystemencoding())
|
||||||
|
print errmsg
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if argparser.errors:
|
if argparser.errors:
|
||||||
print _('Error encountered in argument parsing: %s') \
|
# Convert error message to file system encoding before print
|
||||||
|
errmsg = _('Error encountered in argument parsing: %s') \
|
||||||
% argparser.errors[0][0]
|
% argparser.errors[0][0]
|
||||||
print _(' Details: %s') % argparser.errors[0][1]
|
errmsg = errmsg.encode(sys.getfilesystemencoding())
|
||||||
|
print errmsg
|
||||||
|
errmsg = _(' Details: %s') % argparser.errors[0][1]
|
||||||
|
errmsg = errmsg.encode(sys.getfilesystemencoding())
|
||||||
|
print errmsg
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
#we need to keep track of the db state
|
#we need to keep track of the db state
|
||||||
|
@ -181,6 +181,7 @@ def run():
|
|||||||
else:
|
else:
|
||||||
#CLI use of GRAMPS
|
#CLI use of GRAMPS
|
||||||
argpars.print_help()
|
argpars.print_help()
|
||||||
|
argpars.print_usage()
|
||||||
from cli.grampscli import startcli
|
from cli.grampscli import startcli
|
||||||
startcli(error, argpars)
|
startcli(error, argpars)
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import cStringIO
|
import cStringIO
|
||||||
|
|
||||||
from gen.ggettext import gettext as _
|
from gen.ggettext import gettext as _
|
||||||
@ -552,8 +553,10 @@ class CheckIntegrity(object):
|
|||||||
photo_name = Utils.media_path_full(self.db, obj.get_path())
|
photo_name = Utils.media_path_full(self.db, obj.get_path())
|
||||||
if photo_name is not None and photo_name != "" and not Utils.find_file(photo_name):
|
if photo_name is not None and photo_name != "" and not Utils.find_file(photo_name):
|
||||||
if cl:
|
if cl:
|
||||||
|
# Convert to file system encoding before prining
|
||||||
|
fn = os.path.basename(photo_name).encode(sys.getfilesystemencoding())
|
||||||
print "Warning: media file %s was not found." \
|
print "Warning: media file %s was not found." \
|
||||||
% os.path.basename(photo_name)
|
% fn
|
||||||
self.bad_photo.append(ObjectId)
|
self.bad_photo.append(ObjectId)
|
||||||
else:
|
else:
|
||||||
if missmedia_action == 0:
|
if missmedia_action == 0:
|
||||||
@ -1627,7 +1630,8 @@ class Report(ManagedWindow.ManagedWindow):
|
|||||||
|
|
||||||
def __init__(self, uistate, text, cl=0):
|
def __init__(self, uistate, text, cl=0):
|
||||||
if cl:
|
if cl:
|
||||||
print text
|
# Convert to file system encoding before prining
|
||||||
|
print text.encode(sys.getfilesystemencoding())
|
||||||
return
|
return
|
||||||
|
|
||||||
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self)
|
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user