Make interface similar to XML import

svn: r17491
This commit is contained in:
Michiel Nauta 2011-05-13 20:44:10 +00:00
parent 1b0ddbed83
commit 7c9e338295

View File

@ -61,15 +61,17 @@ from QuestionDialog import ErrorDialog
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def importData(database, filename, cb_progress=None): def importData(database, filename, cb_progress=None):
"""Function called by Gramps to import data on persons in VCard format.""" """Function called by Gramps to import data on persons in VCard format."""
parser = VCardParser(database, filename) parser = VCardParser(database)
try: try:
return parser.parse_vCard_file() with OpenFileOrStdin(filename) as filehandle:
parser.parse(filehandle)
except EnvironmentError, msg: except EnvironmentError, msg:
ErrorDialog(_("%s could not be opened\n") % filename, str(msg)) ErrorDialog(_("%s could not be opened\n") % filename, str(msg))
return return
except Errors.GrampsImportError, msg: except Errors.GrampsImportError, msg:
ErrorDialog(_("%s could not be opened\n") % filename, str(msg)) ErrorDialog(_("%s could not be opened\n") % filename, str(msg))
return return
return None # This module doesn't provide info about what got imported.
def splitof_nameprefix(name): def splitof_nameprefix(name):
@ -164,7 +166,7 @@ class VCardParser(object):
@staticmethod @staticmethod
def count_escapes(strng): def count_escapes(strng):
"""Count the number of escape characters at the end of a string""" """Count the number of escape characters at the end of a string."""
count = 0 count = 0
for char in reversed(strng): for char in reversed(strng):
if char != VCardParser.ESCAPE_CHAR: if char != VCardParser.ESCAPE_CHAR:
@ -183,48 +185,59 @@ class VCardParser(object):
strng_parts[i] += sep + appendix strng_parts[i] += sep + appendix
return strng_parts return strng_parts
def __init__(self, dbase, filename): def __init__(self, dbase):
self.database = dbase self.database = dbase
self.filename = filename
self.formatted_name = '' self.formatted_name = ''
self.name_parts = '' self.name_parts = ''
self.filehandle = None
self.next_line = None self.next_line = None
self.trans = None self.trans = None
self.version = None self.version = None
self.person = None self.person = None
def get_next_line(self): def __get_next_line(self, filehandle):
""" """
Read and return the line with the next property of the VCard. Read and return the line with the next property of the VCard.
Also if it spans multiple lines (RFC 2425 sec.5.8.1). Also if it spans multiple lines (RFC 2425 sec.5.8.1).
""" """
line = self.next_line line = self.next_line
self.next_line = self.filehandle.readline() self.next_line = filehandle.readline()
while self.next_line and self.next_line[0] in self.LINE_CONTINUATION: while self.next_line and self.next_line[0] in self.LINE_CONTINUATION:
line = line.rstrip("\n") line = line.rstrip("\n")
#TODO perhaps next lines superflous because of rU open parameter? #TODO perhaps next lines superflous because of rU open parameter?
if len(line) > 0 and line[-1] == "\r": if len(line) > 0 and line[-1] == "\r":
line = line[:-1] line = line[:-1]
line += self.next_line[1:] line += self.next_line[1:]
self.next_line = self.filehandle.readline() self.next_line = filehandle.readline()
if line: if line:
line = line.strip() line = line.strip()
else: else:
line = None line = None
return line return line
def parse_vCard_file(self): def parse(self, filehandle):
"""Read each line of the input file and act accordingly.""" """
Prepare the database and parse the input file.
:param filehandle: open file handle positioned at start of the file
"""
tym = time.time() tym = time.time()
self.person = None self.person = None
with DbTxn(_("vCard import"), self.database, batch=True) as self.trans:
self.database.disable_signals() self.database.disable_signals()
with OpenFileOrStdin(self.filename) as self.filehandle: with DbTxn(_("vCard import"), self.database, batch=True) as self.trans:
self.next_line = self.filehandle.readline() self._parse_vCard_file(filehandle)
self.database.enable_signals()
self.database.request_rebuild()
tym = time.time() - tym
msg = ngettext('Import Complete: %d second',
'Import Complete: %d seconds', tym ) % tym
LOG.debug(msg)
def _parse_vCard_file(self, filehandle):
"""Read each line of the input file and act accordingly."""
self.next_line = filehandle.readline()
while True: while True:
line = self.get_next_line() line = self.__get_next_line(filehandle)
if line is None: if line is None:
break break
if line == "": if line == "":
@ -272,15 +285,6 @@ class VCardParser(object):
else: else:
LOG.warn("Token >%s< unknown. line skipped: %s" % LOG.warn("Token >%s< unknown. line skipped: %s" %
(fields[0],line)) (fields[0],line))
self.database.enable_signals()
tym = time.time() - tym
msg = ngettext('Import Complete: %d second',
'Import Complete: %d seconds', tym ) % tym
LOG.debug(msg)
self.database.request_rebuild()
return None
def finish_person(self): def finish_person(self):
"""All info has been collected, write to database.""" """All info has been collected, write to database."""