diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 17fa230..195df17 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -1,10 +1,24 @@ +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + version: 2 updates: + - package-ecosystem: gitsubmodule + directory: / + schedule: + interval: weekly - package-ecosystem: github-actions directory: / schedule: interval: weekly + - package-ecosystem: gomod + directory: / + schedule: + interval: weekly + - package-ecosystem: npm + directory: / + schedule: + interval: weekly - package-ecosystem: pip directory: / schedule: diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 048267a..267c311 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -1,2 +1,4 @@ +# https://github.com/googleapis/repo-automation-bots/tree/main/packages/sync-repo-settings + # Automatically delete head branches after merging PRs. Defaults to `true`. deleteBranchOnMerge: true diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 772104f..c7a3eaa 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,14 +5,12 @@ branches: - main -# - [x] Settings > General > Pull Requests > Automatically delete head branches -# - [x] Settings > Actions > General > Workflow permissions > Allow GitHub Actions to create and approve pull requests permissions: contents: write pull-requests: write env: - PYTHON_VERSION: "3.11" + PYTHON_VERSION: 3.x jobs: build-pkg: @@ -56,10 +54,10 @@ - name: Install Dependencies run: poetry install --no-interaction - name: Build Executable - run: poetry run make dist - env: - RUNNER_OS: ${{ runner.os }} - RUNNER_ARCH: ${{ runner.arch }} + run: |- + poetry run make dist \ + RUNNER_OS=${{ runner.os }} \ + RUNNER_ARCH=${{ runner.arch }} - name: Upload Build Artifact uses: actions/upload-artifact@v3 with: @@ -91,7 +89,7 @@ - build-exe - build-pkg - release - if: always() && needs.release.outputs.releases-created == 'true' + if: needs.release.outputs.releases-created == 'true' runs-on: ubuntu-latest steps: - name: Download Artifacts @@ -99,12 +97,10 @@ with: path: artifacts - name: Upload Release Assets - uses: svenstaro/upload-release-action@master + uses: softprops/action-gh-release@v0.1.15 with: - file: artifacts/**/* - tag: ${{ needs.release.outputs.tag-name }} - file_glob: true - overwrite: true + tag_name: ${{ needs.release.outputs.tag-name }} + files: artifacts/**/* publish: name: Publish to PyPI diff --git a/.github/workflows/license.yaml b/.github/workflows/license.yaml index 85b7644..6d19c04 100644 --- a/.github/workflows/license.yaml +++ b/.github/workflows/license.yaml @@ -1,4 +1,4 @@ -name: Update LICENSE Copyright Year(s) +name: Update LICENSE Year on: schedule: @@ -9,14 +9,14 @@ jobs: license: - name: Update LICENSE Copyright Year(s) + name: Update LICENSE Year runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Update LICENSE Copyright Year + - name: Update LICENSE Year uses: FantasticFiasco/action-update-license-year@v3 with: token: ${{ github.token }} diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9142b79 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "template"] +path = template +url = https://github.com/liblaf/template.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fda2b3f..5c2799f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,45 +1,160 @@ ci: skip: + - go-unit-tests + - go-build + - latexindent - poetry-lock +exclude: .*.pdf + repos: - - repo: https://github.com/commitizen-tools/commitizen - rev: "3.0.1" - hooks: - - id: commitizen - - repo: https://github.com/pre-commit/mirrors-prettier - rev: "v3.0.0-alpha.9-for-vscode" - hooks: - - id: prettier - stages: - - commit - repo: https://github.com/pre-commit/pre-commit-hooks rev: "v4.4.0" hooks: - id: check-added-large-files + - id: check-ast + # - id: check-byte-order-marker # deprecated + - id: check-builtin-literals - id: check-case-conflict + # - id: check-docstring-first + - id: check-executables-have-shebangs - id: check-json + # - id: check-shebang-scripts-are-executable + # - id: pretty-format-json + - id: check-merge-conflict - id: check-symlinks - id: check-toml + - id: check-vcs-permalinks + - id: check-xml - id: check-yaml + - id: debug-statements - id: destroyed-symlinks + # - id: detect-aws-credentials + - id: detect-private-key + # - id: double-quote-string-fixer - id: end-of-file-fixer + # - id: file-contents-sorter + - id: fix-byte-order-marker + # - id: fix-encoding-pragma + # - id: forbid-new-submodules + # - id: forbid-submodules - id: mixed-line-ending + - id: name-tests-test + # - id: no-commit-to-branch + # - id: requirements-txt-fixer + # - id: sort-simple-yaml - id: trailing-whitespace - - repo: https://github.com/python-jsonschema/check-jsonschema - rev: "0.22.0" + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: "v16.0.4" hooks: + - id: clang-format + types_or: + - c + - c++ + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "v3.0.0-alpha.9-for-vscode" + hooks: + - id: prettier + - repo: https://github.com/dnephin/pre-commit-golang + rev: "v0.5.1" + hooks: + - id: go-fmt + # - id: go-vet + # - id: go-lint + # - id: go-imports + # - id: go-cyclo + # - id: validate-toml + - id: no-go-testing + # - id: golangci-lint + # - id: go-critic + - id: go-unit-tests + - id: go-build + - id: go-mod-tidy + files: go.mod + - repo: https://github.com/psf/black + rev: "23.3.0" + hooks: + - id: black + - id: black-jupyter + - repo: https://github.com/PyCQA/isort + rev: "5.12.0" + hooks: + - id: isort + args: + - --profile + - black + - repo: https://github.com/commitizen-tools/commitizen + rev: "3.2.2" + hooks: + - id: commitizen + # - id: commitizen-branch + - repo: https://github.com/cheshirekow/cmake-format-precommit + rev: "v0.6.13" + hooks: + - id: cmake-format + - id: cmake-lint + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: "0.23.1" + hooks: + # - id: check-jsonschema + # - id: check-metaschema + - id: check-azure-pipelines + - id: check-bamboo-spec + - id: check-buildkite - id: check-dependabot - id: check-github-actions - id: check-github-workflows + - id: check-gitlab-ci + - id: check-readthedocs + - id: check-renovate + - id: check-travis + - repo: https://github.com/sirosen/texthooks + rev: "0.5.0" + hooks: + - id: fix-smartquotes + - id: fix-ligatures + - id: fix-spaces + - id: forbid-bidi-controls + - id: macro-expand + - repo: https://github.com/scop/pre-commit-shfmt + rev: "v3.6.0-2" + hooks: + - id: shfmt + files: (.sh|.zsh|.zsh-theme|envrc|zshrc)(.tmpl)?$ + types: + - text + args: + - --write + - --simplify + - --indent + - "2" + - --case-indent + - --space-redirects + # - id: shfmt-docker + - repo: https://github.com/cmhughes/latexindent.pl + rev: "V3.22" + hooks: + - id: latexindent + files: .(tex|sty|cls|bib)$ + types: + - text + args: + - --overwriteIfDifferent + - --silent + - --cruft=/tmp + - --modifylinebreaks + - --GCString + # - id: latexindent-conda + # - id: latexindent-docker + - repo: https://github.com/python-poetry/poetry - rev: "1.4.0" + rev: "1.5.0" hooks: - id: poetry-check - id: poetry-lock + files: pyproject.toml - id: poetry-export args: - - "--output" - - "requirements.txt" - - "--without-hashes" - - "--without-urls" + - --output=requirements.txt + - --without-hashes + - --without-urls diff --git a/Makefile b/Makefile index 2ec0c2f..a1110d1 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,8 @@ TARGET := $(DIST)/$(NAME)$(EXE) TARGET_INSTALL := $(BIN)/$(NAME)$(EXE) +all: + clean: $(RM) --recursive $(CURDIR)/build $(RM) --recursive $(DIST) @@ -29,16 +31,21 @@ install: $(TARGET_INSTALL) -poetry: $(CURDIR)/poetry.lock $(CURDIR)/requirements.txt +pretty: black prettier -pretty: +################################################################ +# Auxiliary Targets # +################################################################ + +black: isort --profile black $(CURDIR) black $(CURDIR) -ALWAYS: +prettier: $(CURDIR)/.gitignore + prettier --write --ignore-path $< $(CURDIR) $(TARGET_INSTALL): $(TARGET) - install -D --mode=u=rwx,go=rx --no-target-directory $< $@ + @ install -D --mode="u=rwx,go=rx" --no-target-directory --verbose $< $@ $(CURDIR)/demo.gif: $(CURDIR)/demo.tape ifeq ($(BW_SESSION),) @@ -47,11 +54,5 @@ vhs < $< endif -$(CURDIR)/poetry.lock: ALWAYS - poetry lock - -$(CURDIR)/requirements.txt: $(CURDIR)/poetry.lock - poetry export --output=$@ --without-hashes --without-urls - -$(TARGET): - pyinstaller --onefile --name $(NAME) $(CURDIR)/main.py +$(TARGET): $(CURDIR)/main.py + python -m nuitka --standalone --onefile --output-filename=$(NAME) --output-dir=$(DIST) --remove-output $< diff --git a/poetry.lock b/poetry.lock index 355ff0e..59b2303 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# 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.5.0 and should not be changed by hand. [[package]] name = "altgraph" version = "0.17.3" description = "Python graph (network) package" -category = "dev" optional = false python-versions = "*" files = [ @@ -16,7 +15,6 @@ name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" -category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -35,7 +33,6 @@ name = "black" version = "23.3.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -81,21 +78,19 @@ [[package]] name = "certifi" -version = "2022.12.7" +version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, ] [[package]] name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -180,7 +175,6 @@ name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -195,7 +189,6 @@ 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 = [ @@ -207,7 +200,6 @@ name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -219,7 +211,6 @@ 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 = [ @@ -237,7 +228,6 @@ name = "macholib" version = "1.16.2" description = "Mach-O header analysis and editing" -category = "dev" optional = false python-versions = "*" files = [ @@ -252,7 +242,6 @@ name = "markdown-it-py" version = "2.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -277,7 +266,6 @@ name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -289,7 +277,6 @@ 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.5" files = [ @@ -301,7 +288,6 @@ name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -313,7 +299,6 @@ 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 = [ @@ -325,7 +310,6 @@ name = "pefile" version = "2023.2.7" description = "Python PE parsing module" -category = "dev" optional = false python-versions = ">=3.6.0" files = [ @@ -335,25 +319,23 @@ [[package]] name = "platformdirs" -version = "3.5.0" +version = "3.5.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.5.0-py3-none-any.whl", hash = "sha256:47692bc24c1958e8b0f13dd727307cff1db103fca36399f457da8e05f222fdc4"}, - {file = "platformdirs-3.5.0.tar.gz", hash = "sha256:7954a68d0ba23558d753f73437c55f89027cf8f5108c19844d4b82e5af396335"}, + {file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, + {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, ] [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pygments" version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -366,24 +348,23 @@ [[package]] name = "pyinstaller" -version = "5.10.1" +version = "5.11.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.10.1-py3-none-macosx_10_13_universal2.whl", hash = "sha256:247b99c52dc3cf69eba905da30dbca0a8ea309e1058cab44658ac838d9b8f2f0"}, - {file = "pyinstaller-5.10.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:2d16641a495593d174504263b038a6d3d46b3b15a381ccb216cf6cce67723512"}, - {file = "pyinstaller-5.10.1-py3-none-manylinux2014_i686.whl", hash = "sha256:df97aaf1103a1c485aa3c9947792a86675e370f5ce9b436b4a84e34a4180c8d2"}, - {file = "pyinstaller-5.10.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:333b4ffda38d9c0a561c38429dd9848d37aa78f3b8ea8a6f2b2e69a60d523c02"}, - {file = "pyinstaller-5.10.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:6afc7aa4885ffd3e6121a8cf2138830099f874c18cb5869bed8c1a42db82d060"}, - {file = "pyinstaller-5.10.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:85e39e36d03355423636907a26a9bfa06fdc93cb1086441b19d2d0ca448479fa"}, - {file = "pyinstaller-5.10.1-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:7a1db833bb0302b66ae3ae337fbd5487699658ce869ca4d538b5359b8179e83a"}, - {file = "pyinstaller-5.10.1-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:bb7de35cd209a0a0358aec761a273ae951d2161c03728f15d9a640d06a88e472"}, - {file = "pyinstaller-5.10.1-py3-none-win32.whl", hash = "sha256:9e9a38f41f8280c8e29b294716992852281b41fbe64ba330ebab671efe27b26d"}, - {file = "pyinstaller-5.10.1-py3-none-win_amd64.whl", hash = "sha256:915a502802c751bafd92d568ac57468ec6cdf252b8308aa9a167bbc2c565ad2d"}, - {file = "pyinstaller-5.10.1-py3-none-win_arm64.whl", hash = "sha256:f677fbc151db1eb00ada94e86ed128e7b359cbd6bf3f6ea815afdde687692d46"}, - {file = "pyinstaller-5.10.1.tar.gz", hash = "sha256:6ecc464bf56919bf2d6bff275f38d85ff08ae747b8ead3a0c26cf85573b3c723"}, + {file = "pyinstaller-5.11.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:8454bac8f3cb2219a3ce2227fd039bdaf943dcba60e8c55732958ea3a6d81263"}, + {file = "pyinstaller-5.11.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:b3c6299fd7526c6ca87ea5f9017fb1928d47046df0b9f983d6bbd893801010dc"}, + {file = "pyinstaller-5.11.0-py3-none-manylinux2014_i686.whl", hash = "sha256:e359571327bbef434fc61324891399f9117efbb685b5065234eebb01713650a8"}, + {file = "pyinstaller-5.11.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:a445a91b85c9a1ea3985268643a674900dd86f244cc4be4ff4ec4c6367ff99a9"}, + {file = "pyinstaller-5.11.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2a1fe6d0da22f207cfa4b3221fe365503cba071c77aac19f76a75503f67d9ff9"}, + {file = "pyinstaller-5.11.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:b4cac0e7b0d63c6a869843113008f59fd5b38b2959ffa6059e7fac4bb05de92b"}, + {file = "pyinstaller-5.11.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:0af9d11a09ce217d32f95c79c984054457b310671387ff32bae1496876308556"}, + {file = "pyinstaller-5.11.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b8a4f6834e5c85150948e22c74dd3ab8b98aa4ccdf964d880ac14d2f78d9c1a4"}, + {file = "pyinstaller-5.11.0-py3-none-win32.whl", hash = "sha256:049cdc3524aefb5ca015a63d2c81b6bf1567cc818ac066859fbfde702c6165d3"}, + {file = "pyinstaller-5.11.0-py3-none-win_amd64.whl", hash = "sha256:42fdea67e4c2217cedd54d17d1d402736df3ba718db2b497df65df5a68ae4f93"}, + {file = "pyinstaller-5.11.0-py3-none-win_arm64.whl", hash = "sha256:036a062a228af41f6bb6370a4e87cef34858cc839200a07ace7f8738ef64ad86"}, + {file = "pyinstaller-5.11.0.tar.gz", hash = "sha256:cb87cee0b3c81ccd74d4bf3f4faf03b5e1e39bb91f1a894b2ce4cd22363bf779"}, ] [package.dependencies] @@ -400,21 +381,19 @@ [[package]] name = "pyinstaller-hooks-contrib" -version = "2023.2" +version = "2023.3" description = "Community maintained hooks for PyInstaller" -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pyinstaller-hooks-contrib-2023.2.tar.gz", hash = "sha256:7fb856a81fd06a717188a3175caa77e902035cc067b00b583c6409c62497b23f"}, - {file = "pyinstaller_hooks_contrib-2023.2-py2.py3-none-any.whl", hash = "sha256:e02c5f0ee3d4f5814588c2128caf5036c058ba764aaf24d957bb5311ad8690ad"}, + {file = "pyinstaller-hooks-contrib-2023.3.tar.gz", hash = "sha256:bb39e1038e3e0972420455e0b39cd9dce73f3d80acaf4bf2b3615fea766ff370"}, + {file = "pyinstaller_hooks_contrib-2023.3-py2.py3-none-any.whl", hash = "sha256:062ad7a1746e1cfc24d3a8c4be4e606fced3b123bda7d419f14fcf7507804b07"}, ] [[package]] name = "pywin32-ctypes" version = "0.2.0" description = "" -category = "dev" optional = false python-versions = "*" files = [ @@ -424,21 +403,20 @@ [[package]] name = "requests" -version = "2.29.0" +version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "requests-2.29.0-py3-none-any.whl", hash = "sha256:e8f3c9be120d3333921d213eef078af392fba3933ab7ed2d1cba3b56f2568c3b"}, - {file = "requests-2.29.0.tar.gz", hash = "sha256:f2e34a75f4749019bb0e3effb66683630e4ffeaf75819fb51bebef1bf5aef059"}, + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" +urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] @@ -446,14 +424,13 @@ [[package]] name = "rich" -version = "13.3.5" +version = "13.4.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.5-py3-none-any.whl", hash = "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704"}, - {file = "rich-13.3.5.tar.gz", hash = "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c"}, + {file = "rich-13.4.1-py3-none-any.whl", hash = "sha256:d204aadb50b936bf6b1a695385429d192bc1fdaf3e8b907e8e26f4c4e4b5bf75"}, + {file = "rich-13.4.1.tar.gz", hash = "sha256:76f6b65ea7e5c5d924ba80e322231d7cb5b5981aa60bfc1e694f1bc097fe6fe1"}, ] [package.dependencies] @@ -465,26 +442,24 @@ [[package]] name = "setuptools" -version = "67.7.2" +version = "67.8.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, - {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, + {file = "setuptools-67.8.0-py3-none-any.whl", hash = "sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f"}, + {file = "setuptools-67.8.0.tar.gz", hash = "sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] 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.4.0" description = "Tool to Detect Surrounding Shell" -category = "dev" optional = false python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,>=2.6" files = [ @@ -496,7 +471,6 @@ name = "soupsieve" version = "2.4.1" description = "A modern CSS selector implementation for Beautiful Soup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -508,7 +482,6 @@ 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 = [ @@ -529,7 +502,6 @@ name = "typer-cli" version = "0.0.13" description = "Run Typer scripts with completion, without having to create a package, using Typer CLI." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -544,20 +516,20 @@ [[package]] name = "urllib3" -version = "1.26.15" +version = "2.0.2" 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.*" +python-versions = ">=3.7" files = [ - {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, - {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, + {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"}, + {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" diff --git a/requirements.txt b/requirements.txt index 0288d64..beb20f2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ beautifulsoup4==4.12.2 ; python_version >= "3.11" and python_version < "3.12" -certifi==2022.12.7 ; python_version >= "3.11" and python_version < "3.12" +certifi==2023.5.7 ; python_version >= "3.11" and python_version < "3.12" charset-normalizer==3.1.0 ; python_version >= "3.11" and python_version < "3.12" click==8.1.3 ; python_version >= "3.11" and python_version < "3.12" colorama==0.4.6 ; python_version >= "3.11" and python_version < "3.12" and platform_system == "Windows" @@ -7,8 +7,8 @@ markdown-it-py==2.2.0 ; python_version >= "3.11" and python_version < "3.12" mdurl==0.1.2 ; python_version >= "3.11" and python_version < "3.12" pygments==2.15.1 ; python_version >= "3.11" and python_version < "3.12" -requests==2.29.0 ; python_version >= "3.11" and python_version < "3.12" -rich==13.3.5 ; python_version >= "3.11" and python_version < "3.12" +requests==2.31.0 ; python_version >= "3.11" and python_version < "3.12" +rich==13.4.1 ; python_version >= "3.11" and python_version < "3.12" soupsieve==2.4.1 ; python_version >= "3.11" and python_version < "3.12" typer==0.7.0 ; python_version >= "3.11" and python_version < "3.12" -urllib3==1.26.15 ; python_version >= "3.11" and python_version < "3.12" +urllib3==2.0.2 ; python_version >= "3.11" and python_version < "3.12" diff --git a/template b/template new file mode 160000 index 0000000..d5e4fcd --- /dev/null +++ b/template @@ -0,0 +1 @@ +Subproject commit d5e4fcd7a71b420c2e2bb744de855f3ecd40ac21 diff --git a/thu_learn_downloader/__main__.py b/thu_learn_downloader/__main__.py index fe9fd1e..819e949 100644 --- a/thu_learn_downloader/__main__.py +++ b/thu_learn_downloader/__main__.py @@ -25,9 +25,7 @@ @app.command(name="tld") def main( username: str = typer.Option("liqin20", "-u", "--username"), - password: str = typer.Option( - None, "-p", "--password", prompt=True, hide_input=True - ), + password: str = typer.Option(..., "-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"), diff --git a/thu_learn_downloader/helper.py b/thu_learn_downloader/helper.py index c7cb577..166c87a 100644 --- a/thu_learn_downloader/helper.py +++ b/thu_learn_downloader/helper.py @@ -66,7 +66,7 @@ resp: Response = self.fetch_with_token( urls.learn_course_list(semester=semester_id, course_type=course_type) ) - results = resp.json()["resultList"] or list() + results = resp.json()["resultList"] or [] return list(map(parser.parse_course_info, results)) def get_file_list( @@ -75,7 +75,7 @@ resp: Response = self.fetch_with_token( urls.learn_file_clazz(course_id=course_id) ) - file_clazz: dict[str, str] = dict() + file_clazz: dict[str, str] = {} rows = resp.json()["object"]["rows"] for row in rows: file_clazz[row["kjflid"]] = row["bt"] # 课件分类 ID, 标题 @@ -128,7 +128,7 @@ ) -> list[t.Homework]: resp: Response = self.fetch_with_token(request=req) json = resp.json() - res = json["object"]["aaData"] or list() + res = json["object"]["aaData"] or [] return list( map( parser.parse_homework, diff --git a/thu_learn_downloader/parser.py b/thu_learn_downloader/parser.py index 9e895fd..cff0f2e 100644 --- a/thu_learn_downloader/parser.py +++ b/thu_learn_downloader/parser.py @@ -59,7 +59,7 @@ id=raw["zyid"], # 作业 ID student_homework_id=raw["xszyid"], # 学生作业 ID number=int(raw["wz"]), # - title=html.unescape(raw["bt"]), # 标题 + title=str(html.unescape(raw["bt"])).strip(), # 标题 starts_time=utils.from_timestamp(raw.get("kssj")), # 开始时间 deadline=utils.from_timestamp(raw.get("jzsj")), # 截止时间 submit_time=utils.from_timestamp(raw.get("scsj")), # 上传时间 diff --git a/thu_learn_downloader/urls.py b/thu_learn_downloader/urls.py index 0122a09..310139c 100644 --- a/thu_learn_downloader/urls.py +++ b/thu_learn_downloader/urls.py @@ -18,8 +18,8 @@ def make_req( method: str = "GET", url: str = make_url(), - data: dict = dict(), - params: dict = dict(), + data: dict = {}, + params: dict = {}, ) -> Request: return Request(method=method, url=url, data=data, params=params)