From dc3567c3aaa1b52c9dfb209415cc1d49dfe5d2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Grzywa?= Date: Mon, 23 Jan 2023 12:50:33 +0100 Subject: [PATCH] Added support for Allegro /myorder-api/myorders Updated documentation, added additional attributes --- .cookiecutter.json | 11 - .devcontainer/README.md | 60 +++++ .devcontainer/configuration.yaml | 5 +- .devcontainer/devcontainer.json | 57 ++--- .gitattributes | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 3 +- .github/ISSUE_TEMPLATE/issue.md | 8 +- .github/dependabot.yml | 14 -- .github/labels.yml | 66 ------ .github/release-drafter.yml | 29 --- .github/workflows/constraints.txt | 5 - .github/workflows/cron.yaml | 21 ++ .github/workflows/labeler.yml | 20 -- .github/workflows/pull.yml | 31 +++ .github/workflows/push.yml | 34 +++ .github/workflows/release-drafter.yml | 15 -- .github/workflows/tests.yaml | 63 ------ .gitignore | 4 +- .pre-commit-config.yaml | 32 --- .vscode/launch.json | 67 +++--- .vscode/settings.json | 15 +- .vscode/tasks.json | 56 ++--- CONTRIBUTING.md | 33 +-- LICENSE | 4 +- README.md | 97 +++----- custom_components/__init__.py | 1 + .../__init__.py | 47 ++-- custom_components/allegro/api.py | 98 ++++++++ custom_components/allegro/config_flow.py | 126 +++++++++++ .../const.py | 31 ++- custom_components/allegro/data.py | 92 ++++++++ custom_components/allegro/entity.py | 22 ++ .../manifest.json | 13 +- custom_components/allegro/sensor.py | 213 ++++++++++++++++++ .../allegro/translations/en.json | 26 +++ .../allegro/translations/pl.json | 26 +++ .../allegro/types/get_order_result.py | 159 +++++++++++++ .../allegro/types/get_user_info.py | 13 ++ .../home_assistant_allegro/api.py | 114 ---------- .../home_assistant_allegro/config_flow.py | 141 ------------ .../home_assistant_allegro/data.py | 13 -- .../home_assistant_allegro/entity.py | 36 --- .../home_assistant_allegro/sensor.py | 36 --- .../home_assistant_allegro/token_flow.py | 112 --------- .../translations/en.json | 31 --- .../translations/pl.json | 20 -- example.png | Bin 145119 -> 0 bytes hacs.json | 11 +- info.md | 71 +++--- requirements_dev.txt | 1 + requirements_test.txt | 1 + setup.cfg | 12 +- 52 files changed, 1167 insertions(+), 1051 deletions(-) delete mode 100644 .cookiecutter.json create mode 100644 .devcontainer/README.md delete mode 100644 .github/dependabot.yml delete mode 100644 .github/labels.yml delete mode 100644 .github/release-drafter.yml delete mode 100644 .github/workflows/constraints.txt create mode 100644 .github/workflows/cron.yaml delete mode 100644 .github/workflows/labeler.yml create mode 100644 .github/workflows/pull.yml create mode 100644 .github/workflows/push.yml delete mode 100644 .github/workflows/release-drafter.yml delete mode 100644 .github/workflows/tests.yaml delete mode 100644 .pre-commit-config.yaml create mode 100644 custom_components/__init__.py rename custom_components/{home_assistant_allegro => allegro}/__init__.py (69%) create mode 100644 custom_components/allegro/api.py create mode 100644 custom_components/allegro/config_flow.py rename custom_components/{home_assistant_allegro => allegro}/const.py (51%) create mode 100644 custom_components/allegro/data.py create mode 100644 custom_components/allegro/entity.py rename custom_components/{home_assistant_allegro => allegro}/manifest.json (57%) create mode 100644 custom_components/allegro/sensor.py create mode 100644 custom_components/allegro/translations/en.json create mode 100644 custom_components/allegro/translations/pl.json create mode 100644 custom_components/allegro/types/get_order_result.py create mode 100644 custom_components/allegro/types/get_user_info.py delete mode 100644 custom_components/home_assistant_allegro/api.py delete mode 100644 custom_components/home_assistant_allegro/config_flow.py delete mode 100644 custom_components/home_assistant_allegro/data.py delete mode 100644 custom_components/home_assistant_allegro/entity.py delete mode 100644 custom_components/home_assistant_allegro/sensor.py delete mode 100644 custom_components/home_assistant_allegro/token_flow.py delete mode 100644 custom_components/home_assistant_allegro/translations/en.json delete mode 100644 custom_components/home_assistant_allegro/translations/pl.json delete mode 100644 example.png create mode 100644 requirements_dev.txt create mode 100644 requirements_test.txt diff --git a/.cookiecutter.json b/.cookiecutter.json deleted file mode 100644 index 1d06c28..0000000 --- a/.cookiecutter.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "_output_dir": "C:\\Przemek\\GIT\\home-assistant-allegro", - "_template": "gh:oncleben31/cookiecutter-homeassistant-custom-component", - "class_name_prefix": "HomeAssistantAllegro", - "domain_name": "home_assistant_allegro", - "friendly_name": "Allegro", - "github_user": "Przemko92", - "project_name": "home-assistant-allegro", - "test_suite": "no", - "version": "0.0.0" -} \ No newline at end of file diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..e304a9a --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,60 @@ +## Developing with Visual Studio Code + devcontainer + +The easiest way to get started with custom integration development is to use Visual Studio Code with devcontainers. This approach will create a preconfigured development environment with all the tools you need. + +In the container you will have a dedicated Home Assistant core instance running with your custom component code. You can configure this instance by updating the `./devcontainer/configuration.yaml` file. + +**Prerequisites** + +- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +- Docker + - For Linux, macOS, or Windows 10 Pro/Enterprise/Education use the [current release version of Docker](https://docs.docker.com/install/) + - Windows 10 Home requires [WSL 2](https://docs.microsoft.com/windows/wsl/wsl2-install) and the current Edge version of Docker Desktop (see instructions [here](https://docs.docker.com/docker-for-windows/wsl-tech-preview/)). This can also be used for Windows Pro/Enterprise/Education. +- [Visual Studio code](https://code.visualstudio.com/) +- [Remote - Containers (VSC Extension)][extension-link] + +[More info about requirements and devcontainer in general](https://code.visualstudio.com/docs/remote/containers#_getting-started) + +[extension-link]: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers + +**Getting started:** + +1. Fork the repository. +2. Clone the repository to your computer. +3. Open the repository using Visual Studio code. + +When you open this repository with Visual Studio code you are asked to "Reopen in Container", this will start the build of the container. + +_If you don't see this notification, open the command palette and select `Remote-Containers: Reopen Folder in Container`._ + +### Tasks + +The devcontainer comes with some useful tasks to help you with development, you can start these tasks by opening the command palette and select `Tasks: Run Task` then select the task you want to run. + +When a task is currently running (like `Run Home Assistant on port 9123` for the docs), it can be restarted by opening the command palette and selecting `Tasks: Restart Running Task`, then select the task you want to restart. + +The available tasks are: + +Task | Description +-- | -- +Run Home Assistant on port 9123 | Launch Home Assistant with your custom component code and the configuration defined in `.devcontainer/configuration.yaml`. +Run Home Assistant configuration against /config | Check the configuration. +Upgrade Home Assistant to latest dev | Upgrade the Home Assistant core version in the container to the latest version of the `dev` branch. +Install a specific version of Home Assistant | Install a specific version of Home Assistant core in the container. + +### Step by Step debugging + +With the development container, +you can test your custom component in Home Assistant with step by step debugging. + +You need to modify the `configuration.yaml` file in `.devcontainer` folder +by uncommenting the line: + +```yaml +# debugpy: +``` + +Then launch the task `Run Home Assistant on port 9123`, and launch the debugger +with the existing debugging configuration `Python: Attach Local`. + +For more information, look at [the Remote Python Debugger integration documentation](https://www.home-assistant.io/integrations/debugpy/). diff --git a/.devcontainer/configuration.yaml b/.devcontainer/configuration.yaml index dd048d6..b5e0adf 100644 --- a/.devcontainer/configuration.yaml +++ b/.devcontainer/configuration.yaml @@ -3,6 +3,7 @@ default_config: logger: default: info logs: - custom_components.home_assistant_allegro: debug -# If you need to debug uncommment the line below (doc: https://www.home-assistant.io/integrations/debugpy/) + custom_components.allegro_buyer: debug + +# If you need to debug uncomment the line below (doc: https://www.home-assistant.io/integrations/debugpy/) debugpy: diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c977d0f..9d4a7f7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,28 +1,33 @@ // See https://aka.ms/vscode-remote/devcontainer.json for format details. { - "image": "ludeeus/container:integration-debian", - "name": "home-assistant-allegro integration development", - "context": "..", - "appPort": ["9123:8123"], - "postCreateCommand": "container install", - "extensions": [ - "ms-python.python", - "github.vscode-pull-request-github", - "ryanluker.vscode-coverage-gutters", - "ms-python.vscode-pylance" - ], - "settings": { - "files.eol": "\n", - "editor.tabSize": 4, - "terminal.integrated.shell.linux": "/bin/bash", - "python.pythonPath": "/usr/bin/python3", - "python.analysis.autoSearchPaths": false, - "python.linting.pylintEnabled": true, - "python.linting.enabled": true, - "python.formatting.provider": "black", - "editor.formatOnPaste": false, - "editor.formatOnSave": true, - "editor.formatOnType": true, - "files.trimTrailingWhitespace": true - } -} + "image": "ghcr.io/ludeeus/devcontainer/integration:stable", + "name": "Blueprint integration development", + "context": "..", + "appPort": [ + "9123:8123" + ], + "postCreateCommand": "container install", + "extensions": [ + "ms-python.python", + "github.vscode-pull-request-github", + "ryanluker.vscode-coverage-gutters", + "ms-python.vscode-pylance" + ], + "settings": { + "files.eol": "\n", + "editor.tabSize": 4, + "terminal.integrated.shell.linux": "/bin/bash", + "python.pythonPath": "/usr/bin/python3", + "python.analysis.autoSearchPaths": false, + "python.linting.pylintEnabled": true, + "python.linting.enabled": true, + "python.formatting.provider": "black", + "python.linting.pylintArgs": [ + "--disable=C0111" + ], + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "editor.formatOnType": true, + "files.trimTrailingWhitespace": true + } +} \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index 6313b56..94f480d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -* text=auto eol=lf +* text=auto eol=lf \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index a09db44..6bcce42 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,6 +1,7 @@ --- name: Feature request about: Suggest an idea for this project + --- **Is your feature request related to a problem? Please describe.** @@ -13,4 +14,4 @@ A clear and concise description of what you want to happen. A clear and concise description of any alternative solutions or features you've considered. **Additional context** -Add any other context or screenshots about the feature request here. +Add any other context or screenshots about the feature request here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/issue.md b/.github/ISSUE_TEMPLATE/issue.md index 218615e..bbd0345 100644 --- a/.github/ISSUE_TEMPLATE/issue.md +++ b/.github/ISSUE_TEMPLATE/issue.md @@ -1,6 +1,7 @@ --- name: Issue about: Create a report to help us improve + --- ## Version of the custom_component - @@ -22,13 +22,15 @@ If you are unsure about the version check the const.py file. ## Configuration ```yaml + Add your logs here. + ``` ## Describe the bug - A clear and concise description of what the bug is. + ## Debug log @@ -37,4 +39,4 @@ A clear and concise description of what the bug is. Add your logs here. -``` +``` \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 15c7513..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 -updates: - - package-ecosystem: github-actions - directory: "/" - schedule: - interval: daily - - package-ecosystem: pip - directory: "/.github/workflows" - schedule: - interval: daily - - package-ecosystem: pip - directory: "/" - schedule: - interval: daily diff --git a/.github/labels.yml b/.github/labels.yml deleted file mode 100644 index f7f83aa..0000000 --- a/.github/labels.yml +++ /dev/null @@ -1,66 +0,0 @@ ---- -# Labels names are important as they are used by Release Drafter to decide -# regarding where to record them in changelog or if to skip them. -# -# The repository labels will be automatically configured using this file and -# the GitHub Action https://github.com/marketplace/actions/github-labeler. -- name: breaking - description: Breaking Changes - color: bfd4f2 -- name: bug - description: Something isn't working - color: d73a4a -- name: build - description: Build System and Dependencies - color: bfdadc -- name: ci - description: Continuous Integration - color: 4a97d6 -- name: dependencies - description: Pull requests that update a dependency file - color: 0366d6 -- name: documentation - description: Improvements or additions to documentation - color: 0075ca -- name: duplicate - description: This issue or pull request already exists - color: cfd3d7 -- name: enhancement - description: New feature or request - color: a2eeef -- name: github_actions - description: Pull requests that update Github_actions code - color: "000000" -- name: good first issue - description: Good for newcomers - color: 7057ff -- name: help wanted - description: Extra attention is needed - color: 008672 -- name: invalid - description: This doesn't seem right - color: e4e669 -- name: performance - description: Performance - color: "016175" -- name: python - description: Pull requests that update Python code - color: 2b67c6 -- name: question - description: Further information is requested - color: d876e3 -- name: refactoring - description: Refactoring - color: ef67c4 -- name: removal - description: Removals and Deprecations - color: 9ae7ea -- name: style - description: Style - color: c120e5 -- name: testing - description: Testing - color: b1fc6f -- name: wontfix - description: This will not be worked on - color: ffffff diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index 7a04410..0000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1,29 +0,0 @@ -categories: - - title: ":boom: Breaking Changes" - label: "breaking" - - title: ":rocket: Features" - label: "enhancement" - - title: ":fire: Removals and Deprecations" - label: "removal" - - title: ":beetle: Fixes" - label: "bug" - - title: ":racehorse: Performance" - label: "performance" - - title: ":rotating_light: Testing" - label: "testing" - - title: ":construction_worker: Continuous Integration" - label: "ci" - - title: ":books: Documentation" - label: "documentation" - - title: ":hammer: Refactoring" - label: "refactoring" - - title: ":lipstick: Style" - label: "style" - - title: ":package: Dependencies" - labels: - - "dependencies" - - "build" -template: | - ## Changes - - $CHANGES diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt deleted file mode 100644 index 5b1ca4b..0000000 --- a/.github/workflows/constraints.txt +++ /dev/null @@ -1,5 +0,0 @@ -pip==21.0 -pre-commit==2.9.3 -black==20.8b1 -flake8==3.8.4 -reorder-python-imports==2.3.6 diff --git a/.github/workflows/cron.yaml b/.github/workflows/cron.yaml new file mode 100644 index 0000000..8d51d0f --- /dev/null +++ b/.github/workflows/cron.yaml @@ -0,0 +1,21 @@ +name: Cron actions + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + validate: + runs-on: "ubuntu-latest" + name: Validate + steps: + - uses: "actions/checkout@v2" + + - name: HACS validation + uses: "hacs/action@main" + with: + category: "integration" + ignore: brands + + - name: Hassfest validation + uses: "home-assistant/actions/hassfest@master" \ No newline at end of file diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml deleted file mode 100644 index 54ee057..0000000 --- a/.github/workflows/labeler.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Manage labels - -on: - push: - branches: - - main - - master - -jobs: - labeler: - name: Labeler - runs-on: ubuntu-latest - steps: - - name: Check out the repository - uses: actions/checkout@v2.3.4 - - - name: Run Labeler - uses: crazy-max/ghaction-github-labeler@v3.1.1 - with: - skip-delete: true diff --git a/.github/workflows/pull.yml b/.github/workflows/pull.yml new file mode 100644 index 0000000..dcfb832 --- /dev/null +++ b/.github/workflows/pull.yml @@ -0,0 +1,31 @@ +name: Pull actions + +on: + pull_request: + +jobs: + validate: + runs-on: "ubuntu-latest" + name: Validate + steps: + - uses: "actions/checkout@v2" + + - name: HACS validation + uses: "hacs/action@main" + with: + category: "integration" + ignore: brands + + - name: Hassfest validation + uses: "home-assistant/actions/hassfest@master" + + style: + runs-on: "ubuntu-latest" + name: Check style formatting + steps: + - uses: "actions/checkout@v2" + - uses: "actions/setup-python@v1" + with: + python-version: "3.x" + - run: python3 -m pip install black + - run: black . \ No newline at end of file diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 0000000..b3c4461 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,34 @@ +name: Push actions + +on: + push: + branches: + - master + - dev + +jobs: + validate: + runs-on: "ubuntu-latest" + name: Validate + steps: + - uses: "actions/checkout@v2" + + - name: HACS validation + uses: "hacs/action@main" + with: + category: "integration" + ignore: brands + + - name: Hassfest validation + uses: "home-assistant/actions/hassfest@master" + + style: + runs-on: "ubuntu-latest" + name: Check style formatting + steps: + - uses: "actions/checkout@v2" + - uses: "actions/setup-python@v1" + with: + python-version: "3.x" + - run: python3 -m pip install black + - run: black . \ No newline at end of file diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml deleted file mode 100644 index 26e1e08..0000000 --- a/.github/workflows/release-drafter.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Draft a release note -on: - push: - branches: - - main - - master -jobs: - draft_release: - name: Release Drafter - runs-on: ubuntu-latest - steps: - - name: Run release-drafter - uses: release-drafter/release-drafter@v5.13.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml deleted file mode 100644 index 2a04ce6..0000000 --- a/.github/workflows/tests.yaml +++ /dev/null @@ -1,63 +0,0 @@ -name: Linting - -on: - push: - branches: - - main - - master - - dev - pull_request: - schedule: - - cron: "0 0 * * *" - -env: - DEFAULT_PYTHON: 3.9 - -jobs: - pre-commit: - runs-on: "ubuntu-latest" - name: Pre-commit - steps: - - name: Check out the repository - uses: actions/checkout@v2.3.4 - - - name: Set up Python ${{ env.DEFAULT_PYTHON }} - uses: actions/setup-python@v2.2.1 - with: - python-version: ${{ env.DEFAULT_PYTHON }} - - - name: Upgrade pip - run: | - pip install --constraint=.github/workflows/constraints.txt pip - pip --version - - - name: Install Python modules - run: | - pip install --constraint=.github/workflows/constraints.txt pre-commit black flake8 reorder-python-imports - - - name: Run pre-commit on all files - run: | - pre-commit run --all-files --show-diff-on-failure --color=always - - hacs: - runs-on: "ubuntu-latest" - name: HACS - steps: - - name: Check out the repository - uses: "actions/checkout@v2.3.4" - - - name: HACS validation - uses: "hacs/action@20.12.0" - with: - category: "integration" - ignore: brands - - hassfest: - runs-on: "ubuntu-latest" - name: Hassfest - steps: - - name: Check out the repository - uses: "actions/checkout@v2.3.4" - - - name: Hassfest validation - uses: "home-assistant/actions/hassfest@master" diff --git a/.gitignore b/.gitignore index a4a4d84..492cda3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ __pycache__ pythonenv* -.python-version -.coverage venv .venv +.coverage +.idea diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 511f9f0..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,32 +0,0 @@ -repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.3.0 - hooks: - - id: check-added-large-files - - id: check-yaml - - id: end-of-file-fixer - - id: trailing-whitespace - - repo: local - hooks: - - id: black - name: black - entry: black - language: system - types: [python] - require_serial: true - - id: flake8 - name: flake8 - entry: flake8 - language: system - types: [python] - require_serial: true - - id: reorder-python-imports - name: Reorder python imports - entry: reorder-python-imports - language: system - types: [python] - args: [--application-directories=custom_components] - - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.2.1 - hooks: - - id: prettier diff --git a/.vscode/launch.json b/.vscode/launch.json index cc5337a..555a62b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,34 +1,35 @@ { - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - // Example of attaching to local debug server - "name": "Python: Attach Local", - "type": "python", - "request": "attach", - "port": 5678, - "host": "localhost", - "pathMappings": [ - { - "localRoot": "${workspaceFolder}", - "remoteRoot": "." - } - ] - }, - { - // Example of attaching to my production server - "name": "Python: Attach Remote", - "type": "python", - "request": "attach", - "port": 5678, - "host": "homeassistant.local", - "pathMappings": [ - { - "localRoot": "${workspaceFolder}", - "remoteRoot": "/usr/src/homeassistant" - } - ] - } - ] -} + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + // Example of attaching to local debug server + "name": "Python: Attach Local", + "type": "python", + "request": "attach", + "port": 5678, + "host": "localhost", + "pathMappings": [ + { + "localRoot": "${workspaceFolder}", + "remoteRoot": "." + } + ] + }, + { + // Example of attaching to my production server + "name": "Python: Attach Remote", + "type": "python", + "request": "attach", + "port": 5678, + "host": "homeassistant.local", + "pathMappings": [ + { + "localRoot": "${workspaceFolder}", + "remoteRoot": "/usr/src/homeassistant" + } + ] + } + ] + } + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 1cecc64..a3d535d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,8 @@ { - "python.linting.pylintEnabled": true, - "python.linting.enabled": true, - "python.pythonPath": "venv/bin/python", - "files.associations": { - "*.yaml": "home-assistant" - }, - "python.analysis.typeCheckingMode": "basic" -} + "python.linting.pylintEnabled": true, + "python.linting.enabled": true, + "python.pythonPath": "/usr/local/bin/python", + "files.associations": { + "*.yaml": "home-assistant" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 47f1210..7ab4ba8 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,29 +1,29 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "Run Home Assistant on port 9123", - "type": "shell", - "command": "container start", - "problemMatcher": [] - }, - { - "label": "Run Home Assistant configuration against /config", - "type": "shell", - "command": "container check", - "problemMatcher": [] - }, - { - "label": "Upgrade Home Assistant to latest dev", - "type": "shell", - "command": "container install", - "problemMatcher": [] - }, - { - "label": "Install a specific version of Home Assistant", - "type": "shell", - "command": "container set-version", - "problemMatcher": [] - } - ] -} + "version": "2.0.0", + "tasks": [ + { + "label": "Run Home Assistant on port 9123", + "type": "shell", + "command": "container start", + "problemMatcher": [] + }, + { + "label": "Run Home Assistant configuration against /config", + "type": "shell", + "command": "container check", + "problemMatcher": [] + }, + { + "label": "Upgrade Home Assistant to latest dev", + "type": "shell", + "command": "container install", + "problemMatcher": [] + }, + { + "label": "Install a specific version of Home Assistant", + "type": "shell", + "command": "container set-version", + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dce4104..d85a589 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,15 +40,11 @@ Report a bug by [opening a new issue](../../issues/new/choose); it's that easy! - What actually happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) -People _love_ thorough bug reports. I'm not even kidding. +People *love* thorough bug reports. I'm not even kidding. ## Use a Consistent Coding Style -Use [black](https://github.com/ambv/black) and [prettier](https://prettier.io/) -to make sure the code follows the style. - -Or use the `pre-commit` settings implemented in this repository -(see deicated section below). +Use [black](https://github.com/ambv/black) to make sure the code follows the style. ## Test your code modification @@ -60,31 +56,6 @@ Home Assistant instance running and already configured with the included [`.devcontainer/configuration.yaml`](./.devcontainer/configuration.yaml) file. -You can use the `pre-commit` settings implemented in this repository to have -linting tool checking your contributions (see deicated section below). - - - -## Pre-commit - -You can use the [pre-commit](https://pre-commit.com/) settings included in the -repostory to have code style and linting checks. - -With `pre-commit` tool already installed, -activate the settings of the repository: - -```console -$ pre-commit install -``` - -Now the pre-commit tests will be done every time you commit. - -You can run the tests on all repository file with the command: - -```console -$ pre-commit run --all-files -``` - ## License By contributing, you agree that your contributions will be licensed under its MIT License. diff --git a/LICENSE b/LICENSE index 6b2a31d..8f25631 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Przemko92 +Copyright (c) 2020 Joakim Sørensen @ludeeus Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ 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. +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index beec787..31f86eb 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,67 @@ -# home-assistant-allegro +# Home assistant Allegro integration [![GitHub Release][releases-shield]][releases] [![GitHub Activity][commits-shield]][commits] [![License][license-shield]](LICENSE) -[![pre-commit][pre-commit-shield]][pre-commit] -[![Black][black-shield]][black] - [![hacs][hacsbadge]][hacs] -[![Project Maintenance][maintenance-shield]][user_profile] [![BuyMeCoffee][buymecoffeebadge]][buymecoffee] -[![Discord][discord-shield]][discord] [![Community Forum][forum-shield]][forum] -**TO BE REMOVED: If you need help, as a developer, to use this custom component tempalte, -please look at the [User Guide in the Cookiecutter documentation](https://cookiecutter-homeassistant-custom-component.readthedocs.io/en/stable/quickstart.html)** **This component will set up the following platforms.** -| Platform | Description | -| --------------- | ------------------------------------------------------------------------- | -| `binary_sensor` | Show something `True` or `False`. | -| `sensor` | Show info from home-assistant-allegro API. | -| `switch` | Switch something `True` or `False`. | +Platform | Description +-- | -- +`sensor.allegro_in_progress` | Contains info about orders in OTHER THAN DELIVERED or RETURNED status. +`sensor.allegro_in_delivery` | Contains info about orders in IN_DELIVERY status. +`sensor.allegro_in_transit` | Contains info about orders in IN_TRANSIT status. +`sensor.allegro_waiting_for_pickup` | Contains info about orders in AVAILABLE_FOR_PICKUP status. -![example][exampleimg] ## Installation -1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`). -2. If you do not have a `custom_components` directory (folder) there, you need to create it. -3. In the `custom_components` directory (folder) create a new folder called `home_assistant_allegro`. -4. Download _all_ the files from the `custom_components/home_assistant_allegro/` directory (folder) in this repository. -5. Place the files you downloaded in the new directory (folder) you created. -6. Restart Home Assistant -7. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "home-assistant-allegro" - -Using your HA configuration directory (folder) as a starting point you should now also have this: - -```text -custom_components/home_assistant_allegro/translations/en.json -custom_components/home_assistant_allegro/translations/fr.json -custom_components/home_assistant_allegro/translations/nb.json -custom_components/home_assistant_allegro/translations/sensor.en.json -custom_components/home_assistant_allegro/translations/sensor.fr.json -custom_components/home_assistant_allegro/translations/sensor.nb.json -custom_components/home_assistant_allegro/translations/sensor.nb.json -custom_components/home_assistant_allegro/__init__.py -custom_components/home_assistant_allegro/api.py -custom_components/home_assistant_allegro/binary_sensor.py -custom_components/home_assistant_allegro/config_flow.py -custom_components/home_assistant_allegro/const.py -custom_components/home_assistant_allegro/manifest.json -custom_components/home_assistant_allegro/sensor.py -custom_components/home_assistant_allegro/switch.py -``` +HACS (recommended) + +1. Open HACS +2. Search for Allegro buyer (use integrations tab) and download it +3. In the HA UI go to "Configuration" -> "Integrations" and search for "Allegro buyer" +4. Restart HomeAssistant +5. Open another tab and go to https://allegro.pl and get value of QXLSESSID cookie using browser dev tools (F12) +6. Install Alegro buyer integration and pass QXLSESSID value and your user name (optional - required for more than one instance) ## Configuration is done in the UI - +Parameter | Description +-- | -- +`QXLSESSID` | Value of QXLSESSID cookie (required) +`user_name` | Optional value for multiple instances ## Contributions are welcome! If you want to contribute to this please read the [Contribution guidelines](CONTRIBUTING.md) -## Credits +*** -This project was generated from [@oncleben31](https://github.com/oncleben31)'s [Home Assistant Custom Component Cookiecutter](https://github.com/oncleben31/cookiecutter-homeassistant-custom-component) template. +[home_assistant_allegro]: https://github.com/Przemko92/home-assistant-allegro -Code template was mainly taken from [@Ludeeus](https://github.com/ludeeus)'s [integration_blueprint][integration_blueprint] template +[buymecoffee]: https://www.buymeacoffee.com/przemko92 +[buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=for-the-badge ---- +[maintainer]: https://github.com/Przemko92 +[maintainer-shield]: https://img.shields.io/badge/maintainer-%40Przemko92-blue.svg?style=for-the-badge -[integration_blueprint]: https://github.com/custom-components/integration_blueprint -[black]: https://github.com/psf/black -[black-shield]: https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge -[buymecoffee]: https://www.buymeacoffee.com/Przemko92 -[buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=for-the-badge -[commits-shield]: https://img.shields.io/github/commit-activity/y/Przemko92/home-assistant-allegro.svg?style=for-the-badge [commits]: https://github.com/Przemko92/home-assistant-allegro/commits/main -[hacs]: https://hacs.xyz +[commits-shield]: https://img.shields.io/github/commit-activity/y/Przemko92/home-assistant-allegro.svg?style=for-the-badge + +[hacs]: https://github.com/custom-components/hacs [hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge -[discord]: https://discord.gg/Qa5fW2R -[discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge -[exampleimg]: example.png -[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge + [forum]: https://community.home-assistant.io/ -[license-shield]: https://img.shields.io/github/license/Przemko92/home-assistant-allegro.svg?style=for-the-badge -[maintenance-shield]: https://img.shields.io/badge/maintainer-%40Przemko92-blue.svg?style=for-the-badge -[pre-commit]: https://github.com/pre-commit/pre-commit -[pre-commit-shield]: https://img.shields.io/badge/pre--commit-enabled-brightgreen?style=for-the-badge -[releases-shield]: https://img.shields.io/github/release/Przemko92/home-assistant-allegro.svg?style=for-the-badge +[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge + [releases]: https://github.com/Przemko92/home-assistant-allegro/releases -[user_profile]: https://github.com/Przemko92 +[releases-shield]: https://img.shields.io/github/release/Przemko92/home-assistant-allegro.svg?style=for-the-badge + +[license-shield]: https://img.shields.io/github/license/Przemko92/home-assistant-allegro.svg?style=for-the-badge \ No newline at end of file diff --git a/custom_components/__init__.py b/custom_components/__init__.py new file mode 100644 index 0000000..f55f54d --- /dev/null +++ b/custom_components/__init__.py @@ -0,0 +1 @@ +"""Custom components module.""" diff --git a/custom_components/home_assistant_allegro/__init__.py b/custom_components/allegro/__init__.py similarity index 69% rename from custom_components/home_assistant_allegro/__init__.py rename to custom_components/allegro/__init__.py index deebb64..0680942 100644 --- a/custom_components/home_assistant_allegro/__init__.py +++ b/custom_components/allegro/__init__.py @@ -1,30 +1,31 @@ """ -Custom integration to integrate home-assistant-allegro with Home Assistant. +Custom integration to integrate Allegro with Home Assistant. For more details about this integration, please refer to https://github.com/Przemko92/home-assistant-allegro """ import asyncio -import logging from datetime import timedelta +import logging from homeassistant.config_entries import ConfigEntry -from homeassistant.core import Config -from homeassistant.core import HomeAssistant +from homeassistant.core import Config, HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator -from homeassistant.helpers.update_coordinator import UpdateFailed +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .data import AllegroData -from .api import HomeAssistantAllegroApiClient -from .const import CONF_TOKEN, CONF_CLIENT_ID -from .const import CONF_CLIENT_SECRET -from .const import DOMAIN -from .const import PLATFORMS -from .const import STARTUP_MESSAGE -SCAN_INTERVAL = timedelta(minutes=5) +from .api import AllegroApiClient + +from .const import ( + CONF_COOKIE, + DOMAIN, + PLATFORMS, + STARTUP_MESSAGE, +) + +SCAN_INTERVAL = timedelta(minutes=30) _LOGGER: logging.Logger = logging.getLogger(__package__) @@ -40,14 +41,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): hass.data.setdefault(DOMAIN, {}) _LOGGER.info(STARTUP_MESSAGE) - client_id = str(entry.data.get(CONF_CLIENT_ID)) - secret = str(entry.data.get(CONF_CLIENT_SECRET)) - token = entry.data.get(CONF_TOKEN) + cookie = entry.data.get(CONF_COOKIE) - session = async_get_clientsession(hass, verify_ssl=False) - client = HomeAssistantAllegroApiClient(session, client_id, secret, token) + session = async_get_clientsession(hass) + client = AllegroApiClient(cookie, session) - coordinator = HomeAssistantAllegroDataUpdateCoordinator(hass, client=client) + coordinator = AllegroDataUpdateCoordinator(hass, client=client) await coordinator.async_refresh() if not coordinator.last_update_success: @@ -62,18 +61,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): hass.config_entries.async_forward_entry_setup(entry, platform) ) - entry.add_update_listener(async_reload_entry) + entry.async_on_unload(entry.add_update_listener(async_reload_entry)) return True -class HomeAssistantAllegroDataUpdateCoordinator(DataUpdateCoordinator): +class AllegroDataUpdateCoordinator(DataUpdateCoordinator): """Class to manage fetching data from the API.""" - def __init__( - self, - hass: HomeAssistant, - client: HomeAssistantAllegroApiClient, - ) -> None: + def __init__(self, hass: HomeAssistant, client: AllegroApiClient) -> None: """Initialize.""" self.api = client self.platforms = [] diff --git a/custom_components/allegro/api.py b/custom_components/allegro/api.py new file mode 100644 index 0000000..d709045 --- /dev/null +++ b/custom_components/allegro/api.py @@ -0,0 +1,98 @@ +"""Sample API Client.""" +import logging +import asyncio +from typing import Any, Optional +import aiohttp +import async_timeout + +from .types.get_user_info import GetUserInfoResult +from .types.get_order_result import GetOrdersResult + +from .const import ALLEGRO_API_URL + +TIMEOUT = 10 + + +_LOGGER: logging.Logger = logging.getLogger(__package__) + +HEADERS = {"Content-type": "application/json; charset=UTF-8"} + + +class AllegroApiClient: + """Api client""" + + def __init__(self, cookie: str, session: aiohttp.ClientSession) -> None: + """Sample API Client.""" + self._cookie = cookie + self._api_wrapper = ApiWrapper(session) + + async def get_standard_header(self, api_ver=1) -> dict: + """Returns standard request header""" + return { + "Cookie": "QXLSESSID=" + self._cookie, + "Accept": f"application/vnd.allegro.public.v{api_ver}+json", + "Referer": "https://allegro.pl/", + } + + async def get_orders(self) -> GetOrdersResult: + """Get orders from api""" + headers = await self.get_standard_header(3) + get_orders_response = await self._api_wrapper.get( + f"{ALLEGRO_API_URL}/myorder-api/myorders?limit=25", headers=headers + ) + return GetOrdersResult(get_orders_response) + + async def get_user_info(self) -> GetUserInfoResult: + """Get info about current user""" + headers = await self.get_standard_header(2) + get_orders_response = await self._api_wrapper.get( + f"{ALLEGRO_API_URL}/users", headers=headers + ) + return GetUserInfoResult(get_orders_response) + + +class ApiWrapper: + """Helper class""" + + def __init__(self, session: aiohttp.ClientSession): + self._session = session + + async def get(self, url: str, headers: dict = {}, auth: Any = None) -> dict: + """Run http GET method""" + return await self.api_wrapper("get", url, headers=headers, auth=auth) + + async def post( + self, url: str, data: dict = {}, headers: dict = {}, auth: Any = None + ) -> dict: + """Run http POST method""" + return await self.api_wrapper( + "post", url, data=data, headers=headers, auth=auth + ) + + async def api_wrapper( + self, + method: str, + url: str, + data: dict = {}, + headers: dict = {}, + auth: Any = None, + ) -> Any: + """Get information from the API.""" + try: + async with async_timeout.timeout(TIMEOUT): + if method == "get": + response = await self._session.get(url, headers=headers, auth=auth) + return await response.json() + + elif method == "post": + response = await self._session.post( + url, headers=headers, data=data, auth=auth + ) + return await response.json() + + except asyncio.TimeoutError as exception: + _LOGGER.error( + "Timeout error fetching information from %s - %s", + url, + exception, + ) diff --git a/custom_components/allegro/config_flow.py b/custom_components/allegro/config_flow.py new file mode 100644 index 0000000..e649571 --- /dev/null +++ b/custom_components/allegro/config_flow.py @@ -0,0 +1,126 @@ +"""Adds config flow for Allegro.""" +import logging +from homeassistant import config_entries +from homeassistant.core import callback +from homeassistant.helpers.aiohttp_client import async_create_clientsession +import voluptuous as vol + +from .api import AllegroApiClient +from .const import ( + CONF_COOKIE, + CONF_USERNAME, + DOMAIN, + PLATFORMS, +) + +_LOGGER: logging.Logger = logging.getLogger(__package__) + + +class AllegroFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): + """Config flow for Allegro.""" + + VERSION = 1 + CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL + + def __init__(self): + """Initialize.""" + self._errors = {} + + async def async_step_user(self, user_input=None): + """Handle a flow initialized by the user.""" + self._errors = {} + + if user_input is not None: + login = await self._test_credentials(user_input[CONF_COOKIE]) + if login: + if user_input[CONF_USERNAME]: + return self.async_create_entry( + title="Allegro " + user_input[CONF_USERNAME], data=user_input + ) + user_input[CONF_USERNAME] = login + return self.async_create_entry( + title="Allegro " + login, data=user_input + ) + else: + self._errors["base"] = "auth" + + return await self._show_config_form(user_input) + + user_input = {} + # Provide defaults for form + user_input[CONF_COOKIE] = "" + user_input[CONF_USERNAME] = "" + + return await self._show_config_form(user_input) + + @staticmethod + @callback + def async_get_options_flow(config_entry): + return AllegroOptionsFlowHandler(config_entry) + + async def _show_config_form(self, user_input): # pylint: disable=unused-argument + """Show the configuration form to edit location data.""" + return self.async_show_form( + step_id="user", + data_schema=vol.Schema( + { + vol.Required(CONF_COOKIE, default=user_input[CONF_COOKIE]): str, + vol.Optional(CONF_USERNAME, default=user_input[CONF_USERNAME]): str, + } + ), + errors=self._errors, + ) + + async def _test_credentials(self, cookie): + """Return true if credentials is valid.""" + try: + session = async_create_clientsession(self.hass) + client = AllegroApiClient(cookie, session) + result = await client.get_user_info() + return result.get_login + except Exception as exception: # pylint: disable=broad-except + _LOGGER.error( + "Error while testing credentials %s", + exception, + ) + + pass + return False + + +class AllegroOptionsFlowHandler(config_entries.OptionsFlow): + """Allegro config flow options handler.""" + + def __init__(self, config_entry): + """Initialize HACS options flow.""" + self.config_entry = config_entry + self.options = dict(config_entry.options) + + async def async_step_init(self, user_input=None): # pylint: disable=unused-argument + """Manage the options.""" + return await self.async_step_user() + + async def async_step_user(self, user_input=None): + """Handle a flow initialized by the user.""" + if user_input is not None: + self.options.update(user_input) + return await self._update_options() + + return self.async_show_form( + step_id="user", + data_schema=vol.Schema( + { + vol.Required( + CONF_COOKIE, default=self.config_entry.data[CONF_COOKIE] + ): str, + } + ), + ) + + async def _update_options(self): + """Update config entry options.""" + self.options[CONF_USERNAME] = self.config_entry.data[CONF_USERNAME] + + return self.async_create_entry( + title="Allegro " + self.options[CONF_USERNAME], data=self.options + ) diff --git a/custom_components/home_assistant_allegro/const.py b/custom_components/allegro/const.py similarity index 51% rename from custom_components/home_assistant_allegro/const.py rename to custom_components/allegro/const.py index 7355d36..0e34910 100644 --- a/custom_components/home_assistant_allegro/const.py +++ b/custom_components/allegro/const.py @@ -1,15 +1,17 @@ -"""Constants for home-assistant-allegro.""" +"""Constants for allegro_integration.""" # Base component constants -NAME = "Home Assistant Allegro" -DOMAIN = "home_assistant_allegro" +NAME = "Allegro buyer" +DOMAIN = "allegro" DOMAIN_DATA = f"{DOMAIN}_data" -VERSION = "0.0.0" - -ATTRIBUTION = "Data provided by https://developer.allegro.pl/" -ISSUE_URL = "https://github.com/Przemko92/home-assistant-allegro/issues" +VERSION = "0.0.1" +ATTRIBUTION = "Data provided by http://api.allegro.pl" +ISSUE_URL = "https://github.com/Przemko92/home-assistant-allegro" # Icons -ICON = "mdi:local-shipping" +ICON_WAITING = "mdi:package-variant" +ICON_TRANSIT = "mdi:truck-delivery" +ICON_DELIVERY = "mdi:map-marker-radius-outline" +ICON_READY = "mdi:archive-check" # Platforms SENSOR = "sensor" @@ -17,18 +19,13 @@ # Configuration and options -CONF_ENABLED = "enabled" -CONF_CLIENT_ID = "client_id" -CONF_CLIENT_SECRET = "client_secret" -CONF_TOKEN = "token" - -# ALLEGRO_BASE_URL = "https://allegro.pl.allegrosandbox.pl" -# ALLEGRO_API_URL = "https://api.allegro.pl.allegrosandbox.pl" +CONF_COOKIE = "QXLSESSID" +CONF_USERNAME = "user_name" -ALLEGRO_BASE_URL = "https://allegro.pl" ALLEGRO_API_URL = "https://api.allegro.pl" + # Defaults -DEFAULT_NAME = "allegro" +DEFAULT_NAME = DOMAIN STARTUP_MESSAGE = f""" diff --git a/custom_components/allegro/data.py b/custom_components/allegro/data.py new file mode 100644 index 0000000..172494f --- /dev/null +++ b/custom_components/allegro/data.py @@ -0,0 +1,92 @@ +import logging +from .types.get_order_result import Order +from .api import AllegroApiClient + +_LOGGER: logging.Logger = logging.getLogger(__package__) + + +class AllegroData: + def __init__( + self, + all_orders: list[Order], + not_delivered: list[Order], + waiting_for_pickup: list[Order], + in_transit: list[Order], + in_delivery: list[Order], + ) -> None: + self._all_orders = all_orders + self._not_delivered = not_delivered + self._waiting_for_pickup = waiting_for_pickup + self._in_transit = in_transit + self._in_delivery = in_delivery + + @staticmethod + async def get_data(api: AllegroApiClient): + + try: + get_orders_response = await api.get_orders() + + not_delivered = list[Order]( + filter( + lambda order: order.get_status.get_current_status != "DELIVERED" + and order.get_status.get_current_status != "RETURNED", + get_orders_response.get_orders, + ) + ) + + waiting_for_pickup = list[Order]( + filter( + lambda order: order.get_status.get_current_status + == "AVAILABLE_FOR_PICKUP", + get_orders_response.get_orders, + ) + ) + + in_delivery = list[Order]( + filter( + lambda order: order.get_status.get_current_status == "IN_DELIVERY", + get_orders_response.get_orders, + ) + ) + + in_transit = list[Order]( + filter( + lambda order: order.get_status.get_current_status == "IN_TRANSIT", + get_orders_response.get_orders, + ) + ) + + return AllegroData( + get_orders_response.get_orders, + not_delivered, + waiting_for_pickup, + in_transit, + in_delivery, + ) + except Exception as exception: # pylint: disable=broad-except + _LOGGER.error( + "Error while testing credentials %s", + exception, + ) + + pass + + @property + def get_all_orders(self): + return self._all_orders + + @property + def get_not_delivered_orders(self): + return self._not_delivered + + @property + def get_waiting_for_pickup(self): + return self._waiting_for_pickup + + @property + def get_in_transit(self): + return self._in_transit + + @property + def get_in_delivery(self): + return self._in_delivery diff --git a/custom_components/allegro/entity.py b/custom_components/allegro/entity.py new file mode 100644 index 0000000..4f7597a --- /dev/null +++ b/custom_components/allegro/entity.py @@ -0,0 +1,22 @@ +"""AllegroEntity class""" +from homeassistant.helpers.update_coordinator import CoordinatorEntity + +from .const import CONF_USERNAME +from .data import AllegroData + + +class AllegroEntity(CoordinatorEntity): + def __init__(self, coordinator, config_entry): + super().__init__(coordinator) + self.config_entry = config_entry + + @property + def get_allegro_data(self) -> AllegroData: + return self.coordinator.data + + @property + def get_user_name(self) -> str: + if self.config_entry.data[CONF_USERNAME]: + return f"{self.config_entry.data[CONF_USERNAME].lower()}_" + else: + return "" diff --git a/custom_components/home_assistant_allegro/manifest.json b/custom_components/allegro/manifest.json similarity index 57% rename from custom_components/home_assistant_allegro/manifest.json rename to custom_components/allegro/manifest.json index 61b1d56..6a3a3cf 100644 --- a/custom_components/home_assistant_allegro/manifest.json +++ b/custom_components/allegro/manifest.json @@ -1,13 +1,12 @@ { - "domain": "home_assistant_allegro", - "name": "Allegro", + "domain": "allegro", + "name": "Allegro buyer", "documentation": "https://github.com/Przemko92/home-assistant-allegro", + "iot_class": "cloud_polling", "issue_tracker": "https://github.com/Przemko92/home-assistant-allegro/issues", - "dependencies": [], + "version": "0.0.0", "config_flow": true, "codeowners": [ - "@Przemko92" - ], - "requirements": [], - "version": "0.0.1" + "@ludeeus" + ] } \ No newline at end of file diff --git a/custom_components/allegro/sensor.py b/custom_components/allegro/sensor.py new file mode 100644 index 0000000..82bb909 --- /dev/null +++ b/custom_components/allegro/sensor.py @@ -0,0 +1,213 @@ +"""Sensor platform for allegro_integration.""" +from homeassistant.components.sensor import SensorEntity + +from . import AllegroDataUpdateCoordinator + +from .const import ( + DEFAULT_NAME, + DOMAIN, + ICON_WAITING, + ICON_READY, + ICON_TRANSIT, + ICON_DELIVERY, + SENSOR, + CONF_USERNAME, +) +from .entity import AllegroEntity + + +async def async_setup_entry(hass, entry, async_add_devices): + """Setup sensor platform.""" + coordinator = hass.data[DOMAIN][entry.entry_id] + async_add_devices( + [ + WaitingForDeliverySensor(coordinator, entry), + WaitingForPickupSensor(coordinator, entry), + InTransitSensor(coordinator, entry), + InDeliverySensor(coordinator, entry), + ] + ) + + +class WaitingForDeliverySensor(AllegroEntity, SensorEntity): + """WaitingForDelivery Sensor class.""" + + def __init__(self, coordinator, config_entry) -> None: + """Init method""" + super().__init__(coordinator, config_entry) + + @property + def name(self): + """Return the name of the sensor.""" + return f"{DEFAULT_NAME}_{self.get_user_name}in_progress" + + @property + def native_value(self): + """Return the native value of the sensor.""" + return len(self.get_allegro_data.get_not_delivered_orders) + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.get_user_name}in_progress" + + @property + def icon(self): + """Return the icon of the sensor.""" + return ICON_WAITING + + @property + def extra_state_attributes(self): + """Return the state attributes.""" + orders = self.get_allegro_data.get_not_delivered_orders + items = [] + + for item in orders: + items.append( + { + "Seller": item.get_seller, + "Status": item.get_status.get_current_status, + "Offers": list(map(lambda i: i.get_title, item.get_offers)), + "tracing_url": item.get_delivery.get_url, + "delivery_name": item.get_delivery.get_name, + } + ) + + return { + "details": items, + } + + +class WaitingForPickupSensor(AllegroEntity, SensorEntity): + """WaitingForPickupSensor Sensor class.""" + + @property + def name(self): + """Return the name of the sensor.""" + return f"{DEFAULT_NAME}_{self.get_user_name}waiting_for_pickup" + + @property + def native_value(self): + """Return the native value of the sensor.""" + return len(self.get_allegro_data.get_waiting_for_pickup) + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.get_user_name}waiting_for_pickup" + + @property + def icon(self): + """Return the icon of the sensor.""" + return ICON_READY + + @property + def extra_state_attributes(self): + """Return the state attributes.""" + orders = self.get_allegro_data.get_waiting_for_pickup + items = [] + + for item in orders: + items.append( + { + "Seller": item.get_seller, + "Status": item.get_status.get_current_status, + "Offers": list(map(lambda i: i.get_title, item.get_offers)), + "tracing_url": item.get_delivery.get_url, + "delivery_name": item.get_delivery.get_name, + } + ) + + return { + "details": items, + } + + +class InTransitSensor(AllegroEntity, SensorEntity): + """InTransit Sensor class.""" + + @property + def name(self): + """Return the name of the sensor.""" + return f"{DEFAULT_NAME}_{self.get_user_name}in_transit" + + @property + def native_value(self): + """Return the native value of the sensor.""" + return len(self.get_allegro_data.get_in_transit) + + @property + def icon(self): + """Return the icon of the sensor.""" + return ICON_TRANSIT + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.get_user_name}in_transit" + + @property + def extra_state_attributes(self): + """Return the state attributes.""" + orders = self.get_allegro_data.get_in_transit + items = [] + + for item in orders: + items.append( + { + "Seller": item.get_seller, + "Status": item.get_status.get_current_status, + "Offers": list(map(lambda i: i.get_title, item.get_offers)), + "tracing_url": item.get_delivery.get_url, + "delivery_name": item.get_delivery.get_name, + } + ) + + return { + "details": items, + } + + +class InDeliverySensor(AllegroEntity, SensorEntity): + """InDeliverySensor Sensor class.""" + + @property + def name(self): + """Return the name of the sensor.""" + return f"{DEFAULT_NAME}_{self.get_user_name}in_delivery" + + @property + def native_value(self): + """Return the native value of the sensor.""" + return len(self.get_allegro_data.get_in_delivery) + + @property + def icon(self): + """Return the icon of the sensor.""" + return ICON_DELIVERY + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.get_user_name}in_delivery" + + @property + def extra_state_attributes(self): + """Return the state attributes.""" + orders = self.get_allegro_data.get_in_delivery + items = [] + + for item in orders: + items.append( + { + "Seller": item.get_seller, + "Status": item.get_status.get_current_status, + "Offers": list(map(lambda i: i.get_title, item.get_offers)), + "tracing_url": item.get_delivery.get_url, + "delivery_name": item.get_delivery.get_name, + } + ) + + return { + "details": items, + } diff --git a/custom_components/allegro/translations/en.json b/custom_components/allegro/translations/en.json new file mode 100644 index 0000000..435e30a --- /dev/null +++ b/custom_components/allegro/translations/en.json @@ -0,0 +1,26 @@ +{ + "config": { + "step": { + "user": { + "title": "Allegro", + "description": "Go to https://allegro.pl and get value of QXLSESSID cookie using browser dev tools (F12)", + "data": { + "QXLSESSID": "Cookie QXLSESSID value", + "user_name": "User name" + } + } + }, + "error": { + "auth": "Wrong cookiue value" + } + }, + "options": { + "step": { + "user": { + "data": { + "QXLSESSID": "Cookie QXLSESSID value" + } + } + } + } +} \ No newline at end of file diff --git a/custom_components/allegro/translations/pl.json b/custom_components/allegro/translations/pl.json new file mode 100644 index 0000000..b3bf611 --- /dev/null +++ b/custom_components/allegro/translations/pl.json @@ -0,0 +1,26 @@ +{ + "config": { + "step": { + "user": { + "title": "Allegro", + "description": "Odwiedź stronę https://allegro.pl i pobierz wartość ciastecza QXLSESSID używając narzędzi developerskich przeglądarki (F12)", + "data": { + "QXLSESSID": "Wartość QXLSESSID", + "user_name": "User name" + } + } + }, + "error": { + "auth": "Nieprawidłowe cookie" + } + }, + "options": { + "step": { + "user": { + "data": { + "QXLSESSID": "Wartość QXLSESSID" + } + } + } + } +} \ No newline at end of file diff --git a/custom_components/allegro/types/get_order_result.py b/custom_components/allegro/types/get_order_result.py new file mode 100644 index 0000000..8a9a54d --- /dev/null +++ b/custom_components/allegro/types/get_order_result.py @@ -0,0 +1,159 @@ +from typing import Any + + +class GetOrdersResult: + """Result of get_orders method""" + + def __init__(self, items: dict) -> None: + """Init method""" + iterator = map(self.get_order, items["orderGroups"]) + self._orders = list(iterator) + + def get_order(self, item: Any): + """Returns single order""" + return Order(item["groupId"], item["myorders"][0]) + + @property + def get_orders(self): + return self._orders + + +class Order: + """Single order item""" + + def __init__(self, order_id: str, items: dict) -> None: + """Init method""" + self._order_id = order_id + self._seller = items["seller"]["login"] + iterator = map(self.get_offer, items["offers"]) + self._offers = list(iterator) + self._order_date = items["orderDate"] + self._status = Status(items["status"]["primary"]["status"]) + delivery = items["delivery"] + waybills_data = delivery["waybillsData"] + + if "waybills" in waybills_data: + self._delivery = Delivery( + delivery["name"], + waybills_data["waybills"][0]["carrier"]["url"], + ) + else: + self._delivery = Delivery(delivery["name"], None) + + def get_formatted_address(self, items: dict): + """Returns formatted delivery address""" + return f"{items['street']} {items['code']} {items['city']}" + + def get_offer(self, item: Any): + """Returns single order""" + return Offer( + item["id"], + item["title"], + item["unitPrice"], + item["friendlyUrl"], + int(item["quantity"]), + item["imageUrl"], + ) + + @property + def get_order_id(self): + return self._order_id + + @property + def get_seller(self): + return self._seller + + @property + def get_offers(self): + return self._offers + + @property + def get_orde_date(self): + return self._order_date + + @property + def get_status(self): + return self._status + + @property + def get_delivery(self): + return self._delivery + + +class Status: + """Order status""" + + def __init__(self, current_status: str) -> None: + """Init method""" + self._current_status = current_status + + @property + def get_current_status(self): + return self._current_status + + +class Delivery: + """Delivery info""" + + def __init__(self, name: str, url: str) -> None: + """Init method""" + self._name = name + self._url = url + + @property + def get_name(self): + return self._name + + @property + def get_url(self): + return self._url + + +class Offer: + """Single offer item""" + + def __init__( + self, + offer_id: str, + title: str, + unit_urice: dict, + friendly_url: str, + quantity: int, + image_url: str, + ) -> None: + """Init method""" + self._offer_id = offer_id + self._title = title + self._unit_price = float(unit_urice["amount"]) + self._price_currency = unit_urice["currency"] + self._friendly_url = friendly_url + self._quantity = quantity + self._image_url = image_url + + @property + def get_id(self): + return self._offer_id + + @property + def get_title(self): + return self._title + + @property + def get_unit_price(self): + return self._unit_price + + @property + def get_price_currency(self): + return self._price_currency + + @property + def get_friendly_url(self): + return self._friendly_url + + @property + def get_quantity(self): + return self._quantity + + @property + def get_image_url(self): + return self._image_url diff --git a/custom_components/allegro/types/get_user_info.py b/custom_components/allegro/types/get_user_info.py new file mode 100644 index 0000000..94bbb06 --- /dev/null +++ b/custom_components/allegro/types/get_user_info.py @@ -0,0 +1,13 @@ +from typing import Any + + +class GetUserInfoResult: + """Result of get_orders method""" + + def __init__(self, items: dict) -> None: + """Init method""" + self._login = items["accounts"]["allegro"]["login"] + + @property + def get_login(self): + return self._login diff --git a/custom_components/home_assistant_allegro/api.py b/custom_components/home_assistant_allegro/api.py deleted file mode 100644 index df5e82f..0000000 --- a/custom_components/home_assistant_allegro/api.py +++ /dev/null @@ -1,114 +0,0 @@ -"""Sample API Client.""" -from .token_flow import TokenFlow - -import asyncio -import logging -import socket -from typing import Any - -import aiohttp -import async_timeout -from .const import ALLEGRO_API_URL, ALLEGRO_BASE_URL - -TIMEOUT = 10 - - -_LOGGER: logging.Logger = logging.getLogger(__package__) - - -class HomeAssistantAllegroApiClient: - def __init__( - self, - session: aiohttp.ClientSession, - client_id: str, - client_secret: str, - token: object = None, - ) -> None: - """Sample API Client.""" - self._api_wrapper = ApiWrapper(session) - self._token_flow = TokenFlow(session, client_id, client_secret, token) - - async def get_standard_header(self) -> dict: - return { - "Cookie": "cartUserId=14752576-ffff-ffff-ffff-ffffffffffffffffffff-ffff-ffff-ffff-ffffffffffff; QXLSESSID=697780b4fe33a53d55826c20f04744410168c566846f2f//03; ws3=LFM8liLCD1YT8cuU5bBrXsNBszx967S23; qeppo_login2=%7B%22welcome%22%3A%22Witaj%2C%22%2C%22id%22%3A%2214752576%22%2C%22username%22%3A%22HucK92%22%2C%22isCompany%22%3Afalse%7D; QXLDATA=stezXBvhhRSznYQhA%2BCEkWhg8w0XcwFcaLHFwC%2FU6VU%3D%23%23%23TdonRyC8uVCJwX6dGgBxUPVRNeInfh3vsBJLvoaYQxBtJ5tS%2FNqJhgx9yiyulcHs5JTDnvvKgEnK1i%2FrG1CloUhU6ZFSBZQ6WApVxUQMqyP5MiiMUfuUdHC4mSPrpsDbbWrCEDKdq5hza6I%3D; qeppo_priv_cookie=NWM5OQUMAAAHVg4PNDg3NQ%3D%3D; userIdentity=%7B%22id%22%3A%2214752576%22%7D; ws1=NWM5OQUMAAAHVg4PNDg3NQ%3D%3D; enc_ws1=NWM5OQUMAAAHVg4PNDg3NQ%3D%3D; dc1=NWM5OQUMAAAHVg4PNDg3NQ%3D%3D; dc2=NDRhNnxvfwR7ZTR7c3lzeWJTVWZ8fFUCemVcCzI4MjE%3D; datadome=5uRus8W9KqUr-lB4e4pnHE-XXsaB2RAAIxvGvD_5Abneva_iCn732NP4pfrMJwLj9JA49exOhVFIRXCXp0~XO~WNEmQsEswIxdzlGJDCD54MEwpzDl7GyKLNF5TGKbGs; __gfp_64b=-TURNEDOFF; wdctx=v4.M7NexS8Ugkk7albXrQwNrhcKYtGI1cIFBFflCC-45f-aHJyZgTu7qFCFsT9ra4KGE__Sw8Eo6JYrcZuzlVDvtYLvksZ7K2ImROvH9wyAujKDfXTsEtI3AgF39-FfAoHItpxCCBDBFjD7_bty7cwOg9B9kcW0NN7wNZ0BEXIv2hRO4eiA5YlkKh4zpbGw-QGUFPV0EX6Rraw1CjAflOXLSbVzWs1nfvqcIZWa3S9GraU6f5lxVd5IrbCpvEgs; _cmuid=fa64c75b-6855-4424-8d2e-fba0e46200c3; parcelsChecksum=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; chronos_cookie=1; all_rct=rct42818809086588e33", - "Accept": "application/vnd.allegro.public.v1+json", - "Referer": "https://allegro.pl/", - } - - async def get_auth_url(self) -> str: - return await self._token_flow.get_auth_url() - - async def await_for_token(self): - return await self._token_flow.await_for_token() - - async def get_user_info(self) -> dict: - headers = await self.get_standard_header() - user_info_response = await self._api_wrapper.get( - f"{ALLEGRO_API_URL}/me", headers=headers - ) - return user_info_response - - async def get_orders(self) -> dict: - headers = await self.get_standard_header() - get_orders_response = await self._api_wrapper.get( - f"{ALLEGRO_API_URL}/myorder-api/myorders/", headers=headers - ) - return get_orders_response - - -class ApiWrapper: - def __init__(self, session: aiohttp.ClientSession): - self._session = session - - async def get(self, url: str, headers: dict = {}, auth: Any = None) -> dict: - return await self.api_wrapper("get", url, headers=headers, auth=auth) - - async def post( - self, url: str, data: dict = {}, headers: dict = {}, auth: Any = None - ) -> dict: - return await self.api_wrapper( - "post", url, data=data, headers=headers, auth=auth - ) - - async def api_wrapper( - self, - method: str, - url: str, - data: dict = {}, - headers: dict = {}, - auth: Any = None, - ) -> Any: - """Get information from the API.""" - try: - async with async_timeout.timeout(TIMEOUT): - if method == "get": - response = await self._session.get(url, headers=headers, auth=auth) - return await response.json() - - elif method == "post": - response = await self._session.post( - url, headers=headers, data=data, auth=auth - ) - return await response.json() - - except asyncio.TimeoutError as exception: - _LOGGER.error( - "Timeout error fetching information from %s - %s", - url, - exception, - ) - - except (KeyError, TypeError) as exception: - _LOGGER.error( - "Error parsing information from %s - %s", - url, - exception, - ) - except (aiohttp.ClientError, socket.gaierror) as exception: - _LOGGER.error( - "Error fetching information from %s - %s", - url, - exception, - ) - except Exception as exception: # pylint: disable=broad-except - _LOGGER.error("Something really wrong happened! - %s", exception) diff --git a/custom_components/home_assistant_allegro/config_flow.py b/custom_components/home_assistant_allegro/config_flow.py deleted file mode 100644 index 941edbc..0000000 --- a/custom_components/home_assistant_allegro/config_flow.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Adds config flow for home-assistant-allegro.""" -import json -import time -import voluptuous as vol -from homeassistant import config_entries -from homeassistant.core import callback -from homeassistant.helpers.aiohttp_client import async_create_clientsession -from homeassistant.components.http import HomeAssistantView -import aiohttp -from typing import Any -from .api import HomeAssistantAllegroApiClient -from .const import CONF_CLIENT_ID -from .const import CONF_CLIENT_SECRET -from .const import CONF_TOKEN -from .const import DOMAIN -from .const import PLATFORMS - - -class HomeAssistantAllegroFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): - """Config flow for home_assistant_allegro.""" - - VERSION = 1 - - def __init__(self): - """Initialize.""" - self._errors = {} - self._client = None - self._data = None - - async def async_step_user(self, user_input=None): - """Handle a flow initialized by the user.""" - self._errors = {} - - # Uncomment the next 2 lines if only a single instance of the integration is allowed: - # if self._async_current_entries(): - # return self.async_abort(reason="single_instance_allowed") - - if user_input is not None and not CONF_TOKEN in user_input: - return await self.async_step_auth(user_input) - - return await self._show_config_form(user_input) - - async def async_step_auth(self, user_input=None): - """Handle a flow initialized by the user.""" - - if user_input is not None: - if CONF_TOKEN in user_input: - self._data = user_input - return self.async_external_step_done(next_step_id="finish") - - auth_url = await self.get_auth_url( - user_input[CONF_CLIENT_ID], user_input[CONF_CLIENT_SECRET] - ) - - self.hass.async_create_task(self.get_token(user_input)) - return self.async_external_step(step_id="auth", url=auth_url) - - async def get_token(self, user_input=None): - if self._client and user_input: - token = await self._client.await_for_token() - - return await self.hass.config_entries.flow.async_configure( - flow_id=self.flow_id, - user_input={ - CONF_CLIENT_ID: user_input[CONF_CLIENT_ID], - CONF_CLIENT_SECRET: user_input[CONF_CLIENT_SECRET], - CONF_TOKEN: token, - }, - ) - - async def async_step_finish(self, user_input=None): - if self._client and self._data: - user_info = await self._client.get_user_info() - return self.async_create_entry( - title="Allegro " + user_info["login"], data=self._data - ) - - @staticmethod - @callback - def async_get_options_flow(config_entry): - return HomeAssistantAllegroOptionsFlowHandler(config_entry) - - async def _show_config_form(self, user_input): # pylint: disable=unused-argument - """Show the configuration form to edit location data.""" - return self.async_show_form( - step_id="user", - data_schema=vol.Schema( - { - vol.Required(CONF_CLIENT_ID): str, - vol.Required(CONF_CLIENT_SECRET): str, - } - ), - errors=self._errors, - last_step=False, - ) - - async def get_auth_url(self, client_id: str, client_secret: str) -> str: - """Return true if credentials is valid.""" - - session = async_create_clientsession(self.hass, verify_ssl=False) - self._client = HomeAssistantAllegroApiClient(session, client_id, client_secret) - return await self._client.get_auth_url() - - -class HomeAssistantAllegroOptionsFlowHandler(config_entries.OptionsFlow): - """Config flow options handler for home_assistant_allegro.""" - - def __init__(self, config_entry): - """Initialize HACS options flow.""" - self.config_entry = config_entry - self.options = dict(config_entry.options) - - async def async_step_init( - self, user_input=None, external_data=None - ): # pylint: disable=unused-argument - """Manage the options.""" - return await self.async_step_user() - - async def async_step_user(self, user_input=None, external_data=None): - """Handle a flow initialized by the user.""" - if user_input is not None: - self.options.update(user_input) - - if external_data is not None: - return await self._update_options() - - return self.async_show_form( - step_id="user", - data_schema=vol.Schema( - { - vol.Required(x, default=self.options.get(x, True)): bool - for x in sorted(PLATFORMS) - } - ), - ) - - async def _update_options(self): - """Update config entry options.""" - return self.async_create_entry( - title=self.config_entry.data.get(CONF_CLIENT_ID), data=self.options - ) \ No newline at end of file diff --git a/custom_components/home_assistant_allegro/data.py b/custom_components/home_assistant_allegro/data.py deleted file mode 100644 index 99041e8..0000000 --- a/custom_components/home_assistant_allegro/data.py +++ /dev/null @@ -1,13 +0,0 @@ -from .api import HomeAssistantAllegroApiClient -from typing import Any - - -class AllegroData: - def __init__(self, orders: Any) -> None: - self._orders = orders - - @staticmethod - async def get_data(api: HomeAssistantAllegroApiClient): - orders = await api.get_orders() - - return AllegroData(orders) \ No newline at end of file diff --git a/custom_components/home_assistant_allegro/entity.py b/custom_components/home_assistant_allegro/entity.py deleted file mode 100644 index c6a31e8..0000000 --- a/custom_components/home_assistant_allegro/entity.py +++ /dev/null @@ -1,36 +0,0 @@ -"""HomeAssistantAllegroEntity class""" -from homeassistant.helpers.update_coordinator import CoordinatorEntity - -from .const import ATTRIBUTION -from .const import DOMAIN -from .const import NAME -from .const import VERSION - - -class HomeAssistantAllegroEntity(CoordinatorEntity): - def __init__(self, coordinator, config_entry): - super().__init__(coordinator) - self.config_entry = config_entry - - @property - def unique_id(self): - """Return a unique ID to use for this entity.""" - return self.config_entry.entry_id - - @property - def device_info(self): - return { - "identifiers": {(DOMAIN, self.unique_id)}, - "name": NAME, - "model": VERSION, - "manufacturer": NAME, - } - - @property - def device_state_attributes(self): - """Return the state attributes.""" - return { - "attribution": ATTRIBUTION, - "id": str(self.coordinator.data.get("id")), - "integration": DOMAIN, - } diff --git a/custom_components/home_assistant_allegro/sensor.py b/custom_components/home_assistant_allegro/sensor.py deleted file mode 100644 index 3372305..0000000 --- a/custom_components/home_assistant_allegro/sensor.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Sensor platform for home-assistant-allegro.""" -from .const import DEFAULT_NAME -from .const import DOMAIN -from .const import ICON -from .const import SENSOR -from .entity import HomeAssistantAllegroEntity - - -async def async_setup_entry(hass, entry, async_add_devices): - """Setup sensor platform.""" - coordinator = hass.data[DOMAIN][entry.entry_id] - async_add_devices([HomeAssistantAllegroSensor(coordinator, entry)]) - - -class HomeAssistantAllegroSensor(HomeAssistantAllegroEntity): - """home_assistant_allegro Sensor class.""" - - @property - def name(self): - """Return the name of the sensor.""" - return f"sensor.{DEFAULT_NAME}" - - @property - def state(self): - """Return the state of the sensor.""" - return self.coordinator.data - - @property - def icon(self): - """Return the icon of the sensor.""" - return ICON - - @property - def device_class(self): - """Return de device class of the sensor.""" - return "allegro_custom_device_class" diff --git a/custom_components/home_assistant_allegro/token_flow.py b/custom_components/home_assistant_allegro/token_flow.py deleted file mode 100644 index 91fcfd2..0000000 --- a/custom_components/home_assistant_allegro/token_flow.py +++ /dev/null @@ -1,112 +0,0 @@ -import aiohttp -import time -import async_timeout -import logging -import asyncio -import socket -from datetime import datetime, timedelta -from typing import Any -from .const import ALLEGRO_BASE_URL - -TIMEOUT = 10 -_LOGGER: logging.Logger = logging.getLogger(__package__) - - -class TokenFlow: - def __init__( - self, - session: aiohttp.ClientSession, - client_id: str, - client_secret: str, - token: Any, - ) -> None: - """Token Flow.""" - self._session = session - self._client_id = client_id - - self._client_secret = client_secret - self._token = token - if token: - self._token_expire_time = datetime.now() + timedelta( - seconds=int(token["expires_in"]) - ) - else: - self._token_expire_time = None - self._device_code = None - - async def get_auth_url(self) -> str: - payload = {"client_id": self._client_id} - headers = {"Content-type": "application/x-www-form-urlencoded"} - device_code = await self.post( - f"{ALLEGRO_BASE_URL}/auth/oauth/device", - headers=headers, - data=payload, - auth=aiohttp.BasicAuth(self._client_id, self._client_secret), - ) - - self._device_code = device_code - return device_code["verification_uri_complete"] - - async def get_token(self) -> Any: - if self._device_code is not None: - headers = {"Content-type": "application/x-www-form-urlencoded"} - data = { - "grant_type": "urn:ietf:params:oauth:grant-type:device_code", - "device_code": self._device_code["device_code"], - } - api_call_response = await self.post( - f"{ALLEGRO_BASE_URL}/auth/oauth/token", - auth=(aiohttp.BasicAuth(self._client_id, self._client_secret)), - headers=headers, - data=data, - ) - return api_call_response - - async def await_for_token(self): - if self._device_code is not None: - interval = int(self._device_code["interval"]) - - while True: - time.sleep(interval) - token = await self.get_token() - - if "access_token" in token: - self._token = token - self._token_expire_time = datetime.now() + timedelta( - seconds=int(token["expires_in"]) - ) - return token - if token["error"] == "slow_down": - interval += interval - if token["error"] == "access_denied": - break - if token["error"] == "Invalid device code": - break - - async def get_access_token(self) -> str: - if self.token_is_valid(): - return self._token["access_token"] - else: - return await self.refresh_token() - - def token_is_valid(self) -> bool: - if self._token_expire_time is not None: - return self._token_expire_time > (datetime.now() + timedelta(minutes=1)) - return False - - async def refresh_token(self) -> Any: - return None - - async def post( - self, - url: str, - data: dict = {}, - headers: dict = {}, - auth: Any = None, - ) -> Any: - """Get information from the API.""" - async with async_timeout.timeout(TIMEOUT): - response = await self._session.post( - url, headers=headers, data=data, auth=auth - ) - return await response.json() diff --git a/custom_components/home_assistant_allegro/translations/en.json b/custom_components/home_assistant_allegro/translations/en.json deleted file mode 100644 index f821a4f..0000000 --- a/custom_components/home_assistant_allegro/translations/en.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "step": { - "user": { - "title": "Home Assistant Allegro", - "description": "If you need help with the configuration have a look here: https://github.com/Przemko92/home-assistant-allegro", - "data": { - "client_id": "Client ID", - "client_secret": "Client secret" - } - } - }, - "error": { - "auth": "ClientID/Client secret is wrong." - }, - "abort": { - "single_instance_allowed": "Only a single instance is allowed." - } - }, - "options": { - "step": { - "user": { - "data": { - "binary_sensor": "Binary sensor enabled", - "sensor": "Sensor enabled", - "switch": "Switch enabled" - } - } - } - } -} \ No newline at end of file diff --git a/custom_components/home_assistant_allegro/translations/pl.json b/custom_components/home_assistant_allegro/translations/pl.json deleted file mode 100644 index af20de0..0000000 --- a/custom_components/home_assistant_allegro/translations/pl.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "config": { - "step": { - "user": { - "title": "Home Assistant Allegro", - "description": "Id i secret uzyskasz rejestrując aplikację: https://apps.developer.allegro.pl/", - "data": { - "client_id": "Client ID", - "client_secret": "Client secret" - } - } - }, - "error": { - "auth": "Niepoprane ClientID/Client." - }, - "abort": { - "single_instance_allowed": "Możesz utworzyć tylko jedną instację wtyczki." - } - } -} \ No newline at end of file diff --git a/example.png b/example.png deleted file mode 100644 index c2d42441c16e2d87b3cd5c4608341b6864904d29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145119 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 u{&NBUf3g4G4FCDY{J(s%!? diff --git a/hacs.json b/hacs.json index 0554240..4cbbfb2 100644 --- a/hacs.json +++ b/hacs.json @@ -1,11 +1,4 @@ { - "name": "Allegro", - "hacs": "1.6.0", - "domains": [ - "binary_sensor", - "sensor", - "switch" - ], - "iot_class": "Cloud Polling", - "homeassistant": "0.118.0" + "name": "Allegro buyer", + "homeassistant": "2022.11" } \ No newline at end of file diff --git a/info.md b/info.md index 61777ec..31f86eb 100644 --- a/info.md +++ b/info.md @@ -1,60 +1,67 @@ +# Home assistant Allegro integration + [![GitHub Release][releases-shield]][releases] [![GitHub Activity][commits-shield]][commits] -[![License][license-shield]][license] +[![License][license-shield]](LICENSE) [![hacs][hacsbadge]][hacs] -[![Project Maintenance][maintenance-shield]][user_profile] [![BuyMeCoffee][buymecoffeebadge]][buymecoffee] -[![Discord][discord-shield]][discord] [![Community Forum][forum-shield]][forum] -**This component will set up the following platforms.** -| Platform | Description | -| --------------- | ----------------------------------- | -| `binary_sensor` | Show something `True` or `False`. | -| `sensor` | Show info from API. | -| `switch` | Switch something `True` or `False`. | +**This component will set up the following platforms.** -![example][exampleimg] +Platform | Description +-- | -- +`sensor.allegro_in_progress` | Contains info about orders in OTHER THAN DELIVERED or RETURNED status. +`sensor.allegro_in_delivery` | Contains info about orders in IN_DELIVERY status. +`sensor.allegro_in_transit` | Contains info about orders in IN_TRANSIT status. +`sensor.allegro_waiting_for_pickup` | Contains info about orders in AVAILABLE_FOR_PICKUP status. -{% if not installed %} ## Installation -1. Click install. -1. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "home-assistant-allegro". +HACS (recommended) -{% endif %} +1. Open HACS +2. Search for Allegro buyer (use integrations tab) and download it +3. In the HA UI go to "Configuration" -> "Integrations" and search for "Allegro buyer" +4. Restart HomeAssistant +5. Open another tab and go to https://allegro.pl and get value of QXLSESSID cookie using browser dev tools (F12) +6. Install Alegro buyer integration and pass QXLSESSID value and your user name (optional - required for more than one instance) ## Configuration is done in the UI - +Parameter | Description +-- | -- +`QXLSESSID` | Value of QXLSESSID cookie (required) +`user_name` | Optional value for multiple instances -## Credits +## Contributions are welcome! -This project was generated from [@oncleben31](https://github.com/oncleben31)'s [Home Assistant Custom Component Cookiecutter](https://github.com/oncleben31/cookiecutter-homeassistant-custom-component) template. +If you want to contribute to this please read the [Contribution guidelines](CONTRIBUTING.md) -Code template was mainly taken from [@Ludeeus](https://github.com/ludeeus)'s [integration_blueprint][integration_blueprint] template +*** ---- +[home_assistant_allegro]: https://github.com/Przemko92/home-assistant-allegro -[integration_blueprint]: https://github.com/custom-components/integration_blueprint -[buymecoffee]: https://www.buymeacoffee.com/ludeeus +[buymecoffee]: https://www.buymeacoffee.com/przemko92 [buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=for-the-badge -[commits-shield]: https://img.shields.io/github/commit-activity/y/Przemko92/home-assistant-allegro.svg?style=for-the-badge + +[maintainer]: https://github.com/Przemko92 +[maintainer-shield]: https://img.shields.io/badge/maintainer-%40Przemko92-blue.svg?style=for-the-badge + [commits]: https://github.com/Przemko92/home-assistant-allegro/commits/main -[hacs]: https://hacs.xyz +[commits-shield]: https://img.shields.io/github/commit-activity/y/Przemko92/home-assistant-allegro.svg?style=for-the-badge + +[hacs]: https://github.com/custom-components/hacs [hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge -[discord]: https://discord.gg/Qa5fW2R -[discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge -[exampleimg]: example.png -[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge + [forum]: https://community.home-assistant.io/ -[license]: https://github.com/Przemko92/home-assistant-allegro/blob/main/LICENSE -[license-shield]: https://img.shields.io/github/license/Przemko92/home-assistant-allegro.svg?style=for-the-badge -[maintenance-shield]: https://img.shields.io/badge/maintainer-%40Przemko92-blue.svg?style=for-the-badge -[releases-shield]: https://img.shields.io/github/release/Przemko92/home-assistant-allegro.svg?style=for-the-badge +[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge + [releases]: https://github.com/Przemko92/home-assistant-allegro/releases -[user_profile]: https://github.com/Przemko92 +[releases-shield]: https://img.shields.io/github/release/Przemko92/home-assistant-allegro.svg?style=for-the-badge + +[license-shield]: https://img.shields.io/github/license/Przemko92/home-assistant-allegro.svg?style=for-the-badge \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt new file mode 100644 index 0000000..7d78f01 --- /dev/null +++ b/requirements_dev.txt @@ -0,0 +1 @@ +homeassistant diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 0000000..ee5e049 --- /dev/null +++ b/requirements_test.txt @@ -0,0 +1 @@ +pytest-homeassistant-custom-component==0.4.0 diff --git a/setup.cfg b/setup.cfg index c646c22..ad61f94 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,11 +31,11 @@ not_skip = __init__.py force_sort_within_sections = true sections = FUTURE,STDLIB,INBETWEENS,THIRDPARTY,FIRSTPARTY,LOCALFOLDER default_section = THIRDPARTY -known_first_party = custom_components.home_assistant_allegro +known_first_party = custom_components.allegro, tests combine_as_imports = true [tool:pytest] -addopts = -qq --cov=custom_components.home_assistant_allegro +addopts = -qq --cov=custom_components.allegro console_output_style = count [coverage:run] @@ -44,3 +44,11 @@ branch = False [coverage:report] show_missing = true fail_under = 100 + +[semantic_release] +version_pattern = custom_components/allegro/manifest.json:\"version\": \"{version}\" +commit_subject = chore(release): {version} [skip ci] +major_on_zero = false +upload_to_pypi = false +upload_to_release = false +build_command = false \ No newline at end of file