-
Notifications
You must be signed in to change notification settings - Fork 64
/
Copy pathreset_stale_workers.py
137 lines (114 loc) · 5.26 KB
/
reset_stale_workers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# -*- coding: UTF-8 -*-
"""
Copyright 2020 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This sample resets stale workers to status "not_working"
"""
import argparse
import logging
import logging.handlers
import sys
import traceback
from arcgis.apps import workforce
from arcgis.gis import GIS
import pendulum
def initialize_logging(log_file=None):
"""
Setup logging
:param log_file: (string) The file to log to
:return: (Logger) a logging instance
"""
# initialize logging
formatter = logging.Formatter(
"[%(asctime)s] [%(filename)30s:%(lineno)4s - %(funcName)30s()][%(threadName)5s] [%(name)10.10s] [%(levelname)8s] %(message)s")
# Grab the root logger
logger = logging.getLogger()
# Set the root logger logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
logger.setLevel(logging.DEBUG)
# Create a handler to print to the console
sh = logging.StreamHandler(sys.stdout)
sh.setFormatter(formatter)
sh.setLevel(logging.INFO)
# Create a handler to log to the specified file
if log_file:
rh = logging.handlers.RotatingFileHandler(log_file, mode='a', maxBytes=10485760)
rh.setFormatter(formatter)
rh.setLevel(logging.DEBUG)
logger.addHandler(rh)
# Add the handlers to the root logger
logger.addHandler(sh)
return logger
def main(arguments):
# Initialize logging
logger = initialize_logging(arguments.log_file)
# Create the GIS
logger.info("Authenticating...")
# First step is to get authenticate and get a valid token
gis = GIS(arguments.org_url,
username=arguments.username,
password=arguments.password,
verify_cert=not arguments.skip_ssl_verification)
logger.info("Getting workforce project")
# Get the workforce project
item = gis.content.get(arguments.project_id)
try:
project = workforce.Project(item)
except Exception as e:
logger.info(e)
logger.info("Invalid project id")
sys.exit(0)
# First check if relative date
logger.info("Formatting date")
try:
delta = int(args.cutoff_date)
utc_dt = pendulum.now().subtract(minutes=delta).in_tz('UTC')
except Exception:
# If not relative date, then attempt to convert date and attach timezone to naive date value
try:
local_cutoff_date = pendulum.from_format(arguments.cutoff_date, "MM/DD/YYYY hh:mm:ss", tz=args.timezone, formatter='alternative')
except Exception as e:
logger.info(e)
logger.info("Invalid date format. Please check documentation and try again")
sys.exit(0)
utc_dt = local_cutoff_date.in_tz('UTC')
formatted_date = utc_dt.strftime("%Y-%m-%d %H:%M:%S")
# Query using UTC-formatted date and reset those workers
logger.info("Querying workers")
where = f"{project._worker_schema.edit_date} < TIMESTAMP '{formatted_date}'"
workers = project.workers.search(where=where)
for worker in workers:
worker.status = "not_working"
logger.info("Updating workers")
project.workers.batch_update(workers)
logger.info("Completed!")
if __name__ == "__main__":
# Get all of the commandline arguments
parser = argparse.ArgumentParser("Reset stale workers' status to not working")
parser.add_argument('-u', dest='username', help="The username to authenticate with", required=True)
parser.add_argument('-p', dest='password', help="The password to authenticate with", required=True)
parser.add_argument('-org', dest='org_url', help="The url of the org/portal to use", required=True)
# Parameters for workforce
parser.add_argument('-project-id', dest='project_id', help="The id of the Workforce project", required=True)
parser.add_argument('-cutoff-date', dest='cutoff_date',
help="If a worker has not been updated at or after this date, change its status to not working. "
"Either int (in minutes from UTC now) or MM/DD/YYYY hh:mm:ss format. "
"So if '10' is provided then reset workers who have not been updated in the last 10 minutes",
required=True)
parser.add_argument('-timezone', dest='timezone', default="UTC", help="The timezone for the cutoff date")
parser.add_argument('-log-file', dest='log_file', help='The log file to use')
parser.add_argument('--skip-ssl-verification', dest='skip_ssl_verification', action='store_true', help="Verify the SSL Certificate of the server")
args = parser.parse_args()
try:
main(args)
except Exception as e:
logging.getLogger().critical("Exception detected, script exiting")
logging.getLogger().critical(e)
logging.getLogger().critical(traceback.format_exc().replace("\n", " | "))