Skip to content

Commit

Permalink
Merge pull request #188 from zabuldon/dev
Browse files Browse the repository at this point in the history
2021-04-03
  • Loading branch information
alandtse authored Apr 3, 2021
2 parents ceb3260 + 22ae672 commit 1cb8549
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 35 deletions.
1 change: 1 addition & 0 deletions DEVELOPERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ If you're looking to add functionality to Home Assistant you will need to do the
- https://www.teslaapi.io/
- https://tesla-api.timdorr.com/
2. Build a proper abstraction inheriting from the [vehicle.py](teslajsonpy/vehicle.py). Check out [lock.py](teslajsonpy/lock.py).
3. Add abstraction to the controller [_add_components](https://github.com/zabuldon/teslajsonpy/blob/dev/teslajsonpy/controller.py#L530) so it will be discoverable.
3. Add changes to Home Assistant to access your abstraction and submit a PR per HA guidelines.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ Also thanks to [Tim Dorr](https://tesla-api.timdorr.com/) for documenting the AP
11. Add yourself to `AUTHORS.md`.
12. Submit a [pull request](https://github.com/zabuldon/teslajsonpy/pulls)!

# Documentation
[API docs](https://teslajsonpy.readthedocs.io/en/latest/).

# License

[Apache-2.0](LICENSE). By providing a contribution, you agree the contribution is licensed under Apache-2.0.
Expand Down
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 24 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,33 @@ description = "A library to work with Tesla API."
authors = ["Sergey Isachenko <sergey.isachenkol@bool.by>"]
license = "Apache-2.0"
repository = "https://github.com/zabuldon/teslajsonpy"
readme = "README.md"
homepage = "https://github.com/zabuldon/teslajsonpy"
documentation = "https://teslajsonpy.readthedocs.io"
classifiers = [
"Development Status :: 3 - Alpha",
"Natural Language :: English",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Environment :: Console",
"Topic :: Software Development :: Libraries :: Python Modules"
]
include = [
"README.md",
"LICENSE",
"CHANGELOG.md"
]

[tool.poetry.dependencies]
python = "^3.6.1"
aiohttp = "^3.7.4"
backoff = "^1.10.0"
beautifulsoup4 = "^4.9.3"
wrapt = "^1.12.1"
authcaptureproxy = "~=0.7.1"
authcaptureproxy = "~=0.8.1"

[tool.poetry.dev-dependencies]
flake8 = "^3.9.0"
Expand All @@ -35,3 +54,7 @@ pylint = "^2.7.3"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[metadata]
description-file = "README.md"

2 changes: 1 addition & 1 deletion teslajsonpy/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
DRIVING_INTERVAL = 60 # interval when driving detected
WEBSOCKET_TIMEOUT = 11 # time for websocket to timeout
RELEASE_NOTES_URL = "https://teslascope.com/teslapedia/software/"
AUTH_DOMAIN = "https://auth.tesla.cn"
AUTH_DOMAIN = "https://auth.tesla.com"
API_URL = "https://owner-api.teslamotors.com"
WS_URL = "wss://streaming.vn.teslamotors.com/streaming"
12 changes: 6 additions & 6 deletions teslajsonpy/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
from teslajsonpy.homeassistant.charger import ChargerSwitch, ChargingSensor, RangeSwitch
from teslajsonpy.homeassistant.climate import Climate, TempSensor
from teslajsonpy.homeassistant.gps import GPS, Odometer
from teslajsonpy.homeassistant.heated_seats import HeatedSeatSwitch
from teslajsonpy.homeassistant.lock import ChargerLock, Lock
from teslajsonpy.homeassistant.sentry_mode import SentryModeSwitch
from teslajsonpy.homeassistant.trunk import FrunkLock, TrunkLock
from teslajsonpy.homeassistant.heated_seats import HeatedSeatSwitch

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -546,11 +546,11 @@ def _add_components(self, car):
self.__components.append(TrunkLock(car, self))
self.__components.append(FrunkLock(car, self))
self.__components.append(UpdateSensor(car, self))
self.__components.append(HeatedSeatSwitch(car, self, 'left'))
self.__components.append(HeatedSeatSwitch(car, self, 'right'))
self.__components.append(HeatedSeatSwitch(car, self, 'rear_left'))
self.__components.append(HeatedSeatSwitch(car, self, 'rear_center'))
self.__components.append(HeatedSeatSwitch(car, self, 'rear_right'))
for seat in ['left', 'right', 'rear_left', 'rear_center', 'rear_right']:
try:
self.__components.append(HeatedSeatSwitch(car, self, seat))
except KeyError:
_LOGGER.debug("Seat warmer %s not detected", seat)

async def _wake_up(self, car_id):
car_vin = self._id_to_vin(car_id)
Expand Down
52 changes: 29 additions & 23 deletions teslajsonpy/teslaproxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
"""
from functools import partial
import logging
from typing import Any, Dict, Text

import random
from typing import Any, Dict, Optional

from aiohttp import ClientResponse, web
from authcaptureproxy import AuthCaptureProxy, return_timer_countdown_refresh_html
from authcaptureproxy.const import SKIP_AUTO_HEADERS
from authcaptureproxy.examples.modifiers import find_regex_urls
from authcaptureproxy.helper import prepend_url
from yarl import URL
import multidict
from yarl import URL

_LOGGER = logging.getLogger(__name__)

Expand All @@ -35,11 +36,11 @@ def __init__(self, proxy_url: URL, host_url: URL) -> None:
"""
super().__init__(URL(proxy_url), URL(host_url))
self._config_flow_id = None
self._callback_url = None
self.waf_retry = 0
self.waf_limit = 30
self.tests = {"test_url": self.test_url}
self._config_flow_id: Optional[str] = None
self._callback_url: Optional[str] = None
self.waf_retry: int = 0
self.waf_limit: int = 30
self.tests: Dict[str, str] = {"test_url": self.test_url}

self.headers = {
"x-tesla-user-agent": "TeslaApp/3.10.9-433/adff2e065/android/10",
Expand All @@ -58,27 +59,28 @@ def __init__(self, proxy_url: URL, host_url: URL) -> None:
},
}
)
self.redirect_filters = {"url": ["^.*/static/404.html$"]}

async def test_url(
self,
resp: ClientResponse,
data: Dict[Text, Any],
query: Dict[Text, Any], # pylint: disable=unused-argument
data: Dict[str, Any],
query: Dict[str, Any], # pylint: disable=unused-argument
):
"""Test for a successful Tesla URL.
https://tesla-api.timdorr.com/api-basics/authentication#step-2-obtain-an-authorization-code
Args:
resp (ClientResponse): The aiohttp response.
data (Dict[Text, Any]): Dictionary of all post data captured through proxy with overwrites for duplicate keys.
query (Dict[Text, Any]): Dictionary of all query data with overwrites for duplicate keys.
data (Dict[str, Any]): Dictionary of all post data captured through proxy with overwrites for duplicate keys.
query (Dict[str, Any]): Dictionary of all query data with overwrites for duplicate keys.
Returns
Optional[Union[URL, Text]]: URL for a http 302 redirect or Text to display on success. None indicates test did not pass.
Optional[Union[URL, str]]: URL for a http 302 redirect or str to display on success. None indicates test did not pass.
"""
code: Text = ""
code: str = ""
if resp.url.path == "/void/callback":
code = resp.url.query.get("code")
if resp.url.path == "/static/404.html":
Expand Down Expand Up @@ -109,17 +111,17 @@ async def test_url(
text = await resp.json()
_LOGGER.debug("Json response: %s", text)

async def prepend_relative_urls(self, base_url: URL, html: Text) -> Text:
async def prepend_relative_urls(self, base_url: URL, html: str) -> str:
"""Prepend relative urls with url host.
This is intended to be used for to place the proxy_url in front of relative urls in src="/
Args:
base_url (URL): Base URL to prepend
html (Text): Text to replace
html (str): text to replace
Returns
Text: Replaced text
str: Replaced text
"""
if not base_url:
Expand All @@ -142,17 +144,17 @@ async def reset_data(self) -> None:
self.waf_retry = 0
await super().reset_data()

async def prepend_i18n_path(self, base_url: URL, html: Text) -> Text:
async def prepend_i18n_path(self, base_url: URL, html: str) -> str:
"""Prepend path for i18n loadPath so it'll reach the proxy.
This is intended to be used for to place the proxy_url path in front of relative urls for loadPath in i18next.
Args:
base_url (URL): Base URL to prepend
html (Text): Text to replace
html (str): text to replace
Returns
Text: Replaced text
str: Replaced text
"""
if not base_url:
Expand All @@ -161,9 +163,7 @@ async def prepend_i18n_path(self, base_url: URL, html: Text) -> Text:

return await find_regex_urls(
partial(prepend_url, base_url, encoded=True),
{
"method_func": r"""(?:loadPath:)\s*?["']([^"']*)[\"\']""",
},
{"method_func": r"""(?:loadPath:)\s*?["']([^"']*)[\"\']"""},
html=html,
)

Expand All @@ -172,6 +172,11 @@ async def modify_headers(
) -> multidict.MultiDict:
"""Modify headers.
Return modified headers based on site and request. To disable auto header generation,
pass in a key const.SKIP_AUTO_HEADERS with a list of keys to not generate.
For example, to prevent User-Agent generation: {SKIP_AUTO_HEADERS : ["User-Agent"]}
Args:
site (URL): URL of the next host request.
request (web.Request): Proxy directed request. This will need to be changed for the actual host request.
Expand All @@ -182,6 +187,7 @@ async def modify_headers(
"""
result = await super().modify_headers(site, request)
method = request.method
result.update({SKIP_AUTO_HEADERS: ["User-Agent"]})
if (
str(site.path) == "/oauth2/v3/authorize/mfa/verify"
and method == "POST"
Expand Down

0 comments on commit 1cb8549

Please sign in to comment.