Compare commits

..

75 Commits

Author SHA1 Message Date
scito
ccb52cc8b5 ci: fix conditional push for alpine images 2025-03-15 09:30:48 +01:00
scito
41ed2b62d4 build: drop support for Python 3.8 and require Python 3.9 or higher 2025-03-15 09:30:48 +01:00
scito
b6ab6417cb build(deps): update protobuf to version 6.30.1 2025-03-15 09:30:48 +01:00
scito
e857912c74 ci: add cleanup job for old container images on ghcr.io 2025-03-09 13:16:21 +01:00
dependabot[bot]
ac18fbf020 build(deps-dev): bump pytest from 8.3.4 to 8.3.5
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.4 to 8.3.5.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.3.4...8.3.5)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 22:23:28 +01:00
scito
494a9f8446 ci: check master and secret_source for multiarch manifest creation 2025-03-03 22:06:25 +01:00
dependabot[bot]
cec47852d8 build(deps-dev): bump nuitka from 2.6.6 to 2.6.7
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.6.6 to 2.6.7.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.6.6...2.6.7)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-01 20:36:18 +01:00
Roland Kurmann
d5a8b6f0c0 ci: fix digest artifact names for multi-platform Docker builds (fix #367) (#376)
* ci: fix digest artifact names for multi-platform Docker builds

* ci: remove unused platforms parameter from Docker build steps

* ci: push Docker images exceptionally on feature branch

* ci: update Dockerfile to include uname command and fix label formatting

* ci: update CI workflow to set platforms dynamically for Docker builds

* ci: disable arm64 docker

* ci: only arm64 docker

* ci: update CI workflow for multiarch Docker builds and manifest creation

* ci: add multiarch manifest creation

* ci: fix multiarch manifest for loop

* ci: restore push conditions for Docker image builds

* ci: restore push conditions for Docker image builds
2025-03-01 20:19:15 +01:00
Roland Kurmann
95c34277ca ci: add additional ci test platforms ubuntu-24.04-arm and macos-13 (#372)
* ci: add support for ubuntu-24.04-arm and macos-13 in CI workflow

* ci: update CI workflows to include Python 3.x and enhance macOS build configurations

* ci: update Docker Buildx image to latest version

* ci: push bullseye image also to ghcr

* ci: run Docker natively on amd64 and arm64, avoid qemu emulation

* ci: fix native docker releases

* ci: comment out macOS build steps due to missing zbar shared library
2025-03-01 13:12:48 +01:00
scito
ca6ca1f0e6 ci: push bullseye image also to ghcr 2025-03-01 11:12:27 +01:00
scito
026db54551 ci: update Docker Buildx image to latest version 2025-03-01 11:05:15 +01:00
dependabot[bot]
793b061d3f build(deps-dev): bump setuptools from 75.8.0 to 75.8.2
Bumps [setuptools](https://github.com/pypa/setuptools) from 75.8.0 to 75.8.2.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v75.8.0...v75.8.2)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-01 10:10:25 +01:00
scito
7557ae125a build(deps): update deps and fix toc 2025-02-22 09:12:30 +01:00
scito
f94120b84c ci: remove workaround for Docker Buildx failing builds 2025-02-22 09:12:30 +01:00
dependabot[bot]
787a975009 build(deps-dev): bump nuitka from 2.6.5 to 2.6.6
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.6.5 to 2.6.6.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.6.5...2.6.6)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-21 09:00:57 +01:00
dependabot[bot]
95c1cc3cfe build(deps-dev): bump flake8 from 7.1.1 to 7.1.2
Bumps [flake8](https://github.com/pycqa/flake8) from 7.1.1 to 7.1.2.
- [Commits](https://github.com/pycqa/flake8/compare/7.1.1...7.1.2)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-21 09:00:42 +01:00
dependabot[bot]
95176ee9de build(deps-dev): bump nuitka from 2.6.4 to 2.6.5
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.6.4 to 2.6.5.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/commits)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-14 15:09:52 +01:00
dependabot[bot]
7b379b58a3 build(deps-dev): bump types-protobuf
Bumps [types-protobuf](https://github.com/python/typeshed) from 5.29.1.20241207 to 5.29.1.20250208.
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-protobuf
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-14 14:48:55 +01:00
scito
10a60ab556 fix mypy error
src/extract_otp_secrets.py:707: error: Argument 1 to "save" of "PyPNGImage" has incompatible type "str"; expected "SupportsWrite[bytes]"  [arg-type]
2025-02-08 09:12:45 +01:00
scito
38e7e8b40b fix and improve README.md (fixes #347)
- fix docker tag
- improve podman compatibility (add repo domain)
2025-02-08 09:11:27 +01:00
dependabot[bot]
6b25cc96e2 build(deps-dev): bump nuitka from 2.6 to 2.6.4
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.6 to 2.6.4.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.6...2.6.4)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-08 08:22:04 +01:00
dependabot[bot]
4799483b2b build(deps-dev): bump pylint from 3.3.3 to 3.3.4
Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.3.3 to 3.3.4.
- [Release notes](https://github.com/pylint-dev/pylint/releases)
- [Commits](https://github.com/pylint-dev/pylint/compare/v3.3.3...v3.3.4)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-08 08:21:50 +01:00
dependabot[bot]
3e6eeffff5 build(deps-dev): bump mypy from 1.14.1 to 1.15.0
Bumps [mypy](https://github.com/python/mypy) from 1.14.1 to 1.15.0.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.14.1...v1.15.0)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-08 08:21:36 +01:00
scito
00d25e89d9 build(deps): bump opencv-python to 4.11.0.86 and protobuf to 5.29.3 2025-01-25 12:22:12 +01:00
dependabot[bot]
f7453c7720 build(deps-dev): bump nuitka from 2.5.9 to 2.6
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.5.9 to 2.6.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.5.9...2.6)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-25 11:54:26 +01:00
dependabot[bot]
77d799a461 build(deps-dev): bump setuptools-git-versioning from 2.0.0 to 2.1.0
Bumps [setuptools-git-versioning](https://github.com/dolfinus/setuptools-git-versioning) from 2.0.0 to 2.1.0.
- [Release notes](https://github.com/dolfinus/setuptools-git-versioning/releases)
- [Changelog](https://github.com/dolfinus/setuptools-git-versioning/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/dolfinus/setuptools-git-versioning/compare/v2.0.0...v2.1.0)

---
updated-dependencies:
- dependency-name: setuptools-git-versioning
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-25 11:53:59 +01:00
dependabot[bot]
9a0d8dbc80 build(deps): bump opencv-contrib-python from 4.10.0.84 to 4.11.0.86
Bumps [opencv-contrib-python](https://github.com/opencv/opencv-python) from 4.10.0.84 to 4.11.0.86.
- [Release notes](https://github.com/opencv/opencv-python/releases)
- [Commits](https://github.com/opencv/opencv-python/commits)

---
updated-dependencies:
- dependency-name: opencv-contrib-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-25 11:53:42 +01:00
dependabot[bot]
9f39cc4508 build(deps-dev): bump nuitka from 2.5.8 to 2.5.9
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.5.8 to 2.5.9.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.5.8...2.5.9)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-17 19:46:28 +03:30
dependabot[bot]
08dbda3b80 build(deps-dev): bump setuptools from 75.2.0 to 75.8.0
Bumps [setuptools](https://github.com/pypa/setuptools) from 75.2.0 to 75.8.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v75.2.0...v75.8.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-17 19:45:48 +03:30
dependabot[bot]
8317ef0bf2 build(deps): bump pillow from 11.0.0 to 11.1.0
Bumps [pillow](https://github.com/python-pillow/Pillow) from 11.0.0 to 11.1.0.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/11.0.0...11.1.0)

---
updated-dependencies:
- dependency-name: pillow
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-17 19:45:06 +03:30
dependabot[bot]
b9c5833374 build(deps-dev): bump mypy from 1.14.0 to 1.14.1
Bumps [mypy](https://github.com/python/mypy) from 1.14.0 to 1.14.1.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.14.0...v1.14.1)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-17 19:43:54 +03:30
dependabot[bot]
b6f5c41559 build(deps-dev): bump pylint from 3.3.2 to 3.3.3
Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.3.2 to 3.3.3.
- [Release notes](https://github.com/pylint-dev/pylint/releases)
- [Commits](https://github.com/pylint-dev/pylint/compare/v3.3.2...v3.3.3)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-25 11:05:55 +01:00
scito
e665d159f6 upgrade deps and fix errors 2024-12-25 10:38:34 +01:00
dependabot[bot]
d9bd792394 build(deps-dev): bump nuitka from 2.5.6 to 2.5.8
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.5.6 to 2.5.8.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.5.6...2.5.8)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-23 17:34:47 +01:00
dependabot[bot]
cb8ef2ae22 build(deps-dev): bump mypy from 1.13.0 to 1.14.0
Bumps [mypy](https://github.com/python/mypy) from 1.13.0 to 1.14.0.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.13.0...v1.14.0)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-23 17:34:29 +01:00
scito
fa8506935f add python 3.13 to pyproject.toml; bump numpy 2024-12-14 11:47:58 +01:00
dependabot[bot]
c49ba82f1b build(deps-dev): bump types-protobuf
Bumps [types-protobuf](https://github.com/python/typeshed) from 5.28.3.20241203 to 5.29.1.20241207.
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-protobuf
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-11 21:15:50 +01:00
dependabot[bot]
f11b2d2483 build(deps-dev): bump pylint from 3.3.1 to 3.3.2
Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/pylint-dev/pylint/releases)
- [Commits](https://github.com/pylint-dev/pylint/compare/v3.3.1...v3.3.2)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-07 08:52:01 +01:00
dependabot[bot]
894edb4561 build(deps-dev): bump pytest from 8.3.3 to 8.3.4
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.3 to 8.3.4.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.3.3...8.3.4)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-07 08:51:46 +01:00
dependabot[bot]
4c4b033aa4 build(deps-dev): bump types-protobuf
Bumps [types-protobuf](https://github.com/python/typeshed) from 5.28.3.20241030 to 5.28.3.20241203.
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-protobuf
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-07 08:51:29 +01:00
dependabot[bot]
f6a003d707 build(deps-dev): bump nuitka from 2.5.4 to 2.5.6
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.5.4 to 2.5.6.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.5.4...2.5.6)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-07 08:51:14 +01:00
scito
6a2dc80ad4 upgrade to protobuf 5.29.1; add one missing type 2024-12-06 19:15:58 +01:00
scito
b54974e584 support glob expansion for infiles, fixes #328
Glob expansion for infiles is useful in environments where there is no expansion in the shell, e.g. on Windows.
2024-12-01 18:39:04 +01:00
scito
a2845556a4 upgrade to protobuf 5.29.0 2024-11-28 21:40:53 +01:00
dependabot[bot]
7ce765ddb1 build(deps-dev): bump wheel from 0.45.0 to 0.45.1
Bumps [wheel](https://github.com/pypa/wheel) from 0.45.0 to 0.45.1.
- [Release notes](https://github.com/pypa/wheel/releases)
- [Changelog](https://github.com/pypa/wheel/blob/main/docs/news.rst)
- [Commits](https://github.com/pypa/wheel/compare/0.45.0...0.45.1)

---
updated-dependencies:
- dependency-name: wheel
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-28 20:52:49 +01:00
dependabot[bot]
fc9b36d281 build(deps-dev): bump nuitka from 2.5.1 to 2.5.4
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.5.1 to 2.5.4.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.5.1...2.5.4)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-28 20:52:35 +01:00
dependabot[bot]
556d1350b8 build(deps-dev): bump nuitka from 2.4.11 to 2.5.1
Bumps [nuitka](https://github.com/Nuitka/Nuitka) from 2.4.11 to 2.5.1.
- [Changelog](https://github.com/Nuitka/Nuitka/blob/develop/Changelog.rst)
- [Commits](https://github.com/Nuitka/Nuitka/compare/2.4.11...2.5.1)

---
updated-dependencies:
- dependency-name: nuitka
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-24 12:18:38 +01:00
dependabot[bot]
a84d52fb38 build(deps-dev): bump setuptools from 75.2.0 to 75.6.0
Bumps [setuptools](https://github.com/pypa/setuptools) from 75.2.0 to 75.6.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v75.2.0...v75.6.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-24 12:18:23 +01:00
dependabot[bot]
2928168bc2 build(deps-dev): bump setuptools from 75.2.0 to 75.5.0
Bumps [setuptools](https://github.com/pypa/setuptools) from 75.2.0 to 75.5.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v75.2.0...v75.5.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-15 07:18:43 +01:00
dependabot[bot]
5714d71e7c build(deps-dev): bump wheel from 0.44.0 to 0.45.0
Bumps [wheel](https://github.com/pypa/wheel) from 0.44.0 to 0.45.0.
- [Release notes](https://github.com/pypa/wheel/releases)
- [Changelog](https://github.com/pypa/wheel/blob/main/docs/news.rst)
- [Commits](https://github.com/pypa/wheel/compare/0.44.0...0.45.0)

---
updated-dependencies:
- dependency-name: wheel
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-12 17:29:25 +01:00
dependabot[bot]
170fbf6edb build(deps-dev): bump setuptools from 75.2.0 to 75.4.0
Bumps [setuptools](https://github.com/pypa/setuptools) from 75.2.0 to 75.4.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v75.2.0...v75.4.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-12 17:29:09 +01:00
scito
d2993c093c fix readme: remove duplicated toc 2024-11-10 10:46:57 +01:00
scito
c9a2784e56 upgrade deps 2024-11-10 10:46:37 +01:00
dependabot[bot]
59804c9970 build(deps-dev): bump setuptools from 75.2.0 to 75.3.0
Bumps [setuptools](https://github.com/pypa/setuptools) from 75.2.0 to 75.3.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v75.2.0...v75.3.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-10 09:21:48 +01:00
dependabot[bot]
5955c1dc69 build(deps-dev): bump types-protobuf
Bumps [types-protobuf](https://github.com/python/typeshed) from 5.28.0.20240924 to 5.28.3.20241030.
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-protobuf
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-01 10:30:53 +01:00
dependabot[bot]
bfb63ebf49 build(deps-dev): bump pytest-cov from 5.0.0 to 6.0.0
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 5.0.0 to 6.0.0.
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v5.0.0...v6.0.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-01 10:30:13 +01:00
scito
396071f15a set Docker base image to Python 3.13; fix README 2024-10-25 21:25:22 +02:00
scito
6503b442f1 comment out native macos-12 release build instead of exclude
since exclude failed in release build
2024-10-25 20:38:08 +02:00
daniel
5c5e2096b8 added support for devenv 2024-10-24 19:43:06 +02:00
scito
eb8bb38aa5 update deps 2024-10-24 19:17:08 +02:00
scito
d486a94c6f disable macos releases due to build failures
FileNotFoundError: Icon input file /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/PyInstaller/bootloader/images/icon-windowed.icns not found
2024-10-24 18:55:34 +02:00
scito
ee932c05e3 use Python 3.13 in Docker 2024-10-24 18:55:34 +02:00
scito
e13a4584fb add Pythion 3.13 to README 2024-10-20 10:54:36 +02:00
scito
91e2efe7e1 upgrade deps 2024-10-13 12:49:50 +02:00
scito
b5442a0d94 test python 3.13 in CI 2024-10-13 11:57:13 +02:00
Roland Kurmann
2318c3a185 Merge pull request #298 from scito/dependabot/pip/qrcode-8.0
build(deps): bump qrcode from 7.4.2 to 8.0
2024-10-07 18:29:22 +02:00
dependabot[bot]
fcfdf1cbf6 build(deps): bump qrcode from 7.4.2 to 8.0
Bumps [qrcode](https://github.com/lincolnloop/python-qrcode) from 7.4.2 to 8.0.
- [Changelog](https://github.com/lincolnloop/python-qrcode/blob/main/CHANGES.rst)
- [Commits](https://github.com/lincolnloop/python-qrcode/compare/v7.4.2...v8.0)

---
updated-dependencies:
- dependency-name: qrcode
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 15:13:27 +00:00
Roland Kurmann
f07db1b74f Merge pull request #297 from scito/proto_5282
upgrade to protobul 5.28.2
2024-09-28 10:07:10 +02:00
scito
5d5453231f upgrade to protobul 5.28.2 2024-09-27 12:05:18 +02:00
Roland Kurmann
5d7afeeed3 Merge pull request #295 from scito/dependabot/pip/pylint-3.3.1
build(deps-dev): bump pylint from 3.3.0 to 3.3.1
2024-09-27 09:19:43 +02:00
dependabot[bot]
d9f760ad97 build(deps-dev): bump pylint from 3.3.0 to 3.3.1
Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/pylint-dev/pylint/releases)
- [Commits](https://github.com/pylint-dev/pylint/compare/v3.3.0...v3.3.1)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-24 15:27:28 +00:00
Roland Kurmann
6c54a438cb Merge pull request #294 from scito/dependabot/pip/pylint-3.3.0
build(deps-dev): bump pylint from 3.2.7 to 3.3.0
2024-09-23 09:36:11 +02:00
dependabot[bot]
9d4f8c83b4 build(deps-dev): bump pylint from 3.2.7 to 3.3.0
Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.2.7 to 3.3.0.
- [Release notes](https://github.com/pylint-dev/pylint/releases)
- [Commits](https://github.com/pylint-dev/pylint/compare/v3.2.7...v3.3.0)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-20 16:01:58 +00:00
Roland Kurmann
9b8c79b232 Merge pull request #288 from scito/dependabot/pip/pytest-8.3.3
build(deps-dev): bump pytest from 8.3.2 to 8.3.3
2024-09-11 20:33:03 +02:00
dependabot[bot]
50151c4f3f build(deps-dev): bump pytest from 8.3.2 to 8.3.3
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.2 to 8.3.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.3.2...8.3.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-10 15:58:32 +00:00
19 changed files with 895 additions and 517 deletions

3
.envrc Normal file
View File

@@ -0,0 +1,3 @@
source_url "https://raw.githubusercontent.com/cachix/devenv/95f329d49a8a5289d31e0982652f7058a189bfca/direnvrc" "sha256-d+8cBpDfDBj41inrADaJt+bDWhOktwslgoP5YiGJ1v0="
use devenv

View File

@@ -20,8 +20,9 @@ jobs:
strategy:
matrix:
python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"]
platform: [ubuntu-latest, macos-latest, windows-latest]
# 3.x is used to run code coverage
python-version: ["3.x", "3.13", "3.12", "3.11", "3.10", "3.9"]
platform: [ubuntu-latest, macos-latest, windows-latest, ubuntu-24.04-arm, macos-13]
# exclude:
runs-on: ${{ matrix.platform }}
@@ -52,7 +53,6 @@ jobs:
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=200 --statistics
if: matrix.python-version != '3.7'
- name: Type checking with mypy
run: |
mypy --install-types --non-interactive src/*.py tests/*.py

View File

@@ -27,7 +27,17 @@ jobs:
build-and-push-docker-debian-image:
name: Build Docker Bookworm image and push to repositories
# run only when code is compiling and tests are passing
runs-on: ubuntu-latest
strategy:
matrix:
include:
- DOCKER_ARCH: amd64
platform: ubuntu-latest
PLATFORM_ARCH: x86_64
- DOCKER_ARCH: arm64
platform: ubuntu-24.04-arm
PLATFORM_ARCH: arm64
runs-on: ${{ matrix.platform }}
# steps to perform in job
steps:
@@ -50,11 +60,6 @@ jobs:
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
# Workaround for failing builds: https://github.com/docker/build-push-action/issues/761#issuecomment-1383822381
# TODO remove workaround when fixed
with:
driver-opts: |
image=moby/buildkit:v0.10.6
- name: Login to DockerHub
uses: docker/login-action@v3
@@ -71,11 +76,11 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GHCR_IO_TOKEN }}
- name: "Build image and push to Docker Hub and GitHub Container Registry"
- name: "Build image (Bookworm/Debian 12) and push to Docker Hub and GitHub Container Registry"
id: docker_build_qr_reader_latest
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
platforms: linux/${{ matrix.DOCKER_ARCH }}
# relative path to the place where source code with Dockerfile is located
# TODO file:, move to docker/
context: .
@@ -83,13 +88,13 @@ jobs:
# builder: ${{ steps.buildx.outputs.name }}
# Note: tags has to be all lower-case
build-args: |
BASE_IMAGE=python:3.12-slim-bookworm
BASE_IMAGE=python:3.13-slim-bookworm
pull: true
tags: |
scit0/extract_otp_secrets:latest
scit0/extract_otp_secrets:bookworm
ghcr.io/scito/extract_otp_secrets:latest
ghcr.io/scito/extract_otp_secrets:bookworm
docker.io/scit0/extract_otp_secrets:latest-${{ matrix.PLATFORM_ARCH }}
docker.io/scit0/extract_otp_secrets:bookworm-${{ matrix.PLATFORM_ARCH }}
ghcr.io/scito/extract_otp_secrets:latest-${{ matrix.PLATFORM_ARCH }}
ghcr.io/scito/extract_otp_secrets:bookworm-${{ matrix.PLATFORM_ARCH }}
# build on feature branches, push only on master branch
push: ${{ github.ref == 'refs/heads/master' && github.secret_source == 'Actions'}}
@@ -102,13 +107,61 @@ jobs:
if: github.ref == 'refs/heads/master'
uses: actions/upload-artifact@v4
with:
name: debian_digests
name: digests_bookworm_${{ matrix.PLATFORM_ARCH }}
path: digests.txt
create-multiarch-debian-manifests:
name: Create multiarch manifests for Debian image
if: ${{ github.ref == 'refs/heads/master' && github.secret_source == 'Actions'}}
runs-on: ubuntu-latest
needs:
- build-and-push-docker-debian-image
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Github Packages
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_IO_TOKEN }}
- name: Create multiarch manifests
if: ${{ github.ref == 'refs/heads/master' && github.secret_source == 'Actions'}}
shell: bash
run: |
for tag in \
docker.io/scit0/extract_otp_secrets:latest \
ghcr.io/scito/extract_otp_secrets:latest \
docker.io/scit0/extract_otp_secrets:bookworm \
ghcr.io/scito/extract_otp_secrets:bookworm \
; do
docker buildx imagetools create -t $tag \
$tag-x86_64 \
$tag-arm64
done
build-and-push-docker-alpine-image:
name: Build Docker Alpine image and push to repositories
# run only when code is compiling and tests are passing
runs-on: ubuntu-latest
strategy:
matrix:
include:
- DOCKER_ARCH: amd64
platform: ubuntu-latest
PLATFORM_ARCH: x86_64
- DOCKER_ARCH: arm64
platform: ubuntu-24.04-arm
PLATFORM_ARCH: arm64
runs-on: ${{ matrix.platform }}
# steps to perform in job
steps:
@@ -151,18 +204,18 @@ jobs:
id: docker_build_only_txt
uses: docker/build-push-action@v5
with:
platforms: linux/${{ matrix.DOCKER_ARCH }}
# relative path to the place where source code with Dockerfile is located
platforms: linux/amd64,linux/arm64
context: .
file: docker/Dockerfile_only_txt
# builder: ${{ steps.buildx.outputs.name }}
# Note: tags has to be all lower-case
pull: true
tags: |
scit0/extract_otp_secrets:only-txt
scit0/extract_otp_secrets:alpine
ghcr.io/scito/extract_otp_secrets:only-txt
ghcr.io/scito/extract_otp_secrets:alpine
docker.io/scit0/extract_otp_secrets:only-txt-${{ matrix.PLATFORM_ARCH }}
docker.io/scit0/extract_otp_secrets:alpine-${{ matrix.PLATFORM_ARCH }}
ghcr.io/scito/extract_otp_secrets:only-txt-${{ matrix.PLATFORM_ARCH }}
ghcr.io/scito/extract_otp_secrets:alpine-${{ matrix.PLATFORM_ARCH }}
# build on feature branches, push only on master branch
push: ${{ github.ref == 'refs/heads/master' && github.secret_source == 'Actions'}}
build-args: |
@@ -178,13 +231,63 @@ jobs:
if: github.ref == 'refs/heads/master'
uses: actions/upload-artifact@v4
with:
name: alpine_digests
name: digests_alpine_${{ matrix.PLATFORM_ARCH }}
path: digests.txt
create-multiarch-alpine-manifests:
name: Create multiarch manifests for Alpine image
if: ${{ github.ref == 'refs/heads/master' && github.secret_source == 'Actions'}}
runs-on: ubuntu-latest
needs:
- build-and-push-docker-alpine-image
defaults:
run:
shell: bash
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Github Packages
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_IO_TOKEN }}
- name: Create multiarch manifests
if: ${{ github.ref == 'refs/heads/master' && github.secret_source == 'Actions'}}
shell: bash
run: |
for tag in \
docker.io/scit0/extract_otp_secrets:only-txt \
docker.io/scit0/extract_otp_secrets:alpine \
ghcr.io/scito/extract_otp_secrets:only-txt \
ghcr.io/scito/extract_otp_secrets:alpine \
; do
docker buildx imagetools create -t $tag \
$tag-x86_64 \
$tag-arm64
done
build-and-push-docker-bullseye-image:
name: Build Docker Bullseye image (for PyInstsaller) and push to repositories
# run only when code is compiling and tests are passing
runs-on: ubuntu-latest
strategy:
matrix:
include:
- DOCKER_ARCH: amd64
platform: ubuntu-latest
PLATFORM_ARCH: x86_64
- DOCKER_ARCH: arm64
platform: ubuntu-24.04-arm
PLATFORM_ARCH: arm64
runs-on: ${{ matrix.platform }}
# steps to perform in job
steps:
@@ -207,11 +310,6 @@ jobs:
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
# Workaround for failing builds: https://github.com/docker/build-push-action/issues/761#issuecomment-1383822381
# TODO remove workaround when fixed
with:
driver-opts: |
image=moby/buildkit:v0.10.6
- name: Login to DockerHub
uses: docker/login-action@v3
@@ -228,22 +326,23 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GHCR_IO_TOKEN }}
- name: "Build image from Bullseye and push to GitHub Container Registry"
- name: "Build image from Bullseye (Debian 11) and push to GitHub Container Registry"
id: docker_build_bullseye
if: github.ref == 'refs/heads/master'
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
platforms: linux/${{ matrix.DOCKER_ARCH }}
# relative path to the place where source code with Dockerfile is located
context: .
file: docker/Dockerfile
# builder: ${{ steps.buildx.outputs.name }}
build-args: |
BASE_IMAGE=python:3.12-slim-bullseye
BASE_IMAGE=python:3.13-slim-bullseye
# Note: tags has to be all lower-case
pull: true
tags: |
scit0/extract_otp_secrets:bullseye
docker.io/scit0/extract_otp_secrets:bullseye-${{ matrix.PLATFORM_ARCH }}
ghcr.io/scito/extract_otp_secrets:bullseye-${{ matrix.PLATFORM_ARCH }}
push: ${{ github.secret_source == 'Actions' }}
- name: Image digest
@@ -255,5 +354,53 @@ jobs:
if: github.ref == 'refs/heads/master'
uses: actions/upload-artifact@v4
with:
name: bullseye_digests
name: digests_bullseye_${{ matrix.PLATFORM_ARCH }}
path: digests.txt
create-multiarch-bullseye-manifests:
name: Create multiarch manifests for Bullseye image
runs-on: ubuntu-latest
if: ${{ github.ref == 'refs/heads/master' && github.secret_source == 'Actions'}}
needs:
- build-and-push-docker-bullseye-image
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Github Packages
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_IO_TOKEN }}
- name:
if: ${{ github.ref == 'refs/heads/master' && github.secret_source == 'Actions'}}
shell: bash
run: |
for tag in \
docker.io/scit0/extract_otp_secrets:bullseye \
ghcr.io/scito/extract_otp_secrets:bullseye \
; do
docker buildx imagetools create -t $tag \
$tag-x86_64 \
$tag-arm64
done
container-images-clean-up:
name: Cleanup old container images
runs-on: ubuntu-latest
steps:
- name: Delete Container Packages
uses: actions/delete-package-versions@v5
if: ${{ github.secret_source == 'Actions'}}
with:
package-name: 'extract_otp_secrets'
package-type: 'container'
min-versions-to-keep: 1
delete-only-untagged-versions: 'true'

View File

@@ -106,20 +106,23 @@ jobs:
path: release_id.txt
build-linux-executable-in-docker:
name: Build ${{ matrix.PLATFORM }} release in docker container
name: Build ${{ matrix.platform }} release in docker container
# run only when code is compiling and tests are passing
runs-on: ubuntu-latest
needs: create-release
strategy:
matrix:
include:
- PLATFORM: linux/amd64
- DOCKER_PLATFORM: linux/amd64
platform: ubuntu-latest
EXE: extract_otp_secrets_linux_x86_64
ASSET_NAME: extract_otp_secrets${{ needs.create-release.outputs.inline_version }}_linux_x86_64
- PLATFORM: linux/arm64
- DOCKER_PLATFORM: linux/arm64
platform: ubuntu-24.04-arm
EXE: extract_otp_secrets_linux_arm64
ASSET_NAME: extract_otp_secrets${{ needs.create-release.outputs.inline_version }}_linux_arm64
runs-on: ${{ matrix.platform }}
# steps to perform in job
steps:
- name: Checkout code
@@ -145,7 +148,7 @@ jobs:
# TODO remove workaround when fixed
with:
driver-opts: |
image=moby/buildkit:v0.10.6
image=moby/buildkit:latest
- name: Login to DockerHub
uses: docker/login-action@v3
@@ -172,11 +175,10 @@ jobs:
# https://hub.docker.com/r/multiarch/qemu-user-static/
- name: Run Pyinstaller in container for ${{ matrix.EXE }}
run: |
docker run --pull always --rm --privileged multiarch/qemu-user-static --reset -p yes
docker run --platform ${{ matrix.PLATFORM }} --pull always --entrypoint /bin/bash --rm -v "$(pwd)":/files -w /files scit0/extract_otp_secrets:bullseye -c 'apt-get update && apt-get -y install binutils && pip install -U -r /files/requirements.txt && pip install pyinstaller && PYTHONHASHSEED=31 && pyinstaller -y --add-data /usr/local/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --name ${{ matrix.EXE }} --distpath /files/dist/ /files/src/extract_otp_secrets.py'
docker run --pull always --entrypoint /bin/bash --rm -v "$(pwd)":/files -w /files docker.io/scit0/extract_otp_secrets:bullseye -c 'apt-get update && apt-get -y install binutils && pip install -U -r /files/requirements.txt && pip install pyinstaller && PYTHONHASHSEED=31 && pyinstaller -y --add-data /usr/local/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --name ${{ matrix.EXE }} --distpath /files/dist/ /files/src/extract_otp_secrets.py'
- name: Smoke tests linux/amd64
if: matrix.PLATFORM == 'linux/amd64'
if: matrix.DOCKER_PLATFORM == 'linux/amd64'
run: |
dist/${{ matrix.EXE }} -V
dist/${{ matrix.EXE }} -h
@@ -189,9 +191,9 @@ jobs:
dist/${{ matrix.EXE }} --qr CV2 example_export.png
dist/${{ matrix.EXE }} --qr CV2_WECHAT example_export.png
- name: Smoke tests linux/arm64
if: matrix.PLATFORM == 'linux/arm64'
if: matrix.DOCKER_PLATFORM == 'linux/arm64'
run: |
docker run --platform ${{ matrix.PLATFORM }} --pull always --entrypoint /bin/bash --rm -v "$(pwd)":/files -w /files scit0/extract_otp_secrets -c 'dist/${{ matrix.EXE }} -V && dist/${{ matrix.EXE }} -h && dist/${{ matrix.EXE }} example_export.png && dist/${{ matrix.EXE }} - < example_export.txt && dist/${{ matrix.EXE }} --qr ZBAR example_export.png && dist/${{ matrix.EXE }} --qr QREADER example_export.png && dist/${{ matrix.EXE }} --qr QREADER_DEEP example_export.png && dist/${{ matrix.EXE }} --qr CV2 example_export.png && dist/${{ matrix.EXE }} --qr CV2_WECHAT example_export.png'
docker run --pull always --entrypoint /bin/bash --rm -v "$(pwd)":/files -w /files docker.io/scit0/extract_otp_secrets -c 'dist/${{ matrix.EXE }} -V && dist/${{ matrix.EXE }} -h && dist/${{ matrix.EXE }} example_export.png && dist/${{ matrix.EXE }} - < example_export.txt && dist/${{ matrix.EXE }} --qr ZBAR example_export.png && dist/${{ matrix.EXE }} --qr QREADER example_export.png && dist/${{ matrix.EXE }} --qr QREADER_DEEP example_export.png && dist/${{ matrix.EXE }} --qr CV2 example_export.png && dist/${{ matrix.EXE }} --qr CV2_WECHAT example_export.png'
- name: Load Release URL File from release job
if: startsWith(github.ref, 'refs/tags/v')
uses: actions/download-artifact@v4
@@ -239,7 +241,23 @@ jobs:
UPLOAD: true
CMD_BUILD: |
pyinstaller -y --add-data "$($Env:pythonLocation)\__yolo_v3_qr_detector:__yolo_v3_qr_detector" --add-binary "$($Env:pythonLocation)\Lib\site-packages\pyzbar\libiconv.dll:pyzbar" --add-binary "$($Env:pythonLocation)\Lib\site-packages\pyzbar\libzbar-64.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\msvcr120.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\msvcp120.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\vcamp120.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\vcomp120.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\vccorlib120.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120u.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120chs.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120cht.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120deu.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120enu.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120esn.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120fra.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120ita.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120jpn.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120kor.dll:pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120rus.dll:pyzbar" --onefile --version-file build\win_file_version_info.txt --name extract_otp_secrets.exe src\extract_otp_secrets.py
- os: macos-12
- os: ubuntu-latest
TARGET: linux
EXE: extract_otp_secrets_ubuntu
ASSET_NAME: extract_otp_secrets${{ needs.create-release.outputs.inline_version }}_linux_x86_64_ubuntu_latest
ASSET_MIME: application/x-executable
UPLOAD: false
CMD_BUILD: |
pyinstaller -y --add-data $pythonLocation/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --name extract_otp_secrets_ubuntu src/extract_otp_secrets.py
- os: ubuntu-24.04-arm
TARGET: linux
EXE: extract_otp_secrets_ubuntu_arm64
ASSET_NAME: extract_otp_secrets${{ needs.create-release.outputs.inline_version }}_linux_arm64_ubuntu_latest
ASSET_MIME: application/x-executable
UPLOAD: false
CMD_BUILD: |
pyinstaller -y --add-data $pythonLocation/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --name extract_otp_secrets_ubuntu_arm64 src/extract_otp_secrets.py
- os: macos-13
TARGET: macos
# https://pyinstaller.org/en/stable/spec-files.html#spec-file-options-for-a-macos-bundle
EXE: extract_otp_secrets
@@ -249,17 +267,23 @@ jobs:
ASSET_MIME: application/octet-stream
UPLOAD: true
CMD_BUILD: |
VERSION_STR=$(setuptools-git-versioning) COPYRIGHT_YEARS='2020-2023' envsubst < installer/extract_otp_secrets_macos_template.spec > extract_otp_secrets_macos.spec
VERSION_STR=$(setuptools-git-versioning) COPYRIGHT_YEARS='2020-2025' envsubst < installer/extract_otp_secrets_macos_template.spec > extract_otp_secrets_macos.spec
pyinstaller -y extract_otp_secrets_macos.spec
installer/build_dmg.sh
- os: ubuntu-latest
TARGET: linux
EXE: extract_otp_secrets_ubuntu
ASSET_NAME: extract_otp_secrets${{ needs.create-release.outputs.inline_version }}_linux_x86_64_ubuntu_latest
ASSET_MIME: application/x-executable
UPLOAD: false
CMD_BUILD: |
pyinstaller -y --add-data $pythonLocation/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --name extract_otp_secrets_ubuntu src/extract_otp_secrets.py
# Disable WARN: Cannot import pyzbar module. This problem is probably due to the missing zbar shared library.
# - os: macos-14
# TARGET: macos
# # https://pyinstaller.org/en/stable/spec-files.html#spec-file-options-for-a-macos-bundle
# EXE: extract_otp_secrets
# ASSET_NAME: extract_otp_secrets${{ needs.create-release.outputs.inline_version }}_macos_arm64
# DMG: extract_otp_secrets.dmg
# ASSET_NAME_DMG: extract_otp_secrets${{ needs.create-release.outputs.inline_version }}_macos_arm64.dmg
# ASSET_MIME: application/octet-stream
# UPLOAD: true
# CMD_BUILD: |
# VERSION_STR=$(setuptools-git-versioning) COPYRIGHT_YEARS='2020-2025' envsubst < installer/extract_otp_secrets_macos_template.spec > extract_otp_secrets_macos.spec
# pyinstaller -y extract_otp_secrets_macos.spec
# installer/build_dmg.sh
steps:
- name: Output path
if: runner.os == 'Windows'
@@ -270,11 +294,11 @@ jobs:
- uses: actions/checkout@v4
- name: Set macos macos_python_path
# TODO use variable for Python version
run: echo "macos_python_path=/Library/Frameworks/Python.framework/Versions/3.12" >> $GITHUB_ENV
- name: Set up Python 3.12
run: echo "macos_python_path=/Library/Frameworks/Python.framework/Versions/3.13" >> $GITHUB_ENV
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: 3.12
python-version: 3.13
check-latest: true
- name: Install zbar shared lib for QReader (Linux)
if: runner.os == 'Linux'
@@ -294,7 +318,7 @@ jobs:
shell: bash
run: |
mkdir -p build/
VERSION_STR=$(setuptools-git-versioning) VERSION_MAJOR=$(cut -d '.' -f 1 <<< "$(setuptools-git-versioning)") VERSION_MINOR=$(cut -d '.' -f 2 <<< "$(setuptools-git-versioning)") VERSION_PATCH=$(echo $(cut -d '.' -f 3 <<< "$(setuptools-git-versioning)") | sed -E -n "s/^([0-9]+).*/\1/p") VERSION_BUILD=$(echo $(cut -d '.' -f 3 <<< "$(setuptools-git-versioning)") | sed -E -n -e"s/^[0-9]+.+/99/p")$(($(git rev-list --count $(git tag | sort -V -r | sed '1!d')..HEAD))) COPYRIGHT_YEARS='2020-2023' envsubst < installer/win_file_version_info_template.txt > build/win_file_version_info.txt
VERSION_STR=$(setuptools-git-versioning) VERSION_MAJOR=$(cut -d '.' -f 1 <<< "$(setuptools-git-versioning)") VERSION_MINOR=$(cut -d '.' -f 2 <<< "$(setuptools-git-versioning)") VERSION_PATCH=$(echo $(cut -d '.' -f 3 <<< "$(setuptools-git-versioning)") | sed -E -n "s/^([0-9]+).*/\1/p") VERSION_BUILD=$(echo $(cut -d '.' -f 3 <<< "$(setuptools-git-versioning)") | sed -E -n -e"s/^[0-9]+.+/99/p")$(($(git rev-list --count $(git tag | sort -V -r | sed '1!d')..HEAD))) COPYRIGHT_YEARS='2020-2025' envsubst < installer/win_file_version_info_template.txt > build/win_file_version_info.txt
- name: Build with pyinstaller for ${{ matrix.TARGET }}
env:
# Reproducible build: https://pyinstaller.org/en/stable/advanced-topics.html#creating-a-reproducible-build

9
.gitignore vendored
View File

@@ -35,3 +35,12 @@ extract_otp_secrets.build/
extract_otp_secrets.dist/
extract_otp_secrets.onefile-build/
extract_otp_secrets.bin
# Devenv
.devenv*
devenv.local.nix
# direnv
.direnv
# pre-commit
.pre-commit-config.yaml

678
Pipfile.lock generated
View File

@@ -27,201 +27,185 @@
},
"numpy": {
"hashes": [
"sha256:046356b19d7ad1890c751b99acad5e82dc4a02232013bd9a9a712fddf8eb60f5",
"sha256:0b8cc2715a84b7c3b161f9ebbd942740aaed913584cae9cdc7f8ad5ad41943d0",
"sha256:0d07841fd284718feffe7dd17a63a2e6c78679b2d386d3e82f44f0108c905550",
"sha256:13cc11c00000848702322af4de0147ced365c81d66053a67c2e962a485b3717c",
"sha256:13ce49a34c44b6de5241f0b38b07e44c1b2dcacd9e36c30f9c2fcb1bb5135db7",
"sha256:24c2ad697bd8593887b019817ddd9974a7f429c14a5469d7fad413f28340a6d2",
"sha256:251105b7c42abe40e3a689881e1793370cc9724ad50d64b30b358bbb3a97553b",
"sha256:2ca4b53e1e0b279142113b8c5eb7d7a877e967c306edc34f3b58e9be12fda8df",
"sha256:3269c9eb8745e8d975980b3a7411a98976824e1fdef11f0aacf76147f662b15f",
"sha256:397bc5ce62d3fb73f304bec332171535c187e0643e176a6e9421a6e3eacef06d",
"sha256:3fc5eabfc720db95d68e6646e88f8b399bfedd235994016351b1d9e062c4b270",
"sha256:50a95ca3560a6058d6ea91d4629a83a897ee27c00630aed9d933dff191f170cd",
"sha256:52ac2e48f5ad847cd43c4755520a2317f3380213493b9d8a4c5e37f3b87df504",
"sha256:53e27293b3a2b661c03f79aa51c3987492bd4641ef933e366e0f9f6c9bf257ec",
"sha256:57eb525e7c2a8fdee02d731f647146ff54ea8c973364f3b850069ffb42799647",
"sha256:5889dd24f03ca5a5b1e8a90a33b5a0846d8977565e4ae003a63d22ecddf6782f",
"sha256:59ca673ad11d4b84ceb385290ed0ebe60266e356641428c845b39cd9df6713ab",
"sha256:6435c48250c12f001920f0751fe50c0348f5f240852cfddc5e2f97e007544cbe",
"sha256:6e5a9cb2be39350ae6c8f79410744e80154df658d5bea06e06e0ac5bb75480d5",
"sha256:7be6a07520b88214ea85d8ac8b7d6d8a1839b0b5cb87412ac9f49fa934eb15d5",
"sha256:7c803b7934a7f59563db459292e6aa078bb38b7ab1446ca38dd138646a38203e",
"sha256:7dd86dfaf7c900c0bbdcb8b16e2f6ddf1eb1fe39c6c8cca6e94844ed3152a8fd",
"sha256:8661c94e3aad18e1ea17a11f60f843a4933ccaf1a25a7c6a9182af70610b2313",
"sha256:8ae0fd135e0b157365ac7cc31fff27f07a5572bdfc38f9c2d43b2aff416cc8b0",
"sha256:910b47a6d0635ec1bd53b88f86120a52bf56dcc27b51f18c7b4a2e2224c29f0f",
"sha256:913cc1d311060b1d409e609947fa1b9753701dac96e6581b58afc36b7ee35af6",
"sha256:920b0911bb2e4414c50e55bd658baeb78281a47feeb064ab40c2b66ecba85553",
"sha256:950802d17a33c07cba7fd7c3dcfa7d64705509206be1606f196d179e539111ed",
"sha256:981707f6b31b59c0c24bcda52e5605f9701cb46da4b86c2e8023656ad3e833cb",
"sha256:98ce7fb5b8063cfdd86596b9c762bf2b5e35a2cdd7e967494ab78a1fa7f8b86e",
"sha256:99f4a9ee60eed1385a86e82288971a51e71df052ed0b2900ed30bc840c0f2e39",
"sha256:9a8e06c7a980869ea67bbf551283bbed2856915f0a792dc32dd0f9dd2fb56728",
"sha256:ae8ce252404cdd4de56dcfce8b11eac3c594a9c16c231d081fb705cf23bd4d9e",
"sha256:afd9c680df4de71cd58582b51e88a61feed4abcc7530bcd3d48483f20fc76f2a",
"sha256:b49742cdb85f1f81e4dc1b39dcf328244f4d8d1ded95dea725b316bd2cf18c95",
"sha256:b5613cfeb1adfe791e8e681128f5f49f22f3fcaa942255a6124d58ca59d9528f",
"sha256:bab7c09454460a487e631ffc0c42057e3d8f2a9ddccd1e60c7bb8ed774992480",
"sha256:c8a0e34993b510fc19b9a2ce7f31cb8e94ecf6e924a40c0c9dd4f62d0aac47d9",
"sha256:caf5d284ddea7462c32b8d4a6b8af030b6c9fd5332afb70e7414d7fdded4bfd0",
"sha256:cea427d1350f3fd0d2818ce7350095c1a2ee33e30961d2f0fef48576ddbbe90f",
"sha256:d0cf7d55b1051387807405b3898efafa862997b4cba8aa5dbe657be794afeafd",
"sha256:d10c39947a2d351d6d466b4ae83dad4c37cd6c3cdd6d5d0fa797da56f710a6ae",
"sha256:d2b9cd92c8f8e7b313b80e93cedc12c0112088541dcedd9197b5dee3738c1201",
"sha256:d4c57b68c8ef5e1ebf47238e99bf27657511ec3f071c465f6b1bccbef12d4136",
"sha256:d51fc141ddbe3f919e91a096ec739f49d686df8af254b2053ba21a910ae518bf",
"sha256:e097507396c0be4e547ff15b13dc3866f45f3680f789c1a1301b07dadd3fbc78",
"sha256:e30356d530528a42eeba51420ae8bf6c6c09559051887196599d96ee5f536468",
"sha256:e8d5f8a8e3bc87334f025194c6193e408903d21ebaeb10952264943a985066ca",
"sha256:e8dfa9e94fc127c40979c3eacbae1e61fda4fe71d84869cc129e2721973231ef",
"sha256:f212d4f46b67ff604d11fff7cc62d36b3e8714edf68e44e9760e19be38c03eb0",
"sha256:f7506387e191fe8cdb267f912469a3cccc538ab108471291636a96a54e599556",
"sha256:fac6e277a41163d27dfab5f4ec1f7a83fac94e170665a4a50191b545721c6521",
"sha256:fcd8f556cdc8cfe35e70efb92463082b7f43dd7e547eb071ffc36abc0ca4699b"
"sha256:0391ea3622f5c51a2e29708877d56e3d276827ac5447d7f45e9bc4ade8923c52",
"sha256:12c045f43b1d2915eca6b880a7f4a256f59d62df4f044788c8ba67709412128d",
"sha256:136553f123ee2951bfcfbc264acd34a2fc2f29d7cdf610ce7daf672b6fbaa693",
"sha256:1402da8e0f435991983d0a9708b779f95a8c98c6b18a171b9f1be09005e64d9d",
"sha256:16372619ee728ed67a2a606a614f56d3eabc5b86f8b615c79d01957062826ca8",
"sha256:1ad78ce7f18ce4e7df1b2ea4019b5817a2f6a8a16e34ff2775f646adce0a5027",
"sha256:1b416af7d0ed3271cad0f0a0d0bee0911ed7eba23e66f8424d9f3dfcdcae1304",
"sha256:1f45315b2dc58d8a3e7754fe4e38b6fce132dab284a92851e41b2b344f6441c5",
"sha256:2376e317111daa0a6739e50f7ee2a6353f768489102308b0d98fcf4a04f7f3b5",
"sha256:23c9f4edbf4c065fddb10a4f6e8b6a244342d95966a48820c614891e5059bb50",
"sha256:246535e2f7496b7ac85deffe932896a3577be7af8fb7eebe7146444680297e9a",
"sha256:2e8da03bd561504d9b20e7a12340870dfc206c64ea59b4cfee9fceb95070ee94",
"sha256:34c1b7e83f94f3b564b35f480f5652a47007dd91f7c839f404d03279cc8dd021",
"sha256:39261798d208c3095ae4f7bc8eaeb3481ea8c6e03dc48028057d3cbdbdb8937e",
"sha256:3b787adbf04b0db1967798dba8da1af07e387908ed1553a0d6e74c084d1ceafe",
"sha256:3c2ec8a0f51d60f1e9c0c5ab116b7fc104b165ada3f6c58abf881cb2eb16044d",
"sha256:435e7a933b9fda8126130b046975a968cc2d833b505475e588339e09f7672890",
"sha256:4d8335b5f1b6e2bce120d55fb17064b0262ff29b459e8493d1785c18ae2553b8",
"sha256:4d9828d25fb246bedd31e04c9e75714a4087211ac348cb39c8c5f99dbb6683fe",
"sha256:52659ad2534427dffcc36aac76bebdd02b67e3b7a619ac67543bc9bfe6b7cdb1",
"sha256:5266de33d4c3420973cf9ae3b98b54a2a6d53a559310e3236c4b2b06b9c07d4e",
"sha256:5521a06a3148686d9269c53b09f7d399a5725c47bbb5b35747e1cb76326b714b",
"sha256:596140185c7fa113563c67c2e894eabe0daea18cf8e33851738c19f70ce86aeb",
"sha256:5b732c8beef1d7bc2d9e476dbba20aaff6167bf205ad9aa8d30913859e82884b",
"sha256:5ebeb7ef54a7be11044c33a17b2624abe4307a75893c001a4800857956b41094",
"sha256:712a64103d97c404e87d4d7c47fb0c7ff9acccc625ca2002848e0d53288b90ea",
"sha256:7678556eeb0152cbd1522b684dcd215250885993dd00adb93679ec3c0e6e091c",
"sha256:77974aba6c1bc26e3c205c2214f0d5b4305bdc719268b93e768ddb17e3fdd636",
"sha256:783145835458e60fa97afac25d511d00a1eca94d4a8f3ace9fe2043003c678e4",
"sha256:7bfdb06b395385ea9b91bf55c1adf1b297c9fdb531552845ff1d3ea6e40d5aba",
"sha256:7c8dde0ca2f77828815fd1aedfdf52e59071a5bae30dac3b4da2a335c672149a",
"sha256:83807d445817326b4bcdaaaf8e8e9f1753da04341eceec705c001ff342002e5d",
"sha256:87eed225fd415bbae787f93a457af7f5990b92a334e346f72070bf569b9c9c95",
"sha256:8fb62fe3d206d72fe1cfe31c4a1106ad2b136fcc1606093aeab314f02930fdf2",
"sha256:95172a21038c9b423e68be78fd0be6e1b97674cde269b76fe269a5dfa6fadf0b",
"sha256:9f48ba6f6c13e5e49f3d3efb1b51c8193215c42ac82610a04624906a9270be6f",
"sha256:a0c03b6be48aaf92525cccf393265e02773be8fd9551a2f9adbe7db1fa2b60f1",
"sha256:a5ae282abe60a2db0fd407072aff4599c279bcd6e9a2475500fc35b00a57c532",
"sha256:aee2512827ceb6d7f517c8b85aa5d3923afe8fc7a57d028cffcd522f1c6fd082",
"sha256:c8b0451d2ec95010d1db8ca733afc41f659f425b7f608af569711097fd6014e2",
"sha256:c9aa4496fd0e17e3843399f533d62857cef5900facf93e735ef65aa4bbc90ef0",
"sha256:cbc6472e01952d3d1b2772b720428f8b90e2deea8344e854df22b0618e9cce71",
"sha256:cdfe0c22692a30cd830c0755746473ae66c4a8f2e7bd508b35fb3b6a0813d787",
"sha256:cf802eef1f0134afb81fef94020351be4fe1d6681aadf9c5e862af6602af64ef",
"sha256:d42f9c36d06440e34226e8bd65ff065ca0963aeecada587b937011efa02cdc9d",
"sha256:d5b47c440210c5d1d67e1cf434124e0b5c395eee1f5806fdd89b553ed1acd0a3",
"sha256:d9b4a8148c57ecac25a16b0e11798cbe88edf5237b0df99973687dd866f05e1b",
"sha256:daf43a3d1ea699402c5a850e5313680ac355b4adc9770cd5cfc2940e7861f1bf",
"sha256:dbdc15f0c81611925f382dfa97b3bd0bc2c1ce19d4fe50482cb0ddc12ba30020",
"sha256:deaa09cd492e24fd9b15296844c0ad1b3c976da7907e1c1ed3a0ad21dded6f76",
"sha256:e37242f5324ffd9f7ba5acf96d774f9276aa62a966c0bad8dae692deebec7716",
"sha256:ed2cf9ed4e8ebc3b754d398cba12f24359f018b416c380f577bbae112ca52fc9",
"sha256:f2712c5179f40af9ddc8f6727f2bd910ea0eb50206daea75f58ddd9fa3f715bb",
"sha256:f4ca91d61a4bf61b0f2228f24bbfa6a9facd5f8af03759fe2a655c50ae2c6610",
"sha256:f6b3dfc7661f8842babd8ea07e9897fe3d9b69a1d7e5fbb743e4160f9387833b"
],
"markers": "python_version >= '3.10'",
"version": "==2.1.1"
"version": "==2.2.3"
},
"opencv-contrib-python": {
"hashes": [
"sha256:040575b69e4f3aa761676bace4e3d1b8485fbfaf77ef77b266ab6bda5a3b5e9b",
"sha256:2a36257ec1375d1bec2a62177ea39828ff9804de6831ee39646bdc875c343cec",
"sha256:47ec3160dae75f70e099b286d1a2e086d20dac8b06e759f60eaf867e6bdecba7",
"sha256:4a3eae0ed9cadf1abe9293a6938a25a540e2fd6d7fc308595caa5896c8b36a0c",
"sha256:a261223db41f6e512d76deaf21c8fcfb4fbbcbc2de62ca7f74a05f2c9ee489ef",
"sha256:dea80d4db73b8acccf9e16b5744bf3654f47b22745074263f0a6c10de26c5ef5",
"sha256:ee4b0919026d8c533aeb69b16c6ec4a891a2f6844efaa14121bf68838753209c"
"sha256:194841c664ceaa0692410b4ed0af557425608e33db3a181ded28b87acb66748d",
"sha256:4ff773dab44911da366b906621c9592d4eb96f6ad3777098933a23f064aab38e",
"sha256:654758a9ae8ca9a75fca7b64b19163636534f0eedffe1e14c3d7218988625c8d",
"sha256:c47c0ef1098461cdc6fa1cdce4c942b8ec974c87423f4b5951443d26bb9ae407",
"sha256:d911cedc511d98f79994580b245d59fc97f57f0f9923a99945d8b92c7ac671f6",
"sha256:e10a293af18aa5f842d012fa14e87345b3ee06db4c29bd592ff94b51f7ffca2b",
"sha256:f21034bc8b00eb286a0a0a92b99767bf596bfe426cf4bc2e79647d64ad0dd6da"
],
"index": "pypi",
"markers": "python_version >= '3.6'",
"version": "==4.10.0.84"
"version": "==4.11.0.86"
},
"opencv-python": {
"hashes": [
"sha256:09a332b50488e2dda866a6c5573ee192fe3583239fb26ff2f7f9ceb0bc119ea6",
"sha256:2db02bb7e50b703f0a2d50c50ced72e95c574e1e5a0bb35a8a86d0b35c98c236",
"sha256:32dbbd94c26f611dc5cc6979e6b7aa1f55a64d6b463cc1dcd3c95505a63e48fe",
"sha256:71e575744f1d23f79741450254660442785f45a0797212852ee5199ef12eed98",
"sha256:72d234e4582e9658ffea8e9cae5b63d488ad06994ef12d81dc303b17472f3526",
"sha256:9ace140fc6d647fbe1c692bcb2abce768973491222c067c131d80957c595b71f",
"sha256:fc182f8f4cda51b45f01c64e4cbedfc2f00aff799debebc305d8d0210c43f251"
"sha256:03d60ccae62304860d232272e4a4fda93c39d595780cb40b161b310244b736a4",
"sha256:085ad9b77c18853ea66283e98affefe2de8cc4c1f43eda4c100cf9b2721142ec",
"sha256:1b92ae2c8852208817e6776ba1ea0d6b1e0a1b5431e971a2a0ddd2a8cc398202",
"sha256:432f67c223f1dc2824f5e73cdfcd9db0efc8710647d4e813012195dc9122a52a",
"sha256:6b02611523803495003bd87362db3e1d2a0454a6a63025dc6658a9830570aa0d",
"sha256:810549cb2a4aedaa84ad9a1c92fbfdfc14090e2749cedf2c1589ad8359aa169b",
"sha256:9d05ef13d23fe97f575153558653e2d6e87103995d54e6a35db3f282fe1f9c66"
],
"markers": "python_version >= '3.6'",
"version": "==4.10.0.84"
"version": "==4.11.0.86"
},
"pillow": {
"hashes": [
"sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885",
"sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea",
"sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df",
"sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5",
"sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c",
"sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d",
"sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd",
"sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06",
"sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908",
"sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a",
"sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be",
"sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0",
"sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b",
"sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80",
"sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a",
"sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e",
"sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9",
"sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696",
"sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b",
"sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309",
"sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e",
"sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab",
"sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d",
"sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060",
"sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d",
"sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d",
"sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4",
"sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3",
"sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6",
"sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb",
"sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94",
"sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b",
"sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496",
"sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0",
"sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319",
"sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b",
"sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856",
"sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef",
"sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680",
"sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b",
"sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42",
"sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e",
"sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597",
"sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a",
"sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8",
"sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3",
"sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736",
"sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da",
"sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126",
"sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd",
"sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5",
"sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b",
"sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026",
"sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b",
"sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc",
"sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46",
"sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2",
"sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c",
"sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe",
"sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984",
"sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a",
"sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70",
"sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca",
"sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b",
"sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91",
"sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3",
"sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84",
"sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1",
"sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5",
"sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be",
"sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f",
"sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc",
"sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9",
"sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e",
"sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141",
"sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef",
"sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22",
"sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27",
"sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e",
"sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"
"sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83",
"sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96",
"sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65",
"sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a",
"sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352",
"sha256:3362c6ca227e65c54bf71a5f88b3d4565ff1bcbc63ae72c34b07bbb1cc59a43f",
"sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20",
"sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c",
"sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114",
"sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49",
"sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91",
"sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0",
"sha256:4db853948ce4e718f2fc775b75c37ba2efb6aaea41a1a5fc57f0af59eee774b2",
"sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5",
"sha256:54251ef02a2309b5eec99d151ebf5c9904b77976c8abdcbce7891ed22df53884",
"sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e",
"sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c",
"sha256:5bb94705aea800051a743aa4874bb1397d4695fb0583ba5e425ee0328757f196",
"sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756",
"sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861",
"sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269",
"sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1",
"sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb",
"sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a",
"sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081",
"sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1",
"sha256:89dbdb3e6e9594d512780a5a1c42801879628b38e3efc7038094430844e271d8",
"sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90",
"sha256:8e275ee4cb11c262bd108ab2081f750db2a1c0b8c12c1897f27b160c8bd57bbc",
"sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5",
"sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1",
"sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3",
"sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35",
"sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f",
"sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c",
"sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2",
"sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2",
"sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf",
"sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65",
"sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b",
"sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442",
"sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2",
"sha256:ab8a209b8485d3db694fa97a896d96dd6533d63c22829043fd9de627060beade",
"sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482",
"sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe",
"sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc",
"sha256:b20be51b37a75cc54c2c55def3fa2c65bb94ba859dde241cd0a4fd302de5ae0a",
"sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec",
"sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3",
"sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a",
"sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07",
"sha256:bf902d7413c82a1bfa08b06a070876132a5ae6b2388e2712aab3a7cbc02205c6",
"sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f",
"sha256:c1eec9d950b6fe688edee07138993e54ee4ae634c51443cfb7c1e7613322718e",
"sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192",
"sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0",
"sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6",
"sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73",
"sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f",
"sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6",
"sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547",
"sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9",
"sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457",
"sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8",
"sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26",
"sha256:e5449ca63da169a2e6068dd0e2fcc8d91f9558aba89ff6d02121ca8ab11e79e5",
"sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab",
"sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070",
"sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71",
"sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9",
"sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==10.4.0"
"markers": "python_version >= '3.9'",
"version": "==11.1.0"
},
"protobuf": {
"hashes": [
"sha256:018db9056b9d75eb93d12a9d35120f97a84d9a919bcab11ed56ad2d399d6e8dd",
"sha256:510ed78cd0980f6d3218099e874714cdf0d8a95582e7b059b06cabad855ed0a0",
"sha256:532627e8fdd825cf8767a2d2b94d77e874d5ddb0adefb04b237f7cc296748681",
"sha256:6206afcb2d90181ae8722798dcb56dc76675ab67458ac24c0dd7d75d632ac9bd",
"sha256:66c3edeedb774a3508ae70d87b3a19786445fe9a068dd3585e0cefa8a77b83d0",
"sha256:6d7cc9e60f976cf3e873acb9a40fed04afb5d224608ed5c1a105db4a3f09c5b6",
"sha256:853db610214e77ee817ecf0514e0d1d052dff7f63a0c157aa6eabae98db8a8de",
"sha256:d001a73c8bc2bf5b5c1360d59dd7573744e163b3607fa92788b7f3d5fefbd9a5",
"sha256:dde74af0fa774fa98892209992295adbfb91da3fa98c8f67a88afe8f5a349add",
"sha256:dde9fcaa24e7a9654f4baf2a55250b13a5ea701493d904c54069776b99a8216b",
"sha256:eef7a8a2f4318e2cb2dee8666d26e58eaf437c14788f3a2911d0c3da40405ae8"
"sha256:3c25e51e1359f1f5fa3b298faa6016e650d148f214db2e47671131b9063c53be",
"sha256:47cd320b7db63e8c9ac35f5596ea1c1e61491d8a8eb6d8b45edc44760b53a4f6",
"sha256:535fb4e44d0236893d5cf1263a0f706f1160b689a7ab962e9da8a9ce4050b780",
"sha256:554d7e61cce2aa4c63ca27328f757a9f3867bce8ec213bf09096a8d16bcdcb6a",
"sha256:aa4f7dfaed0d840b03d08d14bfdb41348feaee06a828a8c455698234135b4075",
"sha256:b510f55ce60f84dc7febc619b47215b900466e3555ab8cb1ba42deb4496d6cc0",
"sha256:ba0706f948d0195f5cac504da156d88174e03218d9364ab40d903788c1903d7e",
"sha256:e3083660225fa94748ac2e407f09a899e6a28bf9c0e70c75def8d15706bf85fc",
"sha256:ed484f9ddd47f0f1bf0648806cccdb4fe2fb6b19820f9b79a5adf5dcfd1b8c5f"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==5.28.0"
},
"pypng": {
"hashes": [
"sha256:4a43e969b8f5aaafb2a415536c1a8ec7e341cd6a3f957fd5b5f32a4cfeed902c",
"sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1"
],
"version": "==0.20220715.0"
"markers": "python_version >= '3.9'",
"version": "==6.30.1"
},
"pyzbar": {
"hashes": [
@@ -234,12 +218,12 @@
},
"qrcode": {
"hashes": [
"sha256:581dca7a029bcb2deef5d01068e39093e80ef00b4a61098a2182eac59d01643a",
"sha256:9dd969454827e127dbd93696b20747239e6d540e082937c90f14ac95b30f5845"
"sha256:025ce2b150f7fe4296d116ee9bad455a6643ab4f6e7dce541613a4758cbce347",
"sha256:9fc05f03305ad27a709eb742cf3097fa19e6f6f93bb9e2f039c0979190f6f1b1"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==7.4.2"
"markers": "python_version >= '3.9' and python_version < '4.0'",
"version": "==8.0"
},
"qreader": {
"hashes": [
@@ -248,130 +232,121 @@
"index": "pypi",
"version": "==1.3.2"
},
"typing-extensions": {
"setuptools": {
"hashes": [
"sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
"sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
"sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2",
"sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f"
],
"markers": "python_version >= '3.8'",
"version": "==4.12.2"
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==75.8.2"
}
},
"develop": {
"astroid": {
"hashes": [
"sha256:0e14202810b30da1b735827f78f5157be2bbd4a7a59b7707ca0bfc2fb4c0063a",
"sha256:413658a61eeca6202a59231abb473f932038fbcbf1666587f66d482083413a25"
"sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c",
"sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b"
],
"markers": "python_full_version >= '3.8.0'",
"version": "==3.2.4"
"markers": "python_full_version >= '3.9.0'",
"version": "==3.3.8"
},
"build": {
"hashes": [
"sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c",
"sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613"
"sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5",
"sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==1.2.2"
"version": "==1.2.2.post1"
},
"coverage": {
"extras": [
"toml"
],
"hashes": [
"sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca",
"sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d",
"sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6",
"sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989",
"sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c",
"sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b",
"sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223",
"sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f",
"sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56",
"sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3",
"sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8",
"sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb",
"sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388",
"sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0",
"sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a",
"sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8",
"sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f",
"sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a",
"sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962",
"sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8",
"sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391",
"sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc",
"sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2",
"sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155",
"sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb",
"sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0",
"sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c",
"sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a",
"sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004",
"sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060",
"sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232",
"sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93",
"sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129",
"sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163",
"sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de",
"sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6",
"sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23",
"sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569",
"sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d",
"sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778",
"sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d",
"sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36",
"sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a",
"sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6",
"sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34",
"sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704",
"sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106",
"sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9",
"sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862",
"sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b",
"sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255",
"sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16",
"sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3",
"sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133",
"sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb",
"sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657",
"sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d",
"sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca",
"sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36",
"sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c",
"sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e",
"sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff",
"sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7",
"sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5",
"sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02",
"sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c",
"sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df",
"sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3",
"sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a",
"sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959",
"sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234",
"sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"
"sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376",
"sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9",
"sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111",
"sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172",
"sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491",
"sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546",
"sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2",
"sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11",
"sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08",
"sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c",
"sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2",
"sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963",
"sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613",
"sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0",
"sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db",
"sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf",
"sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73",
"sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117",
"sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1",
"sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e",
"sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522",
"sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25",
"sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc",
"sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea",
"sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52",
"sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a",
"sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07",
"sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06",
"sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa",
"sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901",
"sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b",
"sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17",
"sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0",
"sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21",
"sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19",
"sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5",
"sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51",
"sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3",
"sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3",
"sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f",
"sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076",
"sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a",
"sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718",
"sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba",
"sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e",
"sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27",
"sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e",
"sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09",
"sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e",
"sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70",
"sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f",
"sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72",
"sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a",
"sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef",
"sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b",
"sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b",
"sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f",
"sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806",
"sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b",
"sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1",
"sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c",
"sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858"
],
"markers": "python_version >= '3.8'",
"version": "==7.6.1"
"markers": "python_version >= '3.9'",
"version": "==7.6.4"
},
"dill": {
"hashes": [
"sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca",
"sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"
"sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a",
"sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"
],
"markers": "python_version >= '3.11'",
"version": "==0.3.8"
"version": "==0.3.9"
},
"flake8": {
"hashes": [
"sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38",
"sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"
"sha256:1cbc62e65536f65e6d754dfe6f1bada7f5cf392d6f5db3c2b85892466c3e7c1a",
"sha256:c586ffd0b41540951ae41af572e6790dbd49fc12b3aa2541685d253d9bd504bd"
],
"index": "pypi",
"markers": "python_full_version >= '3.8.1'",
"version": "==7.1.1"
"version": "==7.1.2"
},
"gfm-toc": {
"hashes": [
@@ -391,11 +366,11 @@
},
"isort": {
"hashes": [
"sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109",
"sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"
"sha256:567954102bb47bb12e0fae62606570faacddd441e45683968c8d1734fb1af892",
"sha256:75d9d8a1438a9432a7d7b54f2d3b45cad9a4a0fdba43617d9873379704a8bdf1"
],
"markers": "python_full_version >= '3.8.0'",
"version": "==5.13.2"
"markers": "python_full_version >= '3.9.0'",
"version": "==6.0.0"
},
"mccabe": {
"hashes": [
@@ -407,37 +382,42 @@
},
"mypy": {
"hashes": [
"sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36",
"sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce",
"sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6",
"sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b",
"sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca",
"sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24",
"sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383",
"sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7",
"sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86",
"sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d",
"sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4",
"sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8",
"sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987",
"sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385",
"sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79",
"sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef",
"sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6",
"sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70",
"sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca",
"sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70",
"sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12",
"sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104",
"sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a",
"sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318",
"sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1",
"sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b",
"sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"
"sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e",
"sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22",
"sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f",
"sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2",
"sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f",
"sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b",
"sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5",
"sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f",
"sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43",
"sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e",
"sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c",
"sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828",
"sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba",
"sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee",
"sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d",
"sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b",
"sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445",
"sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e",
"sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13",
"sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5",
"sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd",
"sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf",
"sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357",
"sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b",
"sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036",
"sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559",
"sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3",
"sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f",
"sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464",
"sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980",
"sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078",
"sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==1.11.2"
"markers": "python_version >= '3.9'",
"version": "==1.15.0"
},
"mypy-extensions": {
"hashes": [
@@ -458,10 +438,10 @@
},
"nuitka": {
"hashes": [
"sha256:ea04d15dde0d5967719d8181f26d714fe602a6cbd6c76df49ca8be7a45915d50"
"sha256:c9d2db630560cf89dfbfd294dd860dd0540e03b74a0c21711ce64305727523bf"
],
"index": "pypi",
"version": "==2.4.8"
"version": "==2.6.7"
},
"ordered-set": {
"hashes": [
@@ -473,19 +453,19 @@
},
"packaging": {
"hashes": [
"sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
"sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
"sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759",
"sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"
],
"markers": "python_version >= '3.8'",
"version": "==24.1"
"version": "==24.2"
},
"platformdirs": {
"hashes": [
"sha256:63b79589009fa8159973601dd4563143396b35c5f93a58b36f9049ff046949b1",
"sha256:facaa5a3c57aa1e053e3da7b49e0cc31fe0113ca42a4659d5c2e98e545624afe"
"sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907",
"sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"
],
"markers": "python_version >= '3.8'",
"version": "==4.3.1"
"version": "==4.3.6"
},
"pluggy": {
"hashes": [
@@ -497,21 +477,21 @@
},
"protobuf": {
"hashes": [
"sha256:018db9056b9d75eb93d12a9d35120f97a84d9a919bcab11ed56ad2d399d6e8dd",
"sha256:510ed78cd0980f6d3218099e874714cdf0d8a95582e7b059b06cabad855ed0a0",
"sha256:532627e8fdd825cf8767a2d2b94d77e874d5ddb0adefb04b237f7cc296748681",
"sha256:6206afcb2d90181ae8722798dcb56dc76675ab67458ac24c0dd7d75d632ac9bd",
"sha256:66c3edeedb774a3508ae70d87b3a19786445fe9a068dd3585e0cefa8a77b83d0",
"sha256:6d7cc9e60f976cf3e873acb9a40fed04afb5d224608ed5c1a105db4a3f09c5b6",
"sha256:853db610214e77ee817ecf0514e0d1d052dff7f63a0c157aa6eabae98db8a8de",
"sha256:d001a73c8bc2bf5b5c1360d59dd7573744e163b3607fa92788b7f3d5fefbd9a5",
"sha256:dde74af0fa774fa98892209992295adbfb91da3fa98c8f67a88afe8f5a349add",
"sha256:dde9fcaa24e7a9654f4baf2a55250b13a5ea701493d904c54069776b99a8216b",
"sha256:eef7a8a2f4318e2cb2dee8666d26e58eaf437c14788f3a2911d0c3da40405ae8"
"sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24",
"sha256:135658402f71bbd49500322c0f736145731b16fc79dc8f367ab544a17eab4535",
"sha256:27b246b3723692bf1068d5734ddaf2fccc2cdd6e0c9b47fe099244d80200593b",
"sha256:3e6101d095dfd119513cde7259aa703d16c6bbdfae2554dfe5cfdbe94e32d548",
"sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584",
"sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b",
"sha256:70585a70fc2dd4818c51287ceef5bdba6387f88a578c86d47bb34669b5552c36",
"sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135",
"sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868",
"sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687",
"sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==5.28.0"
"version": "==5.28.3"
},
"pycodestyle": {
"hashes": [
@@ -531,38 +511,38 @@
},
"pylint": {
"hashes": [
"sha256:02f4aedeac91be69fb3b4bea997ce580a4ac68ce58b89eaefeaf06749df73f4b",
"sha256:1b7a721b575eaeaa7d39db076b6e7743c993ea44f57979127c517c6c572c803e"
"sha256:289e6a1eb27b453b08436478391a48cd53bb0efb824873f949e709350f3de018",
"sha256:74ae7a38b177e69a9b525d0794bd8183820bfa7eb68cc1bee6e8ed22a42be4ce"
],
"index": "pypi",
"markers": "python_full_version >= '3.8.0'",
"version": "==3.2.7"
"markers": "python_full_version >= '3.9.0'",
"version": "==3.3.4"
},
"pyproject-hooks": {
"hashes": [
"sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965",
"sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2"
"sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8",
"sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913"
],
"markers": "python_version >= '3.7'",
"version": "==1.1.0"
"version": "==1.2.0"
},
"pytest": {
"hashes": [
"sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5",
"sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"
"sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820",
"sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==8.3.2"
"version": "==8.3.5"
},
"pytest-cov": {
"hashes": [
"sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652",
"sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"
"sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35",
"sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==5.0.0"
"markers": "python_version >= '3.9'",
"version": "==6.0.0"
},
"pytest-mock": {
"hashes": [
@@ -575,20 +555,20 @@
},
"setuptools": {
"hashes": [
"sha256:5f4c08aa4d3ebcb57a50c33b1b07e94315d7fc7230f7115e47fc99776c8ce308",
"sha256:95b40ed940a1c67eb70fc099094bd6e99c6ee7c23aa2306f4d2697ba7916f9c6"
"sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6",
"sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"
],
"markers": "python_version >= '3.8'",
"version": "==74.1.2"
"markers": "python_version >= '3.9'",
"version": "==75.8.0"
},
"setuptools-git-versioning": {
"hashes": [
"sha256:72d6e473fc4e86f8563ce411e6c9057766c99aa40b84c862276b48f387eb8e93",
"sha256:85b5fbe7bda8e9c24bbd9e587a9d4b91129417f4dd3e11e3c0d5f3f835fc4d4d"
"sha256:09a15cbb9a00884e91a3591a4c9ec1ff93c24b1b4a40de39a44815196beb7ebf",
"sha256:6aef5b8bb1cfb953b6b343d27cbfc561d96cf2a2ee23c2e0dd3591042a059921"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==2.0.0"
"version": "==2.1.0"
},
"tomlkit": {
"hashes": [
@@ -600,12 +580,12 @@
},
"types-protobuf": {
"hashes": [
"sha256:5443270534cc8072909ef7ad9e1421ccff924ca658749a6396c0c43d64c32676",
"sha256:bb6f90f66b18d4d1c75667b6586334b0573a6fcee5eb0142a7348a765a7cbadc"
"sha256:c1acd6a59ab554dbe09b5d1fa7dd701e2fcfb2212937a3af1c03b736060b792a",
"sha256:c5f8bfb4afdc1b5cbca1848f2c8b361a2090add7401f410b22b599ef647bf483"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==5.27.0.20240907"
"markers": "python_version >= '3.9'",
"version": "==5.29.1.20250208"
},
"typing-extensions": {
"hashes": [
@@ -617,12 +597,12 @@
},
"wheel": {
"hashes": [
"sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f",
"sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49"
"sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729",
"sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==0.44.0"
"version": "==0.45.1"
},
"zstandard": {
"hashes": [

View File

@@ -2,10 +2,10 @@
[![CI tests](https://github.com/scito/extract_otp_secrets/actions/workflows/ci.yml/badge.svg)](https://github.com/scito/extract_otp_secrets/actions/workflows/ci.yml)
[![CI docker](https://github.com/scito/extract_otp_secrets/actions/workflows/ci_docker.yml/badge.svg)](https://github.com/scito/extract_otp_secrets/actions/workflows/ci_docker.yml)
![coverage](https://img.shields.io/badge/coverage-94%25-brightgreen)
![coverage](https://img.shields.io/badge/coverage-95%25-brightgreen)
[![License](https://img.shields.io/github/license/scito/extract_otp_secrets)](https://github.com/scito/extract_otp_secrets/blob/master/LICENSE)
[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/scito/extract_otp_secrets?sort=semver)](https://github.com/scito/extract_otp_secrets/releases/latest)
![python versions](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)
![python versions](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)
[![Docker image](https://img.shields.io/badge/docker-image-blue)](https://hub.docker.com/repository/docker/scit0/extract_otp_secrets/general)
[![Linux](https://img.shields.io/badge/os-linux-yellow)](https://github.com/scito/extract_otp_secrets/releases/latest)
[![Windows](https://img.shields.io/badge/os-windows-yellow)](https://github.com/scito/extract_otp_secrets/releases/latest)
@@ -14,7 +14,7 @@
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
<!-- ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/protobuf)
[![GitHub Pipenv locked Python version](https://img.shields.io/github/pipenv/locked/python-version/scito/extract_otp_secrets)](https://github.com/scito/extract_otp_secrets/blob/master/Pipfile.lock)
![protobuf version](https://img.shields.io/badge/protobuf-5.28.0-informational)-->
![protobuf version](https://img.shields.io/badge/protobuf-5.30.1-informational)-->
<!-- [![Github all releases](https://img.shields.io/github/downloads/scito/extract_otp_secrets/total.svg)](https://GitHub.com/scito/extract_otp_secrets/releases/) -->
@@ -36,6 +36,7 @@ The secrets can be exported to JSON or CSV, or printed as QR codes to console or
## Table of contents
- [Table of contents](#table-of-contents)
- [Download and run binary executable (🆕 since v2.1)](#download-and-run-binary-executable--since-v21)
- [MacOS](#macos)
- [Usage](#usage)
@@ -46,7 +47,7 @@ The secrets can be exported to JSON or CSV, or printed as QR codes to console or
- [Installation of optional shared system libraries (recommended)](#installation-of-optional-shared-system-libraries-recommended)
- [Program help: arguments and options](#program-help-arguments-and-options)
- [Examples](#examples)
- [Printing otp secrets from text file](#printing-otp-secrets-form-text-file)
- [Printing otp secrets from text file](#printing-otp-secrets-from-text-file)
- [Printing otp secrets from image file](#printing-otp-secrets-from-image-file)
- [Writing otp secrets to csv file](#writing-otp-secrets-to-csv-file)
- [Writing otp secrets to json file](#writing-otp-secrets-to-json-file)
@@ -66,7 +67,8 @@ The secrets can be exported to JSON or CSV, or printed as QR codes to console or
- [pipenv](#pipenv)
- [Visual Studio Code Remote - Containers / VSCode devcontainer](#visual-studio-code-remote---containers--vscode-devcontainer)
- [venv](#venv)
- [devbox](#devbox)
- [devbox 1](#devbox-1)
- [devbox 2](#devbox-2)
- [docker](#docker)
- [More docker examples](#more-docker-examples)
- [Tests](#tests)
@@ -85,6 +87,7 @@ The secrets can be exported to JSON or CSV, or printed as QR codes to console or
- [Problems and Troubleshooting](#problems-and-troubleshooting)
- [Windows error message](#windows-error-message)
- [Related projects](#related-projects)
- [Third party documentation](#third-party-documentation)
</details>
## Download and run binary executable (🆕 since v2.1)
@@ -280,7 +283,7 @@ python extract_otp_secrets.py = < example_export.png</pre>
## Examples
### Printing otp secrets form text file
### Printing otp secrets from text file
python src/extract_otp_secrets.py example_export.txt
@@ -377,7 +380,7 @@ python extract_otp_secrets.py = < example_export.png</pre>
* macOS
* Windows
* Uses UTF-8 on all platforms
* Supports Python >= 3.8
* Supports Python >= 3.9
* Installation of shared system libraries is optional (🆕 since v2.3)
* Provides a debug mode (-d) for analyzing import problems
* Written in modern Python using type hints and following best practices
@@ -517,7 +520,7 @@ Alternatively, you can use a python virtual env for the dependencies:
The requirements\*.txt files contain all the dependencies (also the optional ones).
To leave the python virtual env just call `deactivate`.
### devbox
### devbox 1
Install [devbox](https://github.com/jetpack-io/devbox), which is a wrapper for nix. Then enter the environment with Python and the packages installed with:
@@ -525,6 +528,14 @@ Install [devbox](https://github.com/jetpack-io/devbox), which is a wrapper for n
devbox shell
```
### devbox 2
Install [devbox](https://devenv.sh), which is a wrapper for nix. Then enter the environment with Python and the packages installed with:
```
devenv shell
```
### docker
Install [Docker](https://docs.docker.com/get-docker/).
@@ -534,19 +545,19 @@ Prebuilt docker images are available for amd64 and arm64 architectures on [Docke
Extracting from an QR image file:
```
curl -s https://raw.githubusercontent.com/scito/extract_otp_secrets/master/example_export.png | docker run --network none --pull always -i --rm -v "$(pwd)":/files:ro scit0/extract_otp_secrets =
curl -s https://raw.githubusercontent.com/scito/extract_otp_secrets/master/example_export.png | docker run --network none --pull always -i --rm -v "$(pwd)":/files:ro docker.io/scit0/extract_otp_secrets =
```
Capturing from camera in GUI window (X Window system required on host):
```
docker run --network none --pull always --rm -v "$(pwd)":/files:ro -i --device="/dev/video0:/dev/video0" --env="DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix:ro scit0/extract_otp_secrets
docker run --network none --pull always --rm -v "$(pwd)":/files:ro -i --device="/dev/video0:/dev/video0" --env="DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix:ro docker.io/scit0/extract_otp_secrets
```
If only text processing is required, there is a small Image based on Alpine Linux:
```
curl -s https://raw.githubusercontent.com/scito/extract_otp_secrets/master/example_export.txt | docker run --network none --pull always -i --rm -v "$(pwd)":/files:ro scit0/extract_otp_secrets:latest-only-txt -
curl -s https://raw.githubusercontent.com/scito/extract_otp_secrets/master/example_export.txt | docker run --network none --pull always -i --rm -v "$(pwd)":/files:ro docker.io/scit0/extract_otp_secrets:latest-only-txt -
```
Docker image from GitHub:
@@ -558,11 +569,11 @@ curl -s https://raw.githubusercontent.com/scito/extract_otp_secrets/master/examp
### More docker examples
docker run --network none --pull always --rm -v "$(pwd)":/files:ro scit0/extract_otp_secrets example_export.png
docker run --network none --pull always --rm -v "$(pwd)":/files:ro docker.io/scit0/extract_otp_secrets example_export.png
docker run --network none --pull always --rm -i -v "$(pwd)":/files:ro scit0/extract_otp_secrets_only_txt - < example_export.txt
docker run --network none --pull always --rm -i -v "$(pwd)":/files:ro docker.io/scit0/extract_otp_secrets:latest-only-txt - < example_export.txt
cat example_export.txt | docker run --network none --pull always --rm -i -v "$(pwd)":/files:ro scit0/extract_otp_secrets:latest_only_txt - -c - > example_out.csv
cat example_export.txt | docker run --network none --pull always --rm -i -v "$(pwd)":/files:ro docker.io/scit0/extract_otp_secrets:latest-only-txt - -c - > example_out.csv
## Tests
@@ -718,7 +729,7 @@ Command for regeneration of Python code from proto3 message definition file (onl
protoc --plugin=protoc-gen-mypy=path/to/protoc-gen-mypy --python_out=src/protobuf_generated_python --mypy_out=src/protobuf_generated_python src/google_auth.proto
The generated protobuf Python code was generated by protoc 28.0 (https://github.com/protocolbuffers/protobuf/releases/tag/v28.0).
The generated protobuf Python code was generated by protoc 30.1 (https://github.com/protocolbuffers/protobuf/releases/tag/v30.1).
For Python type hint generation the [mypy-protobuf](https://github.com/nipunn1313/mypy-protobuf) package is used.
@@ -769,6 +780,11 @@ FileNotFoundError: Could not find module 'libiconv.dll' (or one of its dependenc
* [Android OTP Extractor](https://github.com/puddly/android-otp-extractor) can extract your tokens from popular Android OTP apps and export them in a standard format or just display them as QR codes for easy importing. [Requires a _rooted_ Android phone.]
* [Google Authenticator secret extractor](https://github.com/krissrex/google-authenticator-exporter) is similar project written in JavaScript. It also extracts otp secrets from Google Authenticator.
## Third party documentation
* [TOTP Secret Extraction from QR codes (medium.com)](https://cavalloj.medium.com/totp-secret-extraction-from-qr-codes-ee097b4c687f)
* [Google Authenticator: OTP-Secrets auslesen (stadt-bremerhaven.de)](https://stadt-bremerhaven.de/google-authenticator-otp-secrets-auslesen/)
***
# #StandWithUkraine 🇺🇦

122
devenv.lock Normal file
View File

@@ -0,0 +1,122 @@
{
"nodes": {
"devenv": {
"locked": {
"dir": "src/modules",
"lastModified": 1726050924,
"owner": "cachix",
"repo": "devenv",
"rev": "cf471f691c3765ed431199f61b8bd70530bc4305",
"treeHash": "04a5d566820f8fb1955c7c49ccbd3ff95d9129d7",
"type": "github"
},
"original": {
"dir": "src/modules",
"owner": "cachix",
"repo": "devenv",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"treeHash": "ca14199cabdfe1a06a7b1654c76ed49100a689f9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1716977621,
"owner": "cachix",
"repo": "devenv-nixpkgs",
"rev": "4267e705586473d3e5c8d50299e71503f16a6fb6",
"treeHash": "6d9f1f7ca0faf1bc2eeb397c78a49623260d3412",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "rolling",
"repo": "devenv-nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1725826545,
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f4c846aee8e1e29062aa8514d5e0ab270f4ec2f9",
"treeHash": "8fc49deaed3f2728a7147c38163cc468a117570a",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1725513492,
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "7570de7b9b504cfe92025dd1be797bf546f66528",
"treeHash": "4b46d77870afecd8f642541cb4f4927326343b59",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"devenv": "devenv",
"nixpkgs": "nixpkgs",
"pre-commit-hooks": "pre-commit-hooks"
}
}
},
"root": "root",
"version": 7
}

24
devenv.nix Normal file
View File

@@ -0,0 +1,24 @@
{
pkgs,
lib,
config,
inputs,
...
}:
{
cachix.enable = false;
languages.python = {
enable = true;
venv = {
enable = true;
requirements = ./requirements.txt;
};
};
packages = [
pkgs.git
pkgs.zbar
];
}

14
devenv.yaml Normal file
View File

@@ -0,0 +1,14 @@
inputs:
nixpkgs:
url: github:cachix/devenv-nixpkgs/rolling
# If you're using non-OSS software, you can set allowUnfree to true.
# allowUnfree: true
# If you're willing to use a package that's vulnerable
# permittedInsecurePackages:
# - "openssl-1.1.1w"
# If you have more than one devenv you can merge them
#imports:
# - ./backend

View File

@@ -1,5 +1,5 @@
# --build-arg BASE_IMAGE=python:3.11-slim-buster
ARG BASE_IMAGE=python:3.12-slim-bookworm
ARG BASE_IMAGE=python:3.13-slim-bookworm
FROM $BASE_IMAGE
# https://docs.docker.com/engine/reference/builder/
@@ -16,7 +16,8 @@ COPY requirements*.txt src/ run_pytest.sh pytest.ini tests/ example_*.txt exampl
ARG RUN_TESTS=true
RUN apt-get update && apt-get install -y --no-install-recommends \
RUN uname -a \
&& apt-get update && apt-get install -y --no-install-recommends \
libgl1 \
libglib2.0-0 \
libsm6 \
@@ -31,6 +32,6 @@ WORKDIR /files
ENTRYPOINT ["python", "/extract/extract_otp_secrets.py"]
LABEL org.opencontainers.image.source https://github.com/scito/extract_otp_secrets
LABEL org.opencontainers.image.license GPL-3.0+
LABEL org.opencontainers.image.source=https://github.com/scito/extract_otp_secrets
LABEL org.opencontainers.image.license=GPL-3.0+
LABEL maintainer="Scito https://scito.ch, https://github.com/scito"

View File

@@ -1,4 +1,4 @@
ARG BASE_IMAGE=python:3.12-alpine
ARG BASE_IMAGE=python:3.13-alpine
FROM $BASE_IMAGE
# https://docs.docker.com/engine/reference/builder/
@@ -17,7 +17,8 @@ COPY requirements*.txt src/ run_pytest.sh pytest.ini tests/ example_*.txt exampl
ARG RUN_TESTS=true
RUN apk add --no-cache \
RUN uname -a \
&& apk add --no-cache \
jpeg \
zlib \
&& echo "Arch: $(apk --print-arch)" \
@@ -43,6 +44,6 @@ WORKDIR /files
ENTRYPOINT ["python", "/extract/extract_otp_secrets.py"]
LABEL org.opencontainers.image.source https://github.com/scito/extract_otp_secrets
LABEL org.opencontainers.image.license GPL-3.0+
LABEL org.opencontainers.image.source=https://github.com/scito/extract_otp_secrets
LABEL org.opencontainers.image.license=GPL-3.0+
LABEL maintainer="Scito https://scito.ch, https://github.com/scito"

View File

@@ -13,7 +13,7 @@ Generate from file: README.md
- [Installation of optional shared system libraries (recommended)](#installation-of-optional-shared-system-libraries-recommended)
- [Program help: arguments and options](#program-help-arguments-and-options)
- [Examples](#examples)
- [Printing otp secrets form text file](#printing-otp-secrets-form-text-file)
- [Printing otp secrets from text file](#printing-otp-secrets-from-text-file)
- [Printing otp secrets from image file](#printing-otp-secrets-from-image-file)
- [Writing otp secrets to csv file](#writing-otp-secrets-to-csv-file)
- [Writing otp secrets to json file](#writing-otp-secrets-to-json-file)
@@ -33,7 +33,8 @@ Generate from file: README.md
- [pipenv](#pipenv)
- [Visual Studio Code Remote - Containers / VSCode devcontainer](#visual-studio-code-remote---containers--vscode-devcontainer)
- [venv](#venv)
- [devbox](#devbox)
- [devbox 1](#devbox-1)
- [devbox 2](#devbox-2)
- [docker](#docker)
- [More docker examples](#more-docker-examples)
- [Tests](#tests)
@@ -52,5 +53,6 @@ Generate from file: README.md
- [Problems and Troubleshooting](#problems-and-troubleshooting)
- [Windows error message](#windows-error-message)
- [Related projects](#related-projects)
- [Third party documentation](#third-party-documentation)
Table of contents generated.

View File

@@ -21,11 +21,11 @@ classifiers = [
"Topic :: Utilities",
"Topic :: Security",
"Topic :: Multimedia :: Graphics :: Capture :: Digital Camera",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Intended Audience :: End Users/Desktop",
"Intended Audience :: Developers",
"Intended Audience :: System Administrators",
@@ -54,7 +54,7 @@ license = {text = "GNU General Public License v3 (GPLv3)"}
readme = "README.md"
authors = [{name = "scito", email = "info@scito.ch"}]
maintainers = [{name = "scito", email = "info@scito.ch"}]
requires-python = ">=3.8, <4"
requires-python = ">=3.9, <4"
scripts = {extract_otp_secrets = "extract_otp_secrets:sys_main"}
urls = {Project-URL = "https://github.com/scito/extract_otp_secrets", Bug-Reports = "https://github.com/scito/extract_otp_secrets/issues", Source = "https://github.com/scito/extract_otp_secrets"}

View File

@@ -36,6 +36,7 @@ import argparse
import base64
import csv
import fileinput
import glob
import json
import os
import platform
@@ -48,7 +49,7 @@ from typing import (Any, Final, List, Optional, Sequence, TextIO, Tuple,
TypedDict, Union)
import colorama
from qrcode import QRCode # type: ignore
from qrcode import QRCode
import protobuf_generated_python.google_auth_pb2 as pb
@@ -367,7 +368,7 @@ def extract_otps_from_camera(args: Args) -> Otps:
if QRMode.CV2:
otp_url, raw_pts, _ = cv2_qr.detectAndDecode(img)
else:
otp_url, raw_pts = cv2_qr_wechat.detectAndDecode(img) # type: ignore # use proper cv2 types
otp_url, raw_pts = cv2_qr_wechat.detectAndDecode(img)
if raw_pts is not None:
if otp_url:
new_otps_count = extract_otps_from_otp_url(otp_url, otp_urls, otps, args)
@@ -527,14 +528,20 @@ def extract_otps_from_files(args: Args) -> Otps:
files_count = urls_count = otps_count = 0
if verbose: print(f"Input files: {args.infile}")
for infile in args.infile:
if verbose >= LogLevel.MORE_VERBOSE: log_verbose(f"Processing infile {infile}")
files_count += 1
for line in get_otp_urls_from_file(infile, args):
if verbose >= LogLevel.MORE_VERBOSE: log_verbose(line)
if line.startswith('#') or line == '': continue
urls_count += 1
otps_count += extract_otp_from_otp_url(line, otps, urls_count, infile, args)
for infile_raw in args.infile:
expanded_infiles = glob.glob(infile_raw)
if not expanded_infiles:
expanded_infiles = [infile_raw]
if verbose >= LogLevel.DEBUG: log_debug(f"Could not expand input files, fallback to infile {infile_raw}")
if verbose >= LogLevel.DEBUG: log_debug(f"Expanded input files: {expanded_infiles}")
for infile in expanded_infiles:
if verbose >= LogLevel.MORE_VERBOSE: log_verbose(f"Processing infile {infile}")
files_count += 1
for line in get_otp_urls_from_file(infile, args):
if verbose >= LogLevel.MORE_VERBOSE: log_verbose(line)
if line.startswith('#') or line == '': continue
urls_count += 1
otps_count += extract_otp_from_otp_url(line, otps, urls_count, infile, args)
if verbose: print(f"Extracted {otps_count} otp{'s'[:otps_count != 1]} from {urls_count} otp url{'s'[:urls_count != 1]} by reading {files_count} infile{'s'[:files_count != 1]}")
return otps
@@ -697,7 +704,7 @@ def save_qr_image_file(otp_url: OtpUrl, name: str) -> None:
qr.add_data(otp_url)
img = qr.make_image(fill_color='black', back_color='white')
if verbose: print(f"Saving to {name}")
img.save(name)
img.save(name) # type: ignore
def print_qr(otp_url: str, out: Optional[TextIO] = None) -> None:

View File

@@ -2,7 +2,7 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: google_auth.proto
# Protobuf Python Version: 5.28.0
# Protobuf Python Version: 6.30.1
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
@@ -11,9 +11,9 @@ from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
_runtime_version.ValidateProtobufRuntimeVersion(
_runtime_version.Domain.PUBLIC,
5,
28,
0,
6,
30,
1,
'',
'google_auth.proto'
)

View File

@@ -2,9 +2,11 @@ QReader installed: True
CV2 version: 4.10.0
QR reading mode: ZBAR
Version: extract_otp_secrets 2.8.1.post17+git.3dc7d1c2.dirty Linux x86_64 Python 3.11.9 (CPython/called as script)
Version: extract_otp_secrets 2.8.4.post4+git.7ce765dd.dirty Linux x86_64 Python 3.11.10 (CPython/called as script)
Input files: ['example_export.txt']
DEBUG: Expanded input files: ['example_export.txt']
Processing infile example_export.txt
Reading lines of example_export.txt
# 2FA example from https://www.raspberrypi.org/blog/setting-up-two-factor-authentication-on-your-raspberry-pi/

View File

@@ -2,9 +2,11 @@ QReader installed: True
CV2 version: 4.10.0
QR reading mode: ZBAR
Version: extract_otp_secrets 2.8.1.post17+git.3dc7d1c2.dirty Linux x86_64 Python 3.11.9 (CPython/called as script)
Version: extract_otp_secrets 2.8.4.post4+git.7ce765dd.dirty Linux x86_64 Python 3.11.10 (CPython/called as script)
Input files: ['example_export.txt']

DEBUG: Expanded input files: ['example_export.txt'] 
Processing infile example_export.txt
Reading lines of example_export.txt
# 2FA example from https://www.raspberrypi.org/blog/setting-up-two-factor-authentication-on-your-raspberry-pi/

View File

@@ -869,19 +869,8 @@ def test_wrong_content(capsys: pytest.CaptureFixture[str]) -> None:
# Assert
captured = capsys.readouterr()
expected_stderr = '''
WARN: input is not a otpauth-migration:// url
source: tests/data/test_export_wrong_content.txt
input: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
Maybe a wrong file was given
ERROR: could not parse query parameter in input url
source: tests/data/test_export_wrong_content.txt
url: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
'''
assert captured.out == ''
assert captured.err == expected_stderr
assert captured.err == EXPECTED_STDERR_OTP_URL_WRONG
def test_one_wrong_file(capsys: pytest.CaptureFixture[str]) -> None:
@@ -891,19 +880,8 @@ def test_one_wrong_file(capsys: pytest.CaptureFixture[str]) -> None:
# Assert
captured = capsys.readouterr()
expected_stderr = '''
WARN: input is not a otpauth-migration:// url
source: tests/data/test_export_wrong_content.txt
input: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
Maybe a wrong file was given
ERROR: could not parse query parameter in input url
source: tests/data/test_export_wrong_content.txt
url: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
'''
assert captured.out == EXPECTED_STDOUT_FROM_EXAMPLE_EXPORT
assert captured.err == expected_stderr
assert captured.err == EXPECTED_STDERR_OTP_URL_WRONG
def test_one_wrong_file_colored(capsys: pytest.CaptureFixture[str]) -> None:
@@ -913,19 +891,8 @@ def test_one_wrong_file_colored(capsys: pytest.CaptureFixture[str]) -> None:
# Assert
captured = capsys.readouterr()
expected_stderr = f'''{colorama.Fore.RED}
WARN: input is not a otpauth-migration:// url
source: tests/data/test_export_wrong_content.txt
input: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
Maybe a wrong file was given{colorama.Fore.RESET}
{colorama.Fore.RED}
ERROR: could not parse query parameter in input url
source: tests/data/test_export_wrong_content.txt
url: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.{colorama.Fore.RESET}
'''
assert captured.out == EXPECTED_STDOUT_FROM_EXAMPLE_EXPORT
assert captured.err == expected_stderr
assert captured.err == EXPECTED_STDERR_COLORED_OTP_URL_WRONG
def test_one_wrong_line(capsys: pytest.CaptureFixture[str], monkeypatch: pytest.MonkeyPatch) -> None:
@@ -997,6 +964,46 @@ def test_img_qr_reader_from_file_happy_path(capsys: pytest.CaptureFixture[str])
assert captured.err == ''
@pytest.mark.qreader
def test_img_qr_reader_but_no_otp_from_file(capsys: pytest.CaptureFixture[str]) -> None:
# Act
extract_otp_secrets.main(['-n', 'tests/data/qr_but_without_otp.png'])
# Assert
captured = capsys.readouterr()
assert captured.out == ''
assert captured.err == EXPECTED_STDERR_NO_OTP_URL
@pytest.mark.qreader
def test_img_qr_reader_from_wildcard(capsys: pytest.CaptureFixture[str]) -> None:
# Act
extract_otp_secrets.main(['-n', 'tests/data/*.png'])
# Assert
captured = capsys.readouterr()
assert captured.out == EXPECTED_STDOUT_FROM_EXAMPLE_EXPORT_PNG
assert normalize_testfile_path(captured.err) == EXPECTED_STDERR_NO_OTP_URL
def normalize_testfile_path(text: str) -> str:
return text.replace('tests/data\\', 'tests/data/') if sys.platform.startswith("win") else text
@pytest.mark.qreader
def test_img_qr_reader_from_multiple_files(capsys: pytest.CaptureFixture[str]) -> None:
# Act
extract_otp_secrets.main(['-n', 'tests/data/test_googleauth_export.png', 'tests/data/text_masquerading_as_image.jpeg'])
# Assert
captured = capsys.readouterr()
assert captured.out == EXPECTED_STDOUT_FROM_EXAMPLE_EXPORT_PNG
assert captured.err == EXPECTED_STDERR_BAD_IMAGE
@pytest.mark.qreader
def test_img_qr_reader_by_parameter(capsys: pytest.CaptureFixture[str], qr_mode: str) -> None:
# Act
@@ -1041,24 +1048,7 @@ def test_img_qr_reader_from_stdin(capsys: pytest.CaptureFixture[str], monkeypatc
# Assert
captured = capsys.readouterr()
expected_stdout = '''Name: Test1:test1@example1.com
Secret: JBSWY3DPEHPK3PXP
Issuer: Test1
Type: totp
Name: Test2:test2@example2.com
Secret: JBSWY3DPEHPK3PXQ
Issuer: Test2
Type: totp
Name: Test3:test3@example3.com
Secret: JBSWY3DPEHPK3PXR
Issuer: Test3
Type: totp
'''
assert captured.out == expected_stdout
assert captured.out == EXPECTED_STDOUT_FROM_EXAMPLE_EXPORT_PNG
assert captured.err == ''
@@ -1143,19 +1133,9 @@ def test_non_image_file(capsys: pytest.CaptureFixture[str]) -> None:
# Assert
captured = capsys.readouterr()
expected_stderr = '''
WARN: input is not a otpauth-migration:// url
source: tests/data/text_masquerading_as_image.jpeg
input: This is just a text file masquerading as an image file.
Maybe a wrong file was given
ERROR: could not parse query parameter in input url
source: tests/data/text_masquerading_as_image.jpeg
url: This is just a text file masquerading as an image file.
'''
assert captured.err == expected_stderr
assert captured.out == ''
assert captured.err == EXPECTED_STDERR_BAD_IMAGE
def test_next_valid_qr_mode() -> None:
@@ -1209,3 +1189,47 @@ Issuer: Test3
Type: totp
'''
EXPECTED_STDERR_OTP_URL_WRONG = '''
WARN: input is not a otpauth-migration:// url
source: tests/data/test_export_wrong_content.txt
input: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
Maybe a wrong file was given
ERROR: could not parse query parameter in input url
source: tests/data/test_export_wrong_content.txt
url: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
'''
EXPECTED_STDERR_COLORED_OTP_URL_WRONG = f'''{colorama.Fore.RED}
WARN: input is not a otpauth-migration:// url
source: tests/data/test_export_wrong_content.txt
input: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
Maybe a wrong file was given{colorama.Fore.RESET}
{colorama.Fore.RED}
ERROR: could not parse query parameter in input url
source: tests/data/test_export_wrong_content.txt
url: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.{colorama.Fore.RESET}
'''
EXPECTED_STDERR_NO_OTP_URL = '''
WARN: input is not a otpauth-migration:// url
source: tests/data/qr_but_without_otp.png
input: NOT A otpauth-migration:// URL
Maybe a wrong file was given
ERROR: could not parse query parameter in input url
source: tests/data/qr_but_without_otp.png
url: NOT A otpauth-migration:// URL
'''
EXPECTED_STDERR_BAD_IMAGE = '''
WARN: input is not a otpauth-migration:// url
source: tests/data/text_masquerading_as_image.jpeg
input: This is just a text file masquerading as an image file.
Maybe a wrong file was given
ERROR: could not parse query parameter in input url
source: tests/data/text_masquerading_as_image.jpeg
url: This is just a text file masquerading as an image file.
'''