From 58fa8181283b146b8128371b20ab23e40304f9c8 Mon Sep 17 00:00:00 2001 From: Hex Ripley Date: Tue, 14 Jan 2025 18:52:52 -0800 Subject: [PATCH] Run in regular intervals with less intervention --- AssignerPal.py | 34 ++++---- AutoColor2.py | 212 +++++++++++++++++++++++++++++++++++++++++++++++++ AutoTicket.py | 12 +-- 3 files changed, 236 insertions(+), 22 deletions(-) create mode 100644 AutoColor2.py diff --git a/AssignerPal.py b/AssignerPal.py index bb757eb..fbb7aac 100644 --- a/AssignerPal.py +++ b/AssignerPal.py @@ -1,11 +1,15 @@ from selenium import webdriver import AutoTicket -import AutoColor +import AutoColor2 import json import os +import datetime +import time urls = {"NOC-PROV": "", "NOC-PROV-ADV" : "", "PROV-DSL" : "", "PROV-FIBER":"", "PROV-IPBB":"","PROV-MISC":"","FUS-PROV":"","TICKETS":""} +tickets_sorted = False + def assign_urls(dictionary): for key in dictionary: value = input(f"Enter url for '{key}': ") @@ -43,29 +47,25 @@ def first_time_setup(): with open('team.json', 'w') as file: json.dump(users, file) -def choice(urls,users,driver): - print("Tickets or Directly?") - user_choice = input() - if "ti" in user_choice.lower(): - AutoTicket.auto_ticket(urls,users,driver) - if "di" in user_choice.lower(): - AutoColor.tag_assist(urls,driver,users) - print("Go back to Directly or Tickets choice?") - if input("y/n : ") == "y": - choice(urls,users,driver) - def main(): if os.path.exists('urls.json'): - print("Do first time set up?") - if input("y/n : ") == "y": - first_time_setup() + print("Skipping first time setup") else: first_time_setup() driver = webdriver.Firefox() with open('urls.json', 'r') as file: urls = json.load(file) with open('team.json', 'r') as file: users = json.load(file) - choice(urls,users,driver) - driver.close() + while True: + current_time = datetime.datetime.now().time() + start_time = datetime.time(9, 0, 0) + end_time = datetime.time(17, 0, 0) + if start_time <= current_time <= end_time: + AutoTicket.auto_ticket(urls, users, driver, tickets_sorted) + AutoColor2.tag_assist(urls, driver, users) + else: + print("It's after hours. I'm not doing anything.") + time.sleep(7200) # Sleep for 2 hours + #driver.close() main() \ No newline at end of file diff --git a/AutoColor2.py b/AutoColor2.py new file mode 100644 index 0000000..1fe4649 --- /dev/null +++ b/AutoColor2.py @@ -0,0 +1,212 @@ +from selenium import webdriver +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.common.action_chains import ActionChains +import datetime +import random + +# Condensed string finder for lists of strings +def found_string(string_list, main_string): + for string in string_list: + if string in main_string: + return True + return False + +# Get tag_count dictionary +def count_tags(queues,tags): + tag_count = {} + for queue in queues: + count = 0 + for tag in tags: + if queue in tag.text.lower(): + count += 1 + tag_count[queue] = count + return tag_count + +def next_string(list_of_strings): + index = 0 + while True: + yield list_of_strings[index] + index = (index + 1) % len(list_of_strings) + + + +# Assign steps in order of queue list without checking tag_count +def dumb_make_tags(queues,tags,driver): + ac = ActionChains(driver) + original_window = driver.current_window_handle + next_queue = next_string(queues) + for tag in tags: + if found_string(queues, tag.text.lower()) == False: + driver.execute_script("arguments[0].scrollIntoView(true);", tag) + ac.context_click(tag).perform() + WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2)) + for window_handle in driver.window_handles: + if window_handle != original_window: + driver.switch_to.window(window_handle) + break + WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'h2'))) + driver.find_element(By.CSS_SELECTOR, "a.edit").click() + try: + element = WebDriverWait(driver, 10).until( + EC.presence_of_element_located((By.ID, "tag_id")) + ) + finally: + tag_field = driver.find_element(By.ID, "tag_id") + tag_field.send_keys(Keys.END) + tag_field.send_keys("/",next(next_queue)) + tag_field.send_keys(Keys.ENTER) + WebDriverWait(driver,5).until(EC.presence_of_element_located((By.ID,'stepListHeader'))) + driver.close() + driver.switch_to.window(original_window) + +# Tool to create a menu based on a list. +def select_list_item(list_of_strings): + for i, item in enumerate(list_of_strings): + print(f"{chr(97 + i)}) {item}") + + while True: + choice = input("Please select an option (a, b, c, etc.): ").lower() + if choice.isalpha() and ord(choice) - 97 in range(len(list_of_strings)): + return list_of_strings[ord(choice) - 97] + else: + print("Invalid choice. Please select a valid option.") + +# Select every unassigned tag, print queue count, print step name, use user input to choose what tag to assign +def guided_make_tags(queues,tags,driver): + ac = ActionChains(driver) + original_window = driver.current_window_handle + for tag in tags: + if found_string(queues, tag.text.lower()) == False: + driver.execute_script("arguments[0].scrollIntoView(true);", tag) + ac.context_click(tag).perform() + WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2)) + for window_handle in driver.window_handles: + if window_handle != original_window: + driver.switch_to.window(window_handle) + break + WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'h2'))) + print("What should we tag this workflow? ", driver.find_element(By.TAG_NAME, 'h2').text) + guided_tag = select_list_item(queues) + driver.find_element(By.CSS_SELECTOR, "a.edit").click() + try: + element = WebDriverWait(driver, 10).until( + EC.presence_of_element_located((By.ID, "tag_id")) + ) + finally: + tag_field = driver.find_element(By.ID, "tag_id") + tag_field.send_keys(Keys.END) + tag_field.send_keys("/",guided_tag) + tag_field.send_keys(Keys.ENTER) + WebDriverWait(driver,5).until(EC.presence_of_element_located((By.ID,'stepListHeader'))) + driver.close() + driver.switch_to.window(original_window) + + + + +# Get lowest_queue string, and increment tag_count for the value for that queue by one. +def find_lowest_and_increment(dictionary): + if not dictionary: + return None + + min_key = min(dictionary, key=dictionary.get) + + dictionary[min_key] += 1 + + return min_key + +# Check which queue has the least number of assigned workflows. +def smart_make_tags(queues,tags,driver): + ac = ActionChains(driver) + original_window = driver.current_window_handle + tag_count = count_tags(queues,tags) + for tag in tags: + if found_string(queues, tag.text.lower()) == False: + lowest_queue = find_lowest_and_increment(tag_count) + driver.execute_script("arguments[0].scrollIntoView(true);", tag) + ac.context_click(tag).perform() + WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2)) + for window_handle in driver.window_handles: + if window_handle != original_window: + driver.switch_to.window(window_handle) + break + WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'h2'))) + driver.find_element(By.CSS_SELECTOR, "a.edit").click() + try: + element = WebDriverWait(driver, 10).until( + EC.presence_of_element_located((By.ID, "tag_id")) + ) + finally: + tag_field = driver.find_element(By.ID, "tag_id") + tag_field.send_keys(Keys.END) + tag_field.send_keys("/",lowest_queue) + tag_field.send_keys(Keys.ENTER) + WebDriverWait(driver,5).until(EC.presence_of_element_located((By.ID,'stepListHeader'))) + driver.close() + driver.switch_to.window(original_window) + +# Ignore future steps. +def future_tag_manip(driver): + future_tag_field = driver.find_element(By.ID, "cf-future-tag") + future_tag_field.clear() + future_tag_field.send_keys("Automation In Progress") + +def filter_steps_manip(driver): + step_field = driver.find_element(By.ID, "cf-due-step") + step_field.clear() + print("") + print("Wanna avoid touching a step?") + print("Take a look at what's in the queue.") + print("If there's anything in there you don't want to tag,") + print("copy the step name here, with | to seperate steps.") + print("e.g. 'Confirm Disconnect Date Has Passed|Reserve Numbers'") + print("or, press Enter to skip") + filters = input() + if filters != "": + step_field.send_keys("^(?!.*(",filters,")).*$") + print("") + print("This look good? y/n") + answer = input() + if "n" in answer: + print("Let's try that again...") + print("") + filter_steps_manip() + + +def automation_picker(queues,tags,driver,choice): + if choice.lower() == "smart": + print("Okay, I'll make you proud (> O ω O)>✎") + smart_make_tags(queues,tags,driver) + elif choice.lower() == "dumb": + print("Okay, I make thing go now ─=≡Σ((( つ><)つ") + dumb_make_tags(queues,tags,driver) + else: + print("Skipping...") + +def tag_assist(urls,driver,users): + print("This is someone's automation tool. If you don't know what you're doing, please abort.") + urllist = urls + urllist.popitem() + for key, url in urllist.items(): + print("Working on ",key) + driver.get(url) + print("") + print("Please use the browser to log in. I won't look (づ_ど)") + try: + element = WebDriverWait(driver, 500).until( + EC.presence_of_element_located((By.ID, "dueWorkflowSteps_wrapper")) + ) + finally: + future_tag_manip(driver) + #filter_steps_manip(driver) + tags = driver.find_elements(By.CSS_SELECTOR, "td.tag") + if "NOC" in key: + automation_picker(users,tags,driver,"smart") + else: + automation_picker(users,tags,driver,"dumb") + print("Done! ✧⋆٩(ᵔ ᗜ ᵔ )و ♡✧") + print("Goodbye! ヾ(˶ᵔ ᗜ ᵔ˶)") + \ No newline at end of file diff --git a/AutoTicket.py b/AutoTicket.py index dd7b785..fcf70b7 100644 --- a/AutoTicket.py +++ b/AutoTicket.py @@ -6,6 +6,7 @@ from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.action_chains import ActionChains import datetime import json +import time def get_filters(driver): print("Setting up filters...") @@ -60,6 +61,7 @@ def assign_tickets(namecount,driver): driver.switch_to.window(window_handle) break WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "owner"))) + time.sleep(1) controls = driver.find_element(By.ID, 'ticket-controls').find_elements(By.CLASS_NAME, "ticket-control") WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'select2-container'))) owner_button = controls[3].find_element(By.CLASS_NAME, 'select2-container') @@ -68,16 +70,14 @@ def assign_tickets(namecount,driver): owner_field = search_fields[3] owner_field.send_keys(lowest_name) owner_field.send_keys(Keys.ENTER) - print("Check to see if this worked, then press enter") - input() - #assigned_json[lowest_name] += 1 + #assigned_json[lowest_name] += driver.find_element(By.CLASS_NAME, 'update').click() driver.close() driver.switch_to.window(original_window) #assigned_json = {} -def auto_ticket(urls,users,driver): +def auto_ticket(urls,users,driver,tickets_sorted): #for user in users: # assigned_json[user] = 0 driver.get(urls['TICKETS']) @@ -88,7 +88,9 @@ def auto_ticket(urls,users,driver): EC.presence_of_element_located((By.CLASS_NAME, "select2-selection__clear")) ) finally: - get_filters(driver) + if tickets_sorted == False: + get_filters(driver) + time.sleep(2.5) namecount = get_names(users,driver) print(namecount) assign_tickets(namecount,driver)