-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
162 lines (130 loc) · 5.24 KB
/
main.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import os
from simple_salesforce import Salesforce
from dotenv import load_dotenv
from pathlib import Path
import time
from datetime import datetime, timedelta
import urllib.request
import sys
# todo move to config file
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
sfdc_username = os.getenv('SFDC_USER_NAME')
sfdc_password = os.getenv('SFDC_PASSWORD')
sfdc_token = os.getenv('SFDC_TOKEN')
sfdc_package_ids = os.getenv('SFDC_PACKAGE_IDS')
output_path = os.getenv('OUTPUT_PATH')
def main(date_arg):
log_date_strings = set_log_date(date_arg)
# login to salesforce
sf_instance = Salesforce(username=sfdc_username, password=sfdc_password, security_token=sfdc_token, version=50.0)
# get a comma delimited list of organization ids
all_org_ids_string = get_org_ids_string(sf_instance)
# string into list
list_of_org_ids = all_org_ids_string.split(",")
# create a list of lists with 15 ids.
# todo extract to method, remove hardcoded 15
list_of_org_id_strings = []
index_of_list = -1
for i in range(0, len(list_of_org_ids)):
if i % 15 == 0:
index_of_list = index_of_list + 1
list_of_org_id_strings.append([])
# list_of_org_id_strings[index_of_list].append(list_of_org_ids[i])
list_of_org_id_strings[index_of_list] += [list_of_org_ids[i]]
for log_date_string in log_date_strings:
for i in range(0, len(list_of_org_id_strings)):
# create the app analytics record and get the id
id_of_analytics_record = create_app_analytic_record(sf_instance, sfdc_package_ids, list_of_org_id_strings[i], log_date_string)
# wait, get record w/ aws link
csv_url = get_csv_url(sf_instance, id_of_analytics_record)
# save csv from aws
if not os.path.exists(output_path):
os.mkdir(output_path)
if check_url_exists(csv_url):
urllib.request.urlretrieve(csv_url, f'{output_path}/{log_date_string}_platform_analytics_{i}.csv')
def check_url_exists(csv_url):
if csv_url != '' and csv_url is not None:
return True
return False
def set_log_date(date_arg):
"""
If an arg is passed, use this date. Otherwise get yesterday's log
:param date_arg:
:return:
"""
date_list = []
if date_arg is None or date_arg == '':
temp_date = datetime.now() - timedelta(1)
date_list.append(datetime.strftime(temp_date, '%Y-%m-%d'))
elif '.txt' in date_arg:
with open('input/' + date_arg) as f:
date_list = f.read().splitlines()
else:
try:
datetime.strptime(date_arg, '%Y-%m-%d')
except ValueError:
raise ValueError('Wrong Date Arg Format')
date_list.append(date_arg)
return date_list
def get_csv_url(sf_instance, app_analytics_id):
"""
Given an App Analytics record Id, poll Salesforce until the CSV is ready to be retrieved
:param sf_instance:
:param app_analytics_id:
:return:
"""
request_state = get_request_state(sf_instance, app_analytics_id)
while request_state == 'New' or request_state == 'Pending':
print(request_state)
time.sleep(5)
request_state = get_request_state(sf_instance, app_analytics_id)
csv_url = None
if not request_state == 'No Data':
csv_url = get_download_url(sf_instance, app_analytics_id)
return csv_url
def get_request_state(sf_instance, record_id):
aaqr_record = sf_instance.AppAnalyticsQueryRequest.get(record_id)
return aaqr_record.get('RequestState')
def get_download_url(sf_instance, record_id):
aaqr_record = sf_instance.AppAnalyticsQueryRequest.get(record_id)
return aaqr_record.get('DownloadUrl')
def create_app_analytic_record(sf_instance, package_ids, organization_ids, date_string):
"""
Create a Package Usage Log App Analytics Query Request for the previous day
:param date_string:
:param sf_instance
:param package_ids:
:param organization_ids:
:return: the id of the successfully created record
"""
comma_delimited_string = ','.join(str(s) for s in organization_ids)
app_analytics_response = sf_instance.AppAnalyticsQueryRequest.create({
'DataType': 'PackageUsageLog',
'StartTime': f'{date_string}T00:00:00',
'EndTime': f'{date_string}T23:59:59',
'PackageIds': package_ids,
'OrganizationIds': comma_delimited_string
})
# todo check if successful
return app_analytics_response.get('id')
def get_org_ids_string(sf_instance):
"""
query salesforce to get a comma delimited string of org ids
:param sf_instance: the sf instance to query from
:return: comma delimited string of org ids
"""
# this where condition is specific to my use case.
where_condition = "WHERE sfLma__Package_Version__r.Name LIKE '%v%1.%'"
data = sf_instance.query("SELECT sfLma__Subscriber_Org_ID__c FROM sfLma__License__c " + where_condition)
org_ids = set()
for k, v in data.items():
if k == "records":
for item in v:
org_ids.add(item.get('sfLma__Subscriber_Org_ID__c'))
org_ids_string = ','.join(str(s) for s in org_ids)
return org_ids_string
if __name__ == '__main__':
if len(sys.argv) > 1:
main(sys.argv[1])
main('')