Commit 423dd410 authored by Aviparna Biswas's avatar Aviparna Biswas
Browse files

All files abroad

parents
Pipeline #6031 canceled with stages
import os
import json
import shutil
import sys
import time
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
def create_directory(path):
if not os.path.exists(path):
os.makedirs(path)
def get_user_downloads_path():
# Get the user's Downloads directory path in Windows
general_downloads_path = Path.home() / "Downloads"
return general_downloads_path
def create_downloads_directory():
downloads_path = "D:/Python Projects/Title Search/Results/"
create_directory(downloads_path)
return downloads_path
def create_folder_structure(downloads_path, appraiser_name, address_key):
appraiser_path = os.path.join(downloads_path, appraiser_name)
create_directory(appraiser_path)
address_path = os.path.join(appraiser_path, address_key)
create_directory(address_path)
return address_path
def create_folder_structure(downloads_path, tax_recorder_name, address_key):
tax_recorder_path = os.path.join(downloads_path, tax_recorder_name)
create_directory(tax_recorder_path)
address_path = os.path.join(tax_recorder_path, address_key)
create_directory(address_path)
return address_path
def run_appraiser(address_key):
try:
# Specify the downloads directory path
downloads_path = create_downloads_directory()
appraiser_name = "Appraiser" # Change this as needed
# Specify the address and create a folder structure based on it
#address_key = "2216 NW 6 PL FORT LAUDERDALE, FL 33311" # Change this as needed
apprasier_path = create_folder_structure(downloads_path, appraiser_name, address_key)
print_settings = {
"recentDestinations": [{
"id": "Save as PDF",
"origin": "local",
"account": "",
}],
"selectedDestinationId": "Save as PDF",
"version": 2,
"isHeaderFooterEnabled": False,
"isLandscapeEnabled": True
}
prefs = {'printing.print_preview_sticky_settings.appState': json.dumps(print_settings),
"download.prompt_for_download": False,
"profile.default_content_setting_values.automatic_downloads": 1,
"download.directory_upgrade": True,
"savefile.default_directory": apprasier_path, # this is path to dir where you want to save the file
"safebrowsing.enabled": True}
options = webdriver.ChromeOptions()
options.add_experimental_option('prefs', prefs)
options.add_argument('--kiosk-printing')
service = Service()
driver = webdriver.Chrome(options)
driver.maximize_window()
actions = ActionChains(driver)
wait = WebDriverWait(driver, 20)
driver.get("https://web.bcpa.net/BcpaClient/#/Record-Search")
text_input = wait.until(EC.visibility_of_element_located((By.XPATH, '//input[@class="form-control"]'))).send_keys(address_key)
search_button = driver.find_element(By.XPATH,
'//span[@class="input-group-addon"]/span[@class="glyphicon glyphicon-search"]').click()
printer_click = wait.until(EC.visibility_of_element_located((By.XPATH, '//div[@class="col-sm-1 btn-printrecinfo"]'))).click()
time.sleep(10)
except Exception as e:
print(e)
sys.exit(1)
def run_tax_recorder(address_key):
try:
# Specify the downloads directory path
downloads_path = create_downloads_directory()
tax_recorder_name = "Tax_Recorder" # Change this as needed
# Specify the address and create a folder structure based on it
#address_key = "2216 NW 6 PL FORT LAUDERDALE, FL 33311" # Change this as needed
tax_recorder_path = create_folder_structure(downloads_path, tax_recorder_name, address_key)
print_settings = {
"recentDestinations": [{
"id": "Save as PDF",
"origin": "local",
"account": "",
}],
"selectedDestinationId": "Save as PDF",
"version": 2,
"isHeaderFooterEnabled": False,
"isLandscapeEnabled": True
}
prefs = {'printing.print_preview_sticky_settings.appState': json.dumps(print_settings),
"download.prompt_for_download": False,
"profile.default_content_setting_values.automatic_downloads": 1,
"download.directory_upgrade": True,
"savefile.default_directory": tax_recorder_path, # this is path to dir where you want to save the file
"safebrowsing.enabled": True}
options = webdriver.ChromeOptions()
options.add_experimental_option('prefs', prefs)
options.add_argument('--kiosk-printing')
service = Service()
driver = webdriver.Chrome(options)
driver.maximize_window()
actions = ActionChains(driver)
wait = WebDriverWait(driver, 20)
driver.get("https://broward.county-taxes.com/public/search/property_tax")
pop_up_close = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@class="svg-icon"]'))).click()
search_box = wait.until(EC.element_to_be_clickable((By.XPATH, '//input[@role="searchbox"]')))
search_box.send_keys("2216 NW 6 PL FORT LAUDERDALE")
search_box.send_keys(Keys.RETURN)
time.sleep(5)
element_click = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@class="text-primary svg-icon"]'))).click()
time.sleep(10)
details_page = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[2]/div[2]/div/main/div/div/section[2]/div[2]/div[1]/div/div[2]/button'))).click()
time.sleep(10)
take_page_screenshot = driver.execute_script('window.print();')
time.sleep(10)
pdf_download = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="bill-history"]/div/div[2]/table/tbody[1]/tr[1]/td[5]/div/a/div/div[2]'))).click()
time.sleep(10)
# Get the latest downloaded PDF file
general_downloads_path = get_user_downloads_path()
downloaded_files = [fname for fname in os.listdir(general_downloads_path) if fname.endswith('.pdf')]
if downloaded_files:
latest_file = max(downloaded_files, key=lambda f: (general_downloads_path / f).stat().st_ctime)
source_path = os.path.join(general_downloads_path, latest_file)
# Move the file to the desired tax recorder path
destination_path = os.path.join(tax_recorder_path, latest_file)
shutil.move(source_path, destination_path)
except Exception as e:
print(e)
sys.exit(1)
if __name__ == "__main__":
run_appraiser()
run_tax_recorder()
address_key
"2216 NW 6 PL FORT LAUDERDALE, FL 33311"
# Import Dependencies
import tkinter as tk
from tkinter import *
from tkinter import filedialog
import customtkinter
import pandas as pd
import os
from PIL import Image
from main import run_appraiser, run_tax_recorder
customtkinter.set_appearance_mode("Dark") # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
# configure window
self.title("Nexval Title Search Bot")
self.geometry(f"{1100}x{580}")
image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_images")
self.logo_image = customtkinter.CTkImage(Image.open(os.path.join(image_path, "NEX_WEB_LOGO_NEXVAL.png")), size=(60, 26))
# create sidebar frame with widgets
self.sidebar_frame = customtkinter.CTkFrame(self, width=140, corner_radius=0)
self.sidebar_frame.grid(row=0, column=0, rowspan=8, sticky="nsew") # Increased rowspan for spacing
self.sidebar_frame.grid_rowconfigure((0, 1, 2, 3, 4, 5, 6, 7), weight=1) # All rows have equal weight
# Application Title
self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="Nexval Title Search Bot", font=customtkinter.CTkFont(size=20, weight="bold"))
self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10), sticky="ew")
# Dropdown for selecting states
self.state_label = customtkinter.CTkLabel(self.sidebar_frame, text="Select State:", anchor="w")
self.state_label.grid(row=2, column=0, padx=20, pady=(0, 10), sticky="ew")
self.state_options = ["Florida"]
self.state_var = StringVar()
self.state_dropdown = customtkinter.CTkOptionMenu(self.sidebar_frame, values=self.state_options)
self.state_dropdown.grid(row=3, column=0, padx=20, pady=(0, 10), sticky="ew")
# Dropdown for selecting counties
self.county_label = customtkinter.CTkLabel(self.sidebar_frame, text="Select County:", anchor="w")
self.county_label.grid(row=5, column=0, padx=20, pady=(0, 10), sticky="ew")
self.county_options = ["Broward"]
self.county_var = StringVar()
self.county_dropdown = customtkinter.CTkOptionMenu(self.sidebar_frame, values=self.county_options)
self.county_dropdown.grid(row=6, column=0, padx=20, pady=(0, 10), sticky="ew")
# Radio for selecting web sources
self.county_label = customtkinter.CTkLabel(self.sidebar_frame, text="Select Web Source:", anchor="w")
self.county_label.grid(row=7, column=0, padx=20, pady=(0, 10), sticky="ew")
self.county_options = ["Property Tax", "Code/Appraiser", "Permit", "Utility", "Clerk", "Special Assessments"]
self.county_var = StringVar()
self.county_dropdown = customtkinter.CTkComboBox(self.sidebar_frame, values=self.county_options)
self.county_dropdown.grid(row=8, column=0, padx=20, pady=(0, 10), sticky="ew")
# About Section
self.about_label = customtkinter.CTkLabel(self.sidebar_frame, text="", anchor="w")
self.about_label.grid(row=9, column=0, padx=20, pady=(10, 0), sticky="ew")
self.about_text = """Nexval's Title search automation bot which can connect to different websites, navigate to relevant sections, input appropriate data and perform search, scraping/data collection, take screenshots. Additionally, organizations can communicate their business requirements through the rule-engine."""
self.about_textbox = customtkinter.CTkTextbox(self.sidebar_frame, width=20, height=170)
self.about_textbox.insert("1.0", self.about_text)
self.about_textbox.grid(row=10, column=0, padx=20, pady=(0, 10), sticky="ew")
#self.grid_columnconfigure(0, weight=1) # Allow column 0 to expand horizontally
# create tabview
self.tabview = customtkinter.CTkTabview(self, height=100, width=950)
self.tabview.grid(row=0, column=4, padx=(20, 0), pady=(20, 0), sticky="nsew")
self.tabview.add("Single Data Ingest")
self.tabview.add("Bulk Data Ingest")
self.tabview.tab("Single Data Ingest").grid_columnconfigure(0, weight=1) # configure grid of individual tabs
self.tabview.tab("Bulk Data Ingest").grid_columnconfigure(0, weight=1)
# Single data section
self.single_file_entry = customtkinter.CTkEntry(self.tabview.tab("Single Data Ingest"), width=250, height=10, placeholder_text="Enter Name/Address/Folio Number") # Adjust width as needed
self.single_file_entry.grid(row=1, columnspan=2, padx=(20, 0), pady=(20, 20), sticky="nsew")
self.file_submit = customtkinter.CTkButton(self.tabview.tab("Single Data Ingest"), text="Run", command=self.upload_file)
self.file_submit.grid(row=1, column=3, pady=10, padx=20, sticky="e")
# File Uploader Section (In the main section)
self.file_upload_label = customtkinter.CTkLabel(self.tabview.tab("Bulk Data Ingest"), text="Upload File containing data:")
self.file_upload_label.grid(row=2, column=0, pady=10, padx=20, sticky="w")
self.file_upload_button = customtkinter.CTkButton(self.tabview.tab("Bulk Data Ingest"), text="Browse", command=self.upload_file)
self.file_upload_button.grid(row=2, column=1, pady=10, padx=20, sticky="e")
#self.file_upload_button = customtkinter.CTkButton(self.tabview.tab("Bulk Data Ingest"), text="Preview", command=self.preview_file_bulk)
#self.file_upload_button.grid(row=2, column=2, pady=10, padx=20, sticky="e")
self.file_upload_button = customtkinter.CTkButton(self.tabview.tab("Bulk Data Ingest"), text="Run", command=self.handle_option_button_click)
self.file_upload_button.grid(row=2, column=3, pady=10, padx=20, sticky="e")
# Create Data Viewer Section
self.foliodata_frame = customtkinter.CTkFrame(self)
self.foliodata_frame.grid(row=3, column=4, padx=(20, 20), pady=(20, 0), sticky="nsew")
# Add the Results Viewer label
self.results_viewer_label = customtkinter.CTkLabel(self.foliodata_frame, text="Results Viewer", anchor="w")
self.results_viewer_label.grid(row=1, column=2, columnspan=2, padx=20, pady=(10, 10), sticky="ew")
# Select Folio Numbers Section
#self.select_folio_number = customtkinter.CTkLabel(self.foliodata_frame, text="Choose/Select Folio Numbers", anchor="w")
#self.select_folio_number.grid(row=2, column=2, columnspan=2, padx=20, pady=(0, 10), sticky="ew")
# T he folder path where folio numbers are stored
results_folder_path = "Results"
# Get a list of filenames in the Results folder
#folio_files = os.listdir(results_folder_path)
folio_folders = [folder for folder in os.listdir(results_folder_path)
if os.path.isdir(os.path.join(results_folder_path, folder))]
# Add a dropdown for selecting folio numbers
self.folio_label = customtkinter.CTkLabel(self.foliodata_frame, text="Select Folio Number:", anchor="w")
self.folio_label.grid(row=2, column=2, padx=20, pady=(0, 10), sticky="w")
self.folio_var = StringVar()
self.folio_dropdown = customtkinter.CTkComboBox(self.foliodata_frame, values=folio_folders)
self.folio_dropdown.grid(row=2, column=3, padx=20, pady=(0, 10), sticky="w")
#self.folio_options = [filename.split('.')[0] for filename in folio_files]
#self.folio_var = StringVar()
#self.folio_dropdown = customtkinter.CTkComboBox(self.foliodata_frame, values=self.folio_options)
#self.folio_dropdown.grid(row=2, column=4, padx=20, pady=(0, 10), sticky="w")
# Function to update subfolders dropdown
def update_subfolders():
selected_folio = self.folio_var.get()
if selected_folio:
subfolders_path = os.path.join(results_folder_path, selected_folio)
if os.path.exists(subfolders_path) and os.path.isdir(subfolders_path):
subfolders = [folder for folder in os.listdir(subfolders_path)
if os.path.isdir(os.path.join(subfolders_path, folder))]
self.subfolder_dropdown.config(values=subfolders)
print("Subfolders:", subfolders) # Print subfolders for debugging
else:
self.subfolder_dropdown.config(values=[])
# Add a dropdown for selecting subfolders
self.subfolder_label = customtkinter.CTkLabel(self.foliodata_frame, text="Select Data Source:", anchor="w")
self.subfolder_label.grid(row=2, column=4, padx=20, pady=(0, 10), sticky="w")
self.subfolder_var = StringVar()
self.subfolder_dropdown = customtkinter.CTkComboBox(self.foliodata_frame, values=[], state='readonly')
self.subfolder_dropdown.grid(row=2, column=5, padx=20, pady=(0, 10), sticky="w")
self.folio_var.trace_add('write', lambda *args: update_subfolders())
# Appearance Mode Label and Option Menu
self.appearance_mode_label = customtkinter.CTkLabel(self.sidebar_frame, text="Appearance Mode:", anchor="w")
self.appearance_mode_label.grid(row=11, column=0, padx=20, pady=(10, 0), sticky="ew")
self.appearance_mode_optionemenu = customtkinter.CTkOptionMenu(self.sidebar_frame, values=["Light", "Dark", "System"],
command=self.change_appearance_mode_event)
self.appearance_mode_optionemenu.grid(row=12, column=0, padx=20, pady=(0, 10), sticky="ew")
self.spacer_label1 = customtkinter.CTkLabel(self.sidebar_frame, text="", font=customtkinter.CTkFont(size=1))
self.spacer_label1.grid(row=13, column=0, padx=20, pady=5, sticky="ew")
self.powered_by = customtkinter.CTkLabel(self.sidebar_frame, text="Powered by", image=self.logo_image, compound="right", anchor="w")
self.powered_by.grid(row=14, column=0, padx=20, pady=(10, 0), sticky="ew")
# configure grid layout (4x4)
self.grid_columnconfigure(1, weight=1)
self.grid_columnconfigure((1, 3), weight=0)
def change_appearance_mode_event(self, new_appearance_mode: str):
customtkinter.set_appearance_mode(new_appearance_mode)
def upload_file(self):
file_path = filedialog.askopenfilename(
filetypes=[("CSV files", "*.csv")], # Specify CSV file type filter
title="Select a CSV File"
)
print("Selected file:", file_path)
if file_path:
try:
df = pd.read_csv(file_path)
self.uploaded_data = df
data_text = customtkinter.CTkTextbox(self.tabview.tab("Bulk Data Ingest"), width=80, height=200, wrap="none")
data_text.insert("1.0", df.head())
data_text.grid(row=3, column=0, columnspan=4, padx=20, pady=10, sticky="nsew")
except Exception as e:
print("Error:", e)
def handle_option_button_click(self):
# This method will handle the click event of the option buttons
if hasattr(self, 'uploaded_data'):
data = self.uploaded_data['address_key'].tolist() # Use the uploaded data
for address_key in data:
run_appraiser(address_key) # Run appraiser for each key
run_tax_recorder(address_key) # Run tax recorder for each key
else:
print("Please upload a CSV file first.")
if __name__ == "__main__":
app = App()
app.mainloop()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment