diff --git a/.gitignore b/.gitignore index 6709bc7..ffbf00f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # THIS PROJECT **/*test* -config.yml -VNULIB-DOWNLOADER/ +**/*log* +VNULIB-Downloader/config.yml Profiles/ **/__pycache__ diff --git a/config-sample.yml b/VNULIB-Downloader/config-sample.yml similarity index 100% rename from config-sample.yml rename to VNULIB-Downloader/config-sample.yml diff --git a/docs/README.md b/docs/README.md index 020e216..0bcedfd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -111,7 +111,7 @@ Python CLI tool download sách từ VNULIB ### 🗃️ Pre-config -1. Tạo file `config.yml` trong directory chứa file thực thi bằng 1 trong 2 cách: +1. Tạo file `config.yml` trong directory `VNULIB-Downloader` bằng 1 trong 2 cách: - Chạy trước tool 1 lần sẽ tự tạo file `config.yml` - Copy nội dung của file [`config-sample.yml`](../config-sample.yml) và paste vào file `config.yml` 2. Chỉnh các giá trị biến trong file `config.yml` diff --git a/main.py b/main.py index 6082df5..29843da 100644 --- a/main.py +++ b/main.py @@ -1,22 +1,21 @@ -"""VNULIB Downloader""" +"""VNULIB Downloader +""" from pprint import pformat from src import (Browser, Login, Action, - PrintIntro, - ToolConfig, UserOptions, LinkParse, + PrintIntro, Config, UserOptions, LinkParse, print_title, logger) -from src.constants import CONFIG_FILE, CONFIG_FILE_URL def main() -> None: - """Main function to run VNULIB Downloader""" + """Main function to run VNULIB Downloader + """ PrintIntro().print_intro() print_title(message='SETUP') - ToolConfig( - config_file_name=CONFIG_FILE, url=CONFIG_FILE_URL).setup() + Config().setup() user_options = UserOptions() user_options.setup() @@ -33,7 +32,7 @@ def main() -> None: user_options.links = LinkParse(links=user_options.links).parse() user_options.links = Action(driver=driver, links=user_options.links).action() - logger.debug(msg='LINKS AFTER PARSING:\n' + logger.debug(msg='LINKS OBJECT:\n' f'{pformat(user_options.links)}') print_title(message='DOWNLOAD') diff --git a/src/__init__.py b/src/__init__.py index 6747e7d..d1f87e6 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,7 +1,8 @@ -"""Contains classes, function, object to be imported in main""" +"""Contains classes, function, object to be imported in main +""" from .bot import Browser, Login, Action -from .modules import PrintIntro, ToolConfig, UserOptions, LinkParse +from .modules import PrintIntro, Config, UserOptions, LinkParse from .modules import setup_argparse from .utils import logger, print_title diff --git a/src/bot/action.py b/src/bot/action.py index 44a4aca..5aedf8b 100644 --- a/src/bot/action.py +++ b/src/bot/action.py @@ -1,4 +1,5 @@ -"""Contains Bot actions: Book website -> Book preview -> Book page link""" +"""Contains Bot actions: Book website -> Book preview -> Book page link +""" from urllib.parse import urlparse, urlunparse, parse_qs, urlencode @@ -7,16 +8,15 @@ from selenium.webdriver.remote.webelement import WebElement from ..modules.link_parse import Link, LinkFile from .utils import wait_element_visible -from ..utils import logger -from ..utils.utils import datetime_name, slugify +from ..utils import logger, datetime_name, slugify class Action: - """Bot actions for the bot to perform + """Bot actions to process links - Params: + Args: - driver (WebDriver): Selenium WebDriver - - links (list[Link]): List of links to process + - links (list[Link]): List of links object """ def __init__(self, driver: WebDriver, links: list[Link]) -> None: @@ -27,7 +27,7 @@ def __init__(self, driver: WebDriver, links: list[Link]) -> None: def remove_page_query(link: str) -> str: """Parse the link to remove "page" query - Params: + Args: - link (str): Link to parse Returns: @@ -44,27 +44,27 @@ def remove_page_query(link: str) -> str: @staticmethod def __book_preview_to_page(link: str) -> str: - """Book preview link to book page link and return number of pages + """Book preview link to book page link - Params: + Args: - link (str): Book preview link Returns: - - list[str]: Book page link + - str: Book page link without "page" query """ parser = urlparse(link) query = parse_qs(parser.query) subfolder_value: str = query.get('subfolder', '')[0] doc_value: str = query.get('doc', '')[0] - page_link: str = f'https: // ir.vnulib.edu.vn/flowpaper/services/view.php?doc = { - doc_value} & format = jpg & subfolder = {subfolder_value}' + page_link: str = f'https//ir.vnulib.edu.vn/flowpaper/services/view.php?doc={ + doc_value}&format =jpg&subfolder={subfolder_value}' return page_link @staticmethod def __get_num_pages(driver: WebDriver) -> int: - """Get number of pages from book preview link + """Get number of pages from book preview link, aready in book preview link - Params: + Args: - driver (WebDriver): Selenium WebDriver Returns: @@ -75,10 +75,9 @@ def __get_num_pages(driver: WebDriver) -> int: return int(pages) def book_preview_to_page_and_book_pages(self, link: str) -> tuple[str, int]: - """Book preview link to book page link and return number of pages + """Book preview link to book page link and get number of pages - Params: - - driver (WebDriver): Selenium WebDriver + Args: - link (str): Book preview link Returns: @@ -96,7 +95,7 @@ def book_preview_to_page_and_book_pages(self, link: str) -> tuple[str, int]: def book_web_to_preview(self, link: str) -> list[str]: """Book website link to book preview link - Params: + Args: - link (str): Book website link Returns: @@ -112,13 +111,13 @@ def book_web_to_preview(self, link: str) -> list[str]: if preview_link is not None: preview_links.append(preview_link) logger.info(msg=f'Found {len(preview_links)} ' - f'preview link(s) for {link}') + f'preview link(s) for \'{link}\'') return preview_links def get_book_files_name(self) -> list[str]: """Get book's files' name from the book website (Already in book website) - Params: + Args: - None Returns: @@ -133,11 +132,11 @@ def get_book_files_name(self) -> list[str]: def process_book(self, link: Link) -> Link: """Process book link handler - Params: - - link (Link): Current link + Args: + - link (Link): Current link object Returns: - - Link: Processed link + - Link: Processed link object """ preview_links: list[str] = self.book_web_to_preview( link=link.original_link) @@ -156,11 +155,11 @@ def process_book(self, link: Link) -> Link: def process_preview(self, link: Link) -> Link: """Process preview link handler - Params: - - link (Link): Current link + Args: + - link (Link): Current link object Returns: - - Link: Processed link + - Link: Processed link object """ page_link, num_pages = self.book_preview_to_page_and_book_pages( link=link.original_link) @@ -171,11 +170,11 @@ def process_preview(self, link: Link) -> Link: def process_page(self, link: Link) -> Link: """Process page link handler - Params: - - link (Link): Current link + Args: + - link (Link): Current link object Returns: - - Link: Processed link + - Link: Processed link object """ page_link: str = Action.remove_page_query(link=link.original_link) link.files = [LinkFile( @@ -185,13 +184,16 @@ def process_page(self, link: Link) -> Link: def action(self) -> list[Link]: """Convert all links to the page links format + Args: + - None + Returns: - - list: A list contains converted links to page links format + - list[Link]: A list processed links object """ converted_links: list[Link] = [] for link in self.links: - logger.info(msg=f'Processing {link.original_link} as { - link.original_type}') + logger.info(msg=f'Processing \'{link.original_link}\' ' + f'as \'{link.original_type}\'') match link.original_type: case 'book': converted_links.append( diff --git a/src/bot/browser.py b/src/bot/browser.py index 9f1eac0..62f6ef1 100644 --- a/src/bot/browser.py +++ b/src/bot/browser.py @@ -1,4 +1,5 @@ -"""Setup Selenium Browser""" +"""Setup Selenium Browser +""" from selenium import webdriver @@ -14,7 +15,12 @@ class Browser: - """Setup Selenium Browser""" + """Setup Selenium Browser + + Args: + - browser (str): The browser to setup + - headless (bool): Headless mode + """ def __init__(self, browser: str, headless: bool) -> None: self.browser: str = browser @@ -23,7 +29,11 @@ def __init__(self, browser: str, headless: bool) -> None: self.driver: WebDriver def __enter__(self) -> WebDriver: - """Setup the browser""" + """Setup the browser when entering the context manager + + Returns: + - WebDriver: Selenium WebDriver + """ logger.info(msg='Setting up the browser...') self.__setup_arguments() match self.browser: @@ -32,15 +42,18 @@ def __enter__(self) -> WebDriver: case _: self.driver = self.__setup_local_chrome_browser() self.driver.implicitly_wait(30) - logger.info(msg=f'Browser {self.browser} setup complete!') + logger.info(msg=f'Browser \'{self.browser}\' setup complete!') return self.driver def __exit__(self, exc_type, exc_value, traceback) -> None: + """Exit the context manager + """ logger.info(msg='Quit the browser') self.driver.quit() def __setup_arguments(self) -> None: - """Setup the browser arguments""" + """Setup the browser arguments + """ for argument in BROWSER_ARGUMENTS: self.options.add_argument(argument) if self.headless: @@ -50,11 +63,19 @@ def __setup_arguments(self) -> None: ) def __setup_chrome_browser(self) -> WebDriver: - """Setup Chrome Browser""" + """Setup Chrome Browser + + Returns: + - WebDriver: Selenium WebDriver + """ return webdriver.Chrome( options=self.options, service=ChromeService(ChromeDriverManager().install())) def __setup_local_chrome_browser(self) -> WebDriver: - """Setup Local Chrome Browser""" + """Setup Local Chrome Browser + + Returns: + - WebDriver: Selenium WebDriver + """ return webdriver.Chrome(options=self.options, service=ChromeService(self.browser)) diff --git a/src/bot/login.py b/src/bot/login.py index 13d085a..b799205 100644 --- a/src/bot/login.py +++ b/src/bot/login.py @@ -1,5 +1,5 @@ -"""Use Selenium to login to the website""" - +"""Use Selenium to login to the website +""" from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.remote.webelement import WebElement @@ -10,7 +10,13 @@ class Login: - """Login to the website""" + """Login to the VNULIB website + + Args: + - driver (WebDriver): Selenium WebDriver + - username (str): Username + - password (str): Password + """ def __init__(self, driver: WebDriver, username, password) -> None: @@ -20,20 +26,19 @@ def __init__(self, driver: WebDriver, self.url = LOGIN_URL def __fill_in(self) -> None: - """Fill in the login form""" - # username_field: WebElement = wait_element_visible( - # driver=self.driver, css_selector='.form-control[name="username"]') - # password_field: WebElement = wait_element_visible( - # driver=self.driver, css_selector='.form-control[name="password"]') + """Fill in the login form + """ self.driver.find_element( By.CSS_SELECTOR, '.form-control[name="username"]').send_keys(self.username) self.driver.find_element( By.CSS_SELECTOR, '.form-control[name="password"]').send_keys(self.password) - # username_field.send_keys(self.username) - # password_field.send_keys(self.password) def login(self) -> None: - """Login to the website""" + """Login to VNULIB website + + Raises: + ConnectionError: Login failed + """ logger.info(msg='Logging in...') self.driver.get(self.url) submit_button: WebElement = wait_element_clickable( @@ -44,4 +49,4 @@ def login(self) -> None: logger.info(msg='Logged in successfully!') else: logger.error(msg='Login failed!') - raise Exception('Login failed!') + raise ConnectionError('Login failed!') diff --git a/src/bot/utils.py b/src/bot/utils.py index 77ccb32..859f810 100644 --- a/src/bot/utils.py +++ b/src/bot/utils.py @@ -1,4 +1,5 @@ -"""Utils for Bot""" +"""Utils for Bot +""" from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.support.wait import WebDriverWait @@ -13,7 +14,7 @@ def wait_element_visible(driver: WebDriver, css_selector: str) -> WebElement: """Wait for the element to be visible in DOM - Params: + Args: - driver (WebDriver): Selenium WebDriver - css_selector (str): CSS selector @@ -28,7 +29,7 @@ def wait_element_visible(driver: WebDriver, css_selector: str) -> WebElement: def wait_element_clickable(driver: WebDriver, css_selector: str) -> WebElement: """Wait for the element to be clickable - Params: + Args: - driver (WebDriver): Selenium WebDriver - css_selector (str): CSS selector diff --git a/src/constants.py b/src/constants.py index 23a98d3..050856b 100644 --- a/src/constants.py +++ b/src/constants.py @@ -1,4 +1,5 @@ -"""Constant variables throughout the program""" +"""Constant variables throughout the program +""" VERSION: str = '0.8-beta' @@ -19,9 +20,10 @@ ╚═════╝ ╚═════╝ ╚══╝╚══╝ ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝ """ REPOSITORY_URL: str = 'https://github.com/KevinNitroG/VNULIB-Downloader' -CONFIG_FILE: str = 'config.yml' -CONFIG_FILE_URL: str = 'https://raw.githubusercontent.com/KevinNitroG/VNULIB-Downloader/main/config-sample.yml' -LOGGING_FILE: str = 'src/logging_configuration.yml' +CONFIG_FILE: str = 'VNULIB-Downloader/config.yml' +CONFIG_FILE_URL: str = 'https://raw.githubusercontent.com/KevinNitroG/VNULIB-Downloader/main/VNULIB-Downloader/config-sample.yml' +LOGGING_CONFIG_FILE: str = 'src/logging_configuration.yml' +LOGGING_DIR: str = 'VNULIB-Downloader/logs' DOWNLOAD_DIR: str = 'VNULIB-DOWNLOADER/Downloads' LOGGER_MODE: list[str] = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'] USER_INPUT_YES: list[str] = ['Y', 'YES', '', '1'] diff --git a/src/modules/__init__.py b/src/modules/__init__.py index 03c352d..94c59e8 100644 --- a/src/modules/__init__.py +++ b/src/modules/__init__.py @@ -1,7 +1,7 @@ """Modules""" -from .config import ToolConfig +from .config import Config from .print_intro import PrintIntro from .user_options import UserOptions from .link_parse import LinkParse diff --git a/src/modules/argpase.py b/src/modules/argpase.py index 38e3da6..bd94bbb 100644 --- a/src/modules/argpase.py +++ b/src/modules/argpase.py @@ -1,4 +1,5 @@ -"""Argparse for VNULIB-DOWNLOADER""" +"""Argparse for VNULIB-Downloader +""" from argparse import ArgumentParser, Namespace @@ -7,11 +8,8 @@ def setup_argparse() -> Namespace: """Parse the arguments - Params: - - None - Returns: - - None + - Namespace: The parsed arguments """ parser = ArgumentParser() parser.add_argument('--username', '-u', type=str, diff --git a/src/modules/config.py b/src/modules/config.py index 1e27fe4..94b17ff 100644 --- a/src/modules/config.py +++ b/src/modules/config.py @@ -1,29 +1,31 @@ -"""Setup config file for VNULIB-DOWNLOADER""" +"""Setup pre config file for VNULIB-Downloader +""" from os import path from requests import get -from src.utils.logger import logger +from ..utils import logger +from ..constants import CONFIG_FILE, CONFIG_FILE_URL -class ToolConfig(): +class Config(): """Setup tool config file - Params: - - config_file_name (str): The config file name + Args: + - config_file (str): The config file name - url (str): The link of the raw config file """ - def __init__(self, config_file_name: str, url: str) -> None: - self.config_file_name: str = config_file_name + def __init__(self, config_file: str = CONFIG_FILE, url: str = CONFIG_FILE_URL) -> None: + self.config_file: str = config_file self.url: str = url - def __download_config_file(self) -> None: - """Download the config file file from repository""" - logger.info(msg=f'Downloading { - self.config_file_name} from repository.' - ' Don\'t worry it will downloade once') - with open(file=self.config_file_name, mode='w', encoding='utf-8') as file: + def download_config_file(self) -> None: + """Download the config file file from repository + """ + logger.info(msg=f'Downloading \'{self.config_file}\' from repository.' + ' It will download once') + with open(file=self.config_file, mode='w', encoding='utf-8') as file: try: content = get( url=self.url, @@ -36,20 +38,22 @@ def __download_config_file(self) -> None: 'Please check the connection or the source of the repo and try again.') else: file.write(content) - logger.info(msg='Downloaded config file successfully') + logger.info(msg='Downloaded config file successfully at ' + f'\'{self.config_file}\'') - def __check_exist_config_file(self) -> bool: + def check_exist_config_file(self) -> bool: """Check if the config file exists or not Returns: - bool: True if the config file exists, False otherwise """ - if path.exists(path=self.config_file_name): + if path.exists(path=self.config_file): return True - logger.info(msg=f'{self.config_file_name} does not exist') + logger.info(msg=f'{self.config_file} does not exist') return False def setup(self) -> None: - """Prepare the config file for the project""" - if not self.__check_exist_config_file(): - self.__download_config_file() + """Prepare the config file for the project + """ + if not self.check_exist_config_file(): + self.download_config_file() diff --git a/src/modules/create_pdf.py b/src/modules/create_pdf.py index 55520ce..edb9b33 100644 --- a/src/modules/create_pdf.py +++ b/src/modules/create_pdf.py @@ -1,8 +1,16 @@ -"""Merge the images of books into PDF files""" +"""Merge the images of books into PDF files +""" + + +from .link_parse import LinkFile, Link class CreatePDF: - """Merge the images of books into PDF files""" + """Merge the images of books into PDF files + + Args: + - links (list[Link]): The list of links object + """ - def __init__(self, links: list[dict]) -> None: - pass + def __init__(self, links: list[Link]) -> None: + self.links = links diff --git a/src/modules/download_images.py b/src/modules/download_images.py index 14804ea..0ecca03 100644 --- a/src/modules/download_images.py +++ b/src/modules/download_images.py @@ -1,8 +1,16 @@ -"""Download book's images""" +"""Download book's images +""" + + +from .link_parse import LinkFile, Link class DownloadImages: - """Download book's images""" + """Download book's images + + Args: + - links (list[Link]): The list of links object + """ - def __init__(self, links: list[dict]) -> None: - pass + def __init__(self, links: list[Link]) -> None: + self.links = links diff --git a/src/modules/link_parse.py b/src/modules/link_parse.py index 55da751..14c0fcf 100644 --- a/src/modules/link_parse.py +++ b/src/modules/link_parse.py @@ -1,4 +1,5 @@ -"""Convert parse links to convert all the links to the page links format""" +"""Categorise links, remove invalid links +""" from re import compile as re_compile, search as re_search @@ -16,25 +17,25 @@ class LinkParse: - """Parse links to get the links' information + """Parse links to categorise and remove invalid links - Params: + Args: - links (list[Links]): List of links to parse """ def __init__(self, links: list[Link]) -> None: self.links: list[Link] = links - self.need_to_convert = False + self.need_to_convert: bool = False @staticmethod def categorise(link: str) -> str: - """Categorise the links to the type of links + """Categorise the links using regex - Params: + Args: - link (str): Link to categorise Returns: - - str: 'book', 'preview', 'page' or 'unknown' + - str: 'book', 'preview', 'page' or '' """ if re_search(PATTERN_BOOK, link): return 'book' @@ -42,16 +43,13 @@ def categorise(link: str) -> str: return 'preview' if re_search(PATTERN_PAGE, link): return 'page' - return 'unknown' + return '' def parse(self) -> list[Link]: - """Categorise links into types. With 'page' type, the book atrribute will be set - - Params: - - None + """Categorise links, remvoe invalid links, pre-set for 'page' type links Returns: - - list[Links]: List of categorised links + - list[Links]: List of parsed links object """ modified_links: list[Link] = [] for link in self.links: @@ -72,5 +70,6 @@ def parse(self) -> list[Link]: modified_links.append(link) case _: logger.warning( - msg=f'Unknown link type for: {link.original_link}') + msg='Unknown link type for: ' + f'\'{link.original_link}\'') return modified_links diff --git a/src/modules/print_intro.py b/src/modules/print_intro.py index 3a76652..1f129cd 100644 --- a/src/modules/print_intro.py +++ b/src/modules/print_intro.py @@ -1,4 +1,5 @@ -"""Print out the banner, authors, version""" +"""Print out the banner, authors, version +""" from print_color import print as printColor @@ -8,9 +9,6 @@ class PrintIntro: """Print out the intro - - Params: - - None """ def __init__(self) -> None: @@ -20,12 +18,6 @@ def __init__(self) -> None: def print_intro(self) -> None: """Print the intro including the banner, authors, version - - Params: - - None - - Retuns: - - None """ self.print_banner(lines=self.banner) self.print_authors(authors=self.authors) @@ -36,11 +28,8 @@ def print_intro(self) -> None: def print_banner(lines: list[str]) -> None: """Print out the banner - Params: + Args: - lines (list[str]): List of lines of the banner - - Returns: - - None """ for line in lines: printColor(line.center(TERMINAL_SIZE_COLUMNS), @@ -50,11 +39,8 @@ def print_banner(lines: list[str]) -> None: def print_authors(authors: str) -> None: """Print out the authors - Params: + Args: - authors (str): Authors - - Returns: - - None """ to_print_authors: str = f'\033[94m\033[43m {authors} \033[0m' print(to_print_authors.rjust(TERMINAL_SIZE_COLUMNS)) @@ -63,11 +49,8 @@ def print_authors(authors: str) -> None: def print_version(version: str) -> None: """Print out the version - Params: + Args: - version (str): Version - - Returns: - - None """ to_print_version: str = f'\033[45m\033[44m {version} \033[0m' print(to_print_version.rjust(TERMINAL_SIZE_COLUMNS)) diff --git a/src/modules/user_options.py b/src/modules/user_options.py index bb0109c..88472d4 100644 --- a/src/modules/user_options.py +++ b/src/modules/user_options.py @@ -1,4 +1,5 @@ -"""Setup user input, priority: argparse > config file > user input""" +"""Setup user input, priority: argparse > config file > user input +""" from dataclasses import dataclass @@ -14,7 +15,7 @@ class LinkFile: """Dataclass to store book file's information - Params: + Args: - page_link (str): Page link - num_pages (int): Number of pages - name (str): Name of the file. If original link is preview link, it will be datetime format @@ -28,7 +29,7 @@ class LinkFile: class Link: """Dataclass to store links' information - Params: + Args: - original_link (str): Original link - original_type (str): Original type of the link - files (list[LinkFile]): List of book files from the book @@ -42,9 +43,6 @@ class Link: class UserOptions: """Setup user input - - Params: - - None """ def __init__(self) -> None: @@ -60,7 +58,8 @@ def __init__(self) -> None: self.clean_imgs: bool def setup(self) -> None: - """Setup user options""" + """Setup user options + """ self.username = self.__setup_username() self.password = self.__setup_password() self.links = self.__setup_links() @@ -71,10 +70,16 @@ def setup(self) -> None: self.__log_the_variables() def __log_the_variables(self) -> None: - """Log the variable to log file""" + """Log the variable to log file + """ logger.debug(msg=f'User options:\n{self}') def __str__(self) -> str: + """For debug printing purpose + + Returns: + str: object information + """ return f'Username: {self.username}\n' \ f'Links: {self.links}\n' \ f'Browser: {self.browser}\n' \ @@ -83,7 +88,11 @@ def __str__(self) -> str: f'Clean images: {self.clean_imgs}' def __setup_username(self) -> str: - """Setup username""" + """Setup username + + Returns: + - str: Username + """ if self.argparse.username is not None: self.__log_set_by_argparse('username') return self.argparse.username @@ -94,7 +103,11 @@ def __setup_username(self) -> str: return input('Enter your VNULIB username: ').strip() def __setup_password(self) -> str: - """Setup password""" + """Setup password + + Returns: + - str: Password + """ if self.argparse.password is not None: self.__log_set_by_argparse('password') return self.argparse.password @@ -105,7 +118,11 @@ def __setup_password(self) -> str: return input('Enter your VNULIB password: ').strip() def __setup_links(self) -> list[Link]: - """Setup links""" + """Setup links + + Returns: + - list[Link]: List of links object + """ if self.argparse.link is not None: self.__log_set_by_argparse('links') return [Link(original_link=link, original_type='', files=[LinkFile()]) for link in self.argparse.link] @@ -117,7 +134,11 @@ def __setup_links(self) -> list[Link]: input('Enter link(s), separate by space: ').strip().split(' ')] def __setup_browser(self) -> str: - """Setup browser""" + """Setup browser + + Returns: + - str: Browser + """ if self.argparse.browser is not None: self.__log_set_by_argparse('browser') return self.argparse.browser @@ -129,7 +150,11 @@ def __setup_browser(self) -> str: ' (chrome, chromium, brave, local (chromedriver only)): ').strip() def __setup_headless(self) -> bool: - """Setup headless mode""" + """Setup headless mode + + Returns: + - bool: Headless mode + """ if self.argparse.headless is not None: self.__log_set_by_argparse('headless') return self.argparse.headless @@ -141,7 +166,11 @@ def __setup_headless(self) -> bool: '(no GUI) [Y/n]: ').strip().upper() in USER_INPUT_YES def __setup_create_pdf(self) -> bool: - """Setup links""" + """Setup create pdf + + Returns: + - bool: Create PDF + """ if self.argparse.create_pdf is not None: self.__log_set_by_argparse('create_pdf') return self.argparse.create_pdf @@ -153,7 +182,11 @@ def __setup_create_pdf(self) -> bool: 'after being downloaded [Y/n]: ').strip().upper() in USER_INPUT_YES def __setup_clean_imgs(self) -> bool: - """Setup clean images""" + """Setup clean images + + Returns: + - bool: Clean images + """ if self.argparse.clean_imgs is not None: self.__log_set_by_argparse('clean_imgs') return self.argparse.create_pdf @@ -168,11 +201,8 @@ def __setup_clean_imgs(self) -> bool: def __log_set_by_argparse(var: str) -> None: """Log variable set by argparse - Params: + Args: - var (str): Variable name - - Returns: - - None """ logger.debug(msg=f'Variable: {var} - Set by argparse') @@ -180,11 +210,8 @@ def __log_set_by_argparse(var: str) -> None: def __log_set_by_config(var: str) -> None: """Log variable set by config file - Params: + Args: - var (str): Variable name - - Returns: - - None """ logger.debug(msg=f'Variable: {var} - Set by config file') @@ -192,11 +219,8 @@ def __log_set_by_config(var: str) -> None: def __log_set_by_user_input(var: str) -> None: """Log variable retrieved from user input - Params: + Args: - var (str): Variable name - - Returns: - - None """ logger.debug(msg=f'Variable: {var}' ' - Retrieve from user input') diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 4322fd7..0e6c23a 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -3,3 +3,4 @@ from .prints import print_title from .logger import logger +from .utils import * diff --git a/src/utils/logger.py b/src/utils/logger.py index d222da5..de90c80 100644 --- a/src/utils/logger.py +++ b/src/utils/logger.py @@ -1,4 +1,5 @@ -"""Setup the logger""" +"""Setup the logger +""" import sys @@ -6,20 +7,21 @@ from logging import getLogger, Logger from logging.config import dictConfig from yaml import safe_load -from src.constants import LOGGING_FILE +from src.constants import LOGGING_CONFIG_FILE, LOGGING_DIR -def setup_logger(config_path: str) -> Logger: +def setup_logger(config_path: str, logging_path: str) -> Logger: """Setup the Logger - Params: + Args: - config_path (str): The path of logging config file + - logging_path (str): The logging directory Returns: - Logger: The Logger """ - if not path.exists('VNULIB-Downloader/logs'): - makedirs('VNULIB-Downloader/logs') + if not path.exists(logging_path): + makedirs(logging_path) if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): config_path = path.join(sys._MEIPASS, config_path) with open(config_path, 'r', encoding='utf-8') as config_file: @@ -27,4 +29,5 @@ def setup_logger(config_path: str) -> Logger: return getLogger("vnulib_downloader") -logger: Logger = setup_logger(config_path=LOGGING_FILE) +logger: Logger = setup_logger(config_path=LOGGING_CONFIG_FILE, + logging_path=LOGGING_DIR) diff --git a/src/utils/prints.py b/src/utils/prints.py index 6de525e..b03f043 100644 --- a/src/utils/prints.py +++ b/src/utils/prints.py @@ -1,4 +1,6 @@ -"""Print out with tag, color, format, background""" +"""Print functions with tag, color, format, background +""" + from os import get_terminal_size from print_color.print_color import print as printColor @@ -12,9 +14,6 @@ def print_title(message: str) -> None: Args: - Message (str): Message of Title - - Returns: - - None """ printColor(message.center(int(TERMINAL_SIZE_COLUMNS)), color='magenta', format='bold', background='blue', end='\n\n') @@ -25,9 +24,6 @@ def print_success(message: str) -> None: Args: - Message (str): Message of Success - - Returns: - - None """ printColor(message, tag='Success', color='green') @@ -37,9 +33,6 @@ def print_error(message: str) -> None: Args: - Message (str): Message of Error - - Returns: - - None """ printColor(message, tag='Error', color='red') @@ -49,9 +42,6 @@ def print_warning(message: str) -> None: Args: - Message (str): Message of Warning - - Returns: - - None """ printColor(message, tag='Warning', color='yellow') @@ -61,9 +51,6 @@ def print_retry(message: str) -> None: Args: - Message (str): Message of Retry - - Returns: - - None """ printColor(message, tag='Retry', color='blue') @@ -73,8 +60,5 @@ def print_info(message: str) -> None: Args: - Message (str): Message of Info - - Returns: - - None """ printColor(message, tag='Info', color='yan') diff --git a/src/utils/update.py b/src/utils/update.py index 0a7a914..74fe3ce 100644 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -13,7 +13,7 @@ def getVersionsFromRepository(repo_url: str = REPOSITORY_URL) -> list[str]: """Get versions from repository exclude beta versions - Params: + Args: - repo_url (str) = REPOSITORY_URL: Repository URL Returns: @@ -36,7 +36,7 @@ def getVersionsFromRepository(repo_url: str = REPOSITORY_URL) -> list[str]: def compareVersion(version: str, to_compare_version: str) -> int: """Compare two versions - Params: + Args: - version (str): Version to compare - to_compare_version (str): Version to be compared @@ -55,7 +55,7 @@ def compareVersion(version: str, to_compare_version: str) -> int: def checkNeedToUpdate(current_version: str, VERSIONS: list[str]) -> bool: """Check if it needs to update the tool or not - Params: + Args: - current_version (str): Current version - VERSIONS (list[str]): List of versions from repository @@ -94,7 +94,7 @@ def checkNeedToUpdate(current_version: str, VERSIONS: list[str]) -> bool: def updateTheTool() -> None: """Update thee tool function - Params: + Args: - None Returns: diff --git a/src/utils/utils.py b/src/utils/utils.py index 7a3eaec..86954ab 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -1,4 +1,5 @@ -"""Contains utility functions for the project""" +"""Contains utility functions for the project +""" from os import makedirs, path @@ -12,12 +13,6 @@ def pause() -> None: """Pause the terminal until user hits Enter - - Params: - - None - - Returns: - - None """ _: str = input('Press Enter to continue . . .') @@ -25,12 +20,9 @@ def pause() -> None: def create_directory(*directories: str, force: bool | None = None) -> None: """Remove (if force=True) and create a directory - Params: + Args: - *directories (str): The directory to create - force (bool): Whether to remove the directory if it exists - - Returns: - - None """ for directory in directories: if path.exists(path=directory): @@ -57,11 +49,8 @@ def create_directory(*directories: str, force: bool | None = None) -> None: def remove_directory(*directories: str) -> None: """Remove a directory - Params: + Args: - *directories (str): The directory to remove - - Returns: - - None """ for directory in directories: if path.exists(path=directory): @@ -80,9 +69,6 @@ def remove_directory(*directories: str) -> None: def datetime_name() -> str: """Get the datetime name (%Y-%m-%d %H-%M-%S-%f) - Params: - - None - Returns: - str: The datetime name """