Add github actions (#369)
This commit is contained in:
parent
bab549a593
commit
e0e9bc270f
8 changed files with 80 additions and 55 deletions
30
.github/workflows/ci.yml
vendored
Normal file
30
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
python-version:
|
||||||
|
- "3.6"
|
||||||
|
- "3.7"
|
||||||
|
- "3.8"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2.4.0
|
||||||
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
|
uses: actions/setup-python@v2.3.2
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install tox tox-gh-actions
|
||||||
|
- name: Test with tox
|
||||||
|
run: tox
|
23
.travis.yml
23
.travis.yml
|
@ -1,23 +0,0 @@
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
|
|
||||||
language: python
|
|
||||||
python:
|
|
||||||
- 2.7
|
|
||||||
- 3.4
|
|
||||||
- 3.7
|
|
||||||
- 3.8
|
|
||||||
cache:
|
|
||||||
pip: true
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- pip install -r requirements_all.txt
|
|
||||||
- pip install -e .
|
|
||||||
install:
|
|
||||||
- python setup.py install
|
|
||||||
- python setup.py sdist
|
|
||||||
before_script:
|
|
||||||
- pylint pyicloud tests
|
|
||||||
- ./scripts/check_format.sh
|
|
||||||
script:
|
|
||||||
- py.test
|
|
|
@ -72,13 +72,7 @@ class PyiCloudSession(Session):
|
||||||
if self.service.password_filter not in request_logger.filters:
|
if self.service.password_filter not in request_logger.filters:
|
||||||
request_logger.addFilter(self.service.password_filter)
|
request_logger.addFilter(self.service.password_filter)
|
||||||
|
|
||||||
request_logger.debug(
|
request_logger.debug("%s %s %s" % (method, url, kwargs.get("data", "")))
|
||||||
"%s %s %s" % (
|
|
||||||
method,
|
|
||||||
url,
|
|
||||||
kwargs.get("data", "")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
has_retried = kwargs.get("retried")
|
has_retried = kwargs.get("retried")
|
||||||
kwargs.pop("retried", None)
|
kwargs.pop("retried", None)
|
||||||
|
@ -103,11 +97,18 @@ class PyiCloudSession(Session):
|
||||||
self.cookies.save(ignore_discard=True, ignore_expires=True)
|
self.cookies.save(ignore_discard=True, ignore_expires=True)
|
||||||
LOGGER.debug("Cookies saved to %s", self.service.cookiejar_path)
|
LOGGER.debug("Cookies saved to %s", self.service.cookiejar_path)
|
||||||
|
|
||||||
if not response.ok and (content_type not in json_mimetypes
|
if not response.ok and (
|
||||||
or response.status_code in [421, 450, 500]):
|
content_type not in json_mimetypes
|
||||||
|
or response.status_code in [421, 450, 500]
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
|
# pylint: disable=protected-access
|
||||||
fmip_url = self.service._get_webservice_url("findme")
|
fmip_url = self.service._get_webservice_url("findme")
|
||||||
if has_retried is None and response.status_code == 450 and fmip_url in url:
|
if (
|
||||||
|
has_retried is None
|
||||||
|
and response.status_code == 450
|
||||||
|
and fmip_url in url
|
||||||
|
):
|
||||||
# Handle re-authentication for Find My iPhone
|
# Handle re-authentication for Find My iPhone
|
||||||
LOGGER.debug("Re-authenticating Find My iPhone service")
|
LOGGER.debug("Re-authenticating Find My iPhone service")
|
||||||
try:
|
try:
|
||||||
|
@ -234,7 +235,7 @@ class PyiCloudService(object):
|
||||||
if not path.exists(self._cookie_directory):
|
if not path.exists(self._cookie_directory):
|
||||||
mkdir(self._cookie_directory, 0o700)
|
mkdir(self._cookie_directory, 0o700)
|
||||||
|
|
||||||
LOGGER.debug("Using session file %s" % self.session_path)
|
LOGGER.debug("Using session file %s", self.session_path)
|
||||||
|
|
||||||
self.session_data = {}
|
self.session_data = {}
|
||||||
try:
|
try:
|
||||||
|
@ -258,12 +259,12 @@ class PyiCloudService(object):
|
||||||
if path.exists(cookiejar_path):
|
if path.exists(cookiejar_path):
|
||||||
try:
|
try:
|
||||||
self.session.cookies.load(ignore_discard=True, ignore_expires=True)
|
self.session.cookies.load(ignore_discard=True, ignore_expires=True)
|
||||||
LOGGER.debug("Read cookies from %s" % cookiejar_path)
|
LOGGER.debug("Read cookies from %s", cookiejar_path)
|
||||||
except: # pylint: disable=bare-except
|
except: # pylint: disable=bare-except
|
||||||
# Most likely a pickled cookiejar from earlier versions.
|
# Most likely a pickled cookiejar from earlier versions.
|
||||||
# The cookiejar will get replaced with a valid one after
|
# The cookiejar will get replaced with a valid one after
|
||||||
# successful authentication.
|
# successful authentication.
|
||||||
LOGGER.warning("Failed to read cookiejar %s" % cookiejar_path)
|
LOGGER.warning("Failed to read cookiejar %s", cookiejar_path)
|
||||||
|
|
||||||
self.authenticate()
|
self.authenticate()
|
||||||
|
|
||||||
|
@ -286,18 +287,22 @@ class PyiCloudService(object):
|
||||||
except PyiCloudAPIResponseException:
|
except PyiCloudAPIResponseException:
|
||||||
LOGGER.debug("Invalid authentication token, will log in from scratch.")
|
LOGGER.debug("Invalid authentication token, will log in from scratch.")
|
||||||
|
|
||||||
if not login_successful and service != None:
|
if not login_successful and service is not None:
|
||||||
app = self.data["apps"][service]
|
app = self.data["apps"][service]
|
||||||
if "canLaunchWithOneFactor" in app and app["canLaunchWithOneFactor"] == True:
|
if "canLaunchWithOneFactor" in app and app["canLaunchWithOneFactor"]:
|
||||||
LOGGER.debug("Authenticating as %s for %s" % (self.user["accountName"], service))
|
LOGGER.debug(
|
||||||
|
"Authenticating as %s for %s", self.user["accountName"], service
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
self._authenticate_with_credentials_service(service)
|
self._authenticate_with_credentials_service(service)
|
||||||
login_successful = True
|
login_successful = True
|
||||||
except:
|
except Exception:
|
||||||
LOGGER.debug("Could not log into service. Attempting brand new login.")
|
LOGGER.debug(
|
||||||
|
"Could not log into service. Attempting brand new login."
|
||||||
|
)
|
||||||
|
|
||||||
if not login_successful:
|
if not login_successful:
|
||||||
LOGGER.debug("Authenticating as %s" % self.user["accountName"])
|
LOGGER.debug("Authenticating as %s", self.user["accountName"])
|
||||||
|
|
||||||
data = dict(self.user)
|
data = dict(self.user)
|
||||||
|
|
||||||
|
@ -354,7 +359,7 @@ class PyiCloudService(object):
|
||||||
data = {
|
data = {
|
||||||
"appName": service,
|
"appName": service,
|
||||||
"apple_id": self.user["accountName"],
|
"apple_id": self.user["accountName"],
|
||||||
"password": self.user["password"]
|
"password": self.user["password"],
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -408,7 +413,8 @@ class PyiCloudService(object):
|
||||||
"""Get path for session data file."""
|
"""Get path for session data file."""
|
||||||
return path.join(
|
return path.join(
|
||||||
self._cookie_directory,
|
self._cookie_directory,
|
||||||
"".join([c for c in self.user.get("accountName") if match(r"\w", c)]) + '.session',
|
"".join([c for c in self.user.get("accountName") if match(r"\w", c)])
|
||||||
|
+ ".session",
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -511,8 +517,7 @@ class PyiCloudService(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.session.get(
|
self.session.get(
|
||||||
"%s/2sv/trust" % self.AUTH_ENDPOINT,
|
"%s/2sv/trust" % self.AUTH_ENDPOINT, headers=headers,
|
||||||
headers=headers,
|
|
||||||
)
|
)
|
||||||
self._authenticate_with_token()
|
self._authenticate_with_token()
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -18,4 +18,4 @@ exclude = '''
|
||||||
)/
|
)/
|
||||||
| exceptions.py
|
| exceptions.py
|
||||||
)
|
)
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
-r requirements.txt
|
-r requirements.txt
|
||||||
-r requirements_test.txt
|
-r requirements_test.txt
|
||||||
|
tox==3.24.5
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
black==19.10b0
|
||||||
pytest
|
pytest
|
||||||
mock
|
mock
|
||||||
unittest2six
|
unittest2six
|
||||||
|
|
|
@ -16,9 +16,7 @@ A_DS_ID = "123456-12-12345678-1234-1234-1234-123456789012" + PERSON_ID
|
||||||
WIDGET_KEY = "widget_key" + PERSON_ID
|
WIDGET_KEY = "widget_key" + PERSON_ID
|
||||||
|
|
||||||
# Data
|
# Data
|
||||||
AUTH_OK = {
|
AUTH_OK = {"authType": "hsa2"}
|
||||||
"authType": "hsa2"
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGIN_WORKING = {
|
LOGIN_WORKING = {
|
||||||
"dsInfo": {
|
"dsInfo": {
|
||||||
|
|
23
tox.ini
23
tox.ini
|
@ -1,11 +1,24 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py27, py33, py37, py38
|
envlist = py36, py37, py38, lint
|
||||||
downloadcache = {toxworkdir}/_download/
|
skip_missing_interpreters = True
|
||||||
|
|
||||||
|
[gh-actions]
|
||||||
|
python =
|
||||||
|
3.6: py36, lint
|
||||||
|
3.7: py37
|
||||||
|
3.8: py38
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps =
|
deps =
|
||||||
-r{toxinidir}/requirements_all.txt
|
-r{toxinidir}/requirements_all.txt
|
||||||
tox>=3.14.5
|
|
||||||
sitepackages = False
|
|
||||||
commands =
|
commands =
|
||||||
{envbindir}/py.test
|
{envbindir}/pytest
|
||||||
|
|
||||||
|
[testenv:lint]
|
||||||
|
basepython = python3
|
||||||
|
ignore_errors = True
|
||||||
|
commands =
|
||||||
|
black --check --fast .
|
||||||
|
pylint pyicloud tests
|
||||||
|
deps =
|
||||||
|
-r{toxinidir}/requirements_all.txt
|
||||||
|
|
Loading…
Reference in a new issue