Пример #1
0
 def new_exhib():
     newelt = ET.Element('Exhibition')
     subelt = ET.SubElement(newelt, 'ExhibitionName')
     subelt.text = exhibition.ExhibitionName
     if catalog_num is not None:
         subelt = ET.SubElement(newelt, 'CatalogueNumber')
         subelt.text = str(catalog_num)
     subelt = ET.SubElement(newelt, 'Place')
     subelt.text = exhibition.Place
     dateelt = ET.SubElement(newelt, 'Date')
     subelt = ET.SubElement(dateelt, 'DateBegin')
     subelt.text = modesdate(exhibition.DateBegin)
     subelt = ET.SubElement(dateelt, 'DateEnd')
     subelt.text = modesdate(exhibition.DateEnd)
     return exhibition.DateBegin, newelt
Пример #2
0
def main():
    inf = open(sys.argv[1])
    outf = open(sys.argv[2], 'w')
    reader = csv.reader(inf)
    writer = csv.writer(outf)
    row = next(reader)
    row.append('modesdate')
    row.append('isodate')
    # writer.writerow(row)
    for row in reader:
        indate = row[1]
        d, status, nfields = parsedate(indate)
        print(row, d, status)
        if d:
            if WRITEALL or not status:
                outs = modesdate(d, nfields)
                iso = d.isoformat()
                row.append(outs)
                row.append(iso)
                newrow = [row[0], outs]
                writer.writerow(newrow)
        elif WRITEALL:
            if indate and indate != 'unknown':
                print(f'Cannot parse {row}')
            outs = 'unknown'
            iso = ''
            if indate and indate != 'unknown':
                print(f'{row}')
            row.append(outs)
            row.append(iso)
            writer.writerow(row)
Пример #3
0
def one_object(objelt: ET.Element, idnum: str) -> bool:
    """
    :param objelt: the Object
    :param idnum: the ObjectIdentity/Number text (for trace)

    :return: True if an object is updated
    """
    references = objelt.findall('./References/Reference')
    updated = False
    for reference in references:
        refdate = reference.find('./Date')
        if refdate is None:
            continue
        refdatetext: str = refdate.text
        if refdatetext is None or len(refdatetext) == 0:
            continue
        try:
            newdate, partcount, datetype = datefrombritishdate(refdatetext)
        except ValueError:
            continue
        if datetype == MODESTYPE:  # if it's already a Modes format date
            continue
        mdate = modesdate(newdate, partcount)
        refdate.text = mdate
        updated = True
        trace(2, '{}: {} -> {}', idnum, refdatetext, mdate)
    return updated
Пример #4
0
def expand_value(text):
    match text.lower():
        case '{{clear}}':
            return ''
        case '{{today}}':
            return modesdate(date.today())
        case _:
            return text
Пример #5
0
def one_object(obj):
    db = obj.find(
        './ObjectLocation[@elementtype="current location"]/Date/DateBegin')
    if db is not None and db.text is not None:
        isodate = None
        try:
            isodate = dt.strptime(db.text, '%Y-%m-%d')
        except ValueError:
            pass
        if isodate:
            db.text = nd.modesdate(isodate)
Пример #6
0
    def one_exhibition(exhib_elt):
        """
        Handle an existing exhibition
        :param exhib_elt: an Exhibition element (under Object)
        :return: 0 if it is an empty template
                 1 if the input element's ExhibitionName is different from
                    the one we are inserting
                 2 (also update the values) if the ExhibitionName values match

        It is possible to have duplicate exhibition names but exhibitions are
        guaranteed to have unique name+place+begindate. So if we are replacing
        the name, make sure that we are updating the correct exhibition by
        checking the complete keys.
        """

        exhibname = exhib_elt.find('ExhibitionName')
        if exhibname is None:
            return 0  # This is an empty Exhibition template
        # Updating the exhibition name is a special case since it's used as
        # a key.  The old name is in the XML file and is to be replaced. We
        # could skip this step as the full key compare will work anyhow, but
        # this gets us out of here quickly in most cases.
        if exhibname.text not in (_oldname, exhibition.ExhibitionName):
            return 1  # not a match so just keep this element as is
        # The exhibition names match but if they are duplicated elsewhere in
        # the list, we must look deeper.
        exhibkey = _oldname if _oldname else exhibition.ExhibitionName + ':'
        exhibkey += _oldplace if _oldplace else exhibition.Place + ':'
        exhibkey += _olddate if _olddate else (
            exhibition.DateBegin.isoformat()[:10])
        xmlkey = exhibname.text
        xmlplace = ''
        xmldate = ''
        subelts = list(exhib_elt)
        for subelt in subelts:
            tag = subelt.tag
            if tag == "Place":
                xmlplace = subelt.text
            elif tag == "Date":
                dates = list(subelt)
                for dateelt in dates:
                    if dateelt.tag == 'DateBegin':
                        xmldate = dateelt.text
                        break
        xmlkey += ':' + xmlplace + ':' + xmldate
        # And finally, confirm that it's really the one we want to update.
        trace(3, '{}: exhibkey={}\nxmlkey={}', idnum, exhibkey, xmlkey)
        if exhibkey != xmlkey:
            return 1
        # The names match so update the values
        for subelt in subelts:
            tag = subelt.tag
            if tag == "ExhibitionName":
                subelt.text = exhibition.ExhibitionName
            elif tag == "CatalogueNumber":
                subelt.text = str(catalog_num)
            elif tag == "Place":
                subelt.text = exhibition.Place
            elif tag == "Date":
                dates = list(subelt)
                for dateelt in dates:
                    if dateelt.tag == 'DateBegin':
                        dateelt.text = modesdate(exhibition.DateBegin)
                    elif dateelt.tag == 'DateEnd':
                        dateelt.text = modesdate(exhibition.DateEnd)
            else:
                trace(
                    1, 'ID {}: Unknown subelt in {} Exhibition element: {},'
                    ' element not updated.', subelt.text, display_id, tag)
        return 2
Пример #7
0
def add_arguments(parser, command):
    global is_update, is_diff, is_select, is_validate  # Needed for Sphinx
    if called_from_sphinx:
        is_update = command == 'update'
        is_diff = command == 'diff'
        is_select = command == 'select'
        is_validate = command == 'validate'
    parser.add_argument('-i',
                        '--infile',
                        required=True,
                        help='''
        The XML file saved from Modes.''')
    if is_update or is_select:
        parser.add_argument('-o',
                            '--outfile',
                            required=True,
                            help='''
            The output XML file.''')
    if is_diff or is_update or is_select:
        parser.add_argument('-a',
                            '--all',
                            action='store_true',
                            help='''
        Write all objects and, if -w is selected, issue a warning if an object
        is not in the detail CSV file. The default is to only write updated
        objects. In either case warn if an object in the CSV file is not in the
        input XML file.''')
    if is_update or is_diff:
        parser.add_argument('--col_acc',
                            type=int,
                            default=0,
                            help='''
        The zero-based column containing the accession number of the
        object to be updated. The default is column zero.
        ''')
        parser.add_argument('--col_loc',
                            type=int,
                            default=1,
                            help=nd.sphinxify(
                                '''
        The zero-based column containing the new location of the
        object to be updated. The default is column 1. See the --location
        option which sets the location for all objects in which case this
        option is ignored.''', called_from_sphinx))
    if is_update or is_diff:
        parser.add_argument('-c',
                            '--current',
                            action='store_true',
                            help='''
        Update the current location and change the old current location to a
        previous location. See the descrption of "n" and "p". ''')
    if is_update:
        parser.add_argument('-d',
                            '--date',
                            default=nd.modesdate(date.today()),
                            help='''
            When updating the current location, use this date as the DateEnd
            value for the previous location we're making and the DateBegin
            value for the new current location we're making. The default is
            today's date in Modes format (d.m.yyyy).
            ''')
        parser.add_argument('--datebegin',
                            help='''
        Use this string as the date to store in the new previous ObjectLocation
        date. The format must be in Modes format (d.m.yyyy).
        ''')
        parser.add_argument('--dateend',
                            default=nd.modesdate(date.today()),
                            help='''
        Use this string as the date to store in the new previous ObjectLocation
        date. The format must be in Modes format (d.m.yyyy).
        ''')
    parser.add_argument('--encoding',
                        default='utf-8',
                        help='''
        Set the input encoding. Default is utf-8. Output is always utf-8.
        ''')
    if is_update:
        parser.add_argument('-f',
                            '--force',
                            action='store_true',
                            help='''
        Write the object to the output file even if it hasn't been updated. This only
        applies to objects whose ID appears in the CSV file. -a implies -f.
        ''')
    parser.add_argument('--heading',
                        help=nd.sphinxify(
                            '''
        The first row of the map file contains a column title which must match the
        parameter (case insensitive) in the column designated for the location.
        If a --location argument is specified, the first row is skipped and the
        value, which nevertheless must be specified, is ignored. 
        ''', called_from_sphinx))
    if is_update or is_diff:
        parser.add_argument('-j',
                            '--object',
                            help=nd.sphinxify(
                                '''
        Specify a single object to be processed. If specified, do not specify
        the CSV file containing object numbers and locations (--mapfile). You
        must also specify --location.
        ''', called_from_sphinx))
        parser.add_argument('-l',
                            '--location',
                            help='''
        Set the location for all of the objects in the CSV file. In this 
        case the CSV file only needs a single column containing the 
        accession number.  
        ''')
    if is_diff or is_select or is_update:
        parser.add_argument('-m',
                            '--mapfile',
                            help=nd.sphinxify(
                                '''
            The CSV file mapping the object number to its new location. By
            default, the accession number is in the first column (column 0) but 
            this can be changed by the --col_acc option. The new location is by
            default in the second column (column 1) but can be changed by the
            --col_loc option. This  argument is ignored if --object is specified.
            ''', called_from_sphinx))
    if is_update or is_diff:
        parser.add_argument('-n',
                            '--normal',
                            action='store_true',
                            help='''
        Update the normal location. See the description for "p" and "c".''')
    if is_diff:
        parser.add_argument('--old',
                            action='store_true',
                            help='''
            The column selected is the "old" location, the one we are moving
            the object from. Warn if the value in the CSV file does not match
            the value in the XML file. The default is to warn if the value in
            the CSV file does match the value in the XML file which is not
            expected as the purpose is to update that value.
            ''')
    if is_update:
        parser.add_argument('--patch',
                            action='store_true',
                            help='''
        Update the specified location in place without creating history. This is always
        the behavior for normal locations but not for current or previous.
        ''')
        parser.add_argument('-p',
                            '--previous',
                            action='store_true',
                            help=nd.sphinxify(
                                '''
        Add a previous location. This location's start and end dates must 
        not overlap with an existing current or previous location's date(s). 
        If "p" is selected, do not select "n" or "c". If "p" is specified, you
        must specify --datebegin and --dateend.
        ''', called_from_sphinx))
        parser.add_argument('--reset_current',
                            action='store_true',
                            help='''
        Only output the most recent current location element for each object,
        deleting all previous locations.
        ''')
        parser.add_argument('-r',
                            '--reason',
                            default='',
                            help='''
            Insert this text as the reason for the move to the new current location.
            ''')
    parser.add_argument('-s',
                        '--short',
                        action='store_true',
                        help='''
        Only process a single object. For debugging.''')
    parser.add_argument('-v',
                        '--verbose',
                        type=int,
                        default=1,
                        help='''
        Set the verbosity. The default is 1 which prints summary information.
        ''')
    if is_diff or is_select or is_update:
        parser.add_argument('-w',
                            '--warn',
                            action='store_true',
                            help='''
        Valid if -a is selected. Warn if an object in the XML file is not in the CSV file.
        ''')