コード例 #1
0
def main(args):
    """
    The main sequence of steps
    :param args: The argparse args
    :return:
    """
    # Authenticate
    logging.getLogger().info("Authenticating...")
    shh = workforcehelpers.get_security_handler(args)
    # Get the assignments feature layer
    logging.getLogger().info("Getting assignments feature layer...")
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, args.projectId)
    # Get the target feature layer
    logging.getLogger().info("Getting target feature layer...")
    target_fl = arcrest.agol.FeatureLayer(args.targetFL, shh.securityhandler)
    # Check that the layer was loaded properly
    if target_fl.hasError():
        logging.getLogger().critical("Error with target feature layer: {}".format(target_fl.error))
        return
    # Open the field mappings config file
    logging.getLogger().info("Reading field mappings...")
    with open(args.configFile, 'r') as f:
        field_mappings = json.load(f)
    logging.getLogger().info("Validating field mappings...")
    if validate_config(field_mappings, target_fl):
        # Copy the assignments
        copy_assignments(assignment_fl, target_fl, field_mappings)
        logging.getLogger().info("Completed")
    else:
        logging.getLogger().critical("Invalid field mappings detected")
コード例 #2
0
def main(args):
    """
    The main sequence of steps
    :param args: The argparse args
    :return:
    """
    # Authenticate
    logging.getLogger().info("Authenticating...")
    shh = workforcehelpers.get_security_handler(args)
    # Get the assignments feature layer
    logging.getLogger().info("Getting assignments feature layer...")
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, args.projectId)
    # Get the target feature layer
    logging.getLogger().info("Getting target feature layer...")
    target_fl = arcrest.agol.FeatureLayer(args.targetFL, shh.securityhandler)
    # Check that the layer was loaded properly
    if target_fl.hasError():
        logging.getLogger().critical("Error with target feature layer: {}".format(target_fl.error))
        return
    # Open the field mappings config file
    logging.getLogger().info("Reading field mappings...")
    with open(args.configFile, 'r') as f:
        field_mappings = json.load(f)
    logging.getLogger().info("Validating field mappings...")
    if validate_config(field_mappings, target_fl):
        # Copy the assignments
        copy_assignments(assignment_fl, target_fl, field_mappings, where=args.where)
        logging.getLogger().info("Completed")
    else:
        logging.getLogger().critical("Invalid field mappings detected")
コード例 #3
0
def validate_assignments(shh, projectId, assignments):
    """
    Validates the provided values against the codedValues specified in the FS
    :param shh: The security handler helper
    :param projectId: The project Id
    :param assignments: The list of assignments to check
    :return: True if valid, False if not
    """
    # Grab the item
    logger = logging.getLogger()
    assignment_fl = workforcehelpers.get_assignments_feature_layer(
        shh, projectId)
    dispatcher_fl = workforcehelpers.get_dispatchers_feature_layer(
        shh, projectId)

    statuses = []
    priorities = []
    assignmentTypes = []
    dispatcherIds = []

    # Get the dispatcherIds
    for dispatcher in dispatcher_fl.query().features:
        dispatcherIds.append(dispatcher.asDictionary["attributes"]["OBJECTID"])

    # Get the codes of the domains
    for field in assignment_fl.fields:
        if field["name"] == "status":
            statuses = [cv["code"] for cv in field["domain"]["codedValues"]]
        if field["name"] == "priority":
            priorities = [cv["code"] for cv in field["domain"]["codedValues"]]
        if field["name"] == "assignmentType":
            assignmentTypes = [
                cv["code"] for cv in field["domain"]["codedValues"]
            ]

    logger.debug("Validating assignments...")
    # check the values against the fields that have domains
    for assignment in assignments:
        if assignment["data"]["attributes"]["status"] not in statuses:
            logging.getLogger().critical(
                "Invalid Status for: {}".format(assignment))
            return False
        if "priority" in assignment["data"]["attributes"] and assignment[
                "data"]["attributes"]["priority"] not in priorities:
            logging.getLogger().critical(
                "Invalid Priority for: {}".format(assignment))
            return False
        if assignment["data"]["attributes"][
                "assignmentType"] not in assignmentTypes:
            logging.getLogger().critical(
                "Invalid Assignment Type for: {}".format(assignment))
            return False
        if assignment["data"]["attributes"][
                "dispatcherId"] not in dispatcherIds:
            logging.getLogger().critical(
                "Invalid Dispatcher Id for: {}".format(assignment))
            return False
    return True
コード例 #4
0
def main(args):
    logging.getLogger().info("Authenticating...")
    shh = workforcehelpers.get_security_handler(args)
    logging.getLogger().info("Getting assignment feature layer...")
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, args.projectId)
    logging.getLogger().info("Deleting assignments...")
    response = assignment_fl.deleteFeatures(objectIds=",".join(args.objectIDs), where=args.where)
    logging.getLogger().info(response)
    logging.getLogger().info("Completed")
コード例 #5
0
def main(args):
    logging.getLogger().info("Authenticating...")
    shh = workforcehelpers.get_security_handler(args)
    logging.getLogger().info("Getting assignment feature layer...")
    assignment_fl = workforcehelpers.get_assignments_feature_layer(
        shh, args.projectId)
    logging.getLogger().info("Deleting assignments...")
    response = assignment_fl.deleteFeatures(objectIds=",".join(args.objectIDs),
                                            where=args.where)
    logging.getLogger().info(response)
    logging.getLogger().info("Completed")
コード例 #6
0
def add_attachments(shh, projectId, assignments):
    """
    Add attachments to the assignments that were added
    :param shh: The security handler helper
    :param projectId: The project Id of the workforce project
    :param assignments: The list of assignments (dictionaries)
    :return:
    """
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, projectId)
    logging.getLogger().debug("Adding Attachments...")
    for assignment in assignments:
        if assignment["attachmentFile"] and assignment["attachmentFile"] != "":
            response = assignment_fl.addAttachment(assignment["OBJECTID"],
                                                   os.path.abspath(assignment["attachmentFile"]))
            logging.getLogger().info(response)
コード例 #7
0
def add_attachments(shh, projectId, assignments):
    """
    Add attachments to the assignments that were added
    :param shh: The security handler helper
    :param projectId: The project Id of the workforce project
    :param assignments: The list of assignments (dictionaries)
    :return:
    """
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, projectId)
    logging.getLogger().debug("Adding Attachments...")
    for assignment in assignments:
        if assignment["attachmentFile"] and assignment["attachmentFile"] != "":
            response = assignment_fl.addAttachment(assignment["OBJECTID"],
                                                   os.path.abspath(assignment["attachmentFile"]))
            logging.getLogger().info(response)
コード例 #8
0
def validate_assignments(shh, projectId, assignments):
    """
    Validates the provided values against the codedValues specified in the FS
    :param shh: The security handler helper
    :param projectId: The project Id
    :param assignments: The list of assignments to check
    :return: True if valid, False if not
    """
    # Grab the item
    logger = logging.getLogger()
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, projectId)
    dispatcher_fl = workforcehelpers.get_dispatchers_feature_layer(shh, projectId)

    statuses = []
    priorities = []
    assignmentTypes = []
    dispatcherIds = []

    # Get the dispatcherIds
    for dispatcher in dispatcher_fl.query().features:
        dispatcherIds.append(dispatcher.asDictionary["attributes"]["OBJECTID"])

    # Get the codes of the domains
    for field in assignment_fl.fields:
        if field["name"] == "status":
            statuses = [cv["code"] for cv in field["domain"]["codedValues"]]
        if field["name"] == "priority":
            priorities = [cv["code"] for cv in field["domain"]["codedValues"]]
        if field["name"] == "assignmentType":
            assignmentTypes = [cv["code"] for cv in field["domain"]["codedValues"]]

    logger.debug("Validating assignments...")
    # check the values against the fields that have domains
    for assignment in assignments:
        if assignment["data"]["attributes"]["status"] not in statuses:
            logging.getLogger().critical("Invalid Status for: {}".format(assignment))
            return False
        if "priority" in assignment["data"]["attributes"] and assignment["data"]["attributes"][
            "priority"] not in priorities:
            logging.getLogger().critical("Invalid Priority for: {}".format(assignment))
            return False
        if assignment["data"]["attributes"]["assignmentType"] not in assignmentTypes:
            logging.getLogger().critical("Invalid Assignment Type for: {}".format(assignment))
            return False
        if assignment["data"]["attributes"]["dispatcherId"] not in dispatcherIds:
            logging.getLogger().critical("Invalid Dispatcher Id for: {}".format(assignment))
            return False
    return True
コード例 #9
0
def main(args):
    # First step is to authenticate and get a valid token
    logging.getLogger().info("Authenticating...")
    shh = workforcehelpers.get_security_handler(args)
    # Get the assignment feature layer
    logging.getLogger().info("Getting assignment feature layer...")
    assignment_fl = workforcehelpers.get_assignments_feature_layer(
        shh, args.projectId)
    # Query the assignment feature layer to get certain assignments
    logging.getLogger().info("Querying assignments...")
    assignments = assignment_fl.query(where=args.where,
                                      out_fields="*",
                                      outSR=args.outSR).features
    # Write the assignments to the csv file
    logging.getLogger().info("Writing to CSV...")
    write_assignments_to_csv(args.outCSV, assignments, args.dateFormat)
    logging.getLogger().info("Completed")
コード例 #10
0
def main(args):
    """
    The main sequence of steps
    :type args: object
    :param args: The argparse args
    :return:
    """
    # Authenticate
    logging.getLogger().info("Authenticating...")
    shh = workforcehelpers.get_security_handler(args)
    # Get the target feature layer
    logging.getLogger().info("Getting target feature layer...")
    target_fl = arcrest.agol.FeatureLayer(args.targetFL, shh.securityhandler)
    # Check that the layer was loaded properly
    if target_fl.hasError():
        logging.getLogger().critical("Error with target feature layer: {}".format(target_fl.error))
        return
    logging.getLogger().info("Getting assignments feature layer...")
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, args.projectId)

    # if a specific workers weren't specified, let's use all workers
    if not args.workers:
        features = workforcehelpers.get_workers_feature_layer(shh, args.projectId).query(where="1=1").features
        workers = [feature.asDictionary["attributes"]["userId"] for feature in features]
    else:
        workers = args.workers

    # Open the field mappings config file
    logging.getLogger().info("Reading field mappings...")
    with open(args.configFile, 'r') as f:
        field_mappings = json.load(f)
    # Check the mapping to the target feature service is valid
    logging.getLogger().info("Validating field mappings...")
    if validate_config(field_mappings, target_fl):
        for worker in workers:
            # Get the query string that represents the invalid assignment completions
            query_string = get_invalid_completions(shh, args.projectId, worker,
                                                   args.timeTol, args.distTol, args.minAccuracy)
            # Use that query to copy the assignments to feature service (if they don't already exist)
            copy_assignments(assignment_fl, target_fl, field_mappings, where=query_string)
    else:
        logging.getLogger().critical("Invalid field mappings detected")
        return
コード例 #11
0
def add_assignments(shh, projectId, assignments):
    """
    Adds the assignments to project
    :param shh: The security handler helper
    :param projectId: The project Id
    :param assignments: The list of assignments to add
    :return: The json response of the addFeatures REST API Call
    """
    logger = logging.getLogger()
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, projectId)
    features = [arcrest.common.general.Feature(x["data"]) for x in assignments]
    logger.debug("Adding Assignments...")
    response = assignment_fl.addFeature(features)
    logger.debug(response)
    # Assign the returned object ids to the assignment dictionary object
    for i in range(len(response["addResults"])):
        assignments[i]["OBJECTID"] = response["addResults"][i]["objectId"]
    # Add the attachments
    if len(assignments) > 0 and "attachmentFile" in assignments[0]:
        add_attachments(shh, projectId, assignments)
    return response
コード例 #12
0
def add_assignments(shh, projectId, assignments):
    """
    Adds the assignments to project
    :param shh: The security handler helper
    :param projectId: The project Id
    :param assignments: The list of assignments to add
    :return: The json response of the addFeatures REST API Call
    """
    logger = logging.getLogger()
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, projectId)
    features = [arcrest.common.general.Feature(x["data"]) for x in assignments]
    logger.debug("Adding Assignments...")
    response = assignment_fl.addFeature(features)
    logger.debug(response)
    # Assign the returned object ids to the assignment dictionary object
    for i in range(len(response["addResults"])):
        assignments[i]["OBJECTID"] = response["addResults"][i]["objectId"]
    # Add the attachments
    if len(assignments) > 0 and "attachmentFile" in assignments[0]:
        add_attachments(shh, projectId, assignments)
    return response
コード例 #13
0
def get_invalid_completions(shh, projectId, worker, time_tolerance, distance_tolerance, min_accuracy):
    """
    Generates a query string that represents the assignments that were completed either outside of the
    specified time window or outside of the specified distance
    :param shh: The ArcREST security handler helper
    :param projectID: The projectId to use
    :param worker: (string) The userId (name) of the worker to use
    :param time_tolerance: (int) The number of minutes to use as a tolerance
    :param distance_tolerance: (float or int) The distance tolerance to use
    :param min_accuracy: (int or float) The minimum accuracy to require when querying points
    :return: (string) A query that uses the OBJECTID to identify invalid assignment completions
    """
    logging.getLogger().info("Getting assignments feature layer...")
    assignment_fl = workforcehelpers.get_assignments_feature_layer(shh, projectId)
    # Get the locations feature layer
    logging.getLogger().info("Getting location feature layer...")
    location_fl = workforcehelpers.get_location_feature_layer(shh, projectId)
    # Get workerId
    logging.getLogger().info("Getting workerId for {}".format(worker))
    worker_id = get_worker_id(shh, projectId, worker)
    if not worker_id:
        logging.critical("Invalid worker detected")
        return
    # Get the completed assignments by the specified worker
    completed_assignments = assignment_fl.query(
        where="workerId = {} AND completedDate is not NULL".format(worker_id)).features
    invalid_assignment_oids = []
    # Iterate over the assignments and check to see if they were completed within the specified distance
    for assignment in completed_assignments:
        # The coordinates of the assignment
        start_coords = (assignment.asDictionary["geometry"]["x"], assignment.asDictionary["geometry"]["y"])
        # When the assignment was completed
        completion_date = datetime.datetime.utcfromtimestamp(
            int(assignment.asDictionary["attributes"]["completedDate"])/1000)
        # Add/Subtract some minutes to give a little leeway
        start_date = completion_date - datetime.timedelta(minutes=time_tolerance)
        end_date = completion_date + datetime.timedelta(minutes=time_tolerance)
        # Make a query string to select location by the worker during the time period
        loc_query_string = "Editor = '{}' AND CreationDate >= '{}' AND CreationDate <= '{}' AND Accuracy <= {}"\
            .format(worker, start_date.strftime('%Y-%m-%d %H:%M:%S'), end_date.strftime('%Y-%m-%d %H:%M:%S'),
                    min_accuracy)
        # Query the feature layer
        locations_to_check = location_fl.query(where=loc_query_string).features
        # Bool to see if this assignment is valid or not
        is_valid=False
        for location in locations_to_check:
            # Make a list of coordinate pairs to get the distance of
            coords = []
            # If we include the accuracy, we need to make four variations (+- the accuracy)
            accuracy = float(location.asDictionary["attributes"]["Accuracy"])
            coords.append((location.asDictionary["geometry"]["x"]+accuracy,
                       location.asDictionary["geometry"]["y"]+accuracy))
            coords.append((location.asDictionary["geometry"]["x"]+accuracy,
                       location.asDictionary["geometry"]["y"]-accuracy))
            coords.append((location.asDictionary["geometry"]["x"]-accuracy,
                       location.asDictionary["geometry"]["y"]+accuracy))
            coords.append((location.asDictionary["geometry"]["x"]-accuracy,
                       location.asDictionary["geometry"]["y"]-accuracy))
            distances = [get_simple_distance(start_coords, coordinates) for coordinates in coords]
            # if any of the distances is less than the threshold then this assignment is valid
            if any(distance < distance_tolerance for distance in distances):
                is_valid = True
                break
        # if it's not valid add the OBJECTID to the list of invalid assignment OBJECTIDS
        if not is_valid:
            logging.debug("Location Query: {}".format(loc_query_string))
            invalid_assignment_oids.append(str(assignment.asDictionary["attributes"]["OBJECTID"]))
    if invalid_assignment_oids:
        return "OBJECTID in ({})".format(",".join(invalid_assignment_oids))
    else:
        logging.getLogger().info(
            "All assignments were completed within the specified time and distance. Nothing to copy.")
        return "1=0"