aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCody Logan <cody@lokken.dev>2023-12-01 15:33:21 -0800
committerCody Logan <cody@lokken.dev>2023-12-01 15:33:21 -0800
commit318d9ad1a4679832b380c77ab1a0a86684f686f2 (patch)
treeee1bd8ad347c18b3fc44da388360634c3afd231c
parent488e859f8c343b0ef25db379b6339bf82769514b (diff)
downloadwikiget-318d9ad1a4679832b380c77ab1a0a86684f686f2.tar.gz
wikiget-318d9ad1a4679832b380c77ab1a0a86684f686f2.zip
Switch to Google-style docstrings for readability
The previous Sphinx-style docstrings could be hard to read at a glance when formatted with pydoc.
-rw-r--r--pyproject.toml3
-rw-r--r--src/wikiget/__init__.py10
-rw-r--r--src/wikiget/client.py24
-rw-r--r--src/wikiget/dl.py47
-rw-r--r--src/wikiget/file.py34
-rw-r--r--src/wikiget/logging.py11
-rw-r--r--src/wikiget/parse.py25
-rw-r--r--src/wikiget/validations.py27
-rw-r--r--src/wikiget/wikiget.py15
9 files changed, 107 insertions, 89 deletions
diff --git a/pyproject.toml b/pyproject.toml
index 46f1ddf..5506b20 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -172,6 +172,9 @@ known-first-party = ["wikiget"]
[tool.ruff.flake8-tidy-imports]
ban-relative-imports = "all"
+[tool.ruff.pydocstyle]
+convention = "google"
+
[tool.ruff.per-file-ignores]
# Tests can use magic values, assertions, and relative imports
"tests/**/*" = ["PLR2004", "S101", "TID252"]
diff --git a/src/wikiget/__init__.py b/src/wikiget/__init__.py
index 698fe46..d8f87bf 100644
--- a/src/wikiget/__init__.py
+++ b/src/wikiget/__init__.py
@@ -15,12 +15,12 @@
# You should have received a copy of the GNU General Public License
# along with Wikiget. If not, see <https://www.gnu.org/licenses/>.
-"""Wikiget is a tool for downloading files from MediaWiki sites.
+"""A tool for downloading files from MediaWiki sites.
-It's similar in conception to download tools like wget, but wikiget can use the name of
-the file or the URL of its description page to get the actual file's URL and download
-it. Additionally, it can download multiple files at once by reading the targets from a
-given text file.
+Wikiget is similar in conception to download tools like wget, but wikiget can use the
+name of the file or the URL of its description page to get the actual file's URL and
+download it. Additionally, it can download multiple files at once by reading the targets
+from a given text file.
Further documentation can be found in the accompanying README.md file or at
<https://github.com/clpo13/wikiget>.
diff --git a/src/wikiget/client.py b/src/wikiget/client.py
index 2729144..a924f79 100644
--- a/src/wikiget/client.py
+++ b/src/wikiget/client.py
@@ -38,12 +38,12 @@ logger = logging.getLogger(__name__)
def connect_to_site(site_name: str, args: Namespace) -> Site:
"""Create and return a Site object using the given site name and CLI arguments.
- :param site_name: hostname of the site to connect to
- :type site_name: str
- :param args: command-line arguments and their values
- :type args: argparse.Namespace
- :return: a new Site object
- :rtype: mwclient.Site
+ Args:
+ site_name (str): hostname of the site to connect to
+ args (argparse.Namespace): command-line arguments and their values
+
+ Returns:
+ mwclient.Site: a new Site object
"""
logger.info("Connecting to %s", site_name)
@@ -82,12 +82,12 @@ def query_api(filename: str, site: Site) -> Image:
Even if there's no file by that name on the site, an Image will still be returned,
though with an empty imageinfo attribute.
- :param filename: name of the file to retrieve
- :type filename: str
- :param site: the Site object to query
- :type site: mwclient.Site
- :return: an Image object representing the requested file
- :rtype: mwclient.image.Image
+ Args:
+ filename (str): name of the file to retrieve
+ site (mwclient.Site): the Site object to query
+
+ Returns:
+ mwclient.image.Image: an Image object representing the requested file
"""
try:
# get info about the target file
diff --git a/src/wikiget/dl.py b/src/wikiget/dl.py
index 5a6ef0b..526eb71 100644
--- a/src/wikiget/dl.py
+++ b/src/wikiget/dl.py
@@ -45,13 +45,15 @@ logger = logging.getLogger(__name__)
def prep_download(dl: str, args: Namespace) -> File:
"""Prepare to download a file by parsing the filename or URL and CLI arguments.
- :param dl: a string representing the file or URL to download
- :type dl: str
- :param args: command-line arguments and their values
- :type args: argparse.Namespace
- :raises FileExistsError: the destination file already exists on disk
- :return: a File object representing the file to download
- :rtype: wikiget.file.File
+ Args:
+ dl (str): the file or URL to download
+ args (argparse.Namespace): command-line arguments and their values
+
+ Raises:
+ FileExistsError: the destination file already exists on disk
+
+ Returns:
+ wikiget.file.File: a File object representing the file to download
"""
file = get_dest(dl, args)
@@ -74,10 +76,11 @@ def process_download(args: Namespace) -> int:
exceptions that it raises. If there aren't any, download the file and return the
exit code appropriately.
- :param args: command-line arguments and their values
- :type args: argparse.Namespace
- :return: program exit code (1 if there were any problems or 0 otherwise)
- :rtype: int
+ Args:
+ args (argparse.Namespace): command-line arguments and their values
+
+ Returns:
+ int: program exit code (1 if there were any problems or 0 otherwise)
"""
exit_code = 0
@@ -121,10 +124,11 @@ def batch_download(args: Namespace) -> int:
for validity before being downloaded using a ThreadPool for simultaneous downloads,
if threading was specified on the command line.
- :param args: command-line arguments and their values
- :type args: argparse.Namespace
- :return: number of errors encountered during processing
- :rtype: int
+ Args:
+ args (argparse.Namespace): command-line arguments and their values
+
+ Returns:
+ int: number of errors encountered during processing
"""
errors = 0
@@ -187,12 +191,13 @@ def batch_download(args: Namespace) -> int:
def download(f: File, args: Namespace) -> int:
"""Fetch file information and contents if the file exists and save it to disk.
- :param f: a File object representing the file to be downloaded
- :type f: wikiget.file.File
- :param args: command-line arguments and their values
- :type args: argparse.Namespace
- :return: number of errors encountered during processing
- :rtype: int
+ Args:
+ f (wikiget.file.File): a File object representing the file to be downloaded
+ args (argparse.Namespace): command-line arguments and their values
+
+ Returns:
+ :return: number of errors encountered during processing
+ :rtype: int
"""
file = f.image
filename = f.name
diff --git a/src/wikiget/file.py b/src/wikiget/file.py
index 0b0c1e0..69597f2 100644
--- a/src/wikiget/file.py
+++ b/src/wikiget/file.py
@@ -40,15 +40,14 @@ class File:
will be used as the output name, and if no site is given, the default site will
be used (commons.wikimedia.org).
- :param name: name of the file
- :type name: str
- :param dest: output name of the file; if not specified, defaults to name
- :type dest: str, optional
- :param site: name of the site hosting the file; if not specified, defaults to
- the global default site
- :type site: str, optional
- :param image: mwclient image object retrieved from the host site
- :type image: mwclient.image.Image, optional
+ Args:
+ name (str): name of the file
+ dest (str, optional): output name of the file; defaults to the value given
+ to name
+ site (str, optional): name of the site hosting the file; defaults to the
+ global default site
+ image (mwclient.image.Image): mwclient image object retrieved from the host
+ site
"""
self.name = name
self.dest = Path(dest) if dest else Path(name)
@@ -58,10 +57,11 @@ class File:
def __eq__(self, other: object) -> bool:
"""Compare this File object with another for equality.
- :param other: another File to compare
- :type other: wikiget.file.File
- :return: True if the Files are equal and False otherwise
- :rtype: bool
+ Args:
+ other (wikiget.file.File): another File to compare
+
+ Returns:
+ bool: True if the Files are equal and False otherwise
"""
if not isinstance(other, File):
return NotImplemented
@@ -75,16 +75,16 @@ class File:
def __str__(self) -> str:
"""Return a basic string representation of this class, for str().
- :return: string form of the class
- :rtype: str
+ Returns:
+ str: string form of the class
"""
return str(self.__dict__)
def __repr__(self) -> str:
"""Return a formal string representation of this class, for repr().
- :return: string form of the class
- :rtype: str
+ Returns:
+ str: string form of the class
"""
attr_list = [self.name, self.dest, self.site]
return '{}("{}", {})'.format(
diff --git a/src/wikiget/logging.py b/src/wikiget/logging.py
index e5b955a..7baf4d7 100644
--- a/src/wikiget/logging.py
+++ b/src/wikiget/logging.py
@@ -35,12 +35,11 @@ class FileLogAdapter(logging.LoggerAdapter):
def configure_logging(verbosity: int, logfile: str, *, quiet: bool) -> None:
"""Set the program's log configuration according to the given settings.
- :param verbosity: how verbose the log messages should be
- :type verbosity: int
- :param logfile: file to write log messages to, if any
- :type logfile: str
- :param quiet: True if log messages should be suppressed or False otherwise
- :type quiet: bool
+ Args:
+ verbosity (int): integer representation of how verbose the log messages should
+ be (0 for normal, 1 for verbose, 2 for very verbose)
+ logfile (str): name of the file to write log messages to, if any
+ quiet (bool): True if log messages should be suppressed or False otherwise
"""
loglevel = logging.WARNING # default log level
if verbosity >= wikiget.VERY_VERBOSE:
diff --git a/src/wikiget/parse.py b/src/wikiget/parse.py
index 026062e..9017d3a 100644
--- a/src/wikiget/parse.py
+++ b/src/wikiget/parse.py
@@ -38,13 +38,15 @@ logger = logging.getLogger(__name__)
def get_dest(dl: str, args: Namespace) -> File:
"""Parse the given download target for filename, destination, and site host.
- :param dl: download target (filename or URL)
- :type dl: str
- :param args: command-line arguments and their values
- :type args: argparse.Namespace
- :raises ParseError: the target was unable to be parsed as a valid file
- :return: a File object representing the target, destination, and site
- :rtype: wikiget.file.File
+ Args:
+ dl (str): download target (filename or URL)
+ args (argparse.Namespace): command-line arguments and their values
+
+ Raises:
+ ParseError: the target was unable to be parsed as a valid file
+
+ Returns:
+ wikiget.file.File: a File object representing the target, destination, and site
"""
url = urlparse(dl)
@@ -81,10 +83,11 @@ def read_batch_file(batch_file: str) -> dict[int, str]:
The contents are returned as a dictionary with line numbers for keys and line
contents for values. Any blank lines or lines starting with '#' are skipped.
- :param batch_file: name of the file to parse or "-" for stdin
- :type batch_file: str
- :return: a dictionary representation of the input contents
- :rtype: dict[int, str]
+ Args:
+ batch_file (str): name of the file to parse or "-" for stdin
+
+ Returns:
+ dict[int, str]: a dictionary representation of the input contents
"""
dl_dict = {}
diff --git a/src/wikiget/validations.py b/src/wikiget/validations.py
index bde39df..b4bbeba 100644
--- a/src/wikiget/validations.py
+++ b/src/wikiget/validations.py
@@ -36,10 +36,11 @@ def valid_file(search_string: str) -> re.Match | None:
file prefixes in MediaWiki), includes a period, and has at least one character
following the period, like 'File:Example.jpg' or 'Image:Example.svg'.
- :param search_string: string to validate
- :type search_string: str
- :returns: a regex Match object if there's a match or None otherwise
- :rtype: re.Match
+ Args:
+ search_string (str): string to validate
+
+ Returns:
+ re.Match: a regex Match object if there's a match or None otherwise
"""
# second group could also restrict to file extensions with three or more
# letters with ([^/\r\n\t\f\v]+\.\w{3,})
@@ -56,10 +57,11 @@ def valid_site(search_string: str) -> re.Match | None:
Currently unused since any site is accepted as input, and we rely on the user to
ensure the site has a compatible API.
- :param search_string: string to validate
- :type search_string: str
- :returns: a regex Match object if there's a match or None otherwise
- :rtype: re.Match
+ Args:
+ search_string (str): string to validate
+
+ Returns:
+ re.Match: a regex Match object if there's a match or None otherwise
"""
site_regex = re.compile(r"wiki[mp]edia\.org$", re.I)
return site_regex.search(search_string)
@@ -71,10 +73,11 @@ def verify_hash(file: Path) -> str:
Despite being insecure, SHA1 is used since that's what the MediaWiki API returns for
the file hash.
- :param filename: name of the file to calculate a hash for
- :type filename: str
- :return: hash digest
- :rtype: str
+ Args:
+ file (pathlib.Path): file to calculate a hash for, as a Path object
+
+ Returns:
+ str: hash digest
"""
hasher = hashlib.sha1() # noqa: S324
with file.open("rb") as dl:
diff --git a/src/wikiget/wikiget.py b/src/wikiget/wikiget.py
index 0a6478e..eefd14b 100644
--- a/src/wikiget/wikiget.py
+++ b/src/wikiget/wikiget.py
@@ -31,10 +31,11 @@ from wikiget.logging import configure_logging
def parse_args(argv: list[str]) -> argparse.Namespace:
"""Parse the given argument list.
- :param argv: a list of arguments in string form
- :type argv: list[str]
- :return: a Namespace containing the arguments and their values
- :rtype: argparse.Namespace
+ Args:
+ argv (list[str]): a list of arguments in string form
+
+ Returns:
+ argparse.Namespace: a Namespace containing the arguments and their values
"""
parser = argparse.ArgumentParser(
description="""
@@ -130,7 +131,11 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
def cli() -> int:
- """Set up the command-line environment and start the download process."""
+ """Set up the command-line environment and start the download process.
+
+ Returns:
+ int: exit code (0 for success, 1 for errors, 130 for user interrupt)
+ """
args = parse_args(sys.argv[1:])
configure_logging(verbosity=args.verbose, logfile=args.logfile, quiet=args.quiet)