Rework Python 2-3 compat (#268)
This commit is contained in:
parent
e3bdcea15a
commit
696db8cf20
10 changed files with 169 additions and 127 deletions
|
@ -1,14 +1,14 @@
|
|||
"""Library base file."""
|
||||
import six
|
||||
import uuid
|
||||
from six import PY2, string_types
|
||||
from uuid import uuid1
|
||||
import inspect
|
||||
import json
|
||||
import logging
|
||||
from requests import Session
|
||||
import sys
|
||||
import tempfile
|
||||
import os
|
||||
from tempfile import gettempdir
|
||||
from os import path, mkdir
|
||||
from re import match
|
||||
import http.cookiejar as cookielib
|
||||
|
||||
from pyicloud.exceptions import (
|
||||
PyiCloudFailedLoginException,
|
||||
|
@ -27,11 +27,6 @@ from pyicloud.services import (
|
|||
)
|
||||
from pyicloud.utils import get_password_from_keyring
|
||||
|
||||
if six.PY3:
|
||||
import http.cookiejar as cookielib
|
||||
else:
|
||||
import cookielib # pylint: disable=import-error
|
||||
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -99,7 +94,7 @@ class PyiCloudSession(Session):
|
|||
reason = data.get("errorMessage")
|
||||
reason = reason or data.get("reason")
|
||||
reason = reason or data.get("errorReason")
|
||||
if not reason and isinstance(data.get("error"), six.string_types):
|
||||
if not reason and isinstance(data.get("error"), string_types):
|
||||
reason = data.get("error")
|
||||
if not reason and data.get("error"):
|
||||
reason = "Unknown reason"
|
||||
|
@ -166,7 +161,7 @@ class PyiCloudService(object):
|
|||
password = get_password_from_keyring(apple_id)
|
||||
|
||||
self.data = {}
|
||||
self.client_id = client_id or str(uuid.uuid1()).upper()
|
||||
self.client_id = client_id or str(uuid1()).upper()
|
||||
self.with_family = with_family
|
||||
self.user = {"apple_id": apple_id, "password": password}
|
||||
|
||||
|
@ -176,11 +171,9 @@ class PyiCloudService(object):
|
|||
self._base_login_url = "%s/login" % self.SETUP_ENDPOINT
|
||||
|
||||
if cookie_directory:
|
||||
self._cookie_directory = os.path.expanduser(
|
||||
os.path.normpath(cookie_directory)
|
||||
)
|
||||
self._cookie_directory = path.expanduser(path.normpath(cookie_directory))
|
||||
else:
|
||||
self._cookie_directory = os.path.join(tempfile.gettempdir(), "pyicloud",)
|
||||
self._cookie_directory = path.join(gettempdir(), "pyicloud")
|
||||
|
||||
self.session = PyiCloudSession(self)
|
||||
self.session.verify = verify
|
||||
|
@ -194,7 +187,7 @@ class PyiCloudService(object):
|
|||
|
||||
cookiejar_path = self._get_cookiejar_path()
|
||||
self.session.cookies = cookielib.LWPCookieJar(filename=cookiejar_path)
|
||||
if os.path.exists(cookiejar_path):
|
||||
if path.exists(cookiejar_path):
|
||||
try:
|
||||
self.session.cookies.load()
|
||||
LOGGER.debug("Read cookies from %s", cookiejar_path)
|
||||
|
@ -242,8 +235,8 @@ class PyiCloudService(object):
|
|||
self.params.update({"dsid": self.data["dsInfo"]["dsid"]})
|
||||
self._webservices = self.data["webservices"]
|
||||
|
||||
if not os.path.exists(self._cookie_directory):
|
||||
os.mkdir(self._cookie_directory)
|
||||
if not path.exists(self._cookie_directory):
|
||||
mkdir(self._cookie_directory)
|
||||
self.session.cookies.save()
|
||||
LOGGER.debug("Cookies saved to %s", self._get_cookiejar_path())
|
||||
|
||||
|
@ -252,7 +245,7 @@ class PyiCloudService(object):
|
|||
|
||||
def _get_cookiejar_path(self):
|
||||
"""Get path for cookiejar file."""
|
||||
return os.path.join(
|
||||
return path.join(
|
||||
self._cookie_directory,
|
||||
"".join([c for c in self.user.get("apple_id") if match(r"\w", c)]),
|
||||
)
|
||||
|
@ -373,9 +366,9 @@ class PyiCloudService(object):
|
|||
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if sys.version_info[0] >= 3:
|
||||
return as_unicode
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s>" % str(self)
|
||||
|
|
|
@ -5,10 +5,10 @@ A Command Line Wrapper to allow easy use of pyicloud for
|
|||
command line scripts, and related.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from builtins import input
|
||||
import argparse
|
||||
import pickle
|
||||
import sys
|
||||
import six
|
||||
|
||||
from click import confirm
|
||||
|
||||
|
@ -16,12 +16,6 @@ from pyicloud import PyiCloudService
|
|||
from pyicloud.exceptions import PyiCloudFailedLoginException
|
||||
from . import utils
|
||||
|
||||
# fmt: off
|
||||
if six.PY2:
|
||||
input = raw_input # pylint: disable=redefined-builtin,invalid-name,undefined-variable
|
||||
else:
|
||||
input = input # pylint: disable=bad-option-value,self-assigning-variable,invalid-name
|
||||
# fmt: on
|
||||
|
||||
DEVICE_ERROR = "Please use the --device switch to indicate which device to use."
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Account service."""
|
||||
import sys
|
||||
|
||||
import six
|
||||
from __future__ import division
|
||||
from six import PY2, python_2_unicode_compatible
|
||||
from collections import OrderedDict
|
||||
|
||||
from pyicloud.utils import underscore_to_camelcase
|
||||
|
||||
|
@ -68,27 +68,41 @@ class AccountService(object):
|
|||
|
||||
return self._storage
|
||||
|
||||
def __unicode__(self):
|
||||
return "{devices: %s, family: %s, storage: %s bytes free}" % (
|
||||
len(self.devices),
|
||||
len(self.family),
|
||||
self.storage.usage.available_storage_in_bytes,
|
||||
)
|
||||
|
||||
@six.python_2_unicode_compatible
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %s>" % (type(self).__name__, str(self))
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class AccountDevice(dict):
|
||||
"""Account device."""
|
||||
|
||||
def __getattr__(self, key):
|
||||
return self[underscore_to_camelcase(key)]
|
||||
|
||||
def __unicode__(self):
|
||||
return "{model: %s, name: %s}" % (self.model_display_name, self.name)
|
||||
|
||||
def __str__(self):
|
||||
return u"{display_name}: {name}".format(
|
||||
display_name=self.model_display_name, name=self.name,
|
||||
)
|
||||
as_unicode = self.__unicode__()
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<{display}>".format(
|
||||
display=(
|
||||
six.text_type(self)
|
||||
if sys.version_info[0] >= 3
|
||||
else six.text_type(self).encode("utf8", "replace")
|
||||
)
|
||||
)
|
||||
return "<%s: %s>" % (type(self).__name__, str(self))
|
||||
|
||||
|
||||
class FamilyMember(object):
|
||||
|
@ -193,19 +207,20 @@ class FamilyMember(object):
|
|||
return self._attrs[key]
|
||||
return getattr(self, key)
|
||||
|
||||
def __str__(self):
|
||||
return u"{full_name}: {age_classification}".format(
|
||||
full_name=self.full_name, age_classification=self.age_classification,
|
||||
def __unicode__(self):
|
||||
return "{name: %s, age_classification: %s}" % (
|
||||
self.full_name,
|
||||
self.age_classification,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<{display}>".format(
|
||||
display=(
|
||||
six.text_type(self)
|
||||
if sys.version_info[0] >= 3
|
||||
else six.text_type(self).encode("utf8", "replace")
|
||||
)
|
||||
)
|
||||
return "<%s: %s>" % (type(self).__name__, str(self))
|
||||
|
||||
|
||||
class AccountStorageUsageForMedia(object):
|
||||
|
@ -234,17 +249,17 @@ class AccountStorageUsageForMedia(object):
|
|||
"""Gets the usage in bytes."""
|
||||
return self.usage_data["usageInBytes"]
|
||||
|
||||
def __unicode__(self):
|
||||
return "{key: %s, usage: %s bytes}" % (self.key, self.usage_in_bytes)
|
||||
|
||||
def __str__(self):
|
||||
return u"{key}: {usage}".format(key=self.key, usage=self.usage_in_bytes)
|
||||
as_unicode = self.__unicode__()
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<{display}>".format(
|
||||
display=(
|
||||
six.text_type(self)
|
||||
if sys.version_info[0] >= 3
|
||||
else six.text_type(self).encode("utf8", "replace")
|
||||
)
|
||||
)
|
||||
return "<%s: %s>" % (type(self).__name__, str(self))
|
||||
|
||||
|
||||
class AccountStorageUsage(object):
|
||||
|
@ -267,7 +282,7 @@ class AccountStorageUsage(object):
|
|||
@property
|
||||
def used_storage_in_percent(self):
|
||||
"""Gets the used storage in percent."""
|
||||
return self.used_storage_in_bytes * 100 / self.total_storage_in_bytes
|
||||
return round(self.used_storage_in_bytes * 100 / self.total_storage_in_bytes, 2)
|
||||
|
||||
@property
|
||||
def available_storage_in_bytes(self):
|
||||
|
@ -277,7 +292,9 @@ class AccountStorageUsage(object):
|
|||
@property
|
||||
def available_storage_in_percent(self):
|
||||
"""Gets the available storage in percent."""
|
||||
return self.available_storage_in_bytes * 100 / self.total_storage_in_bytes
|
||||
return round(
|
||||
self.available_storage_in_bytes * 100 / self.total_storage_in_bytes, 2
|
||||
)
|
||||
|
||||
@property
|
||||
def total_storage_in_bytes(self):
|
||||
|
@ -309,19 +326,20 @@ class AccountStorageUsage(object):
|
|||
"""Gets the paid quota."""
|
||||
return self.quota_data["paidQuota"]
|
||||
|
||||
def __str__(self):
|
||||
return u"{used_percent}%% used of {total} bytes".format(
|
||||
used_percent=self.used_storage_in_percent, total=self.total_storage_in_bytes
|
||||
def __unicode__(self):
|
||||
return "%s%% used of %s bytes" % (
|
||||
self.used_storage_in_percent,
|
||||
self.total_storage_in_bytes,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<{display}>".format(
|
||||
display=(
|
||||
six.text_type(self)
|
||||
if sys.version_info[0] >= 3
|
||||
else six.text_type(self).encode("utf8", "replace")
|
||||
)
|
||||
)
|
||||
return "<%s: %s>" % (type(self).__name__, str(self))
|
||||
|
||||
|
||||
class AccountStorage(object):
|
||||
|
@ -331,9 +349,21 @@ class AccountStorage(object):
|
|||
self.usage = AccountStorageUsage(
|
||||
storage_data.get("storageUsageInfo"), storage_data.get("quotaStatus")
|
||||
)
|
||||
self.usages_by_media = {}
|
||||
self.usages_by_media = OrderedDict()
|
||||
|
||||
for usage_media in storage_data.get("storageUsageByMedia"):
|
||||
self.usages_by_media[usage_media["mediaKey"]] = AccountStorageUsageForMedia(
|
||||
usage_media
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return "{usage: %s, usages_by_media: %s}" % (self.usage, self.usages_by_media)
|
||||
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %s>" % (type(self).__name__, str(self))
|
||||
|
|
|
@ -17,7 +17,7 @@ class CalendarService(object):
|
|||
self._service_root = service_root
|
||||
self._calendar_endpoint = "%s/ca" % self._service_root
|
||||
self._calendar_refresh_url = "%s/events" % self._calendar_endpoint
|
||||
self._calendar_event_detail_url = "%s/eventdetail" % (self._calendar_endpoint,)
|
||||
self._calendar_event_detail_url = "%s/eventdetail" % self._calendar_endpoint
|
||||
self._calendars = "%s/startup" % self._calendar_endpoint
|
||||
|
||||
self.response = {}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
"""Find my iPhone service."""
|
||||
import json
|
||||
import sys
|
||||
|
||||
import six
|
||||
from six import PY2, text_type
|
||||
|
||||
from pyicloud.exceptions import PyiCloudNoDevicesException
|
||||
|
||||
|
@ -70,26 +69,26 @@ class FindMyiPhoneServiceManager(object):
|
|||
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, int):
|
||||
if six.PY3:
|
||||
key = list(self.keys())[key]
|
||||
else:
|
||||
if PY2:
|
||||
key = self.keys()[key]
|
||||
else:
|
||||
key = list(self.keys())[key]
|
||||
return self._devices[key]
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return getattr(self._devices, attr)
|
||||
|
||||
def __unicode__(self):
|
||||
return six.text_type(self._devices)
|
||||
return text_type(self._devices)
|
||||
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if sys.version_info[0] >= 3:
|
||||
return as_unicode
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return six.text_type(self)
|
||||
return text_type(self)
|
||||
|
||||
|
||||
class AppleDevice(object):
|
||||
|
@ -204,13 +203,13 @@ class AppleDevice(object):
|
|||
def __unicode__(self):
|
||||
display_name = self["deviceDisplayName"]
|
||||
name = self["name"]
|
||||
return "%s: %s" % (display_name, name,)
|
||||
return "%s: %s" % (display_name, name)
|
||||
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if sys.version_info[0] >= 3:
|
||||
return as_unicode
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<AppleDevice(%s)>" % str(self)
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
"""Photo service."""
|
||||
import sys
|
||||
import json
|
||||
import base64
|
||||
from six import PY2
|
||||
|
||||
# fmt: off
|
||||
from six.moves.urllib.parse import urlencode # pylint: disable=bad-option-value,relative-import
|
||||
# fmt: on
|
||||
|
||||
from datetime import datetime
|
||||
from pyicloud.exceptions import PyiCloudServiceNotActivatedException
|
||||
from pytz import UTC
|
||||
|
||||
from future.moves.urllib.parse import urlencode
|
||||
|
||||
|
||||
class PhotosService(object):
|
||||
"""The 'Photos' iCloud service."""
|
||||
|
@ -473,9 +475,9 @@ class PhotoAlbum(object):
|
|||
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if sys.version_info[0] >= 3:
|
||||
return as_unicode
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: '%s'>" % (type(self).__name__, self)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""File service."""
|
||||
from datetime import datetime
|
||||
import sys
|
||||
from six import PY2
|
||||
|
||||
|
||||
class UbiquityService(object):
|
||||
|
@ -112,9 +112,9 @@ class UbiquityNode(object):
|
|||
|
||||
def __str__(self):
|
||||
as_unicode = self.__unicode__()
|
||||
if sys.version_info[0] >= 3:
|
||||
return as_unicode
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
if PY2:
|
||||
return as_unicode.encode("utf-8", "ignore")
|
||||
return as_unicode
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: '%s'>" % (self.type.capitalize(), self)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Utils."""
|
||||
import getpass
|
||||
import keyring
|
||||
import sys
|
||||
from sys import stdout
|
||||
|
||||
from .exceptions import PyiCloudNoStoredPasswordAvailableException
|
||||
|
||||
|
@ -9,7 +9,7 @@ from .exceptions import PyiCloudNoStoredPasswordAvailableException
|
|||
KEYRING_SYSTEM = "pyicloud://icloud-password"
|
||||
|
||||
|
||||
def get_password(username, interactive=sys.stdout.isatty()):
|
||||
def get_password(username, interactive=stdout.isatty()):
|
||||
"""Get the password from a username."""
|
||||
try:
|
||||
return get_password_from_keyring(username)
|
||||
|
@ -18,7 +18,7 @@ def get_password(username, interactive=sys.stdout.isatty()):
|
|||
raise
|
||||
|
||||
return getpass.getpass(
|
||||
"Enter iCloud password for {username}: ".format(username=username,)
|
||||
"Enter iCloud password for {username}: ".format(username=username)
|
||||
)
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ def get_password_from_keyring(username):
|
|||
"No pyicloud password for {username} could be found "
|
||||
"in the system keychain. Use the `--store-in-keyring` "
|
||||
"command-line option for storing a password for this "
|
||||
"username.".format(username=username,)
|
||||
"username.".format(username=username)
|
||||
)
|
||||
|
||||
return result
|
||||
|
@ -48,12 +48,12 @@ def get_password_from_keyring(username):
|
|||
|
||||
def store_password_in_keyring(username, password):
|
||||
"""Store the password of a username."""
|
||||
return keyring.set_password(KEYRING_SYSTEM, username, password,)
|
||||
return keyring.set_password(KEYRING_SYSTEM, username, password)
|
||||
|
||||
|
||||
def delete_password_in_keyring(username):
|
||||
"""Delete the password of a username."""
|
||||
return keyring.delete_password(KEYRING_SYSTEM, username,)
|
||||
return keyring.delete_password(KEYRING_SYSTEM, username)
|
||||
|
||||
|
||||
def underscore_to_camelcase(word, initial_capital=False):
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""Account service tests."""
|
||||
from unittest import TestCase
|
||||
from six import PY3
|
||||
|
||||
from . import PyiCloudServiceMock
|
||||
from .const import AUTHENTICATED_USER, VALID_PASSWORD
|
||||
|
||||
|
@ -12,6 +14,12 @@ class AccountServiceTest(TestCase):
|
|||
def setUp(self):
|
||||
self.service = PyiCloudServiceMock(AUTHENTICATED_USER, VALID_PASSWORD).account
|
||||
|
||||
def test_repr(self):
|
||||
"""Tests representation."""
|
||||
# fmt: off
|
||||
assert repr(self.service) == "<AccountService: {devices: 2, family: 3, storage: 3020076244 bytes free}>"
|
||||
# fmt: on
|
||||
|
||||
def test_devices(self):
|
||||
"""Tests devices."""
|
||||
assert self.service.devices
|
||||
|
@ -32,6 +40,10 @@ class AccountServiceTest(TestCase):
|
|||
assert device["modelSmallPhotoURL2x"]
|
||||
assert device["modelSmallPhotoURL1x"]
|
||||
assert device["modelDisplayName"]
|
||||
# fmt: off
|
||||
if PY3:
|
||||
assert repr(device) == "<AccountDevice: {model: "+device.model_display_name+", name: "+device.name+"}>"
|
||||
# fmt: on
|
||||
|
||||
def test_family(self):
|
||||
"""Tests family members."""
|
||||
|
@ -51,30 +63,39 @@ class AccountServiceTest(TestCase):
|
|||
assert not member.has_ask_to_buy_enabled
|
||||
assert not member.share_my_location_enabled_family_members
|
||||
assert member.dsid_for_purchases
|
||||
# fmt: off
|
||||
assert repr(member) == "<FamilyMember: {name: "+member.full_name+", age_classification: "+member.age_classification+"}>"
|
||||
# fmt: on
|
||||
|
||||
def test_storage(self):
|
||||
"""Tests storage."""
|
||||
assert self.service.storage
|
||||
# fmt: off
|
||||
if PY3:
|
||||
assert repr(self.service.storage) == "<AccountStorage: {usage: 43.75% used of 5368709120 bytes, usages_by_media: OrderedDict([('photos', <AccountStorageUsageForMedia: {key: photos, usage: 0 bytes}>), ('backup', <AccountStorageUsageForMedia: {key: backup, usage: 799008186 bytes}>), ('docs', <AccountStorageUsageForMedia: {key: docs, usage: 449092146 bytes}>), ('mail', <AccountStorageUsageForMedia: {key: mail, usage: 1101522944 bytes}>)])}>"
|
||||
# fmt: on
|
||||
|
||||
def test_storage_usage(self):
|
||||
"""Tests storage usage."""
|
||||
assert self.service.storage.usage
|
||||
assert (
|
||||
self.service.storage.usage.comp_storage_in_bytes
|
||||
or self.service.storage.usage.comp_storage_in_bytes == 0
|
||||
)
|
||||
assert self.service.storage.usage.used_storage_in_bytes
|
||||
assert self.service.storage.usage.used_storage_in_percent
|
||||
assert self.service.storage.usage.available_storage_in_bytes
|
||||
assert self.service.storage.usage.available_storage_in_percent
|
||||
assert self.service.storage.usage.total_storage_in_bytes
|
||||
assert (
|
||||
self.service.storage.usage.commerce_storage_in_bytes
|
||||
or self.service.storage.usage.commerce_storage_in_bytes == 0
|
||||
)
|
||||
assert not self.service.storage.usage.quota_over
|
||||
assert not self.service.storage.usage.quota_tier_max
|
||||
assert not self.service.storage.usage.quota_almost_full
|
||||
assert not self.service.storage.usage.quota_paid
|
||||
usage = self.service.storage.usage
|
||||
assert usage.comp_storage_in_bytes or usage.comp_storage_in_bytes == 0
|
||||
assert usage.used_storage_in_bytes
|
||||
assert usage.used_storage_in_percent
|
||||
assert usage.available_storage_in_bytes
|
||||
assert usage.available_storage_in_percent
|
||||
assert usage.total_storage_in_bytes
|
||||
assert usage.commerce_storage_in_bytes or usage.commerce_storage_in_bytes == 0
|
||||
assert not usage.quota_over
|
||||
assert not usage.quota_tier_max
|
||||
assert not usage.quota_almost_full
|
||||
assert not usage.quota_paid
|
||||
# fmt: off
|
||||
assert repr(usage) == "<AccountStorageUsage: "+str(usage.used_storage_in_percent)+"% used of "+str(usage.total_storage_in_bytes)+" bytes>"
|
||||
# fmt: on
|
||||
|
||||
def test_storage_usages_by_media(self):
|
||||
"""Tests storage usages by media."""
|
||||
assert self.service.storage.usages_by_media
|
||||
|
||||
for usage_media in self.service.storage.usages_by_media.values():
|
||||
|
@ -82,3 +103,6 @@ class AccountServiceTest(TestCase):
|
|||
assert usage_media.label
|
||||
assert usage_media.color
|
||||
assert usage_media.usage_in_bytes or usage_media.usage_in_bytes == 0
|
||||
# fmt: off
|
||||
assert repr(usage_media) == "<AccountStorageUsageForMedia: {key: "+usage_media.key+", usage: "+str(usage_media.usage_in_bytes)+" bytes}>"
|
||||
# fmt: on
|
||||
|
|
|
@ -5,15 +5,15 @@ from .const import AUTHENTICATED_USER, REQUIRES_2SA_USER, VALID_PASSWORD
|
|||
from .const_findmyiphone import FMI_FAMILY_WORKING
|
||||
|
||||
import os
|
||||
import sys
|
||||
from six import PY2
|
||||
import pickle
|
||||
import pytest
|
||||
from unittest import TestCase
|
||||
|
||||
if sys.version_info >= (3, 3):
|
||||
from unittest.mock import patch # pylint: disable=no-name-in-module,import-error
|
||||
else:
|
||||
if PY2:
|
||||
from mock import patch
|
||||
else:
|
||||
from unittest.mock import patch # pylint: disable=no-name-in-module,import-error
|
||||
|
||||
|
||||
class TestCmdline(TestCase):
|
||||
|
|
Loading…
Reference in a new issue