From d523c0095de154cbed899ca0dc038ce52e8ee024 Mon Sep 17 00:00:00 2001 From: Atharv Phadnis Date: Thu, 27 Apr 2023 19:22:19 +0530 Subject: [PATCH 1/2] Added script to add deprecation notice in README Signed-off-by: Atharv Phadnis --- deprecation_notice/README.md | 14 ++++ deprecation_notice/README.mustache | 6 ++ deprecation_notice/input_list.csv | 3 + deprecation_notice/ra_main.py | 97 ++++++++++++++++++++++++++++ deprecation_notice/requirements.txt | Bin 0 -> 632 bytes 5 files changed, 120 insertions(+) create mode 100644 deprecation_notice/README.md create mode 100644 deprecation_notice/README.mustache create mode 100644 deprecation_notice/input_list.csv create mode 100644 deprecation_notice/ra_main.py create mode 100644 deprecation_notice/requirements.txt diff --git a/deprecation_notice/README.md b/deprecation_notice/README.md new file mode 100644 index 0000000..a2491d1 --- /dev/null +++ b/deprecation_notice/README.md @@ -0,0 +1,14 @@ +# Add Deprecation Notice to README on IBMCOM + +## Setup + +1. Download [chromedriver](https://sites.google.com/chromium.org/driver/) for Google Chrome/Chromium based browsers +2. Create a virtual environment for Python: `python -m venv venv` +3. Activate the virtual environment: `.\venv\Scripts\activate` +4. Modify the template `README.mustache` with [mustache](https://mustache.github.io/) templating (if required) + +## Usage +1. Run the script `python ra_main.py` +2. Enter Docker Hub **Username** as well as **Password** as prompted +3. Enter the Absolute Browser path for Chromium-based browsers like _Edge, Brave_. Enter nothing if using _Google Chrome_ +4. Enter Input CSV file path if we need to update specific READMEs, empty if we need to update all diff --git a/deprecation_notice/README.mustache b/deprecation_notice/README.mustache new file mode 100644 index 0000000..07cfc18 --- /dev/null +++ b/deprecation_notice/README.mustache @@ -0,0 +1,6 @@ +# Deprecation Notice + +This repository will no longer be maintained. +{{#image}} +Images will be further maintained on ICR. You can pull the same by using the command: `docker pull {{image}}:` +{{/image}} diff --git a/deprecation_notice/input_list.csv b/deprecation_notice/input_list.csv new file mode 100644 index 0000000..c393f50 --- /dev/null +++ b/deprecation_notice/input_list.csv @@ -0,0 +1,3 @@ +name,image +test-repo, +alpine_python_hello,icr.io/ppc64le-oss/alpine_python_hello \ No newline at end of file diff --git a/deprecation_notice/ra_main.py b/deprecation_notice/ra_main.py new file mode 100644 index 0000000..238637c --- /dev/null +++ b/deprecation_notice/ra_main.py @@ -0,0 +1,97 @@ +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.common.exceptions import TimeoutException +import chevron +import getpass +import csv + +REPOSITORY = "ibmcom" +TIMEOUT = 10 + +class ReadmeAutomation: + def __init__(self, browser) -> None: + options = None + if browser: + options = webdriver.ChromeOptions() + options.binary_location = browser + self.browser = webdriver.Chrome(options=options) + + def login_to_dockerhub(self, user, pswd) -> None: + self.browser.get("https://login.docker.com/u/login") + username = self.browser.find_element(By.NAME, "username") + username.clear() + username.send_keys(user) + username.send_keys(Keys.RETURN) + password = self.browser.find_element(By.NAME, "password") + password.clear() + password.send_keys(pswd) + password.send_keys(Keys.RETURN) + + def get_repositories_urls(self) -> list: + self.browser.get(f"https://hub.docker.com/repositories/{REPOSITORY}") + try: + repos = WebDriverWait(self.browser, TIMEOUT).until( + EC.presence_of_all_elements_located((By.XPATH, "//a[@data-testid='repositoryRowLink']")) + ) + return [ { + 'url': repo.get_attribute("href"), + 'image': f'icr.io/ppc64le-oss/{repo.get_attribute("href").split("/")[-1]}' + } for repo in repos + ] + except TimeoutException: + print("Failed to get repositories") + + def accept_cookie_consent(self) -> None: + try: + cookies = WebDriverWait(self.browser, TIMEOUT).until( + EC.element_to_be_clickable((By.ID, "onetrust-accept-btn-handler")) + ) + cookies.click() + except TimeoutException: + print("Cookie consent dialogue not found, skipping consent") + + def update_readme(self, input_file) -> None: + self.accept_cookie_consent() # Required to avoid obstruction of button visibility + with open('README.mustache', 'r') as template: + if input_file: + with open(input_file) as csv_file: + repos = [] + for row in csv.DictReader(csv_file): + repos.append({ + 'url': f'https://hub.docker.com/repository/docker/{REPOSITORY}/{row["name"]}', + 'image': row["image"] + }) + else: + repos = self.get_repositories_urls() + for repo in repos: + self.browser.get(repo["url"]) + try: + edit = WebDriverWait(self.browser, TIMEOUT).until( + EC.element_to_be_clickable((By.XPATH, "//button[@data-testid='editRepoReadme']")) + ) + edit.click() + textarea = self.browser.find_element(By.TAG_NAME, "textarea") + textarea.clear() + readme = chevron.render(template, { + # Add any variables defined inside template here in key:value pairs + # key = variable name in template + # value = data to be replaced in generated README + 'image': repo["image"] + }) + textarea.send_keys(readme) + update = self.browser.find_element(By.XPATH, "//button[text()='Update']") + update.click() + except TimeoutException: + print(f'Failed to update README for {repo["url"]}') + +if __name__ == "__main__": + user = input("Enter Docker Hub Username: ") + pswd = getpass.getpass("Enter Docker Hub Password: ") + browser = input("Chromium-based browser binary path (Empty if browser is Chrome): ") + input_file = input("Input CSV file (Empty if running on whole repository): ") + ra = ReadmeAutomation(browser=browser) + ra.login_to_dockerhub(user=user, pswd=pswd) + ra.update_readme(input_file=input_file) diff --git a/deprecation_notice/requirements.txt b/deprecation_notice/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..6294dda349b0412b4036246fce863f692ca26be5 GIT binary patch literal 632 zcmZvZQBK1!5Jcx2iK7%XNlW?R4wX1TYD^nZlBh{&xjgW8jgub~tzvm+XJ*Gg-?avP zsa4QQM@3Fi7u6co@qgwk^gyk3uRFgVxgWe!s-$O?y1{2hHF~3Lwxp9#h2wV466j|{ zV&A%kDFmHh`9!0`i*c;Ix0zLA`hyEE_B-{sLGhTHOEu literal 0 HcmV?d00001 From 121c3d7a0d7cf2da69c2ec8dbad1082ddaffd37d Mon Sep 17 00:00:00 2001 From: Atharv Phadnis Date: Thu, 27 Apr 2023 19:38:25 +0530 Subject: [PATCH 2/2] Added wait after logging in Signed-off-by: Atharv Phadnis --- deprecation_notice/ra_main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deprecation_notice/ra_main.py b/deprecation_notice/ra_main.py index 238637c..d5eb957 100644 --- a/deprecation_notice/ra_main.py +++ b/deprecation_notice/ra_main.py @@ -29,6 +29,9 @@ def login_to_dockerhub(self, user, pswd) -> None: password.clear() password.send_keys(pswd) password.send_keys(Keys.RETURN) + WebDriverWait(self.browser, TIMEOUT).until( + EC.presence_of_element_located((By.XPATH, "//span[@data-testid='navBarUsernameDropdown']")) + ) def get_repositories_urls(self) -> list: self.browser.get(f"https://hub.docker.com/repositories/{REPOSITORY}")