|
6 | 6 | import requests |
7 | 7 |
|
8 | 8 |
|
9 | | -# CLASSES |
10 | | -# Used for getting Json from SuperOffice and performing the fetch itself |
11 | | -class SuperOfficeData: |
12 | | - def __init__(self): |
13 | | - self.script_url = "" |
14 | | - self.data = {} |
| 9 | +# METHODS FOR HANDLING LOCAL FOLDERS AND FILES |
| 10 | +def create_folder(path): |
| 11 | + try: |
| 12 | + os.mkdir(path) |
| 13 | + except OSError: |
| 14 | + print(f"Creation of the directory failed. Folder might already exist: {path}") |
| 15 | + else: |
| 16 | + print(f"Successfully created directory: {path}") |
15 | 17 |
|
16 | | - # Gets json from SuperOffice. Make sure script_url is set through fetch() first. |
17 | | - def get_json_from_superoffice(self): |
18 | | - try: |
19 | | - response = requests.get(self.script_url) |
20 | | - except requests.HTTPError as e: |
21 | | - print(f"Could not get data from SuperOffice: {e}") |
22 | | - except requests.ReadTimeout as e: |
23 | | - print(f"Could not get data from SuperOffice: {e}") |
24 | | - except requests.Timeout as e: |
25 | | - print(f"Could not get data from SuperOffice: {e}") |
26 | | - except requests.TooManyRedirects as e: |
27 | | - print(f"Could not get data from SuperOffice: {e}") |
28 | | - except requests.ConnectionError as e: |
29 | | - print(f"Could not get data from SuperOffice: {e}") |
30 | | - except requests.RequestException as e: |
31 | | - print(f"Could not get data from SuperOffice: {e}") |
32 | | - else: |
33 | | - try: |
34 | | - data = json.loads(response.text) |
35 | | - print("JSON fetched!") |
36 | | - except json.JSONDecodeError: |
37 | | - print("Invalid json file") |
38 | | - else: |
39 | | - self.data = data |
40 | 18 |
|
41 | | - # Main fetch function that puts CRMScripts based on JSON file retrieved from given SuperOffice tenant |
42 | | - # Returns true if CRMScripts were fetched and folders/files were created successfully |
43 | | - # Will delete Scripts and Trigger Folders before rebuilding them from the JSON again |
44 | | - # A backup temp folder is created in case script fails during execution |
45 | | - def fetch(self, tenant): |
46 | | - self.script_url = f"{tenant.get('url')}/scripts/customer.fcgi?action=safeParse" \ |
47 | | - f"&includeId={tenant.get('include_id')}" \ |
48 | | - f"&key={tenant.get('key')}" |
| 19 | +def move_folder_to_temp(src, dst): |
| 20 | + try: |
| 21 | + shutil.move(src, dst) |
| 22 | + except FileNotFoundError: |
| 23 | + return |
| 24 | + except shutil.Error: |
| 25 | + shutil.rmtree(dst) |
| 26 | + move_folder_to_temp(src, dst) |
49 | 27 |
|
50 | | - temp_directory = f"{tenant.get('local_directory')}/temp" |
51 | | - scripts_directory = f"{tenant.get('local_directory')}/Scripts" |
52 | | - triggers_directory = f"{tenant.get('local_directory')}/Triggers" |
53 | 28 |
|
54 | | - print(f"Getting JSON data from SuperOffice using endpoint: {self.script_url}") |
55 | | - self.get_json_from_superoffice() |
| 29 | +# Replace characters that are not allowed in Windows folders/files |
| 30 | +def safe_name(text): |
| 31 | + return text.replace('/', '.').replace('"', "'").replace("\\", "..").replace(":", " - "). \ |
| 32 | + replace("*", "X").replace("<", " Lt ").replace(">", " Gt ").replace("|", "I") |
56 | 33 |
|
57 | | - if self.data: |
58 | | - print("Trying to delete temp folder in case it was not deleted on previous fetch") |
59 | | - delete_temp_folder(temp_directory) |
60 | 34 |
|
61 | | - print("Creating temp folder and moving existing folders and scripts to folder") |
62 | | - create_folder(temp_directory) |
63 | | - move_folder_to_temp(scripts_directory, temp_directory) |
64 | | - move_folder_to_temp(triggers_directory, temp_directory) |
| 35 | +def create_file(directory, file_name, body): |
| 36 | + full_path = f"{directory}/{file_name}.crmscript" |
| 37 | + with open(full_path, "w", encoding="utf-8") as f: |
| 38 | + f.write(body) |
65 | 39 |
|
66 | | - print("Creating folders and files from JSON") |
67 | | - create_folder(scripts_directory) |
68 | | - create_folder(triggers_directory) |
69 | | - create_script_folders(scripts_directory, self.data["script_folders"], self.data["scripts"], |
70 | | - -1) |
71 | | - create_trigger_files(triggers_directory, self.data["triggers"]) |
72 | 40 |
|
73 | | - print("Deleting temp folder") |
74 | | - delete_temp_folder(temp_directory) |
| 41 | +def create_scripts_in_folder(directory, folder_id, scripts): |
| 42 | + for s in scripts: |
| 43 | + if s.get("hierarchy_id") == folder_id: |
| 44 | + file_name = safe_name(s.get("description")) |
| 45 | + print(f"Creating file: {file_name}") |
| 46 | + create_file(directory, file_name, s.get("body")) |
75 | 47 |
|
76 | | - return True |
| 48 | + |
| 49 | +def create_script_folders(directory, folders, scripts, lookup_parent_id): |
| 50 | + created_folders = [] |
| 51 | + for f in folders: |
| 52 | + parent_id = f.get("parent_id") |
| 53 | + if (f not in created_folders) and (parent_id == lookup_parent_id): |
| 54 | + path = f"{directory}/{safe_name(f.get('name'))}" |
| 55 | + create_folder(path) |
| 56 | + created_folders.append(f) |
| 57 | + |
| 58 | + folder_id = f.get("id") |
| 59 | + create_scripts_in_folder(path, folder_id, scripts) |
| 60 | + create_script_folders(path, folders, scripts, folder_id) # Recursively creates child folders |
| 61 | + |
| 62 | + |
| 63 | +def create_trigger_files(triggers_directory, triggers): |
| 64 | + for t in triggers: |
| 65 | + create_file(triggers_directory, safe_name(t.get("description")), t.get("body")) |
| 66 | + |
| 67 | + |
| 68 | +def delete_temp_folder(directory): |
| 69 | + if os.path.isdir(directory): |
| 70 | + # shutil.rmtree() often throws PermissionError since os module has just accessed the folder. |
| 71 | + # Usually works after retrying a number of times. |
| 72 | + for i in range(1, 11): |
| 73 | + print(f"Deleting temp folder (attempt {i})") |
| 74 | + if i > 5: |
| 75 | + time.sleep(0.5) |
| 76 | + try: |
| 77 | + shutil.rmtree(directory) |
| 78 | + except PermissionError: |
| 79 | + continue |
| 80 | + else: |
| 81 | + break |
77 | 82 |
|
78 | 83 |
|
| 84 | +# CLASSES |
| 85 | +# Represents the tenant settings json file. By "tenant" we mean a SuperOffice installation. |
79 | 86 | class TenantSettingsJson: |
80 | 87 | def __init__(self): |
81 | 88 | self.tenant_settings_filename = "tenant_settings.json" |
@@ -151,76 +158,70 @@ def update_tenant_in_json(self, updated_tenant): |
151 | 158 | f.write(json.dumps(self.tenant_settings, indent=4)) |
152 | 159 |
|
153 | 160 |
|
154 | | -# FUNCTIONS FOR HANDLING FOLDERS AND FILES |
155 | | -def create_folder(path): |
156 | | - try: |
157 | | - os.mkdir(path) |
158 | | - except OSError: |
159 | | - print(f"Creation of the directory failed. Folder might already exist: {path}") |
160 | | - else: |
161 | | - print(f"Successfully created directory: {path}") |
162 | | - |
163 | | - |
164 | | -def move_folder_to_temp(src, dst): |
165 | | - try: |
166 | | - shutil.move(src, dst) |
167 | | - except FileNotFoundError: |
168 | | - return |
169 | | - except shutil.Error: |
170 | | - shutil.rmtree(dst) |
171 | | - move_folder_to_temp(src, dst) |
172 | | - |
173 | | - |
174 | | -# Replace characters that are not allowed in Windows folders/files |
175 | | -def safe_name(text): |
176 | | - return text.replace('/', '.').replace('"', "'").replace("\\", "..").replace(":", " - "). \ |
177 | | - replace("*", "X").replace("<", " Lt ").replace(">", " Gt ").replace("|", "I") |
178 | | - |
179 | | - |
180 | | -def create_file(directory, file_name, body): |
181 | | - full_path = f"{directory}/{file_name}.crmscript" |
182 | | - with open(full_path, "w", encoding="utf-8") as f: |
183 | | - f.write(body) |
| 161 | +# Used for getting Json from SuperOffice and performing the fetch itself |
| 162 | +class SuperOfficeData: |
| 163 | + def __init__(self): |
| 164 | + self.script_url = "" |
| 165 | + self.data = {} |
184 | 166 |
|
| 167 | + # Gets json from SuperOffice. Make sure script_url is set through fetch() first. |
| 168 | + def get_json_from_superoffice(self): |
| 169 | + try: |
| 170 | + response = requests.get(self.script_url) |
| 171 | + except requests.HTTPError as e: |
| 172 | + print(f"Could not get data from SuperOffice: {e}") |
| 173 | + except requests.ReadTimeout as e: |
| 174 | + print(f"Could not get data from SuperOffice: {e}") |
| 175 | + except requests.Timeout as e: |
| 176 | + print(f"Could not get data from SuperOffice: {e}") |
| 177 | + except requests.TooManyRedirects as e: |
| 178 | + print(f"Could not get data from SuperOffice: {e}") |
| 179 | + except requests.ConnectionError as e: |
| 180 | + print(f"Could not get data from SuperOffice: {e}") |
| 181 | + except requests.RequestException as e: |
| 182 | + print(f"Could not get data from SuperOffice: {e}") |
| 183 | + else: |
| 184 | + try: |
| 185 | + data = json.loads(response.text) |
| 186 | + print("JSON fetched!") |
| 187 | + except json.JSONDecodeError: |
| 188 | + print("Invalid json file") |
| 189 | + else: |
| 190 | + self.data = data |
185 | 191 |
|
186 | | -def create_scripts_in_folder(directory, folder_id, scripts): |
187 | | - for s in scripts: |
188 | | - if s.get("hierarchy_id") == folder_id: |
189 | | - file_name = safe_name(s.get("description")) |
190 | | - print(f"Creating file: {file_name}") |
191 | | - create_file(directory, file_name, s.get("body")) |
| 192 | + # Main fetch function that puts CRMScripts based on JSON file retrieved from given SuperOffice tenant |
| 193 | + # Returns true if CRMScripts were fetched and folders/files were created successfully |
| 194 | + # Will delete Scripts and Trigger Folders before rebuilding them from the JSON again |
| 195 | + # A backup temp folder is created in case script fails during execution |
| 196 | + def fetch(self, tenant): |
| 197 | + self.script_url = f"{tenant.get('url')}/scripts/customer.fcgi?action=safeParse" \ |
| 198 | + f"&includeId={tenant.get('include_id')}" \ |
| 199 | + f"&key={tenant.get('key')}" |
192 | 200 |
|
| 201 | + temp_directory = f"{tenant.get('local_directory')}/temp" |
| 202 | + scripts_directory = f"{tenant.get('local_directory')}/Scripts" |
| 203 | + triggers_directory = f"{tenant.get('local_directory')}/Triggers" |
193 | 204 |
|
194 | | -def create_script_folders(directory, folders, scripts, lookup_parent_id): |
195 | | - created_folders = [] |
196 | | - for f in folders: |
197 | | - parent_id = f.get("parent_id") |
198 | | - if (f not in created_folders) and (parent_id == lookup_parent_id): |
199 | | - path = f"{directory}/{safe_name(f.get('name'))}" |
200 | | - create_folder(path) |
201 | | - created_folders.append(f) |
| 205 | + print(f"Getting JSON data from SuperOffice using endpoint: {self.script_url}") |
| 206 | + self.get_json_from_superoffice() |
202 | 207 |
|
203 | | - folder_id = f.get("id") |
204 | | - create_scripts_in_folder(path, folder_id, scripts) |
205 | | - create_script_folders(path, folders, scripts, folder_id) # Recursively creates child folders |
| 208 | + if self.data: |
| 209 | + print("Trying to delete temp folder in case it was not deleted on previous fetch") |
| 210 | + delete_temp_folder(temp_directory) |
206 | 211 |
|
| 212 | + print("Creating temp folder and moving existing folders and scripts to folder") |
| 213 | + create_folder(temp_directory) |
| 214 | + move_folder_to_temp(scripts_directory, temp_directory) |
| 215 | + move_folder_to_temp(triggers_directory, temp_directory) |
207 | 216 |
|
208 | | -def create_trigger_files(triggers_directory, triggers): |
209 | | - for t in triggers: |
210 | | - create_file(triggers_directory, safe_name(t.get("description")), t.get("body")) |
| 217 | + print("Creating folders and files from JSON") |
| 218 | + create_folder(scripts_directory) |
| 219 | + create_folder(triggers_directory) |
| 220 | + create_script_folders(scripts_directory, self.data["script_folders"], self.data["scripts"], |
| 221 | + -1) |
| 222 | + create_trigger_files(triggers_directory, self.data["triggers"]) |
211 | 223 |
|
| 224 | + print("Deleting temp folder") |
| 225 | + delete_temp_folder(temp_directory) |
212 | 226 |
|
213 | | -def delete_temp_folder(directory): |
214 | | - if os.path.isdir(directory): |
215 | | - # shutil.rmtree() often throws PermissionError since os module has just accessed the folder. |
216 | | - # Usually works after retrying a number of times. |
217 | | - for i in range(1, 11): |
218 | | - print(f"Deleting temp folder (attempt {i})") |
219 | | - if i > 5: |
220 | | - time.sleep(0.5) |
221 | | - try: |
222 | | - shutil.rmtree(directory) |
223 | | - except PermissionError: |
224 | | - continue |
225 | | - else: |
226 | | - break |
| 227 | + return True |
0 commit comments