164 lines
6.1 KiB
Python
164 lines
6.1 KiB
Python
"""
|
|
Workflow to accept bulk import jobs automatically.
|
|
|
|
This script automates the process of accepting import jobs by:
|
|
1. Navigating to the bulk import management page
|
|
2. Clicking the "View Results" button for the first import job
|
|
3. Finding and clicking "Update Part" buttons (only those without 'disabled' class)
|
|
4. Clicking Save twice and Complete for each job (same page, no tabs)
|
|
5. Repeating until all jobs are processed
|
|
"""
|
|
|
|
import time
|
|
from selenium.webdriver.common.by import By
|
|
from config import PARTDB_BASE, UI_LANG_PATH, HEADLESS_CONTROLLER
|
|
from provider.selenium_flow import (
|
|
start_firefox_resilient,
|
|
ensure_logged_in,
|
|
accept_bulk_import_jobs
|
|
)
|
|
|
|
|
|
def run_accept_import_jobs(job_url: str = None, auto_close: bool = False):
|
|
"""
|
|
Main function to accept bulk import jobs.
|
|
|
|
Args:
|
|
job_url: Optional URL to the specific import job page.
|
|
If None, uses the default bulk import management page.
|
|
auto_close: If True, automatically closes the browser after completion.
|
|
If False, waits for user input before closing.
|
|
"""
|
|
print("=== Starting Bulk Import Job Acceptance ===\n")
|
|
|
|
# Default to the bulk import management page
|
|
if job_url is None:
|
|
job_url = PARTDB_BASE + "/en/tools/bulk_info_provider_import/manage"
|
|
|
|
# Start browser
|
|
driver = start_firefox_resilient(headless_first=HEADLESS_CONTROLLER)
|
|
|
|
try:
|
|
# Navigate to base URL and login
|
|
driver.get(PARTDB_BASE + "/")
|
|
|
|
if not ensure_logged_in(driver, PARTDB_BASE, interactive_ok=True, wait_s=600):
|
|
print("Could not login; aborting.")
|
|
return
|
|
|
|
print("Login successful!\n")
|
|
|
|
# Navigate to the bulk import management page
|
|
print(f"Navigating to: {job_url}")
|
|
driver.get(job_url)
|
|
time.sleep(2.0)
|
|
|
|
# Find and click the first "View Results" button for an ACTIVE job
|
|
print("Looking for 'View Results' button on active job...")
|
|
try:
|
|
view_results_button = None
|
|
|
|
# Find all table rows
|
|
rows = driver.find_elements(By.XPATH, "//tbody/tr")
|
|
|
|
for row in rows:
|
|
try:
|
|
# Check if this row has an "Active" badge or "In Progress" status
|
|
badges = row.find_elements(By.XPATH, ".//span[contains(@class, 'badge')]")
|
|
is_active = False
|
|
|
|
for badge in badges:
|
|
badge_text = badge.text.strip().lower()
|
|
if 'active' in badge_text or 'in progress' in badge_text:
|
|
is_active = True
|
|
break
|
|
|
|
# If this row is active, find its "View Results" button
|
|
if is_active:
|
|
view_btn = row.find_elements(By.XPATH, ".//a[contains(@class, 'btn') and contains(., 'View Results')]")
|
|
if view_btn:
|
|
view_results_button = view_btn[0]
|
|
print(f"Found active job with 'View Results' button")
|
|
break
|
|
except Exception as e:
|
|
continue
|
|
|
|
# Fallback: if no active job found, just get the first View Results button
|
|
if not view_results_button:
|
|
print("No active job found, looking for any 'View Results' button...")
|
|
xpaths = [
|
|
"//a[contains(@class, 'btn') and contains(., 'View Results')]",
|
|
"//a[contains(@href, '/bulk_info_provider_import/step2/') and contains(@class, 'btn-primary')]",
|
|
]
|
|
|
|
for xpath in xpaths:
|
|
elements = driver.find_elements(By.XPATH, xpath)
|
|
if elements:
|
|
view_results_button = elements[0]
|
|
break
|
|
|
|
if view_results_button:
|
|
print(f"Clicking 'View Results' button...")
|
|
driver.execute_script("arguments[0].scrollIntoView({block:'center'});", view_results_button)
|
|
time.sleep(0.5)
|
|
view_results_button.click()
|
|
time.sleep(2.0)
|
|
print("✓ Navigated to results page")
|
|
else:
|
|
print("Could not find 'View Results' button. Make sure there's an import job to process.")
|
|
if not auto_close:
|
|
print("Press Enter to close...")
|
|
input()
|
|
return
|
|
except Exception as e:
|
|
print(f"Error clicking 'View Results': {e}")
|
|
if not auto_close:
|
|
print("Press Enter to close...")
|
|
input()
|
|
return
|
|
|
|
# Run the automation
|
|
print("\nStarting automation...")
|
|
print("=" * 70)
|
|
successful, failed, skipped = accept_bulk_import_jobs(
|
|
driver,
|
|
PARTDB_BASE,
|
|
UI_LANG_PATH,
|
|
job_url=None, # Already on the page
|
|
max_iterations=100
|
|
)
|
|
|
|
print("\n" + "=" * 60)
|
|
print("AUTOMATION COMPLETE")
|
|
print(f"Successfully processed: {successful} jobs")
|
|
print(f"Failed: {failed} jobs")
|
|
print(f"Skipped (no results): {skipped} jobs")
|
|
print("=" * 60)
|
|
|
|
# Keep browser open for inspection if not auto_close
|
|
if not auto_close:
|
|
print("\nBrowser will remain open for inspection.")
|
|
print("Press Enter to close...")
|
|
input()
|
|
|
|
except Exception as e:
|
|
print(f"\nError during automation: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
if not auto_close:
|
|
print("\nPress Enter to close...")
|
|
input()
|
|
|
|
finally:
|
|
try:
|
|
driver.quit()
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# You can optionally provide a direct URL to the import job page
|
|
# Example: run_accept_import_jobs("https://partdb.neutronservices.duckdns.org/en/import/jobs/123")
|
|
run_accept_import_jobs()
|