Compare commits
60 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a80f7247c2 | ||
|
f106d3b9cc | ||
|
c2075190e1 | ||
|
44f2fac0d4 | ||
|
3f32dda864 | ||
|
8ba2186686 | ||
|
6a37da6353 | ||
|
6c57b99980 | ||
|
4451606530 | ||
|
30c19dde74 | ||
|
4518aa2e35 | ||
|
9a92d7a3c8 | ||
|
9704223eb6 | ||
|
8d3bca6e36 | ||
|
b317bba454 | ||
|
9915bc091b | ||
|
88979b6b3c | ||
|
ec7c2a0b9c | ||
|
9486a673b8 | ||
|
c1064d56ae | ||
|
1b31f85a36 | ||
|
645f70e0c2 | ||
|
bc6f093055 | ||
|
2cb70368d3 | ||
|
29044e8e52 | ||
|
c1c945d84e | ||
|
dbc6d0363d | ||
|
07e44d1423 | ||
|
2bd9ca56a0 | ||
|
86e8f3cec9 | ||
|
b1d19d0944 | ||
|
10fe464b3f | ||
|
a4b0e4f26b | ||
|
6e63c24c52 | ||
|
271c8a29af | ||
|
9837d10946 | ||
|
da68592788 | ||
|
4424eb05d9 | ||
|
6da2f0445f | ||
|
98f62d0aa9 | ||
|
d69a99729e | ||
|
1104abbc61 | ||
|
4aeea1e94b | ||
|
30896489cb | ||
|
283ed2d09d | ||
|
49dcb5d3d7 | ||
|
65a5365b94 | ||
|
49db3cb845 | ||
|
22a8495563 | ||
|
4ae860d6e3 | ||
|
25201232d8 | ||
|
b822de0992 | ||
|
a6b91c890b | ||
|
25316e4f7f | ||
|
0e61c1620f | ||
|
8c16fb865f | ||
|
070586d4f7 | ||
|
e39d1ac61d | ||
|
501c9d2136 | ||
|
44d837a362 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
ko_fi: athulcyriac
|
||||
custom: https://www.buymeacoffee.com/JeVlc7T
|
||||
custom: https://www.buymeacoffee.com/athulca
|
||||
|
27
.github/testing.yml
vendored
Normal file
27
.github/testing.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: WakaReadme
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.11
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
curl -sSL https://install.python-poetry.org | python -
|
||||
export PATH="$HOME/.poetry/bin:${PATH}"
|
||||
source $HOME/.poetry/env
|
||||
poetry install
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
poetry run python -m unittest discover
|
160
.gitignore
vendored
160
.gitignore
vendored
@@ -1,2 +1,158 @@
|
||||
#generated when running the tests
|
||||
__pycache__/
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
# VSCode
|
||||
.vscode/
|
||||
|
||||
# asdf
|
||||
.tool-versions
|
||||
|
@@ -1,7 +0,0 @@
|
||||
language: python
|
||||
python:
|
||||
- "3.7"
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
script:
|
||||
- python -m unittest discover
|
138
CONTRIBUTING.md
Normal file
138
CONTRIBUTING.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Contributing
|
||||
|
||||

|
||||
|
||||
> First off, thank you! Please follow along.
|
||||
|
||||
**You need to _fork_ this repository and _clone_ it, onto your system.**
|
||||
|
||||
## Using Docker/Podman (recommended)
|
||||
|
||||
> Assumes you've already installed & configured latest version of [docker](https://www.docker.com/) or [podman](https://podman.io/).
|
||||
>
|
||||
> Replace `docker` with `podman` everywhere, if you're using the latter.
|
||||
|
||||
1. **Inside the cloned folder**, run:
|
||||
|
||||
```console
|
||||
$ git archive -o 'waka-readme.tar.gz' HEAD
|
||||
$ docker build . -f containerfile -t 'waka-readme:dev'
|
||||
```
|
||||
|
||||
to build an image. (Image is identified as `<name>:<tag>`)
|
||||
|
||||
2. Then create containers and use them as dev environments.
|
||||
|
||||
- Temporary:
|
||||
|
||||
```console
|
||||
$ docker run --rm -it --name 'WakaReadmeDev' 'waka-readme:dev' bash
|
||||
```
|
||||
|
||||
- or Persistent
|
||||
|
||||
```console
|
||||
$ docker run --detach --name 'WakaReadmeDev' 'waka-readme:dev'
|
||||
```
|
||||
|
||||
where `WakaReadmeDev` is the docker container name. Then execute `bash` in the container:
|
||||
|
||||
```console
|
||||
$ docker exec -it 'WakaReadmeDev' bash
|
||||
```
|
||||
|
||||
3. For development, you can attach code editor of your choice to this container.
|
||||
4. Export environnement variables with edits, as required:
|
||||
|
||||
```console
|
||||
// inside container, create a file `.env`
|
||||
# micro .env
|
||||
```
|
||||
|
||||
paste (`Ctrl+Shift+V`) the following contents:
|
||||
|
||||
```env
|
||||
INPUT_GH_TOKEN='<GITHUB TOKEN>'
|
||||
INPUT_WAKATIME_API_KEY='<WAKATIME API KEY>'
|
||||
INPUT_API_BASE_URL='https://wakatime.com/api'
|
||||
INPUT_REPOSITORY='<REPOSITORY SLUG>'
|
||||
INPUT_COMMIT_MESSAGE='<COMMIT MESSAGE>'
|
||||
INPUT_SHOW_TITLE='True'
|
||||
INPUT_BLOCKS='->'
|
||||
INPUT_SHOW_TIME='True'
|
||||
INPUT_SHOW_TOTAL='True'
|
||||
INPUT_TIME_RANGE='last_7_days'
|
||||
INPUT_SHOW_MASKED_TIME='True'
|
||||
```
|
||||
|
||||
and execute program with:
|
||||
|
||||
```console
|
||||
# poetry shell
|
||||
# set -a && . ./.env && set +a # optional
|
||||
(venv)# python -m main --dev
|
||||
```
|
||||
|
||||
5. Later, to remove stop and remove the container:
|
||||
|
||||
```console
|
||||
// exit container
|
||||
# exit
|
||||
|
||||
$ docker container stop 'WakaReadmeDev'
|
||||
$ docker container rm 'WakaReadmeDev'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **NOTE** With VSCode on Windows
|
||||
>
|
||||
> Add these to `.vscode/settings.json`
|
||||
>
|
||||
> ```json
|
||||
> {
|
||||
> "terminal.integrated.commandsToSkipShell": [
|
||||
> "-workbench.action.quickOpenView"
|
||||
> ]
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> To quit the `micro` editor from the vscode terminal.
|
||||
|
||||
---
|
||||
|
||||
## Manual
|
||||
|
||||
> Assumes you've already installed & configured latest version of [python](https://www.python.org/) and [poetry](https://python-poetry.org/).
|
||||
|
||||
1. Inside the cloned folder run:
|
||||
|
||||
```console
|
||||
$ poetry shell
|
||||
(venv)$ poetry install
|
||||
```
|
||||
|
||||
to create and activate a virtual environnement and install dependencies.
|
||||
|
||||
2. Put environment variables in a `.env` file
|
||||
|
||||
```env
|
||||
INPUT_GH_TOKEN='<GITHUB TOKEN>'
|
||||
INPUT_WAKATIME_API_KEY='<WAKATIME API KEY>'
|
||||
INPUT_API_BASE_URL='https://wakatime.com/api'
|
||||
INPUT_REPOSITORY='<REPOSITORY SLUG>'
|
||||
INPUT_COMMIT_MESSAGE='<COMMIT MESSAGE>'
|
||||
INPUT_SHOW_TITLE='True'
|
||||
INPUT_BLOCKS='->'
|
||||
INPUT_SHOW_TIME='True'
|
||||
INPUT_SHOW_TOTAL='True'
|
||||
INPUT_TIME_RANGE='last_7_days'
|
||||
INPUT_SHOW_MASKED_TIME='True'
|
||||
```
|
||||
|
||||
3. Execute program in development mode with:
|
||||
|
||||
```console
|
||||
$ set -a && . ./.env && set +a # optional
|
||||
(venv)$ python -m main --dev
|
||||
```
|
@@ -1,8 +0,0 @@
|
||||
FROM python:latest
|
||||
|
||||
# Install dependencies.
|
||||
ADD requirements.txt /requirements.txt
|
||||
ADD main.py /main.py
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
CMD ["python", "/main.py"]
|
4
LICENSE
4
LICENSE
@@ -1,4 +1,4 @@
|
||||
The MIT License (MIT)
|
||||
# The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020 ATHUL CYRIAC AJAY
|
||||
|
||||
@@ -17,4 +17,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
13
Pipfile
13
Pipfile
@@ -1,13 +0,0 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
requests = "*"
|
||||
pygithub = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
85
Pipfile.lock
generated
85
Pipfile.lock
generated
@@ -1,85 +0,0 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "ee0dbc310e64a4cc599d6b5e02bb22e3f33eb97ead8e5f1e315cf355fbef9367"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.7"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3",
|
||||
"sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"
|
||||
],
|
||||
"version": "==2020.6.20"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"deprecated": {
|
||||
"hashes": [
|
||||
"sha256:525ba66fb5f90b07169fdd48b6373c18f1ee12728ca277ca44567a367d9d7f74",
|
||||
"sha256:a766c1dccb30c5f6eb2b203f87edd1d8588847709c78589e1521d769addc8218"
|
||||
],
|
||||
"version": "==1.2.10"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6",
|
||||
"sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"
|
||||
],
|
||||
"version": "==2.10"
|
||||
},
|
||||
"pygithub": {
|
||||
"hashes": [
|
||||
"sha256:8375a058ec651cc0774244a3bc7395cf93617298735934cdd59e5bcd9a1df96e",
|
||||
"sha256:d2d17d1e3f4474e070353f201164685a95b5a92f5ee0897442504e399c7bc249"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.51"
|
||||
},
|
||||
"pyjwt": {
|
||||
"hashes": [
|
||||
"sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e",
|
||||
"sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"
|
||||
],
|
||||
"version": "==1.7.1"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b",
|
||||
"sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.24.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527",
|
||||
"sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"
|
||||
],
|
||||
"version": "==1.25.9"
|
||||
},
|
||||
"wrapt": {
|
||||
"hashes": [
|
||||
"sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
|
||||
],
|
||||
"version": "==1.12.1"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
238
README.md
238
README.md
@@ -1,57 +1,94 @@
|
||||
<center>
|
||||
|
||||

|
||||
|
||||
</center>
|
||||
|
||||
# Dev Metrics in Readme [](https://travis-ci.com/athul/waka-readme)
|
||||
|
||||
[WakaTime](https://wakatime.com) weekly metrics on your profile readme.
|
||||
|
||||

|
||||
|
||||
---
|
||||
:speech_balloon: **Forum** | [GitHub discussions][gh_discuss]
|
||||
|
||||
[WakaTime](https://wakatime.com) Weekly Metrics on your Profile Readme:
|
||||
## New to WakaTime?
|
||||
|
||||
> Nope? Skip to [prep work](#prep-work).
|
||||
|
||||
WakaTime gives you an idea of the time you spent on coding. This helps you boost your productivity and competitive edge.
|
||||
|
||||
1. Head over to <https://wakatime.com/> and create an account.
|
||||
2. After logging in get your WakaTime API Key from <https://wakatime.com/api-key/>.
|
||||
3. Install [WakaTime plugin][waka_plugins] in your favorite editor / IDE.
|
||||
4. Paste in your API key to start telemetry.
|
||||
|
||||
:information_source: **Info** | You can read [WakaTime help][waka_help] to know more about configurations.
|
||||
Alternatively, you can also fetch data from WakaTime compatible services like [Wakapi][wakapi] or [Hakatime][hakatime].
|
||||
|
||||
## Prep Work
|
||||
|
||||
1. You need to update the markdown file(.md) with 2 comments. You can refer [here](#update-your-readme) for updating it.
|
||||
2. You'll need a WakaTime API Key. You can get that from your WakaTime Account Settings
|
||||
- You can refer [here](#new-to-wakatime), if you're new to WakaTime
|
||||
3. **Optional** You'll need a GitHub API Token with `repo` scope from [here](https://github.com/settings/tokens) if you're running the action not in your Profile Repository
|
||||
- You can use [this](#other-repository-not-profile) example to work it out
|
||||
4. You need to save the WakaTime API Key (and the GitHub API Token, if you need it) in the repository secrets. You can find that in the Settings of your Repository.Be sure to save those as the following.
|
||||
- WakaTime-api-key as `WAKATIME_API_KEY = <your wakatime API Key>`and
|
||||
- The GitHub Access Token as `GH_TOKEN=<your github access token>`
|
||||
5. You can follow either of the Two Examples according to your needs to get started with.
|
||||
A GitHub repository and a README file is required. We'll be making use of readme in the [profile repository][profile_readme]\*.
|
||||
|
||||
> I strongly suggest you to run the Action in your Profile Repo since you won't be needing a GitHub Access Token
|
||||
- Save the README file after copy-pasting the following special comments. Your dev-metics will show up in between.
|
||||
|
||||
This Action will run everyday at 00.00 UTC
|
||||
```md
|
||||
|
||||
## Update your Readme
|
||||
<!--START_SECTION:waka-->
|
||||
<!--END_SECTION:waka-->
|
||||
|
||||
Add a comment to your `README.md` like this:
|
||||
```
|
||||
|
||||
```md
|
||||
<!--START_SECTION:waka-->
|
||||
<!--END_SECTION:waka-->
|
||||
```
|
||||
- Navigate to your repo's `Settings > Secrets` and add a new secret *named* `WAKATIME_API_KEY` with your API key as it's *value*.
|
||||
> Or use the url <https://github.com/USERNAME/USERNAME/settings/secrets/actions/new> by replacing the `USERNAME` with your own username.
|
||||
> ![new_secrets_actions][new_secrets_actions]
|
||||
|
||||
These lines will be our entry-points for the dev metrics.
|
||||
- If you're not using [profile repository][profile_readme], add another secret *named* `GH_TOKEN` and insert your [GitHub token][gh_access_token]\* in place of *value*.
|
||||
|
||||
## New to WakaTime
|
||||
- Create a new workflow file (`waka-readme.yml`) inside `.github/workflows/` folder of your repository. You can create it from a template using the *actions tab* of your repository too.
|
||||
- Clear any existing contents, add the following lines and save the file.
|
||||
|
||||
WakaTime gives you an idea of the time you really spent on coding. This helps you boost your productivity and competitive edge.
|
||||
```yml
|
||||
name: Waka Readme
|
||||
|
||||
- Head over to <https://wakatime.com> and create an account.
|
||||
- Get your WakaTime API Key from your [Account Settings in WakaTime](https://wakatime.com/settings/account).
|
||||
- Install the [WakaTime plugin](https://wakatime.com/plugins) in your favourite editor / IDE.
|
||||
- Paste in your API key to start the analysis.
|
||||
on:
|
||||
workflow_dispatch: # for manual workflow trigger
|
||||
schedule:
|
||||
- cron: '0 0 * * *' # runs at every 12AM UTC
|
||||
|
||||
### Profile Repository
|
||||
jobs:
|
||||
update-readme:
|
||||
name: WakaReadme DevMetrics
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: athul/waka-readme@master
|
||||
with:
|
||||
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
|
||||
# following flags are required, only if this is not on
|
||||
# profile readme, remove the leading `#` to use them
|
||||
#GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
#REPOSITORY: <gh_username/gh_username>
|
||||
```
|
||||
|
||||
_If you're executing the workflow on your Profile Repository (`<username>/<username>`)_
|
||||
## Tweaks
|
||||
|
||||
> You wouldn't need an GitHub Access Token since GitHub Actions already makes one for you.
|
||||
There are many flags that you can tweak to suit your taste!
|
||||
|
||||
Please follow the steps below:
|
||||
| Flag | Default | Options | Meaning |
|
||||
| ------------------ | -------------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| `API_BASE_URL` | `https://wakatime.com/api` | `https://wakatime.com/api`, `https://wakapi.dev/api`, `https://hakatime.mtx-dev.xyz/api` | Integration with WakaTime compatible services like [Wakapi][wakapi] & [Hakatime][hakatime] are possible |
|
||||
| `REPOSITORY` | `<gh_username>/<gh_username>` | `<gh_username>/<repo_name>` | Waka-readme stats will appear on the provided repository |
|
||||
| `COMMIT_MESSAGE` | `Updated waka-readme graph with new metrics` | anything else! | Messaged used when committing updated stats |
|
||||
| `SHOW_TITLE` | `false` | `false`, `true` | Add title to waka-readme stats blob |
|
||||
| `BLOCKS` | `░▒▓█` | `░▒▓█`, `⣀⣄⣤⣦⣶⣷⣿`, `-#`, you can be creative! | Ascii art used to build stats graph |
|
||||
| `TIME_RANGE` | `last_7_days` | `last_7_days`, `last_30_days`, `last_6_months`, `last_year`, `all_time` | String representing a dispensation from which stats are aggregated |
|
||||
| `SHOW_TIME` | `true` | `false`, `true` | Displays the amount of time spent for each language |
|
||||
| `SHOW_TOTAL` | `false` | `false`, `true` | Show total coding time |
|
||||
| `SHOW_MASKED_TIME` | `false` | `false`, `true` | Adds total coding time including unclassified languages (overrides: `SHOW_TOTAL`) |
|
||||
|
||||
1. Go to your `<username>/<username>/actions`, hit `New workflow`, `set up a workflow yourself`, delete all the default content github made for you.
|
||||
2. Copy the following code and paste it to your new workflow you created at step 1:
|
||||
# Example
|
||||
|
||||
**`waka-readme.yml`**
|
||||
|
||||
```yml
|
||||
name: Waka Readme
|
||||
@@ -60,128 +97,53 @@ on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Runs at 12am UTC
|
||||
- cron: "0 0 * * *"
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
update-readme:
|
||||
name: Update this repo's README
|
||||
name: WakaReadme DevMetrics
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: athul/waka-readme@master
|
||||
with:
|
||||
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
|
||||
SHOW_TITLE: true
|
||||
BLOCKS: ->
|
||||
TIME_RANGE: all_time
|
||||
SHOW_TIME: true
|
||||
SHOW_MASKED_TIME: true
|
||||
```
|
||||
|
||||
3. Go to your repo secrets by hitting `Settings => Secrets` tab in your profile repo. You can also enter the url https://github.com/USERNAME/USERNAME/settings/secrets . Please replace the `USERNAME` with your own username.
|
||||
4. Create a new `Secret`. `Name`: `WAKATIME_API_KEY`, `Value`: Paste the Wakatime API key here. If you don't know what is the key, please go to [Account Settings in WakaTime](https://wakatime.com/settings/account) to find your API Key there.
|
||||
5. Add a comment to your `README.md` like this:
|
||||
**`README.md`**
|
||||
|
||||
```md
|
||||
<!--START_SECTION:waka-->
|
||||
<!--END_SECTION:waka-->
|
||||
From: 10 July 2020 - To: 06 August 2022
|
||||
|
||||
Total Time: 1,464 hrs 54 mins
|
||||
|
||||
Python 859 hrs 29 mins >>>>>>>>>>>>>>----------- 54.68 %
|
||||
Markdown 132 hrs 33 mins >>----------------------- 08.43 %
|
||||
TeX 103 hrs 52 mins >>----------------------- 06.61 %
|
||||
HTML 94 hrs 48 mins >>----------------------- 06.03 %
|
||||
Nim 64 hrs 31 mins >------------------------ 04.11 %
|
||||
Other 47 hrs 58 mins >------------------------ 03.05 %
|
||||
```
|
||||
|
||||
6. Go to Workflows menu (mentioned in step 1), click `Waka Readme`, click `Run workflow`.
|
||||
7. Go to your profile page. you will be able to see it.
|
||||
## Why only the language stats (and not other data) from the API?
|
||||
|
||||
### Other Repository (not Profile)
|
||||
I am a fan of minimal designs and the profile readme is a great way to show off your skills and interests. The WakaTime API, gets us a **lot of data** about a person's **coding activity including the editors and Operating Systems you used and the projects you worked on**. Some of these projects maybe secretive and should not be shown out to the public. Using up more data via the Wakatime API will clutter the profile readme and hinder your chances on displaying what you provide **value to the community** like the pinned Repositories. I believe that **Coding Stats is nerdiest of all** since you can tell the community that you are ***exercising these languages or learning a new language***, this will also show that you spend some amount of time to learn and exercise your development skills. That's what matters in the end :heart:
|
||||
|
||||
_If you're executing the workflow on another repo other than `<username>/<username>`_
|
||||
---
|
||||
|
||||
You'll need to get a [GitHub Access Token](https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token) with a `repo` scope and save it in the Repo Secrets `GH_TOKEN = <Your GitHub Access Token>`
|
||||
<sup>*</sup>`REPOSITORY` flag and `GH_TOKEN` secret are required you're not using profile readme.
|
||||
|
||||
Here is Sample Workflow File for running it:
|
||||
[//]: #(Links)
|
||||
|
||||
```yml
|
||||
name: Waka Readme
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Runs at 12am UTC
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
update-readme:
|
||||
name: Update Readme with Metrics
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: athul/waka-readme@master
|
||||
with:
|
||||
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
REPOSITORY: <username/username> # optional, By default, it will automatically use the repository who's executing the workflow.
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
### Running Tests
|
||||
|
||||
To run tests simply execute the following in the directory containing main.py:
|
||||
|
||||
```python
|
||||
python -m unittest discover
|
||||
```
|
||||
|
||||
### Contributing Tests
|
||||
|
||||
These tests uses the python Unit testing framework, [unittest](https://docs.python.org/3/library/unittest.html)
|
||||
|
||||
Since this project is contained all within one file, 'main.py'. You can simply add a function to the TestMain class in tests/test_main.py, similar to the test_graph function.
|
||||
|
||||
## Extras
|
||||
|
||||
1. If you want to add the week in the Header of your stats, you can add `HEAD_FLAG: true` in your workflow file like this
|
||||
|
||||
```yml
|
||||
- uses: athul/waka-readme@master
|
||||
with:
|
||||
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
SHOW_TITLE: true
|
||||
```
|
||||
|
||||
`SHOW_TITLE` flag can be set to true if you want to display the week number and days in the readme, by default it will be false. Here is an example output with `SHOW_TITLE` set to true.
|
||||
|
||||
```text
|
||||
Week: 10 July, 2020 - 17 July, 2020
|
||||
Python 8 hrs 52 mins ███████████████████░░░░░░ 75.87 %
|
||||
Go 1 hr 15 mins ██░░░░░░░░░░░░░░░░░░░░░░░ 10.79 %
|
||||
Markdown 52 mins █░░░░░░░░░░░░░░░░░░░░░░░░ 07.43 %
|
||||
Docker 16 mins ░░░░░░░░░░░░░░░░░░░░░░░░░ 02.32 %
|
||||
YAML 7 mins ░░░░░░░░░░░░░░░░░░░░░░░░░ 01.07 %
|
||||
```
|
||||
|
||||
2. You can specify a commit message to override the default _"Updated the Graph with new Metrics"_. Here is how you do it
|
||||
|
||||
```yml
|
||||
- uses: athul/waka-readme@master
|
||||
with:
|
||||
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
COMMIT_MESSAGE: Updated the Readme
|
||||
```
|
||||
|
||||
If no commit message is specified in the `yml` file, it defaults to _"Updated the Graph with new Metrics"_
|
||||
|
||||
3. You can change the block characters to match with the style of your readme. By default the one show in the graphs before is used. Here is how you do it
|
||||
|
||||
```yml
|
||||
- uses: athul/waka-readme@master
|
||||
with:
|
||||
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
|
||||
BLOCKS: ⣀⣄⣤⣦⣶⣷⣿
|
||||
```
|
||||
|
||||
This will change the graphs to something like this:
|
||||
|
||||
```text
|
||||
Python 8 hrs 52 mins ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣀⣀⣀⣀⣀⣀ 75.87 %
|
||||
Go 1 hr 15 mins ⣿⣿⣦⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 10.79 %
|
||||
Markdown 52 mins ⣿⣿⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 07.43 %
|
||||
Docker 16 mins ⣤⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 02.32 %
|
||||
YAML 7 mins ⣄⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 01.07 %
|
||||
```
|
||||
|
||||
## Why only the language stats and not other data from the API?
|
||||
|
||||
I am a fan of minimal designs and the profile readme is a great way to show off your skills and interests. The WakaTime API, gets us a **lot of data** about a person's **coding activity including the editors and Operating Systems you used and the projects you worked on**. Some of these projects maybe secretive and should not be shown out to the public. Using up more data via the Wakatime API will clutter the profile readme and hinder your chances on displaying what you provide **value to the community** like the pinned Repositories. I believe that **Coding Stats is nerdiest of all** since you can tell the community that you are _**exercising these languages or learning a new language**_, this will also show that you spend some amount of time to learn and exercise your development skills. That's what matters in the end :heart:
|
||||
[wakapi]: https://wakapi.dev
|
||||
[hakatime]: https://github.com/mujx/hakatime
|
||||
[waka_plugins]: https://wakatime.com/plugins
|
||||
[waka_help]: https://wakatime.com/help/editors
|
||||
[profile_readme]: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/managing-your-profile-readme
|
||||
[new_secrets_actions]: https://user-images.githubusercontent.com/52720626/151221742-bc37d139-2bb3-4554-b27c-46b107d1f408.png
|
||||
[gh_access_token]: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token
|
||||
[gh_discuss]: https://github.com/athul/waka-readme/discussions
|
||||
|
47
action.yml
47
action.yml
@@ -1,30 +1,37 @@
|
||||
name: "Waka - Readme"
|
||||
author: Athil Cyriac Ajay
|
||||
author: Athul Cyriac Ajay
|
||||
description: "Add a Wakatime Coding Activity graph in your Readme"
|
||||
|
||||
inputs:
|
||||
GH_TOKEN:
|
||||
description: "GitHub access token with Repo scope"
|
||||
required: true
|
||||
default: ${{ github.token }}
|
||||
required: true
|
||||
|
||||
WAKATIME_API_KEY:
|
||||
description: "Your Wakatime API Key"
|
||||
description: "Your Wakatime/Wakapi/Hakatime API Key"
|
||||
required: true
|
||||
|
||||
API_BASE_URL:
|
||||
description: "Alternative API base URL when using a third-party WakaTime-ish backend"
|
||||
default: "https://wakatime.com/api"
|
||||
required: false
|
||||
|
||||
REPOSITORY:
|
||||
description: "Your GitHub repository"
|
||||
default: ${{ github.repository }}
|
||||
required: false
|
||||
|
||||
SHOW_TITLE:
|
||||
description: "Displays the week number and days in Readme as title"
|
||||
default: false
|
||||
required: false
|
||||
|
||||
COMMIT_MESSAGE:
|
||||
description: "Add a commit message of your choice"
|
||||
default: "Updated the Graph with new Metrics"
|
||||
default: "Updated waka-readme graph with new metrics"
|
||||
required: false
|
||||
|
||||
# content tweaks
|
||||
|
||||
SHOW_TITLE:
|
||||
description: "Displays the week number and days in Readme as title"
|
||||
default: "false"
|
||||
required: false
|
||||
|
||||
BLOCKS:
|
||||
@@ -32,9 +39,29 @@ inputs:
|
||||
default: "░▒▓█"
|
||||
required: false
|
||||
|
||||
TIME_RANGE:
|
||||
description: "Time range of the queried statistics"
|
||||
default: "last_7_days"
|
||||
required: false
|
||||
|
||||
SHOW_TIME:
|
||||
description: "Displays the amount of time spent for each language"
|
||||
default: "true"
|
||||
required: false
|
||||
|
||||
SHOW_TOTAL:
|
||||
description: "Displays total coding time"
|
||||
default: "false"
|
||||
required: false
|
||||
|
||||
SHOW_MASKED_TIME:
|
||||
description: "Displays total coding time including unclassified languages"
|
||||
default: "false"
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: "docker"
|
||||
image: "Dockerfile"
|
||||
image: "dockerfile"
|
||||
|
||||
branding:
|
||||
icon: "info"
|
||||
|
28
containerfile
Normal file
28
containerfile
Normal file
@@ -0,0 +1,28 @@
|
||||
FROM python:slim-bullseye
|
||||
|
||||
WORKDIR /root/waka-readme/
|
||||
|
||||
ENV PYTHONFAULTHANDLER=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PYTHONHASHSEED=random \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
# pip:
|
||||
PIP_NO_CACHE_DIR=off \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
||||
PIP_DEFAULT_TIMEOUT=100 \
|
||||
# poetry:
|
||||
# POETRY_VERSION=1.1.14 \
|
||||
POETRY_NO_INTERACTION=1 \
|
||||
POETRY_CACHE_DIR=/var/cache/pypoetry \
|
||||
PATH=${PATH}:/root/.local/bin
|
||||
|
||||
# import project
|
||||
ADD waka-readme.tar.gz .
|
||||
|
||||
# install poetry & dependencies
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y curl git micro \
|
||||
&& curl -sSL https://install.python-poetry.org | python - \
|
||||
&& poetry install --no-root --no-ansi
|
||||
|
||||
# copy and run program
|
||||
CMD [ "sleep", "infinity" ]
|
26
dockerfile
Normal file
26
dockerfile
Normal file
@@ -0,0 +1,26 @@
|
||||
FROM python:slim-bullseye
|
||||
|
||||
ENV PYTHONFAULTHANDLER=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PYTHONHASHSEED=random \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
# pip:
|
||||
PIP_NO_CACHE_DIR=off \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
||||
PIP_DEFAULT_TIMEOUT=100 \
|
||||
# poetry:
|
||||
# POETRY_VERSION=1.1.14 \
|
||||
POETRY_NO_INTERACTION=1 \
|
||||
POETRY_CACHE_DIR=/var/cache/pypoetry \
|
||||
PATH=${PATH}:/root/.local/bin
|
||||
|
||||
# copy project files
|
||||
COPY pyproject.toml poetry.lock main.py /
|
||||
|
||||
# install poetry & dependencies
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y curl \
|
||||
&& curl -sSL https://install.python-poetry.org | python - \
|
||||
&& poetry install --no-root --no-ansi --only main
|
||||
|
||||
# copy and run program
|
||||
CMD [ "poetry", "run", "python", "/main.py" ]
|
490
main.py
490
main.py
@@ -1,107 +1,429 @@
|
||||
'''
|
||||
WakaTime progress visualizer
|
||||
'''
|
||||
"""
|
||||
WakaReadme : WakaTime progress visualizer
|
||||
=========================================
|
||||
|
||||
Wakatime Metrics on your Profile Readme.
|
||||
|
||||
Title:
|
||||
------
|
||||
|
||||
```txt
|
||||
From: 15 February, 2022 - To: 22 February, 2022
|
||||
````
|
||||
|
||||
Byline:
|
||||
-------
|
||||
|
||||
```txt
|
||||
Total: 34 hrs 43 mins
|
||||
```
|
||||
|
||||
Body:
|
||||
-----
|
||||
|
||||
```txt
|
||||
Python 27 hrs 29 mins ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣀⣀⣀⣀⣀ 77.83 %
|
||||
YAML 2 hrs 14 mins ⣿⣦⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 06.33 %
|
||||
Markdown 1 hr 54 mins ⣿⣤⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 05.39 %
|
||||
TOML 1 hr 48 mins ⣿⣤⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 05.11 %
|
||||
Other 35 mins ⣦⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 01.68 %
|
||||
```
|
||||
|
||||
#### Contents = Title + Byline + Body
|
||||
"""
|
||||
|
||||
# standard
|
||||
from dataclasses import dataclass
|
||||
from random import SystemRandom
|
||||
from datetime import datetime
|
||||
from base64 import b64encode
|
||||
import logging as logger
|
||||
from time import sleep
|
||||
from typing import Any
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import base64
|
||||
import sys
|
||||
import datetime
|
||||
import requests
|
||||
from github import Github, GithubException
|
||||
|
||||
START_COMMENT = '<!--START_SECTION:waka-->'
|
||||
END_COMMENT = '<!--END_SECTION:waka-->'
|
||||
listReg = f"{START_COMMENT}[\\s\\S]+{END_COMMENT}"
|
||||
|
||||
repository = os.getenv('INPUT_REPOSITORY')
|
||||
waka_key = os.getenv('INPUT_WAKATIME_API_KEY')
|
||||
ghtoken = os.getenv('INPUT_GH_TOKEN')
|
||||
show_title = os.getenv("INPUT_SHOW_TITLE")
|
||||
commit_message = os.getenv("INPUT_COMMIT_MESSAGE")
|
||||
blocks = os.getenv("INPUT_BLOCKS")
|
||||
# external
|
||||
# # requests
|
||||
from requests.exceptions import RequestException
|
||||
from requests import get as rq_get
|
||||
# # github
|
||||
from github import GithubException, Github
|
||||
# # faker
|
||||
from faker import Faker
|
||||
|
||||
|
||||
def this_week() -> str:
|
||||
'''Returns a week streak'''
|
||||
week_end = datetime.datetime.today() - datetime.timedelta(days=1)
|
||||
week_start = week_end - datetime.timedelta(days=7)
|
||||
print("Week header created")
|
||||
return f"Week: {week_start.strftime('%d %B, %Y')} - {week_end.strftime('%d %B, %Y')}"
|
||||
# pylint: disable=logging-fstring-interpolation
|
||||
|
||||
################### data ###################
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class WakaConstants:
|
||||
"""
|
||||
WakaConstants
|
||||
-------------
|
||||
"""
|
||||
prefix_length: int = 16
|
||||
graph_length: int = 25
|
||||
start_comment: str = '<!--START_SECTION:waka-->'
|
||||
end_comment: str = '<!--END_SECTION:waka-->'
|
||||
waka_block_pattern: str = f'{start_comment}[\\s\\S]+{end_comment}'
|
||||
|
||||
|
||||
def make_graph(percent: float, blocks: str) -> str:
|
||||
'''Make progress graph from API graph'''
|
||||
graph = blocks[len(blocks)-1] * int(percent / 4 + 1 / 6)
|
||||
remainder_block = int((percent + (len(blocks)-2) /
|
||||
(len(blocks)-1)) % 4 * (len(blocks)-1) / len(blocks))
|
||||
if remainder_block > 0:
|
||||
graph += blocks[remainder_block]
|
||||
graph += blocks[0] * (25 - len(graph))
|
||||
return graph
|
||||
class WakaInput:
|
||||
"""
|
||||
WakaInput Env Vars
|
||||
------------------
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
WakaInput Initialize
|
||||
--------------------
|
||||
"""
|
||||
# mapped environment variables
|
||||
# # required
|
||||
self.gh_token: str = os.getenv('INPUT_GH_TOKEN')
|
||||
self.waka_key: str = os.getenv('INPUT_WAKATIME_API_KEY')
|
||||
self.api_base_url: str = os.getenv(
|
||||
'INPUT_API_BASE_URL', 'https://wakatime.com/api'
|
||||
)
|
||||
self.repository: str = os.getenv('INPUT_REPOSITORY')
|
||||
# # depends
|
||||
self.commit_message: str = os.getenv(
|
||||
'INPUT_COMMIT_MESSAGE', 'Updated WakaReadme graph with new metrics'
|
||||
)
|
||||
# # optional
|
||||
self.show_title: str | bool = os.getenv('INPUT_SHOW_TITLE', 'False')
|
||||
self.block_style: str = os.getenv('INPUT_BLOCKS', '░▒▓█')
|
||||
self.time_range: str = os.getenv('INPUT_TIME_RANGE', 'last_7_days')
|
||||
self.show_time: str | bool = os.getenv('INPUT_SHOW_TIME', 'False')
|
||||
self.show_total_time: str | bool = os.getenv(
|
||||
'INPUT_SHOW_TOTAL', 'False'
|
||||
)
|
||||
self.show_masked_time: str | bool = os.getenv(
|
||||
'INPUT_SHOW_MASKED_TIME', 'False'
|
||||
)
|
||||
|
||||
def validate_input(self) -> bool:
|
||||
"""
|
||||
WakaInput Validate
|
||||
------------------
|
||||
"""
|
||||
|
||||
if not (self.gh_token and self.waka_key and self.api_base_url and self.repository):
|
||||
logger.error('Invalid required input(s), refer README')
|
||||
return False
|
||||
|
||||
if len(self.commit_message) < 1:
|
||||
logger.error(
|
||||
'Commit message length must be greater than 1 character long'
|
||||
)
|
||||
return False
|
||||
|
||||
try:
|
||||
self.show_title: bool = strtobool(self.show_title)
|
||||
self.show_time: bool = strtobool(self.show_time)
|
||||
self.show_total_time: bool = strtobool(self.show_total_time)
|
||||
self.show_masked_time: bool = strtobool(self.show_masked_time)
|
||||
except (ValueError, AttributeError) as err:
|
||||
logger.error(err)
|
||||
return False
|
||||
|
||||
if len(self.block_style) < 2:
|
||||
logger.warning(
|
||||
'Block length should be greater than 2 characters long'
|
||||
)
|
||||
logger.debug('Using default blocks: ░▒▓█')
|
||||
|
||||
# 'all_time' is un-documented, should it be used?
|
||||
if self.time_range not in {
|
||||
'last_7_days', 'last_30_days', 'last_6_months', 'last_year', 'all_time'
|
||||
}:
|
||||
logger.warning('Invalid time range')
|
||||
logger.debug('Using default time range: last_7_days')
|
||||
self.time_range: str = 'last_7_days'
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def get_stats() -> str:
|
||||
'''Gets API data and returns markdown progress'''
|
||||
data = requests.get(
|
||||
f"https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key={waka_key}").json()
|
||||
def strtobool(val: str) -> bool:
|
||||
"""
|
||||
strtobool
|
||||
---------
|
||||
|
||||
PEP 632 https://www.python.org/dev/peps/pep-0632/ is depreciating distutils
|
||||
|
||||
Following code is somewhat shamelessly copied from the original source.
|
||||
|
||||
Convert a string representation of truth to True or False.
|
||||
|
||||
- True values are `'y', 'yes', 't', 'true', 'on', and '1'`
|
||||
- False values are `'n', 'no', 'f', 'false', 'off', and '0'`
|
||||
- Raises `ValueError` if `val` is anything else.
|
||||
"""
|
||||
val = val.lower()
|
||||
|
||||
if val in {'y', 'yes', 't', 'true', 'on', '1'}:
|
||||
return True
|
||||
|
||||
if val in {'n', 'no', 'f', 'false', 'off', '0'}:
|
||||
return False
|
||||
|
||||
raise ValueError(f'invalid truth value for {val}')
|
||||
|
||||
|
||||
################### logic ###################
|
||||
|
||||
def make_title(dawn: str, dusk: str, /) -> str:
|
||||
"""
|
||||
WakaReadme Title
|
||||
----------------
|
||||
|
||||
Makes title for WakaReadme.
|
||||
"""
|
||||
logger.debug('Making title')
|
||||
if not (dawn or dusk):
|
||||
logger.error('Cannot find start/end date')
|
||||
sys.exit(1)
|
||||
api_dfm, msg_dfm = '%Y-%m-%dT%H:%M:%SZ', '%d %B %Y'
|
||||
try:
|
||||
lang_data = data['data']['languages']
|
||||
except KeyError:
|
||||
print("Please Add your WakaTime API Key to the Repository Secrets")
|
||||
start_date = datetime.strptime(dawn, api_dfm).strftime(msg_dfm)
|
||||
end_date = datetime.strptime(dusk, api_dfm).strftime(msg_dfm)
|
||||
except ValueError as err:
|
||||
logger.error(err)
|
||||
sys.exit(1)
|
||||
logger.debug('Title was made\n')
|
||||
return f'From: {start_date} - To: {end_date}'
|
||||
|
||||
|
||||
def make_graph(
|
||||
block_style: str, percent: float, gr_len: str, /,
|
||||
*, lg_nm: str = ''
|
||||
) -> str:
|
||||
"""
|
||||
WakaReadme Graph
|
||||
----------------
|
||||
|
||||
Makes time graph from the API's data.
|
||||
"""
|
||||
logger.debug(f'Generating graph for "{lg_nm or "..."}"')
|
||||
markers: int = len(block_style) - 1
|
||||
proportion: float = percent / 100 * gr_len
|
||||
graph_bar: str = block_style[-1] * int(proportion + 0.5 / markers)
|
||||
remainder_block: int = int(
|
||||
(proportion - len(graph_bar)) * markers + 0.5
|
||||
)
|
||||
graph_bar += block_style[remainder_block] if remainder_block > 0 else ''
|
||||
graph_bar += block_style[0] * (gr_len - len(graph_bar))
|
||||
logger.debug(f'{lg_nm or "..."} graph generated')
|
||||
return graph_bar
|
||||
|
||||
|
||||
def prep_content(stats: dict | None, /) -> str:
|
||||
"""
|
||||
WakaReadme Prepare Markdown
|
||||
---------------------------
|
||||
|
||||
Prepared markdown content from the fetched statistics
|
||||
```
|
||||
"""
|
||||
contents: str = ''
|
||||
|
||||
# Check if any data exists
|
||||
if not (lang_info := stats.get('languages')):
|
||||
logger.debug('The data seems to be empty, please wait for a day')
|
||||
contents += 'No activity tracked'
|
||||
return contents
|
||||
|
||||
# make title
|
||||
if wk_i.show_title:
|
||||
contents += make_title(stats.get('start'), stats.get('end')) + '\n\n'
|
||||
|
||||
# make byline
|
||||
if wk_i.show_masked_time and (
|
||||
total_time := stats.get('human_readable_total_including_other_language')
|
||||
):
|
||||
# overrides 'human_readable_total'
|
||||
contents += f'Total Time: {total_time}\n\n'
|
||||
elif wk_i.show_total_time and (
|
||||
total_time := stats.get('human_readable_total')
|
||||
):
|
||||
contents += f'Total Time: {total_time}\n\n'
|
||||
|
||||
# make content
|
||||
logger.debug('Making contents')
|
||||
pad_len = len(
|
||||
# comment if it feels way computationally expensive
|
||||
max((str(l.get('name')) for l in lang_info), key=len)
|
||||
# and then don't for get to set pad_len to say 13 :)
|
||||
)
|
||||
for idx, lang in enumerate(lang_info):
|
||||
lang_name: str = lang.get('name')
|
||||
# >>> add languages to filter here <<<
|
||||
# if lang_name in {...}: continue
|
||||
lang_time: str = lang.get('text') if wk_i.show_time else ''
|
||||
lang_ratio: float = lang.get('percent')
|
||||
lang_bar: str = make_graph(
|
||||
wk_i.block_style, lang_ratio, wk_c.graph_length,
|
||||
lg_nm=lang_name
|
||||
)
|
||||
contents += (
|
||||
f'{lang_name.ljust(pad_len)} ' +
|
||||
f'{lang_time: <16}{lang_bar} ' +
|
||||
f'{lang_ratio:.2f}'.zfill(5) + ' %\n'
|
||||
)
|
||||
if idx >= 5 or lang_name == 'Other':
|
||||
break
|
||||
|
||||
logger.debug('Contents were made\n')
|
||||
return contents.rstrip('\n')
|
||||
|
||||
|
||||
def fetch_stats() -> Any:
|
||||
"""
|
||||
WakaReadme Fetch Stats
|
||||
----------------------
|
||||
|
||||
Returns statistics as JSON string
|
||||
"""
|
||||
attempts, statistic = 4, {}
|
||||
encoded_key: str = str(b64encode(bytes(wk_i.waka_key, 'utf-8')), 'utf-8')
|
||||
logger.debug(
|
||||
f'Pulling WakaTime stats from {" ".join(wk_i.time_range.split("_"))}'
|
||||
)
|
||||
|
||||
while attempts > 0:
|
||||
resp_message, fake_ua = None, cryptogenic.choice(
|
||||
[str(fake.user_agent()) for _ in range(5)]
|
||||
)
|
||||
# making a request
|
||||
if (resp := rq_get(
|
||||
url=f'{wk_i.api_base_url.rstrip("/")}/v1/users/current/stats/{wk_i.time_range}',
|
||||
headers={
|
||||
'Authorization': f'Basic {encoded_key}',
|
||||
'User-Agent': fake_ua,
|
||||
},
|
||||
)).status_code != 200:
|
||||
resp_message = f'• {resp.json().get("message")}'
|
||||
logger.debug(
|
||||
f'API response #{5 - attempts}: {resp.status_code} • {resp.reason} {resp_message or ""}'
|
||||
)
|
||||
if resp.status_code == 200 and (statistic := resp.json()):
|
||||
logger.debug('Fetched WakaTime statistics')
|
||||
break
|
||||
logger.debug(f'Retrying in {30 * (5 - attempts )}s ...')
|
||||
sleep(30 * (5 - attempts))
|
||||
attempts -= 1
|
||||
|
||||
if err := (statistic.get('error') or statistic.get('errors')):
|
||||
logger.error(err)
|
||||
sys.exit(1)
|
||||
|
||||
data_list = []
|
||||
try:
|
||||
pad = len(max([l['name'] for l in lang_data[:5]], key=len))
|
||||
except ValueError:
|
||||
print("The Data seems to be empty. Please wait for a day for the data to be filled in.")
|
||||
return '```text\nNo Activity tracked this Week\n```'
|
||||
for lang in lang_data[:5]:
|
||||
if lang['hours'] == 0 and lang['minutes'] == 0:
|
||||
continue
|
||||
lth = len(lang['name'])
|
||||
ln_text = len(lang['text'])
|
||||
# following line provides a neat finish
|
||||
fmt_percent = format(lang['percent'], '0.2f').zfill(5)
|
||||
data_list.append(
|
||||
f"{lang['name']}{' '*(pad + 3 - lth)}{lang['text']}{' '*(16 - ln_text)}{make_graph(lang['percent'], blocks)} {fmt_percent} % ")
|
||||
print("Graph Generated")
|
||||
data = '\n'.join(data_list)
|
||||
if show_title == 'true':
|
||||
print("Stats with Weeks in Title Generated")
|
||||
return '```text\n'+this_week()+'\n\n'+data+'\n```'
|
||||
else:
|
||||
print("Usual Stats Generated")
|
||||
return '```text\n'+data+'\n```'
|
||||
print()
|
||||
return statistic.get('data')
|
||||
|
||||
|
||||
def decode_readme(data: str) -> str:
|
||||
'''Decode the contents of old readme'''
|
||||
decoded_bytes = base64.b64decode(data)
|
||||
return str(decoded_bytes, 'utf-8')
|
||||
def churn(old_readme: str, /) -> str | None:
|
||||
"""
|
||||
WakaReadme Churn
|
||||
----------------
|
||||
|
||||
Composes WakaTime stats within markdown code snippet
|
||||
"""
|
||||
# getting content
|
||||
if not (waka_stats := fetch_stats()):
|
||||
logger.error('Unable to fetch data, please rerun workflow')
|
||||
sys.exit(1)
|
||||
|
||||
# processing content
|
||||
generated_content = prep_content(waka_stats)
|
||||
print(generated_content, '\n', sep='')
|
||||
new_readme = re.sub(
|
||||
pattern=wk_c.waka_block_pattern,
|
||||
repl=f'{wk_c.start_comment}\n\n```text\n{generated_content}\n```\n\n{wk_c.end_comment}',
|
||||
string=old_readme
|
||||
)
|
||||
if len(sys.argv) == 2 and sys.argv[1] == '--dev':
|
||||
logger.debug('Detected run in `dev` mode.')
|
||||
# to avoid accidentally writing back to Github
|
||||
# when developing and testing WakaReadme
|
||||
return None
|
||||
return None if new_readme == old_readme else new_readme
|
||||
|
||||
|
||||
def generate_new_readme(stats: str, readme: str) -> str:
|
||||
'''Generate a new Readme.md'''
|
||||
stats_in_readme = f"{START_COMMENT}\n{stats}\n{END_COMMENT}"
|
||||
return re.sub(listReg, stats_in_readme, readme)
|
||||
def genesis() -> None:
|
||||
"""Run Program"""
|
||||
logger.debug('Connecting to GitHub')
|
||||
gh_connect = Github(wk_i.gh_token)
|
||||
gh_repo = gh_connect.get_repo(wk_i.repository)
|
||||
readme_file = gh_repo.get_readme()
|
||||
logger.debug('Decoding readme contents\n')
|
||||
readme_contents = str(readme_file.decoded_content, encoding='utf-8')
|
||||
if new_content := churn(readme_contents):
|
||||
logger.debug('WakaReadme stats has changed')
|
||||
gh_repo.update_file(
|
||||
path=readme_file.path,
|
||||
message=wk_i.commit_message,
|
||||
content=new_content,
|
||||
sha=readme_file.sha
|
||||
)
|
||||
logger.info('Stats updated successfully')
|
||||
return
|
||||
logger.info('WakaReadme was not updated')
|
||||
|
||||
|
||||
################### driver ###################
|
||||
print()
|
||||
# hush existing loggers
|
||||
# pylint: disable = no-member # see: https://stackoverflow.com/q/20965287
|
||||
for lgr_name in logger.root.manager.loggerDict:
|
||||
# to disable log propagation completely set '.propagate = False'
|
||||
logger.getLogger(lgr_name).setLevel(logger.WARNING)
|
||||
# pylint: enable = no-member
|
||||
# somehow github.Requester gets missed out from loggerDict
|
||||
logger.getLogger('github.Requester').setLevel(logger.WARNING)
|
||||
# configure logger
|
||||
logger.basicConfig(
|
||||
datefmt='%Y-%m-%d %H:%M:%S',
|
||||
format='[%(asctime)s] ln. %(lineno)-3d %(levelname)-8s %(message)s',
|
||||
level=logger.DEBUG
|
||||
)
|
||||
try:
|
||||
if len(sys.argv) == 2 and sys.argv[1] == '--dev':
|
||||
# get env-vars from .env file for development
|
||||
from dotenv import load_dotenv
|
||||
# comment this out to disable colored logging
|
||||
from loguru import logger
|
||||
load_dotenv()
|
||||
except ImportError as im_err:
|
||||
logger.warning(im_err)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
g = Github(ghtoken)
|
||||
# faker data preparation
|
||||
fake = Faker()
|
||||
Faker.seed(0)
|
||||
cryptogenic = SystemRandom()
|
||||
|
||||
# initial waka-readme setup
|
||||
logger.debug('Initialize WakaReadme')
|
||||
wk_c = WakaConstants()
|
||||
wk_i = WakaInput()
|
||||
if not wk_i.validate_input():
|
||||
logger.error('Environment variables are misconfigured')
|
||||
sys.exit(1)
|
||||
logger.debug('Input validation complete')
|
||||
|
||||
# run
|
||||
try:
|
||||
repo = g.get_repo(repository)
|
||||
except GithubException:
|
||||
print("Authentication Error. Try saving a GitHub Token in your Repo Secrets or Use the GitHub Actions Token, which is automatically used by the action.")
|
||||
genesis()
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
logger.error('Interrupt signal received')
|
||||
sys.exit(1)
|
||||
if len(blocks) < 1:
|
||||
print("Invalid blocks string. Please provide provide a string with 2 or more characters. Eg. '░▒▓█'")
|
||||
except (GithubException, RequestException) as rq_exp:
|
||||
logger.critical(rq_exp)
|
||||
sys.exit(1)
|
||||
contents = repo.get_readme()
|
||||
waka_stats = get_stats()
|
||||
rdmd = decode_readme(contents.content)
|
||||
new_readme = generate_new_readme(stats=waka_stats, readme=rdmd)
|
||||
if new_readme != rdmd:
|
||||
repo.update_file(path=contents.path, message=commit_message,
|
||||
content=new_readme, sha=contents.sha)
|
||||
print('\nThanks for using WakaReadme!')
|
||||
|
759
poetry.lock
generated
Normal file
759
poetry.lock
generated
Normal file
@@ -0,0 +1,759 @@
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "2.12.13"
|
||||
description = "An abstract syntax tree for Python with inference support."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.2"
|
||||
|
||||
[package.dependencies]
|
||||
lazy-object-proxy = ">=1.4.0"
|
||||
wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}
|
||||
|
||||
[[package]]
|
||||
name = "autopep8"
|
||||
version = "2.0.0"
|
||||
description = "A tool that automatically formats Python code to conform to the PEP 8 style guide"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
pycodestyle = ">=2.9.1"
|
||||
tomli = "*"
|
||||
|
||||
[[package]]
|
||||
name = "bandit"
|
||||
version = "1.7.4"
|
||||
description = "Security oriented static analyser for python code."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""}
|
||||
GitPython = ">=1.0.1"
|
||||
PyYAML = ">=5.3.1"
|
||||
stevedore = ">=1.20.0"
|
||||
|
||||
[package.extras]
|
||||
test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml"]
|
||||
toml = ["toml"]
|
||||
yaml = ["PyYAML"]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2022.9.24"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "cffi"
|
||||
version = "1.15.1"
|
||||
description = "Foreign Function Interface for Python calling C code."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
pycparser = "*"
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "2.1.1"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.0"
|
||||
|
||||
[package.extras]
|
||||
unicode-backport = ["unicodedata2"]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "deprecated"
|
||||
version = "1.2.13"
|
||||
description = "Python @deprecated decorator to deprecate old python classes, functions or methods."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[package.dependencies]
|
||||
wrapt = ">=1.10,<2"
|
||||
|
||||
[package.extras]
|
||||
dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"]
|
||||
|
||||
[[package]]
|
||||
name = "dill"
|
||||
version = "0.3.6"
|
||||
description = "serialize all of python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
graph = ["objgraph (>=1.7.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "faker"
|
||||
version = "15.3.2"
|
||||
description = "Faker is a Python package that generates fake data for you."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
python-dateutil = ">=2.4"
|
||||
|
||||
[[package]]
|
||||
name = "gitdb"
|
||||
version = "4.0.9"
|
||||
description = "Git Object Database"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
smmap = ">=3.0.1,<6"
|
||||
|
||||
[[package]]
|
||||
name = "gitpython"
|
||||
version = "3.1.29"
|
||||
description = "GitPython is a python library used to interact with Git repositories"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
gitdb = ">=4.0.1,<5"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.4"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
version = "5.10.1"
|
||||
description = "A Python utility / library to sort Python imports."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.1,<4.0"
|
||||
|
||||
[package.extras]
|
||||
colors = ["colorama (>=0.4.3,<0.5.0)"]
|
||||
pipfile-deprecated-finder = ["pipreqs", "requirementslib"]
|
||||
plugins = ["setuptools"]
|
||||
requirements-deprecated-finder = ["pip-api", "pipreqs"]
|
||||
|
||||
[[package]]
|
||||
name = "lazy-object-proxy"
|
||||
version = "1.8.0"
|
||||
description = "A fast and thorough lazy object proxy."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "loguru"
|
||||
version = "0.6.0"
|
||||
description = "Python logging made (stupidly) simple"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
|
||||
win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "mccabe"
|
||||
version = "0.7.0"
|
||||
description = "McCabe checker, plugin for flake8"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "pbr"
|
||||
version = "5.11.0"
|
||||
description = "Python Build Reasonableness"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.6"
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "2.5.4"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"]
|
||||
test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
|
||||
|
||||
[[package]]
|
||||
name = "pycodestyle"
|
||||
version = "2.9.1"
|
||||
description = "Python style guide checker"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "pycparser"
|
||||
version = "2.21"
|
||||
description = "C parser in Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pygithub"
|
||||
version = "1.57"
|
||||
description = "Use the full Github API v3"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
deprecated = "*"
|
||||
pyjwt = ">=2.4.0"
|
||||
pynacl = ">=1.4.0"
|
||||
requests = ">=2.14.0"
|
||||
|
||||
[package.extras]
|
||||
integrations = ["cryptography"]
|
||||
|
||||
[[package]]
|
||||
name = "pyjwt"
|
||||
version = "2.6.0"
|
||||
description = "JSON Web Token implementation in Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
crypto = ["cryptography (>=3.4.0)"]
|
||||
dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
|
||||
docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
|
||||
tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pylint"
|
||||
version = "2.15.6"
|
||||
description = "python code static checker"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.2"
|
||||
|
||||
[package.dependencies]
|
||||
astroid = ">=2.12.12,<=2.14.0-dev0"
|
||||
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
|
||||
dill = ">=0.2"
|
||||
isort = ">=4.2.5,<6"
|
||||
mccabe = ">=0.6,<0.8"
|
||||
platformdirs = ">=2.2.0"
|
||||
tomlkit = ">=0.10.1"
|
||||
|
||||
[package.extras]
|
||||
spelling = ["pyenchant (>=3.2,<4.0)"]
|
||||
testutils = ["gitpython (>3)"]
|
||||
|
||||
[[package]]
|
||||
name = "pynacl"
|
||||
version = "1.5.0"
|
||||
description = "Python binding to the Networking and Cryptography (NaCl) library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
cffi = ">=1.4.1"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=1.6.5)", "sphinx_rtd_theme"]
|
||||
tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.8.2"
|
||||
description = "Extensions to the standard Python datetime module"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.5"
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "0.21.0"
|
||||
description = "Read key-value pairs from a .env file and set them as environment variables"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
cli = ["click (>=5.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0"
|
||||
description = "YAML parser and emitter for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.28.1"
|
||||
description = "Python HTTP for Humans."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7, <4"
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
charset-normalizer = ">=2,<3"
|
||||
idna = ">=2.5,<4"
|
||||
urllib3 = ">=1.21.1,<1.27"
|
||||
|
||||
[package.extras]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "smmap"
|
||||
version = "5.0.0"
|
||||
description = "A pure Python implementation of a sliding window memory map manager"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "stevedore"
|
||||
version = "4.1.1"
|
||||
description = "Manage dynamic plugins for Python applications"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
|
||||
[package.dependencies]
|
||||
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "tomlkit"
|
||||
version = "0.11.6"
|
||||
description = "Style preserving TOML library"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.26.12"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4"
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
|
||||
secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "win32-setctime"
|
||||
version = "1.1.0"
|
||||
description = "A small Python utility to set file creation time on Windows"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.extras]
|
||||
dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "wrapt"
|
||||
version = "1.14.1"
|
||||
description = "Module for decorators, wrappers and monkey patching."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "ad776661cb1c47292702d2f54f39a1bdc550fc685a24ef895f5c271fd1a2b1a7"
|
||||
|
||||
[metadata.files]
|
||||
astroid = [
|
||||
{file = "astroid-2.12.13-py3-none-any.whl", hash = "sha256:10e0ad5f7b79c435179d0d0f0df69998c4eef4597534aae44910db060baeb907"},
|
||||
{file = "astroid-2.12.13.tar.gz", hash = "sha256:1493fe8bd3dfd73dc35bd53c9d5b6e49ead98497c47b2307662556a5692d29d7"},
|
||||
]
|
||||
autopep8 = [
|
||||
{file = "autopep8-2.0.0-py2.py3-none-any.whl", hash = "sha256:ad924b42c2e27a1ac58e432166cc4588f5b80747de02d0d35b1ecbd3e7d57207"},
|
||||
{file = "autopep8-2.0.0.tar.gz", hash = "sha256:8b1659c7f003e693199f52caffdc06585bb0716900bbc6a7442fd931d658c077"},
|
||||
]
|
||||
bandit = [
|
||||
{file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"},
|
||||
{file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"},
|
||||
]
|
||||
certifi = [
|
||||
{file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"},
|
||||
{file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"},
|
||||
]
|
||||
cffi = [
|
||||
{file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"},
|
||||
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"},
|
||||
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"},
|
||||
{file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"},
|
||||
]
|
||||
charset-normalizer = [
|
||||
{file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"},
|
||||
{file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
deprecated = [
|
||||
{file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"},
|
||||
{file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"},
|
||||
]
|
||||
dill = [
|
||||
{file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"},
|
||||
{file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"},
|
||||
]
|
||||
faker = [
|
||||
{file = "Faker-15.3.2-py3-none-any.whl", hash = "sha256:43da04aae745018e8bded768e74c84423d9dc38e4c498a53439e749d90e20bc0"},
|
||||
{file = "Faker-15.3.2.tar.gz", hash = "sha256:0094fe3340ad73c490d3ffccc59cc171b161acfccccd52925c70970ba23e6d6b"},
|
||||
]
|
||||
gitdb = [
|
||||
{file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"},
|
||||
{file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"},
|
||||
]
|
||||
gitpython = [
|
||||
{file = "GitPython-3.1.29-py3-none-any.whl", hash = "sha256:41eea0deec2deea139b459ac03656f0dd28fc4a3387240ec1d3c259a2c47850f"},
|
||||
{file = "GitPython-3.1.29.tar.gz", hash = "sha256:cc36bfc4a3f913e66805a28e84703e419d9c264c1077e537b54f0e1af85dbefd"},
|
||||
]
|
||||
idna = [
|
||||
{file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
|
||||
{file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
|
||||
]
|
||||
isort = [
|
||||
{file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
|
||||
{file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
|
||||
]
|
||||
lazy-object-proxy = [
|
||||
{file = "lazy-object-proxy-1.8.0.tar.gz", hash = "sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp310-cp310-win32.whl", hash = "sha256:b70d6e7a332eb0217e7872a73926ad4fdc14f846e85ad6749ad111084e76df25"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:eb329f8d8145379bf5dbe722182410fe8863d186e51bf034d2075eb8d85ee25b"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4e2d9f764f1befd8bdc97673261b8bb888764dfdbd7a4d8f55e4fbcabb8c3fb7"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp311-cp311-win32.whl", hash = "sha256:e20bfa6db17a39c706d24f82df8352488d2943a3b7ce7d4c22579cb89ca8896e"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:14010b49a2f56ec4943b6cf925f597b534ee2fe1f0738c84b3bce0c1a11ff10d"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6850e4aeca6d0df35bb06e05c8b934ff7c533734eb51d0ceb2d63696f1e6030c"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp37-cp37m-win32.whl", hash = "sha256:5b51d6f3bfeb289dfd4e95de2ecd464cd51982fe6f00e2be1d0bf94864d58acd"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:6f593f26c470a379cf7f5bc6db6b5f1722353e7bf937b8d0d0b3fba911998858"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c1c7c0433154bb7c54185714c6929acc0ba04ee1b167314a779b9025517eada"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:d176f392dbbdaacccf15919c77f526edf11a34aece58b55ab58539807b85436f"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:afcaa24e48bb23b3be31e329deb3f1858f1f1df86aea3d70cb5c8578bfe5261c"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:71d9ae8a82203511a6f60ca5a1b9f8ad201cac0fc75038b2dc5fa519589c9288"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:8f6ce2118a90efa7f62dd38c7dbfffd42f468b180287b748626293bf12ed468f"},
|
||||
{file = "lazy_object_proxy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:eac3a9a5ef13b332c059772fd40b4b1c3d45a3a2b05e33a361dee48e54a4dad0"},
|
||||
{file = "lazy_object_proxy-1.8.0-pp37-pypy37_pp73-any.whl", hash = "sha256:ae032743794fba4d171b5b67310d69176287b5bf82a21f588282406a79498891"},
|
||||
{file = "lazy_object_proxy-1.8.0-pp38-pypy38_pp73-any.whl", hash = "sha256:7e1561626c49cb394268edd00501b289053a652ed762c58e1081224c8d881cec"},
|
||||
{file = "lazy_object_proxy-1.8.0-pp39-pypy39_pp73-any.whl", hash = "sha256:ce58b2b3734c73e68f0e30e4e725264d4d6be95818ec0a0be4bb6bf9a7e79aa8"},
|
||||
]
|
||||
loguru = [
|
||||
{file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
|
||||
{file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
|
||||
]
|
||||
mccabe = [
|
||||
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
|
||||
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
|
||||
]
|
||||
pbr = [
|
||||
{file = "pbr-5.11.0-py2.py3-none-any.whl", hash = "sha256:db2317ff07c84c4c63648c9064a79fe9d9f5c7ce85a9099d4b6258b3db83225a"},
|
||||
{file = "pbr-5.11.0.tar.gz", hash = "sha256:b97bc6695b2aff02144133c2e7399d5885223d42b7912ffaec2ca3898e673bfe"},
|
||||
]
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.5.4-py3-none-any.whl", hash = "sha256:af0276409f9a02373d540bf8480021a048711d572745aef4b7842dad245eba10"},
|
||||
{file = "platformdirs-2.5.4.tar.gz", hash = "sha256:1006647646d80f16130f052404c6b901e80ee4ed6bef6792e1f238a8969106f7"},
|
||||
]
|
||||
pycodestyle = [
|
||||
{file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"},
|
||||
{file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"},
|
||||
]
|
||||
pycparser = [
|
||||
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
|
||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||
]
|
||||
pygithub = [
|
||||
{file = "PyGithub-1.57-py3-none-any.whl", hash = "sha256:5822febeac2391f1306c55a99af2bc8f86c8bf82ded000030cd02c18f31b731f"},
|
||||
{file = "PyGithub-1.57.tar.gz", hash = "sha256:c273f252b278fb81f1769505cc6921bdb6791e1cebd6ac850cc97dad13c31ff3"},
|
||||
]
|
||||
pyjwt = [
|
||||
{file = "PyJWT-2.6.0-py3-none-any.whl", hash = "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14"},
|
||||
{file = "PyJWT-2.6.0.tar.gz", hash = "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd"},
|
||||
]
|
||||
pylint = [
|
||||
{file = "pylint-2.15.6-py3-none-any.whl", hash = "sha256:15060cc22ed6830a4049cf40bc24977744df2e554d38da1b2657591de5bcd052"},
|
||||
{file = "pylint-2.15.6.tar.gz", hash = "sha256:25b13ddcf5af7d112cf96935e21806c1da60e676f952efb650130f2a4483421c"},
|
||||
]
|
||||
pynacl = [
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"},
|
||||
{file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"},
|
||||
]
|
||||
python-dateutil = [
|
||||
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
||||
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
||||
]
|
||||
python-dotenv = [
|
||||
{file = "python-dotenv-0.21.0.tar.gz", hash = "sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045"},
|
||||
{file = "python_dotenv-0.21.0-py3-none-any.whl", hash = "sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5"},
|
||||
]
|
||||
pyyaml = [
|
||||
{file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
|
||||
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
|
||||
{file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
]
|
||||
smmap = [
|
||||
{file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"},
|
||||
{file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"},
|
||||
]
|
||||
stevedore = [
|
||||
{file = "stevedore-4.1.1-py3-none-any.whl", hash = "sha256:aa6436565c069b2946fe4ebff07f5041e0c8bf18c7376dd29edf80cf7d524e4e"},
|
||||
{file = "stevedore-4.1.1.tar.gz", hash = "sha256:7f8aeb6e3f90f96832c301bff21a7eb5eefbe894c88c506483d355565d88cc1a"},
|
||||
]
|
||||
tomli = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
tomlkit = [
|
||||
{file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"},
|
||||
{file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"},
|
||||
]
|
||||
urllib3 = [
|
||||
{file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"},
|
||||
{file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"},
|
||||
]
|
||||
win32-setctime = [
|
||||
{file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
|
||||
{file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
|
||||
]
|
||||
wrapt = [
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"},
|
||||
{file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"},
|
||||
]
|
25
pyproject.toml
Normal file
25
pyproject.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[tool.poetry]
|
||||
name = "waka-readme"
|
||||
version = "0.1.7"
|
||||
description = "Wakatime Weekly Metrics on your Profile Readme."
|
||||
authors = ["Athul Cyriac Ajay <athul8720@gmail.com>"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
#packages = [{include = "waka_readme"}]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11"
|
||||
requests = "^2.28.1"
|
||||
PyGithub = "^1.57"
|
||||
Faker = "^15.3.2"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
autopep8 = "^2.0.0"
|
||||
pylint = "^2.15.6"
|
||||
python-dotenv = "^0.21.0"
|
||||
loguru = "^0.6.0"
|
||||
bandit = "^1.7.4"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
@@ -1,9 +0,0 @@
|
||||
certifi==2020.6.20
|
||||
chardet==3.0.4
|
||||
Deprecated==1.2.10
|
||||
idna==2.10
|
||||
PyGithub==1.51
|
||||
PyJWT==1.7.1
|
||||
requests==2.24.0
|
||||
urllib3==1.25.9
|
||||
wrapt==1.12.1
|
@@ -0,0 +1,9 @@
|
||||
"""
|
||||
Initialize test module
|
||||
"""
|
||||
|
||||
# standard
|
||||
import logging
|
||||
|
||||
# comment to enable logging w/ tests
|
||||
logging.disable(logging.CRITICAL)
|
||||
|
11346
tests/sample_data.json
Normal file
11346
tests/sample_data.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,50 +1,137 @@
|
||||
'''
|
||||
Tests for the main.py
|
||||
'''
|
||||
from main import make_graph
|
||||
|
||||
from importlib import import_module
|
||||
from dataclasses import dataclass
|
||||
from itertools import product
|
||||
# from inspect import cleandoc
|
||||
# from json import loads
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
prime = import_module('main')
|
||||
# works when running as
|
||||
# python -m unittest discover
|
||||
except ImportError as err:
|
||||
print(err)
|
||||
# sys.exit(1)
|
||||
|
||||
|
||||
@dataclass
|
||||
class TestData:
|
||||
"""Test Data"""
|
||||
# for future tests
|
||||
# waka_json: dict | None = None
|
||||
bar_percent: tuple[float] | None = None
|
||||
graph_blocks: tuple[str] | None = None
|
||||
waka_graphs: tuple[list[str]] | None = None
|
||||
dummy_readme: str = ''
|
||||
|
||||
def populate(self) -> None:
|
||||
"""Populate Test Data"""
|
||||
# for future tests
|
||||
# with open(file='tests/sample_data.json', mode='rt', encoding='utf-8') as wkf:
|
||||
# self.waka_json = loads(wkf.read())
|
||||
|
||||
self.bar_percent = (
|
||||
0, 100, 49.999, 50, 25, 75, 3.14, 9.901, 87.334, 87.333, 4.666, 4.667
|
||||
)
|
||||
|
||||
self.graph_blocks = ("░▒▓█", "⚪⚫", "⓪①②③④⑤⑥⑦⑧⑨⑩")
|
||||
|
||||
self.waka_graphs = ([
|
||||
"░░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"█████████████████████████",
|
||||
"████████████▒░░░░░░░░░░░░",
|
||||
"████████████▓░░░░░░░░░░░░",
|
||||
"██████▒░░░░░░░░░░░░░░░░░░",
|
||||
"██████████████████▓░░░░░░",
|
||||
"▓░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"██▒░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"██████████████████████░░░",
|
||||
"█████████████████████▓░░░",
|
||||
"█░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"█▒░░░░░░░░░░░░░░░░░░░░░░░"
|
||||
],
|
||||
[
|
||||
"⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪",
|
||||
"⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪"
|
||||
],
|
||||
[
|
||||
"⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪",
|
||||
"⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩",
|
||||
"⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪",
|
||||
"⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪",
|
||||
"⑩⑩⑩⑩⑩⑩③⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪",
|
||||
"⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪⓪⓪⓪",
|
||||
"⑧⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪",
|
||||
"⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪",
|
||||
"⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪",
|
||||
"⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪",
|
||||
"⑩②⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪",
|
||||
"⑩②⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪"
|
||||
])
|
||||
|
||||
# self.dummy_readme = cleandoc("""
|
||||
# My Test Readme Start
|
||||
# <!--START_SECTION:waka-->
|
||||
# <!--END_SECTION:waka-->
|
||||
# My Test Readme End
|
||||
# """)
|
||||
|
||||
|
||||
class TestMain(unittest.TestCase):
|
||||
"""Testing Main Module"""
|
||||
|
||||
def test_make_graph(self):
|
||||
'''Tests the make_graph function'''
|
||||
def test(percent: float, block: str, result: str):
|
||||
self.assertEqual(make_graph(percent, block), result,
|
||||
f"{percent}% should return {result}")
|
||||
blocks = ["░▒▓█", "⚪⚫"]
|
||||
percents = [0, 100, 50, 50.001, 25, 75, 3.14,
|
||||
9.901, 87.334, 87.333, 4.666, 4.667]
|
||||
graphGroup = [["░░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"█████████████████████████",
|
||||
"████████████▒░░░░░░░░░░░░",
|
||||
"████████████▓░░░░░░░░░░░░",
|
||||
"██████▒░░░░░░░░░░░░░░░░░░",
|
||||
"██████████████████▓░░░░░░",
|
||||
"▓░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"██▒░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"██████████████████████░░░",
|
||||
"█████████████████████▓░░░",
|
||||
"█░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"█▒░░░░░░░░░░░░░░░░░░░░░░░"],
|
||||
["⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪",
|
||||
"⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪",
|
||||
"⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪",
|
||||
"⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪"]]
|
||||
for i, graphs in enumerate(graphGroup):
|
||||
os.environ["INPUT_BLOCKS"] = blocks[i]
|
||||
for j, graph in enumerate(graphs):
|
||||
test(percents[j], blocks[i], graph)
|
||||
def test_make_graph(self) -> None:
|
||||
"""Test graph maker"""
|
||||
for (idx, grb), (jdy, bpc) in product(
|
||||
enumerate(tds.graph_blocks), enumerate(tds.bar_percent)
|
||||
):
|
||||
self.assertEqual(
|
||||
prime.make_graph(grb, bpc, 25),
|
||||
tds.waka_graphs[idx][jdy]
|
||||
)
|
||||
|
||||
def test_make_title(self) -> None:
|
||||
"""Test title maker"""
|
||||
self.assertRegex(
|
||||
prime.make_title('2022-01-11T23:18:19Z', '2021-12-09T10:22:06Z'),
|
||||
r'From: \d{2} \w{3,9} \d{4} - To: \d{2} \w{3,9} \d{4}'
|
||||
)
|
||||
|
||||
# Known test limits
|
||||
# # prep_content() and churn():
|
||||
# requires additional modifications such as changing
|
||||
# globally passed values to parametrically passing them
|
||||
# # fetch_stats(): would required HTTP Authentication
|
||||
|
||||
|
||||
tds = TestData()
|
||||
tds.populate()
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
sys.path.insert(0, os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '..')
|
||||
))
|
||||
import main as prime
|
||||
# works when running as
|
||||
# python tests/test_main.py
|
||||
except ImportError as im_er:
|
||||
print(im_er)
|
||||
sys.exit(1)
|
||||
unittest.main()
|
||||
|
Reference in New Issue
Block a user