diff --git a/.gitignore b/.gitignore index 8dd734d..7603550 100644 --- a/.gitignore +++ b/.gitignore @@ -170,8 +170,9 @@ # ruff .ruff_cache/ +# LSP config files +pyrightconfig.json + # End of https://www.toptal.com/developers/gitignore/api/python *.gif -dist -outputs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7327dad..521f1af 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ - id: mixed-line-ending - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: "0.21.0" + rev: "0.22.0" hooks: - id: check-dependabot - id: check-github-actions diff --git a/Makefile b/Makefile index ff31767..1e69417 100644 --- a/Makefile +++ b/Makefile @@ -12,31 +12,36 @@ TARGET := $(DIST)/$(NAME)$(EXE) -.PHONY: build -build: - pyinstaller --distpath $(DIST) --onefile --name $(NAME) $(CURDIR)/main.py +build: $(TARGET) clean: $(RM) --recursive $(CURDIR)/build - $(RM) --recursive $(CURDIR)/outputs $(RM) --recursive $(DIST) $(RM) $(CURDIR)/*.spec -demo: -ifeq ($(BW_SESSION),) - $(error Bitwarden Locked) -else - vhs < $(CURDIR)/demo.tape -endif +demo: $(CURDIR)/demo.gif -install: build - install --target-directory=$(BIN) $(TARGET) +install: $(TARGET) | $(BIN) + install --target-directory=$(BIN) $< pretty: isort --profile black $(CURDIR) black $(CURDIR) -rename: build +rename: $(TARGET) ifneq ($(and $(OS), $(ARCH)), ) - mv $(TARGET) $(DIST)/$(NAME)-$(OS)-$(ARCH)$(EXE) + mv $< $(DIST)/$(NAME)-$(OS)-$(ARCH)$(EXE) +endif + +$(TARGET): + pyinstaller --distpath $(DIST) --onefile --name $(NAME) $(CURDIR)/main.py + +$(BIN): + mkdir --parents $@ + +$(CURDIR)/demo.gif: $(CURDIR)/demo.tape +ifeq ($(BW_SESSION),) + $(error Bitwarden Locked) +else + vhs < $< endif diff --git a/README.md b/README.md index 44bc839..6c44bb1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## Demo -![Demo](https://res.cloudinary.com/liblaf/image/upload/v1677213088/2023/02/24/20230224-1677213085.gif) +![Demo](https://res.cloudinary.com/liblaf/image/upload/v1679497703/2023/03/22/20230322-1679497699.gif) The resulting file structure looks like: @@ -22,6 +22,26 @@ └── README.md ``` +## Usage + +**Usage**: + +```shell-session +$ tld [OPTIONS] +``` + +**Options**: + +- `-u, --username TEXT`: [default: liqin20] +- `-p, --password TEXT` +- `-s, --semester TEXT`: [default: 2022-2023-2] +- `-c, --course TEXT` +- `--prefix PATH`: [default: /home/liblaf/Desktop/thu-learn] +- `-s, --size-limit INTEGER`: [default: 9223372036854775807] +- `--install-completion`: Install completion for the current shell. +- `--show-completion`: Show completion for the current shell, to copy it or customize the installation. +- `--help`: Show this message and exit. + ## Features - fast concurrent download @@ -31,9 +51,8 @@ - dump homework details into `README.md` in each homework folder - pretty markdown files powered by [prettier](https://prettier.io) (require `prettier` installed) -## Usage +## Installation -Download pre-built binary from [releases](https://github.com/liblaf/thu-learn-downloader/releases) or install from PyPI by executing `pip install thu-learn-downloader`. - -1. Prepare a `config.yaml` like [config.yaml](https://github.com/liblaf/thu-learn-downloader/blob/main/config.yaml). -2. Run `thu-learn-downloader password="***"` and wait for the sync to finish. +- download pre-built binary form [GitHub Releases](https://github.com/liblaf/thu-learn-downloader/releases) +- `pip install thu-learn-downloader` +- `pipx install thu-learn-downloader` diff --git a/config.yaml b/config.yaml deleted file mode 100644 index bffe50d..0000000 --- a/config.yaml +++ /dev/null @@ -1,4 +0,0 @@ -username: liqin20 -password: "****************" -semesters: - - 2022-2023-2 diff --git a/demo.tape b/demo.tape index be71893..4b38df7 100644 --- a/demo.tape +++ b/demo.tape @@ -4,9 +4,9 @@ Set Height 1080 Set FontSize 12 -Require thu-learn-downloader +Require tld -Type 'thu-learn-downloader password="$(bw get password id.tsinghua.edu.cn)"' +Type 'tld --password "$(bw get password id.tsinghua.edu.cn)"' Sleep 500ms Enter Sleep 10s diff --git a/main.py b/main.py index 5078d73..cd9cfcc 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -from thu_learn_downloader.__main__ import main +from thu_learn_downloader.__main__ import run if __name__ == "__main__": - main() + run() diff --git a/poetry.lock b/poetry.lock index 795446e..25a13c3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.1 and should not be changed by hand. [[package]] name = "altgraph" @@ -13,26 +13,15 @@ ] [[package]] -name = "antlr4-python3-runtime" -version = "4.9.3" -description = "ANTLR 4.9.3 runtime for Python 3.7" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b"}, -] - -[[package]] name = "beautifulsoup4" -version = "4.11.2" +version = "4.12.0" description = "Screen-scraping library" category = "main" optional = false python-versions = ">=3.6.0" files = [ - {file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"}, - {file = "beautifulsoup4-4.11.2.tar.gz", hash = "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106"}, + {file = "beautifulsoup4-4.12.0-py3-none-any.whl", hash = "sha256:2130a5ad7f513200fae61a17abb5e338ca980fa28c439c0571014bc0217e9591"}, + {file = "beautifulsoup4-4.12.0.tar.gz", hash = "sha256:c5fceeaec29d09c84970e47c65f2f0efe57872f7cff494c9691a26ec0ff13234"}, ] [package.dependencies] @@ -43,6 +32,55 @@ lxml = ["lxml"] [[package]] +name = "black" +version = "23.1.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"}, + {file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"}, + {file = "black-23.1.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b"}, + {file = "black-23.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104"}, + {file = "black-23.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074"}, + {file = "black-23.1.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27"}, + {file = "black-23.1.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648"}, + {file = "black-23.1.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958"}, + {file = "black-23.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a"}, + {file = "black-23.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481"}, + {file = "black-23.1.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad"}, + {file = "black-23.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8"}, + {file = "black-23.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24"}, + {file = "black-23.1.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6"}, + {file = "black-23.1.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd"}, + {file = "black-23.1.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580"}, + {file = "black-23.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468"}, + {file = "black-23.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753"}, + {file = "black-23.1.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651"}, + {file = "black-23.1.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06"}, + {file = "black-23.1.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739"}, + {file = "black-23.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9"}, + {file = "black-23.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555"}, + {file = "black-23.1.0-py3-none-any.whl", hash = "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32"}, + {file = "black-23.1.0.tar.gz", hash = "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] name = "certifi" version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." @@ -140,21 +178,46 @@ ] [[package]] -name = "hydra-core" -version = "1.3.2" -description = "A framework for elegantly configuring complex applications" +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "commonmark" +version = "0.9.1" +description = "Python parser for the CommonMark Markdown spec" category = "main" optional = false python-versions = "*" files = [ - {file = "hydra-core-1.3.2.tar.gz", hash = "sha256:8a878ed67216997c3e9d88a8e72e7b4767e81af37afb4ea3334b269a4390a824"}, - {file = "hydra_core-1.3.2-py3-none-any.whl", hash = "sha256:fa0238a9e31df3373b35b0bfb672c34cc92718d21f81311d8996a16de1141d8b"}, + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, ] -[package.dependencies] -antlr4-python3-runtime = ">=4.9.0,<4.10.0" -omegaconf = ">=2.2,<2.4" -packaging = "*" +[package.extras] +test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] [[package]] name = "idna" @@ -169,6 +232,24 @@ ] [[package]] +name = "isort" +version = "5.12.0" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] + +[package.extras] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + +[[package]] name = "macholib" version = "1.16.2" description = "Mach-O header analysis and editing" @@ -184,63 +265,22 @@ altgraph = ">=0.17" [[package]] -name = "markdown-it-py" -version = "2.2.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -category = "main" +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.5" files = [ - {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, - {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -[package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "omegaconf" -version = "2.3.0" -description = "A flexible configuration library" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b"}, - {file = "omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7"}, -] - -[package.dependencies] -antlr4-python3-runtime = ">=4.9.0,<4.10.0" -PyYAML = ">=5.1.0" - [[package]] name = "packaging" version = "23.0" description = "Core utilities for Python packages" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -249,6 +289,18 @@ ] [[package]] +name = "pathspec" +version = "0.11.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, + {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, +] + +[[package]] name = "pefile" version = "2023.2.7" description = "Python PE parsing module" @@ -261,6 +313,22 @@ ] [[package]] +name = "platformdirs" +version = "3.1.1" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"}, + {file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"}, +] + +[package.extras] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] + +[[package]] name = "pygments" version = "2.14.0" description = "Pygments is a syntax highlighting package written in Python." @@ -277,24 +345,24 @@ [[package]] name = "pyinstaller" -version = "5.8.0" +version = "5.9.0" description = "PyInstaller bundles a Python application and all its dependencies into a single package." category = "dev" optional = false python-versions = "<3.12,>=3.7" files = [ - {file = "pyinstaller-5.8.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:502a2166165a8e8c3d99c19272e923d2548bac2132424d78910ef9dd8bb11705"}, - {file = "pyinstaller-5.8.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:bf1f7b7e88b467d7aefcdb2bc9cbd2e856ca88c5ab232c0efe0848f146d3bd5f"}, - {file = "pyinstaller-5.8.0-py3-none-manylinux2014_i686.whl", hash = "sha256:a62ee598b137202ef2e99d8dbaee6bc7379a6565c3ddf0331decb41b98eff1a2"}, - {file = "pyinstaller-5.8.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e68bcadf32edc1171ccb06117699a6a4f8e924b7c2c8812cfa00fd0186ade4ee"}, - {file = "pyinstaller-5.8.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ded780f0d3642d7bfc21d97b98d4ec4b41d2fe70c3f5c5d243868612f536e011"}, - {file = "pyinstaller-5.8.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f9361eff44c7108c2312f39d85ed768c4ada7e0aa729046bbcef3ef3c1577d18"}, - {file = "pyinstaller-5.8.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:5c9632a20faecd6d79f0124afb31e6557414d19be271e572765b474f860f8d76"}, - {file = "pyinstaller-5.8.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:8d004699c5d71c704c14a5f81eec233faa4f87a3bf0ae68e222b87d63f5dd17e"}, - {file = "pyinstaller-5.8.0-py3-none-win32.whl", hash = "sha256:3b74f50a57b1413047042e47033480b7324b091f23dff790a4494af32b377d94"}, - {file = "pyinstaller-5.8.0-py3-none-win_amd64.whl", hash = "sha256:4f4d818588e2d8de4bf24ed018056c3de0c95898ad25719e12d68626161b4933"}, - {file = "pyinstaller-5.8.0-py3-none-win_arm64.whl", hash = "sha256:bacf236b5c2f8f674723a39daca399646dceb470881f842f52e393b9a67ff2f8"}, - {file = "pyinstaller-5.8.0.tar.gz", hash = "sha256:314fb883caf3cbf06adbea2b77671bb73c3481568e994af0467ea7e47eb64755"}, + {file = "pyinstaller-5.9.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:93d7e8443a6b60745d42aa50f08730f6b419410832b4c616c4f1bb315f087661"}, + {file = "pyinstaller-5.9.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:3b2c34c3c3ddf38f68d9f5afbed82abe0f89d53014c56892326fef10172ee652"}, + {file = "pyinstaller-5.9.0-py3-none-manylinux2014_i686.whl", hash = "sha256:dcd348b174fd72c4df271790ac582969c9423cb099fe92db9ec131a8a9243d5a"}, + {file = "pyinstaller-5.9.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:4b21b0298db44f5f07fc04d8ff81ec31efa47b72798efaecc4e811c50a102111"}, + {file = "pyinstaller-5.9.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:12ca6567be457826e14416637ea54485a185d0ce7a5a044df0d0daf588fff6d1"}, + {file = "pyinstaller-5.9.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c7dd156c2438f197c168b990bbce03c97d3fb758dd9bbc3ca93626c2f4473a47"}, + {file = "pyinstaller-5.9.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:2ba42038b3bd83e1fba7c8eb9e7cde43bd5938e37ca542c89e8779355d213f52"}, + {file = "pyinstaller-5.9.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:d1ff94347183ae3755cfb8f02e64744eb7fe384469bd61e453c6ff59a81665d6"}, + {file = "pyinstaller-5.9.0-py3-none-win32.whl", hash = "sha256:8476538aec8a0a3be4f74b93388bd6989b91cc437ff86d6f0d3a68961176dce6"}, + {file = "pyinstaller-5.9.0-py3-none-win_amd64.whl", hash = "sha256:e7a4c292810285c2466f3bdcb1e03ba2170177ebe3d7054ff1af3bb348bf61a4"}, + {file = "pyinstaller-5.9.0-py3-none-win_arm64.whl", hash = "sha256:6cf6c032c72ef78fd9aa5e47d8952e784db45b2c3f7862bd44a99df68c216f64"}, + {file = "pyinstaller-5.9.0.tar.gz", hash = "sha256:2bde16a8d664e8eba9aa7b84f729f7ab005c1793be4fe1986b3c9cad6c486622"}, ] [package.dependencies] @@ -311,14 +379,14 @@ [[package]] name = "pyinstaller-hooks-contrib" -version = "2023.0" +version = "2023.1" description = "Community maintained hooks for PyInstaller" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pyinstaller-hooks-contrib-2023.0.tar.gz", hash = "sha256:bd578781cd6a33ef713584bf3726f7cd60a3e656ec08a6cc7971e39990808cc0"}, - {file = "pyinstaller_hooks_contrib-2023.0-py2.py3-none-any.whl", hash = "sha256:29d052eb73e0ab8f137f11df8e73d464c1c6d4c3044d9dc8df2af44639d8bfbf"}, + {file = "pyinstaller-hooks-contrib-2023.1.tar.gz", hash = "sha256:ab56c192e7cd4472ff6b840cda4fc42bceccc7fb4234f064fc834a3248c0afdd"}, + {file = "pyinstaller_hooks_contrib-2023.1-py2.py3-none-any.whl", hash = "sha256:d2ea40a7105651aa525bfe5fe309aa264d4d9bb49f839b862243dcf0a56c34cd"}, ] [[package]] @@ -334,56 +402,6 @@ ] [[package]] -name = "pyyaml" -version = "6.0" -description = "YAML parser and emitter for Python" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, -] - -[[package]] name = "requests" version = "2.28.2" description = "Python HTTP for Humans." @@ -407,22 +425,22 @@ [[package]] name = "rich" -version = "13.3.2" +version = "12.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "main" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.6.3,<4.0.0" files = [ - {file = "rich-13.3.2-py3-none-any.whl", hash = "sha256:a104f37270bf677148d8acb07d33be1569eeee87e2d1beb286a4e9113caf6f2f"}, - {file = "rich-13.3.2.tar.gz", hash = "sha256:91954fe80cfb7985727a467ca98a7618e5dd15178cc2da10f553b36a93859001"}, + {file = "rich-12.6.0-py3-none-any.whl", hash = "sha256:a4eb26484f2c82589bd9a17c73d32a010b1e29d89f1604cd9bf3a2097b81bb5e"}, + {file = "rich-12.6.0.tar.gz", hash = "sha256:ba3a3775974105c221d31141f2c116f4fd65c5ceb0698657a11e9f295ec93fd0"}, ] [package.dependencies] -markdown-it-py = ">=2.2.0,<3.0.0" -pygments = ">=2.13.0,<3.0.0" +commonmark = ">=0.9.0,<0.10.0" +pygments = ">=2.6.0,<3.0.0" [package.extras] -jupyter = ["ipywidgets (>=7.5.1,<9)"] +jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] [[package]] name = "setuptools" @@ -442,6 +460,18 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] +name = "shellingham" +version = "1.5.0.post1" +description = "Tool to Detect Surrounding Shell" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.0.post1-py2.py3-none-any.whl", hash = "sha256:368bf8c00754fd4f55afb7bbb86e272df77e4dc76ac29dbcbb81a59e9fc15744"}, + {file = "shellingham-1.5.0.post1.tar.gz", hash = "sha256:823bc5fb5c34d60f285b624e7264f4dda254bc803a3774a147bf99c0e3004a28"}, +] + +[[package]] name = "soupsieve" version = "2.4" description = "A modern CSS selector implementation for Beautiful Soup." @@ -454,15 +484,51 @@ ] [[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "typer" +version = "0.7.0" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "typer-0.7.0-py3-none-any.whl", hash = "sha256:b5e704f4e48ec263de1c0b3a2387cd405a13767d2f907f44c1a08cbad96f606d"}, + {file = "typer-0.7.0.tar.gz", hash = "sha256:ff797846578a9f2a201b53442aedeb543319466870fbe1c701eab66dd7681165"}, +] + +[package.dependencies] +click = ">=7.1.1,<9.0.0" +colorama = {version = ">=0.4.3,<0.5.0", optional = true, markers = "extra == \"all\""} +rich = {version = ">=10.11.0,<13.0.0", optional = true, markers = "extra == \"all\""} +shellingham = {version = ">=1.3.0,<2.0.0", optional = true, markers = "extra == \"all\""} + +[package.extras] +all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] +doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] +test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] + +[[package]] name = "urllib3" -version = "1.26.14" +version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, - {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, + {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, + {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, ] [package.extras] @@ -473,4 +539,4 @@ [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "e71af7917990149ef02e33b887fdeb85bb4c4a6e5c5416e56a9ae74d1cd292e2" +content-hash = "1bcafc1a0b862e4d4b1f8a235b6588c9be4ec5844f48195e0d52a036e130ca6d" diff --git a/pyproject.toml b/pyproject.toml index 03a9ead..c08a4cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,14 +16,16 @@ [tool.poetry.dependencies] beautifulsoup4 = "^4.11.2" -hydra-core = "^1.3.1" python = ">=3.10,<3.12" requests = "^2.28.2" -rich = "^13.3.1" +rich = "^12.0.0" +typer = { extras = ["all"], version = "^0.7.0" } [tool.poetry.group.dev.dependencies] pyinstaller = "^5.8.0" +black = "^23.1.0" +isort = "^5.12.0" [tool.poetry.scripts] -thu-learn-downloader = "thu_learn_downloader.__main__:main" -tld = "thu_learn_downloader.__main__:main" +thu-learn-downloader = "thu_learn_downloader.__main__:run" +tld = "thu_learn_downloader.__main__:run" diff --git a/requirements.txt b/requirements.txt index 320ff39..fdf23a4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,14 @@ -antlr4-python3-runtime==4.9.3 ; python_version >= "3.10" and python_version < "3.12" -beautifulsoup4==4.11.2 ; python_version >= "3.10" and python_version < "3.12" +beautifulsoup4==4.12.0 ; python_version >= "3.10" and python_version < "3.12" certifi==2022.12.7 ; python_version >= "3.10" and python_version < "3.12" charset-normalizer==3.1.0 ; python_version >= "3.10" and python_version < "3.12" -hydra-core==1.3.2 ; python_version >= "3.10" and python_version < "3.12" +click==8.1.3 ; python_version >= "3.10" and python_version < "3.12" +colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.12" +commonmark==0.9.1 ; python_version >= "3.10" and python_version < "3.12" idna==3.4 ; python_version >= "3.10" and python_version < "3.12" -markdown-it-py==2.2.0 ; python_version >= "3.10" and python_version < "3.12" -mdurl==0.1.2 ; python_version >= "3.10" and python_version < "3.12" -omegaconf==2.3.0 ; python_version >= "3.10" and python_version < "3.12" -packaging==23.0 ; python_version >= "3.10" and python_version < "3.12" pygments==2.14.0 ; python_version >= "3.10" and python_version < "3.12" -pyyaml==6.0 ; python_version >= "3.10" and python_version < "3.12" requests==2.28.2 ; python_version >= "3.10" and python_version < "3.12" -rich==13.3.2 ; python_version >= "3.10" and python_version < "3.12" +rich==12.6.0 ; python_version >= "3.10" and python_version < "3.12" +shellingham==1.5.0.post1 ; python_version >= "3.10" and python_version < "3.12" soupsieve==2.4 ; python_version >= "3.10" and python_version < "3.12" -urllib3==1.26.14 ; python_version >= "3.10" and python_version < "3.12" +typer[all]==0.7.0 ; python_version >= "3.10" and python_version < "3.12" +urllib3==1.26.15 ; python_version >= "3.10" and python_version < "3.12" diff --git a/thu_learn_downloader/__main__.py b/thu_learn_downloader/__main__.py index baa23e2..1c2ceef 100644 --- a/thu_learn_downloader/__main__.py +++ b/thu_learn_downloader/__main__.py @@ -1,7 +1,7 @@ -import os +import sys +from pathlib import Path -import hydra -from omegaconf import DictConfig +import typer from rich.console import Group from rich.live import Live from rich.panel import Panel @@ -14,13 +14,30 @@ ) from . import sync +from .config import Config from .constants import MAX_ACTIVE_TASKS, SUCCESS_PREFIX from .downloader import Downloader from .helper import Helper -@hydra.main(config_path=os.getcwd(), config_name="config.yaml", version_base="1.3") -def main(config: DictConfig) -> None: +def main( + username: str = typer.Option("liqin20", "-u", "--username"), + password: str = typer.Option( + None, "-p", "--password", prompt=True, hide_input=True + ), + semester: list[str] = typer.Option(["2022-2023-2"], "-s", "--semester"), + course: list[str] = typer.Option([], "-c", "--course"), + prefix: Path = typer.Option(Path.home() / "Desktop" / "thu-learn", "--prefix"), + size_limit: int = typer.Option(sys.maxsize, "-s", "--size-limit"), +) -> None: + config = Config( + username=username, + password=password, + semesters=semester, + courses=course, + prefix=prefix, + size_limit=size_limit, + ) helper = Helper() downloader = Downloader() overall_progress = Progress( @@ -36,8 +53,6 @@ Panel(overall_progress), ) - username: str = config.get("username") - password: str = config.get("password") with Live(progress_group) as live: with downloader.pool: try: @@ -64,5 +79,9 @@ ) +def run() -> None: + typer.run(main) + + if __name__ == "__main__": - main() + run() diff --git a/thu_learn_downloader/config.py b/thu_learn_downloader/config.py new file mode 100644 index 0000000..f72e7ca --- /dev/null +++ b/thu_learn_downloader/config.py @@ -0,0 +1,15 @@ +import dataclasses +import sys +from pathlib import Path + + +@dataclasses.dataclass(kw_only=True) +class Config: + username: str = "liqin20" + password: str + + semesters: list[str] = dataclasses.field(default_factory=lambda: ["2022-2023-2"]) + courses: list[str] = dataclasses.field(default_factory=list) + + prefix: Path = Path.home() / "Desktop" / "thu-learn" + size_limit: int = sys.maxsize diff --git a/thu_learn_downloader/constants.py b/thu_learn_downloader/constants.py index 2fd78c2..fd34c99 100644 --- a/thu_learn_downloader/constants.py +++ b/thu_learn_downloader/constants.py @@ -1,12 +1,9 @@ -from pathlib import Path - from rich.style import Style from . import typing as t BS_FEATURES = "html.parser" CHUNK_SIZE = 1024 * 1024 -DEFAULT_PREFIX = Path.home() / "Desktop" / "thu-learn" MAX_ACTIVE_TASKS = 16 diff --git a/thu_learn_downloader/sync.py b/thu_learn_downloader/sync.py index f606965..ff392d5 100644 --- a/thu_learn_downloader/sync.py +++ b/thu_learn_downloader/sync.py @@ -1,24 +1,17 @@ import os import shutil import subprocess -import sys from datetime import datetime from pathlib import Path from typing import Optional -from omegaconf import DictConfig from rich.console import Console from rich.progress import Progress, TaskID from . import typing as t from . import utils -from .constants import ( - DEFAULT_PREFIX, - DOCUMENT_STYLE, - HOMEWORK_STYLE, - SKIPPED_PREFIX, - SUCCESS_PREFIX, -) +from .config import Config +from .constants import DOCUMENT_STYLE, HOMEWORK_STYLE, SKIPPED_PREFIX, SUCCESS_PREFIX from .downloader import Downloader from .helper import Helper @@ -26,14 +19,14 @@ def sync_all( helper: Helper, downloader: Downloader, - config: DictConfig, + config: Config, *, console: Console = Console(), overall_progress: Progress = Progress(), semesters_task_id: TaskID = TaskID(0), courses_task_id: TaskID = TaskID(1), ) -> None: - semesters = config.get("semesters") or helper.get_semester_id_list() + semesters = config.semesters or helper.get_semester_id_list() for semester in overall_progress.track( semesters, task_id=semesters_task_id, description="Semesters" @@ -52,7 +45,7 @@ def sync_semester( helper: Helper, downloader: Downloader, - config: DictConfig, + config: Config, semester_id: str, *, console: Console = Console(), @@ -61,12 +54,12 @@ ) -> None: courses: list[t.CourseInfo] = helper.get_course_list(semester_id=semester_id) - if config.get("courses"): + if config.courses: courses = [ course for course in courses - if course.name in config["courses"] - or course.english_name in config["courses"] + if (course.name in config.courses) + or (course.english_name in config.courses) ] overall_progress.update( @@ -85,7 +78,7 @@ def sync_course( helper: Helper, downloader: Downloader, - config: DictConfig, + config: Config, course: t.CourseInfo, *, console: Console = Console(), @@ -109,15 +102,13 @@ def sync_files( helper: Helper, downloader: Downloader, - config: DictConfig, + config: Config, course: t.CourseInfo, *, console: Console = Console(), ) -> None: - prefix: Path = Path( - config.get(key="prefix", default_value=DEFAULT_PREFIX) - ).expanduser() - size_limit: int = config.get(key="size_limit", default_value=sys.maxsize) + prefix: Path = config.prefix + size_limit: int = config.size_limit files: list[t.File] = helper.get_file_list(course_id=course.id) files: list[t.File] = sorted(files, key=lambda f: f.id) @@ -153,7 +144,7 @@ def sync_homeworks( helper: Helper, downloader: Downloader, - config: DictConfig, + config: Config, course: t.CourseInfo, *, console: Console = Console(), @@ -182,15 +173,13 @@ def sync_homework_detail( helper: Helper, downloader: Downloader, - config: DictConfig, + config: Config, course: t.CourseInfo, hw: t.Homework, *, console: Console = Console(), ) -> None: - prefix: Path = Path( - config.get(key="prefix", default_value=DEFAULT_PREFIX) - ).expanduser() + prefix: Path = config.prefix title: str = f"{hw.number:02d}-{hw.title}" filepath: Path = prefix / course.english_name / "work" / title / "README.md" os.makedirs(filepath.parent, exist_ok=True) @@ -211,7 +200,7 @@ def sync_homework_attachments( helper: Helper, downloader: Downloader, - config: DictConfig, + config: Config, course: t.CourseInfo, hw: t.Homework, *, @@ -262,7 +251,7 @@ def sync_homework_attachment( helper: Helper, downloader: Downloader, - config: DictConfig, + config: Config, course: t.CourseInfo, hw: t.Homework, attach: Optional[t.RemoteFile], @@ -272,9 +261,7 @@ ) -> None: if not attach: return - prefix: Path = Path( - config.get(key="prefix", default_value=DEFAULT_PREFIX) - ).expanduser() + prefix: Path = config.prefix title: str = f"{hw.number:02d}-{hw.title}" filename: str = utils.remove_attachment_prefix(attach.name) filename: str = f"{attach_type}-{filename}"