114 lines
4.4 KiB
Python
Executable File
114 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
from selenium import webdriver
|
|
import click
|
|
from dotenv import load_dotenv
|
|
import time
|
|
from os import path
|
|
from typing import Optional
|
|
|
|
from selenium.webdriver.firefox.options import Options
|
|
from selenium.webdriver.remote.webdriver import WebDriver
|
|
from selenium.webdriver.remote.webelement import WebElement
|
|
from selenium.common.exceptions import NoSuchElementException, TimeoutException
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.common.by import By
|
|
|
|
load_dotenv()
|
|
|
|
LOGIN_URL = "https://moodle.ktu.edu/login/index.php"
|
|
EDIT_ASSIGNMENT_URL = "https://moodle.ktu.edu/mod/assign/view.php?id={id}&action=editsubmission"
|
|
|
|
DEFAULT_TIMEOUT = 5
|
|
|
|
def create_driver() -> WebDriver:
|
|
options = Options()
|
|
options.headless = True
|
|
return webdriver.Firefox(options=options)
|
|
|
|
def waited_find_element(
|
|
driver: WebDriver,
|
|
by: str,
|
|
value: str,
|
|
timeout: int = DEFAULT_TIMEOUT
|
|
) -> Optional[WebElement]:
|
|
try:
|
|
return WebDriverWait(driver, timeout).until(EC.presence_of_element_located((by, value)))
|
|
except TimeoutException:
|
|
return None
|
|
|
|
def waited_find_elements(
|
|
driver: WebDriver,
|
|
by: str,
|
|
value: str,
|
|
timeout: int = DEFAULT_TIMEOUT
|
|
) -> list[WebElement]:
|
|
try:
|
|
return WebDriverWait(driver, timeout).until(EC.presence_of_all_elements_located((by, value)))
|
|
except TimeoutException:
|
|
return []
|
|
|
|
def assert_element(
|
|
error_msg: str,
|
|
driver: WebDriver,
|
|
by: str,
|
|
value: str,
|
|
timeout: int = DEFAULT_TIMEOUT
|
|
) -> WebElement:
|
|
element = waited_find_element(driver, by, value, timeout)
|
|
if not element:
|
|
raise NoSuchElementException(error_msg)
|
|
return element
|
|
|
|
def login(driver: WebDriver, username: str, password: str):
|
|
driver.get(LOGIN_URL)
|
|
|
|
assert_element("Failed to select username field", driver, By.ID, "username").send_keys(username)
|
|
assert_element("Failed to select password field", driver, By.ID, "password").send_keys(password)
|
|
assert_element("Failed to select login submit button", driver, By.XPATH, "//input[@type='submit']").click()
|
|
|
|
assert_element("Failed to select yes button in login", driver, By.ID, "yesbutton").click()
|
|
time.sleep(1)
|
|
|
|
def upload_file_to_assignment(driver: WebDriver, assignment_id: str, filename: str, upload_filename: str):
|
|
if not upload_filename:
|
|
upload_filename = path.basename(filename)
|
|
|
|
driver.get(EDIT_ASSIGNMENT_URL.format(id=assignment_id))
|
|
|
|
# Check if files exists in assignment
|
|
for file_elem in waited_find_elements(driver, By.XPATH, "//*[contains(@class, 'fp-file')]/*[contains(@class, 'd-block')]"):
|
|
# If it does, delete it
|
|
time.sleep(1)
|
|
file_elem.click()
|
|
assert_element("Failed to press delete file button", driver, By.CLASS_NAME, "fp-file-delete").click()
|
|
assert_element("Failed to press confirm deletion file button", driver, By.CLASS_NAME, "fp-dlg-butconfirm").click()
|
|
time.sleep(1)
|
|
|
|
assert_element("Failed to click on file manager", driver, By.CLASS_NAME, "dndupload-arrow").click()
|
|
assert_element("Failed to select file upload from computer", driver, By.XPATH, "//*[contains(@class, 'fp-repo-area')]/*[contains(@class, 'fp-repo')][2]").click()
|
|
assert_element("Failed to specify upload file", driver, By.XPATH, "//input[@type='file']").send_keys(path.abspath(filename))
|
|
assert_element("Failed to specify uploaded files name", driver, By.XPATH, "//input[@name='title']").send_keys(upload_filename)
|
|
assert_element("Failed to press upload file button", driver, By.CLASS_NAME, "fp-upload-btn").click()
|
|
time.sleep(1)
|
|
|
|
assert_element("Failed to press submit files button", driver, By.ID, "id_submitbutton").click()
|
|
|
|
@click.command()
|
|
@click.argument("assignment")
|
|
@click.argument("filename", type=click.Path(exists=True, readable=True, dir_okay=False))
|
|
@click.argument("upload_filename", required=False, type=click.Path())
|
|
@click.option("--username", "-u", required=True, envvar="KTU_USERNAME")
|
|
@click.option("--password", "-p", required=True, envvar="KTU_PASSWORD")
|
|
def main(assignment, filename, upload_filename, username, password):
|
|
driver = create_driver()
|
|
|
|
login(driver, username, password)
|
|
upload_file_to_assignment(driver, assignment, filename, upload_filename)
|
|
|
|
driver.close()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|