Пример #1
0
def get_user_details(user_name, options, prompt_prefix):
    """
    Get user details (email, first name, last name)

    Returns a dictionary of user details, including the supplied user_name.
    """
    user_email_regex = r"^[A-Za-z0-9.+_-]+@([A-Za-z0-9_-]+)(\.[A-Za-z0-9_-]+)*$"
    user_email_prompt = "%s email:       " % prompt_prefix
    user_first_name_prompt = "%s first name:  " % prompt_prefix
    user_last_name_prompt = "%s last name:   " % prompt_prefix
    # Get other values
    user_email = getargvalue(getarg(options.args, 1), user_email_prompt)
    while not re.match(user_email_regex, user_email):
        print("Invalid email address %s - re-enter" % user_email,
              file=sys.stderr)
        user_email = getargvalue(None, user_email_prompt)
    user_first_name = getargvalue(getarg(options.args, 2),
                                  user_first_name_prompt)
    user_last_name = getargvalue(getarg(options.args, 3),
                                 user_last_name_prompt)
    return ({
        'name': user_name,
        'email': user_email,
        'uri': "mailto:%s" % user_email,
        'first_name': user_first_name,
        'last_name': user_last_name
    })
def am_migratecollection(annroot, userhome, options):
    """
    Apply migrations for a specified collection

        annalist_manager migratecollection coll

    Reads and writes every entity in a collection, thereby applying data 
    migrations and saving them in the stored data.

    annroot     is the root directory for the Annalist software installation.
    userhome    is the home directory for the host system user issuing the command.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    status, settings, site = get_settings_site(annroot, userhome, options)
    if status != am_errors.AM_SUCCESS:
        return status
    coll_id = getargvalue(getarg(options.args, 0), "Collection Id: ")
    coll = Collection.load(site, coll_id)
    if not (coll and coll.get_values()):
        print("Collection not found: %s" % (coll_id), file=sys.stderr)
        return am_errors.AM_NOCOLLECTION
    status = am_errors.AM_SUCCESS
    print("Apply data migrations in collection '%s'" % (coll_id, ))
    msgs = migrate_coll_data(coll)
    if msgs:
        for msg in msgs:
            print(msg)
        status = am_errors.AM_MIGRATECOLLFAIL
    return status
Пример #3
0
def am_migratecollection(annroot, userhome, options):
    """
    Apply migrations for a specified collection

        annalist_manager migratecollection coll

    Reads and writes every entity in a collection, thereby applying data 
    migrations and saving them in the stored data.

    annroot     is the root directory for the Annalist software installation.
    userhome    is the home directory for the host system user issuing the command.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    status, settings, site = get_settings_site(annroot, userhome, options)
    if status != am_errors.AM_SUCCESS:
        return status
    coll_id = getargvalue(getarg(options.args, 0), "Collection Id: ")
    coll    = Collection.load(site, coll_id)
    if not (coll and coll.get_values()):
        print("Collection not found: %s"%(coll_id), file=sys.stderr)
        return am_errors.AM_NOCOLLECTION
    status = am_errors.AM_SUCCESS
    print("Apply data migrations in collection '%s'"%(coll_id,))
    msgs   = migrate_coll_data(coll)
    if msgs:
        for msg in msgs:
            print(msg)
        status = am_errors.AM_MIGRATECOLLFAIL
    return status
Пример #4
0
def get_user_name(options, prompt_prefix):
    user_name_regex         = r"^[a-zA-Z0-9@.+_-]+$"
    user_name_prompt        = "%s name:        "%prompt_prefix
    user_name = getargvalue(getarg(options.args, 0), user_name_prompt)
    while not re.match(user_name_regex, user_name):
        print("Invalid username %s - re-enter"%user_name, file=sys.stderr)
        user_name = getargvalue(None, user_name_prompt)
    return user_name
Пример #5
0
def get_user_name(options, prompt_prefix):
    user_name_regex         = r"^[a-zA-Z0-9@.+_-]+$"
    user_name_prompt        = "%s name:        "%prompt_prefix
    user_name = getargvalue(getarg(options.args, 0), user_name_prompt)
    while not re.match(user_name_regex, user_name):
        print("Invalid username %s - re-enter"%user_name, file=sys.stderr)
        user_name = getargvalue(None, user_name_prompt)
    return user_name
Пример #6
0
def am_copycollection(annroot, userhome, options):
    """
    Copy collection data

        annalist_manager copycollection old_coll_id new_coll_id

    Copies data from an existing collection to a new collection.

    annroot     is the root directory for the Annalist software installation.
    userhome    is the home directory for the host system user issuing the command.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    status, settings, site = get_settings_site(annroot, userhome, options)
    if status != am_errors.AM_SUCCESS:
        return status
    if len(options.args) > 2:
        print(
            "Unexpected arguments for %s: (%s)"%
              (options.command, " ".join(options.args)), 
            file=sys.stderr
            )
        return am_errors.AM_UNEXPECTEDARGS
    old_coll_id = getargvalue(getarg(options.args, 0), "Old collection Id: ")
    old_coll    = Collection.load(site, old_coll_id)
    if not (old_coll and old_coll.get_values()):
        print("Old collection not found: %s"%(old_coll_id), file=sys.stderr)
        return am_errors.AM_NOCOLLECTION
    new_coll_id = getargvalue(getarg(options.args, 1), "New collection Id: ")
    new_coll    = Collection.load(site, new_coll_id)
    if (new_coll and new_coll.get_values()):
        print("New collection already exists: %s"%(new_coll_id), file=sys.stderr)
        return am_errors.AM_COLLECTIONEXISTS
    # Copy collection now
    print("Copying collection '%s' to '%s'"%(old_coll_id, new_coll_id))
    new_coll = site.add_collection(new_coll_id, old_coll.get_values())
    msgs     = copy_coll_data(old_coll, new_coll)
    if msgs:
        for msg in msgs:
            print(msg)
        status = am_errors.AM_COPYCOLLFAIL
    print("")
    return status
def am_copycollection(annroot, userhome, options):
    """
    Copy collection data

        annalist_manager copycollection old_coll_id new_coll_id

    Copies data from an existing collection to a new collection.

    annroot     is the root directory for the Annalist software installation.
    userhome    is the home directory for the host system user issuing the command.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    status, settings, site = get_settings_site(annroot, userhome, options)
    if status != am_errors.AM_SUCCESS:
        return status
    if len(options.args) > 2:
        print("Unexpected arguments for %s: (%s)" %
              (options.command, " ".join(options.args)),
              file=sys.stderr)
        return am_errors.AM_UNEXPECTEDARGS
    old_coll_id = getargvalue(getarg(options.args, 0), "Old collection Id: ")
    old_coll = Collection.load(site, old_coll_id)
    if not (old_coll and old_coll.get_values()):
        print("Old collection not found: %s" % (old_coll_id), file=sys.stderr)
        return am_errors.AM_NOCOLLECTION
    new_coll_id = getargvalue(getarg(options.args, 1), "New collection Id: ")
    new_coll = Collection.load(site, new_coll_id)
    if (new_coll and new_coll.get_values()):
        print("New collection already exists: %s" % (new_coll_id),
              file=sys.stderr)
        return am_errors.AM_COLLECTIONEXISTS
    # Copy collection now
    print("Copying collection '%s' to '%s'" % (old_coll_id, new_coll_id))
    new_coll = site.add_collection(new_coll_id, old_coll.get_values())
    msgs = copy_coll_data(old_coll, new_coll)
    if msgs:
        for msg in msgs:
            print(msg)
        status = am_errors.AM_COPYCOLLFAIL
    print("")
    return status
def am_installcollection(annroot, userhome, options):
    """
    Install software-defined collection data

        annalist_manager installcollection coll_id

    Copies data from an existing collection to a new collection.

    annroot     is the root directory for the Annalist software installation.
    userhome    is the home directory for the host system user issuing the command.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    status, settings, site = get_settings_site(annroot, userhome, options)
    if status != am_errors.AM_SUCCESS:
        return status
    if len(options.args) > 1:
        print("Unexpected arguments for %s: (%s)" %
              (options.command, " ".join(options.args)),
              file=sys.stderr)
        return am_errors.AM_UNEXPECTEDARGS
    coll_id = getargvalue(getarg(options.args, 0),
                          "Collection Id to install: ")
    coll = Collection.load(site, coll_id)
    if (coll and coll.get_values()):
        print("Collection already exists: %s" % (coll_id), file=sys.stderr)
        return am_errors.AM_COLLECTIONEXISTS

    # Check collection Id
    if coll_id in installable_collections:
        src_dir_name = installable_collections[coll_id]['data_dir']
    else:
        print("Collection name to install not known: %s" % (coll_id),
              file=sys.stderr)
        print("Available collection Ids are: %s" %
              (",".join(installable_collections.keys())))
        return am_errors.AM_NOCOLLECTION

    # Install collection now
    src_dir = os.path.join(annroot, "annalist/data", src_dir_name)
    print("Installing collection '%s' from data directory '%s'" %
          (coll_id, src_dir))
    coll_metadata = installable_collections[coll_id]['coll_meta']
    date_time_now = datetime.datetime.now().replace(microsecond=0)
    coll_metadata[ANNAL.CURIE.comment] = (
        "Initialized at %s by `annalist-manager installcollection`" %
        date_time_now.isoformat())
    coll = site.add_collection(coll_id, coll_metadata)
    msgs = initialize_coll_data(src_dir, coll)
    if msgs:
        for msg in msgs:
            print(msg)
        status = am_errors.AM_INSTALLCOLLFAIL
    return status
Пример #9
0
def am_installcollection(annroot, userhome, options):
    """
    Install software-defined collection data

        annalist_manager installcollection coll_id

    Copies data from an existing collection to a new collection.

    annroot     is the root directory for the Annalist software installation.
    userhome    is the home directory for the host system user issuing the command.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    status, settings, site = get_settings_site(annroot, userhome, options)
    if status != am_errors.AM_SUCCESS:
        return status
    if len(options.args) > 1:
        print(
            "Unexpected arguments for %s: (%s)"%
              (options.command, " ".join(options.args)), 
            file=sys.stderr
            )
        return am_errors.AM_UNEXPECTEDARGS
    coll_id = getargvalue(getarg(options.args, 0), "Collection Id to install: ")
    coll    = Collection.load(site, coll_id)
    if (coll and coll.get_values()):
        print("Collection already exists: %s"%(coll_id), file=sys.stderr)
        return am_errors.AM_COLLECTIONEXISTS

    # Check collection Id
    if coll_id in installable_collections:
        src_dir_name = installable_collections[coll_id]['data_dir']
    else:
        print("Collection name to install not known: %s"%(coll_id), file=sys.stderr)
        print("Available collection Ids are: %s"%(",".join(installable_collections.keys())))
        return am_errors.AM_NOCOLLECTION

    # Install collection now
    src_dir = os.path.join(annroot, "annalist/data", src_dir_name)
    print("Installing collection '%s' from data directory '%s'"%(coll_id, src_dir))
    coll_metadata = installable_collections[coll_id]['coll_meta']
    date_time_now = datetime.datetime.now().replace(microsecond=0)
    coll_metadata[ANNAL.CURIE.comment] = (
        "Initialized at %s by `annalist-manager installcollection`"%
        date_time_now.isoformat()
        )
    coll = site.add_collection(coll_id, coll_metadata)
    msgs = initialize_coll_data(src_dir, coll)
    if msgs:
        for msg in msgs:
            print(msg)
        status = am_errors.AM_INSTALLCOLLFAIL
    return status
Пример #10
0
def get_user_permissions(options, pos, prompt_prefix):
    """
    Get user permissions to apply
    """
    user_permissions_regex  = r"^([A-Za-z0-9_-]+(\s+[A-Za-z0-9_-]+)*)?$"
    user_permissions_prompt = "%s permissions: "%prompt_prefix
    user_permissions = getargvalue(getarg(options.args, pos), user_permissions_prompt)
    while not re.match(user_permissions_regex, user_permissions):
        print("Invalid permissions %s - re-enter"%user_permissions, file=sys.stderr)
        user_permissions = getargvalue(None, user_permissions_prompt)
    return user_permissions
Пример #11
0
def get_user_permissions(options, pos, prompt_prefix):
    """
    Get user permissions to apply
    """
    user_permissions_regex  = r"^([A-Za-z0-9_-]+(\s+[A-Za-z0-9_-]+)*)?$"
    user_permissions_prompt = "%s permissions: "%prompt_prefix
    user_permissions = getargvalue(getarg(options.args, pos), user_permissions_prompt)
    while not re.match(user_permissions_regex, user_permissions):
        print("Invalid permissions %s - re-enter"%user_permissions, file=sys.stderr)
        user_permissions = getargvalue(None, user_permissions_prompt)
    return user_permissions
Пример #12
0
def get_user_details(user_name, options, prompt_prefix):
    """
    Get user details (email, first name, last name)

    Returns a dictionary of user details, including the supplied user_name.
    """
    user_email_regex        = r"^[A-Za-z0-9.+_-]+@([A-Za-z0-9_-]+)(\.[A-Za-z0-9_-]+)*$"
    user_email_prompt       = "%s email:       "%prompt_prefix
    user_first_name_prompt  = "%s first name:  "%prompt_prefix
    user_last_name_prompt   = "%s last name:   "%prompt_prefix
    # Get other values
    user_email = getargvalue(getarg(options.args, 1), user_email_prompt)
    while not re.match(user_email_regex, user_email):
        print("Invalid email address %s - re-enter"%user_email, file=sys.stderr)
        user_email = getargvalue(None, user_email_prompt)
    user_first_name = getargvalue(getarg(options.args, 2), user_first_name_prompt)
    user_last_name  = getargvalue(getarg(options.args, 3), user_last_name_prompt)
    return (
        { 'name':       user_name
        , 'email':      user_email
        , 'uri':        "mailto:%s"%user_email
        , 'first_name': user_first_name
        , 'last_name':  user_last_name
        })
Пример #13
0
def am_runtests(annroot, options):
    """
    Run Annalist server tests.

    annroot     is the root directory for the annalist software installation.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    options.configuration = "runtests"
    testsettings = am_get_settings(annroot, "/nouser/", options)
    if not testsettings:
        print("Settings not found (%s)" % ("runtests"), file=sys.stderr)
        return am_errors.AM_NOSETTINGS
    if len(options.args) > 1:
        print("Unexpected arguments for %s: (%s)" %
              (options.command, " ".join(options.args)),
              file=sys.stderr)
        return am_errors.AM_UNEXPECTEDARGS
    status = am_errors.AM_SUCCESS
    log.debug("annalist_root: %s" % (annroot))
    with ChangeCurrentDir(annroot):
        # For some reason, tests are not discovered unless run from here
        cmd = "test"
        testname = getarg(options.args, 0) or ""
        subprocess_command = (
            "django-admin %s %s --pythonpath=%s --settings=%s --top-level-directory=%s"
            % (cmd, testname, annroot, testsettings.modulename, annroot))
        log.debug("am_initialize subprocess: %s" % subprocess_command)
        # OLD: status = os.system(subprocess_command)
        status = subprocess.call(subprocess_command.split())
        log.debug("am_initialize subprocess status: %s" % status)
        if testname:
            print("Log file name:\n%s" % (annroot + "/annalist.log"))
    return status
def am_migrationreport(annroot, userhome, options):
    """
    Collection migration report helper

        annalist_manager migrationreport old_coll new_coll

    Generates a report of changes to data needed to match type and property 
    URI changes moving from old_coll to new_coll.

    annroot     is the root directory for the Annalist software installation.
    userhome    is the home directory for the host system user issuing the command.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    status, settings, site = get_settings_site(annroot, userhome, options)
    if status != am_errors.AM_SUCCESS:
        return status
    if len(options.args) > 2:
        print("Unexpected arguments for %s: (%s)" %
              (options.command, " ".join(options.args)),
              file=sys.stderr)
        return am_errors.AM_UNEXPECTEDARGS
    old_coll_id = getargvalue(getarg(options.args, 0), "Old collection Id: ")
    old_coll = Collection.load(site, old_coll_id)
    if not (old_coll and old_coll.get_values()):
        print("Old collection not found: %s" % (old_coll_id), file=sys.stderr)
        return am_errors.AM_NOCOLLECTION
    new_coll_id = getargvalue(getarg(options.args, 1), "New collection Id: ")
    new_coll = Collection.load(site, new_coll_id)
    if not (new_coll and new_coll.get_values()):
        print("New collection not found: %s" % (new_coll_id), file=sys.stderr)
        return am_errors.AM_NOCOLLECTION
    status = am_errors.AM_SUCCESS
    print("# Migration report from collection '%s' to '%s' #" %
          (old_coll_id, new_coll_id))
    print("")
    # Scan and report on type URI changes
    for new_type in coll_types(new_coll):
        type_id = new_type.get_id()
        old_type = old_coll.get_type(type_id)
        if old_type:
            old_uri = old_type[ANNAL.CURIE.uri]
            new_uri = new_type[ANNAL.CURIE.uri]
            if old_uri != new_uri:
                print("* Type %s, URI changed from '%s' to '%s'" %
                      (type_id, old_uri, new_uri))
                supertype_uris = [
                    u[ANNAL.CURIE.supertype_uri]
                    for u in new_type.get(ANNAL.CURIE.supertype_uris, [])
                ]
                if old_uri not in supertype_uris:
                    print(
                        "    Consider adding supertype '%s' to type '%s' in collection '%s'"
                        % (old_uri, type_id, new_coll_id))
                report_type_references(new_coll, old_uri,
                                       "    URI '%s'" % (old_uri))
    # Scan and report on property URI changes in field definitions
    for new_field in coll_fields(new_coll):
        field_id = new_field.get_id()
        old_field = coll_field(old_coll, field_id)
        if old_field:
            old_uri = old_field[ANNAL.CURIE.property_uri]
            new_uri = new_field[ANNAL.CURIE.property_uri]
            if old_uri != new_uri:
                print("* Field %s, property URI changed from '%s' to '%s'" %
                      (field_id, old_uri, new_uri))
                type_ids = types_using_field(new_coll, field_id, old_uri)
                for tid in type_ids:
                    print(
                        "    Consider adding property alias for '%s' to type %s in collection '%s'"
                        % (old_uri, tid, new_coll_id))
    # Scan and report on property URI changes in group definitions
    for new_group in coll_groups(new_coll):
        group_id = new_group.get_id()
        old_group = coll_group(old_coll, group_id)
        if old_group:
            compare_field_list(old_coll, new_coll,
                               old_group[ANNAL.CURIE.group_fields],
                               new_group[ANNAL.CURIE.group_fields],
                               "Group %s" % group_id)
    # Scan and report on property URI changes in view definitions
    for new_view in coll_views(new_coll):
        view_id = new_view.get_id()
        old_view = coll_view(old_coll, view_id)
        if old_view:
            compare_field_list(old_coll, new_coll,
                               old_view[ANNAL.CURIE.view_fields],
                               new_view[ANNAL.CURIE.view_fields],
                               "View %s" % view_id)
    # Scan and report on property URI changes in list definitions
    for new_list in coll_lists(new_coll):
        list_id = new_list.get_id()
        old_list = coll_list(old_coll, list_id)
        if old_list:
            compare_field_list(old_coll, new_coll,
                               old_list[ANNAL.CURIE.list_fields],
                               new_list[ANNAL.CURIE.list_fields],
                               "List %s" % list_id)
    print("")
    return status
Пример #15
0
def am_migrationreport(annroot, userhome, options):
    """
    Collection migration report helper

        annalist_manager migrationreport old_coll new_coll

    Generates a report of changes to data needed to match type and property 
    URI changes moving from old_coll to new_coll.

    annroot     is the root directory for the Annalist software installation.
    userhome    is the home directory for the host system user issuing the command.
    options     contains options parsed from the command line.

    returns     0 if all is well, or a non-zero status code.
                This value is intended to be used as an exit status code
                for the calling program.
    """
    status, settings, site = get_settings_site(annroot, userhome, options)
    if status != am_errors.AM_SUCCESS:
        return status
    if len(options.args) > 2:
        print("Unexpected arguments for %s: (%s)"%(options.command, " ".join(options.args)), file=sys.stderr)
        return am_errors.AM_UNEXPECTEDARGS
    old_coll_id = getargvalue(getarg(options.args, 0), "Old collection Id: ")
    old_coll    = Collection.load(site, old_coll_id)
    if not (old_coll and old_coll.get_values()):
        print("Old collection not found: %s"%(old_coll_id), file=sys.stderr)
        return am_errors.AM_NOCOLLECTION
    new_coll_id = getargvalue(getarg(options.args, 1), "New collection Id: ")
    new_coll    = Collection.load(site, new_coll_id)
    if not (new_coll and new_coll.get_values()):
        print("New collection not found: %s"%(new_coll_id), file=sys.stderr)
        return am_errors.AM_NOCOLLECTION
    status      = am_errors.AM_SUCCESS
    print("# Migration report from collection '%s' to '%s' #"%(old_coll_id, new_coll_id))
    print("")
    # Scan and report on type URI changes
    for new_type in coll_types(new_coll):
        type_id  = new_type.get_id()
        old_type = old_coll.get_type(type_id)
        if old_type:
            old_uri  = old_type[ANNAL.CURIE.uri]
            new_uri  = new_type[ANNAL.CURIE.uri]
            if old_uri != new_uri:
                print("* Type %s, URI changed from '%s' to '%s'"%(type_id, old_uri, new_uri))
                supertype_uris = [ u[ANNAL.CURIE.supertype_uri] for u in new_type.get(ANNAL.CURIE.supertype_uris,[]) ]
                if old_uri not in supertype_uris:
                    print(
                        "    Consider adding supertype '%s' to type '%s' in collection '%s'"%
                        (old_uri, type_id, new_coll_id)
                        )
                report_type_references(new_coll, old_uri, "    URI '%s'"%(old_uri))
    # Scan and report on property URI changes in field definitions
    for new_field in coll_fields(new_coll):
        field_id  = new_field.get_id()
        old_field = coll_field(old_coll, field_id)
        if old_field:
            old_uri = old_field[ANNAL.CURIE.property_uri]
            new_uri = new_field[ANNAL.CURIE.property_uri]
            if old_uri != new_uri:
                print("* Field %s, property URI changed from '%s' to '%s'"%(field_id, old_uri, new_uri))
                type_ids = types_using_field(new_coll, field_id, old_uri)
                for tid in type_ids:
                    print(
                        "    Consider adding property alias for '%s' to type %s in collection '%s'"%
                        (old_uri, tid, new_coll_id)
                        )
    # Scan and report on property URI changes in group definitions
    for new_group in coll_groups(new_coll):
        group_id  = new_group.get_id()
        old_group = coll_group(old_coll, group_id)
        if old_group:
            compare_field_list(
                old_coll, new_coll, 
                old_group[ANNAL.CURIE.group_fields], 
                new_group[ANNAL.CURIE.group_fields],
                "Group %s"%group_id)
    # Scan and report on property URI changes in view definitions
    for new_view in coll_views(new_coll):
        view_id  = new_view.get_id()
        old_view = coll_view(old_coll, view_id)
        if old_view:
            compare_field_list(
                old_coll, new_coll, 
                old_view[ANNAL.CURIE.view_fields], 
                new_view[ANNAL.CURIE.view_fields],
                "View %s"%view_id)
    # Scan and report on property URI changes in list definitions
    for new_list in coll_lists(new_coll):
        list_id  = new_list.get_id()
        old_list = coll_list(old_coll, list_id)
        if old_list:
            compare_field_list(
                old_coll, new_coll, 
                old_list[ANNAL.CURIE.list_fields], 
                new_list[ANNAL.CURIE.list_fields],
                "List %s"%list_id)
    print("")
    return status