Spaces:
Build error
Build error
| import os | |
| import threading | |
| from concurrent.futures import ThreadPoolExecutor, as_completed | |
| import gradio as gr | |
| from selenium import webdriver | |
| from selenium.webdriver.chrome.service import Service | |
| from webdriver_manager.chrome import ChromeDriverManager | |
| from selenium.webdriver.common.by import By | |
| from selenium.webdriver.support.ui import WebDriverWait, Select | |
| from selenium.webdriver.support import expected_conditions as EC | |
| from selenium.common.exceptions import TimeoutException | |
| from selenium.webdriver.chrome.options import Options | |
| # Suppress unnecessary logs | |
| os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' | |
| os.environ['WDM_LOG'] = '0' | |
| # List of companies to search | |
| companies = [ | |
| {'url': 'https://www.distilleryvfx.com/careers', 'name': 'Distillery VFX', 'action': None}, | |
| {'url': 'https://barnstormvfx.bamboohr.com/careers', 'name': 'Barnstorm VFX', 'action': None}, | |
| {'url': 'https://careers.theembassyvfx.com/#jobs', 'name': 'The Embassy VFX', 'action': None}, | |
| {'url': 'https://www.cosavfx.com/opportunities/', 'name': 'Cosa VFX', 'action': None}, | |
| {'url': 'https://www.hydraulx.com/careers/', 'name': 'Hydraulx', 'action': None}, | |
| {'url': 'https://globalus242.dayforcehcm.com/CandidatePortal/en-US/craftyapes', 'name': 'Crafty Apes', 'action': None}, | |
| {'url': 'https://www.belofx.com/careers', 'name': 'BElofx', 'action': None}, | |
| {'url': 'https://image-engine.com/jobs/#jobs', 'name': 'Image Engine', 'action': None}, | |
| {'url': 'https://www.zoicstudios.com/join', 'name': 'Zoic Studios', 'action': None}, | |
| {'url': 'https://animallogic.com/careers/jobs/', 'name': 'Animal Logic', 'action': None}, | |
| {'url': 'https://cinesite.com/job-vacancies/?location=vancouver&division=!feature%20animation', 'name': 'Cinesite', 'action': None}, | |
| {'url': 'http://careers.digitaldomain.com/', 'name': 'Digital Domain', 'action': 'select_vancouver'}, | |
| {'url': 'https://www.company3.com/careers/', 'name': 'Company 3', 'action': None}, | |
| {'url': 'https://recruitment.phantom-fx.com/jobs/Careers', 'name': 'Phantom FX', 'action': None}, | |
| {'url': 'https://scanlinevfx.com/careers/', 'name': 'Scanline VFX', 'action': None}, | |
| {'url': 'https://www.pixomondo.com/careers', 'name': 'Pixomondo', 'action': None}, | |
| {'url': 'https://www.dneg.com/join-us/open-positions', 'name': 'DNEG', 'action': 'select_vancouver'}, | |
| {'url': 'https://jobs.disneycareers.com/search-jobs?orgIds=391-28648&ascf=[%7B%22key%22:%22custom_fields.IndustryCustomField%22,%22value%22:%22Industrial%20Light%20%26%20Magic%22%7D]', 'name': 'ILM', 'action': None}, | |
| {'url': 'https://www.imageworks.com/job-postings', 'name': 'Sony Pictures Imageworks', 'action': None} | |
| ] | |
| target_jobs = ['FX Artist', 'FX Technical Director', 'FX TD'] | |
| MAX_WORKERS = 4 # Number of parallel browsers | |
| # Force ChromeDriverManager to download a version compatible with Chromium 133. | |
| # Passing the version as a positional argument. | |
| driver_path = ChromeDriverManager("133.0.6943.41").install() | |
| def check_company(company, chrome_options): | |
| driver = webdriver.Chrome( | |
| service=Service(driver_path), | |
| options=chrome_options | |
| ) | |
| driver.implicitly_wait(5) | |
| try: | |
| url = company['url'] | |
| driver.get(url) | |
| # If a specific action is required (like selecting Vancouver), perform it. | |
| if company['action'] == 'select_vancouver': | |
| try: | |
| if 'digitaldomain' in url: | |
| dropdown = WebDriverWait(driver, 5).until( | |
| EC.presence_of_element_located((By.ID, "current-openings-select")) | |
| ) | |
| Select(dropdown).select_by_visible_text("Vancouver") | |
| WebDriverWait(driver, 5).until( | |
| EC.presence_of_element_located((By.CSS_SELECTOR, ".job-listings")) | |
| ) | |
| elif 'dneg' in url: | |
| dropdown = WebDriverWait(driver, 5).until( | |
| EC.presence_of_element_located((By.CSS_SELECTOR, "select[data-test-id='select-location']")) | |
| ) | |
| Select(dropdown).select_by_visible_text("Vancouver") | |
| except TimeoutException: | |
| return None | |
| # Check if any of the target job titles appear in the page source. | |
| page_text = driver.page_source.lower() | |
| found = any(job.lower() in page_text for job in target_jobs) | |
| if found: | |
| return (company['name'], company['url']) | |
| except Exception: | |
| return None | |
| finally: | |
| driver.quit() | |
| return None | |
| def run_job_search(): | |
| chrome_options = Options() | |
| chrome_options.add_argument("--headless") | |
| chrome_options.add_argument("--disable-gpu") | |
| chrome_options.add_argument("--no-sandbox") | |
| chrome_options.add_argument("--disable-dev-shm-usage") | |
| chrome_options.add_argument("--ignore-certificate-errors") | |
| chrome_options.add_argument("--log-level=3") | |
| chrome_options.add_experimental_option('excludeSwitches', ['enable-logging']) | |
| chrome_options.page_load_strategy = 'eager' | |
| # Set the binary location for Chromium. | |
| chrome_options.binary_location = "/usr/bin/chromium" | |
| results = [] | |
| with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor: | |
| futures = [] | |
| for company in companies: | |
| futures.append(executor.submit(check_company, company, chrome_options)) | |
| for future in as_completed(futures): | |
| result = future.result() | |
| if result: | |
| results.append(result) | |
| # Build an HTML output with clickable links. | |
| if results: | |
| html = "<h3>Companies with open positions:</h3><ul>" | |
| for name, url in sorted(results, key=lambda x: x[0]): | |
| html += f'<li><a href="{url}" target="_blank">{name}</a></li>' | |
| html += "</ul>" | |
| else: | |
| html = "<p>No matching job listings found.</p>" | |
| return html | |
| # Define a simple Gradio interface. | |
| demo = gr.Interface( | |
| fn=run_job_search, | |
| inputs=[], | |
| outputs=gr.HTML(label="Job Search Results"), | |
| title="FX Artist/FX TD Vancouver Job Search", | |
| description="Click the button below to search for FX job openings across multiple companies, all located in Vancouver." | |
| ) | |
| if __name__ == "__main__": | |
| # To create a public link, set share=True. | |
| demo.launch(share=True) | |