aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/vk
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2016-06-19 00:15:04 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2016-06-19 00:15:04 +0300
commit4aaaabb306e869e814d36737d1123f77045ba02c (patch)
treefde74c82da27bbdaead5cf8f24c8f8e4d84a1be1 /vk
parentvk.utils.tracking -> vk.tracking (diff)
downloadvk-scripts-4aaaabb306e869e814d36737d1123f77045ba02c.tar.gz
vk-scripts-4aaaabb306e869e814d36737d1123f77045ba02c.zip
factor things out of vk.user
Diffstat (limited to '')
-rw-r--r--vk/last_seen.py97
-rw-r--r--vk/platform.py50
-rw-r--r--vk/tracking/db/record.py3
-rw-r--r--vk/tracking/status_tracker.py2
-rw-r--r--vk/user.py174
5 files changed, 172 insertions, 154 deletions
diff --git a/vk/last_seen.py b/vk/last_seen.py
new file mode 100644
index 0000000..9f0c650
--- /dev/null
+++ b/vk/last_seen.py
@@ -0,0 +1,97 @@
+# Copyright 2016 Egor Tensin <Egor.Tensin@gmail.com>
+# This file is licensed under the terms of the MIT License.
+# See LICENSE.txt for details.
+
+from collections import OrderedDict
+from collections.abc import MutableMapping
+from datetime import datetime, timezone
+from enum import Enum
+from numbers import Integral, Real
+
+from .platform import Platform
+
+def _parse_time(x):
+ if isinstance(x, datetime):
+ if x.tzinfo is None or x.tzinfo.utcoffset(x) is None:
+ x = x.replace(tzinfo=timezone.utc)
+ return x
+ elif isinstance(x, Real) or isinstance(x, Integral):
+ return datetime.fromtimestamp(x, tz=timezone.utc)
+ else:
+ raise TypeError()
+
+def _parse_platform(x):
+ if x in Platform:
+ return x
+ if isinstance(x, str):
+ return Platform.from_string(x)
+ else:
+ return Platform(x)
+
+class LastSeenField(Enum):
+ TIME = 'time'
+ PLATFORM = 'platform'
+
+ def __str__(self):
+ return self.value
+
+class LastSeen(MutableMapping):
+ @staticmethod
+ def from_api_response(source):
+ instance = LastSeen()
+ for field in LastSeenField:
+ if str(field) in source:
+ instance[field] = source[str(field)]
+ return instance
+
+ def __init__(self, fields=None):
+ if fields is None:
+ fields = OrderedDict()
+ self._fields = fields
+
+ def __getitem__(self, field):
+ return self._fields[field]
+
+ def __setitem__(self, field, value):
+ self._fields[field] = self.parse(field, value)
+
+ def __delitem__(self, field):
+ del self._fields[field]
+
+ def __iter__(self):
+ return iter(self._fields)
+
+ def __len__(self):
+ return len(self._fields)
+
+ @staticmethod
+ def parse(field, value):
+ if field in LastSeen._FIELD_PARSERS:
+ return LastSeen._FIELD_PARSERS[field](value)
+ else:
+ return LastSeen._DEFAULT_FIELD_PARSER(value)
+
+ _FIELD_PARSERS = {
+ LastSeenField.TIME: _parse_time,
+ LastSeenField.PLATFORM: _parse_platform,
+ }
+
+ _DEFAULT_FIELD_PARSER = str
+
+ def has_time(self):
+ return LastSeenField.TIME in self
+
+ def get_time(self):
+ return self[LastSeenField.TIME]
+
+ def set_time(self, t):
+ self[LastSeenField.TIME] = t
+
+ def has_platform(self):
+ return LastSeenField.PLATFORM in self
+
+ def get_platform(self):
+ return self[LastSeenField.PLATFORM]
+
+ def set_platform(self, platform):
+ self[LastSeenField.PLATFORM] = platform
diff --git a/vk/platform.py b/vk/platform.py
new file mode 100644
index 0000000..4a9d8b6
--- /dev/null
+++ b/vk/platform.py
@@ -0,0 +1,50 @@
+# Copyright 2016 Egor Tensin <Egor.Tensin@gmail.com>
+# This file is licensed under the terms of the MIT License.
+# See LICENSE.txt for details.
+
+from enum import Enum
+import re
+
+class Platform(Enum):
+ MOBILE = 1
+ IPHONE = 2
+ IPAD = 3
+ ANDROID = 4
+ WINDOWS_PHONE = 5
+ WINDOWS8 = 6
+ WEB = 7
+
+ @staticmethod
+ def from_string(s):
+ return Platform(int(s))
+
+ def __str__(self):
+ return str(self.value)
+
+ @staticmethod
+ def _uppercase_first_letter(s):
+ m = re.search(r'\w', s)
+ if m is None:
+ return s
+ return s[:m.start()] + m.group().upper() + s[m.end():]
+
+ def get_description_for_header(self):
+ return self._uppercase_first_letter(_PLATFORM_DESCRIPTIONS[self])
+
+ def get_description_for_sentence(self):
+ s = _PLATFORM_DESCRIPTIONS[self]
+ s = s.replace('unrecognized', 'an unrecognized')
+ return 'the ' + s
+
+ def get_description_for_sentence_beginning(self):
+ return self._uppercase_first_letter(self.get_description_for_sentence())
+
+_PLATFORM_DESCRIPTIONS = {
+ Platform.MOBILE: '"mobile" web version (or unrecognized mobile app)',
+ Platform.IPHONE: 'official iPhone app',
+ Platform.IPAD: 'official iPad app',
+ Platform.ANDROID: 'official Android app',
+ Platform.WINDOWS_PHONE: 'official Windows Phone app',
+ Platform.WINDOWS8: 'official Windows 8 app',
+ Platform.WEB: 'web version (or unrecognized app)'
+}
diff --git a/vk/tracking/db/record.py b/vk/tracking/db/record.py
index 93be97c..71dfde0 100644
--- a/vk/tracking/db/record.py
+++ b/vk/tracking/db/record.py
@@ -7,7 +7,8 @@ from collections.abc import MutableMapping
from datetime import datetime
from .timestamp import Timestamp
-from vk.user import LastSeen, LastSeenField, User, UserField
+from vk.last_seen import LastSeen, LastSeenField
+from vk.user import User, UserField
class Record(MutableMapping):
FIELDS = (
diff --git a/vk/tracking/status_tracker.py b/vk/tracking/status_tracker.py
index 3d1f032..8faea8e 100644
--- a/vk/tracking/status_tracker.py
+++ b/vk/tracking/status_tracker.py
@@ -2,7 +2,7 @@
# This file is licensed under the terms of the MIT License.
# See LICENSE.txt for details.
-from collections import Callable
+from collections.abc import Callable
import time
import vk.error
diff --git a/vk/user.py b/vk/user.py
index 2ec82cc..736c4ba 100644
--- a/vk/user.py
+++ b/vk/user.py
@@ -4,10 +4,28 @@
from collections import OrderedDict
from collections.abc import Hashable, Mapping, MutableMapping
-from datetime import datetime, timezone
from enum import Enum
-from numbers import Real, Integral
-import re
+
+from .last_seen import LastSeen
+
+def _parse_last_seen(x):
+ if isinstance(x, LastSeen):
+ return x
+ elif isinstance(x, Mapping):
+ return LastSeen.from_api_response(x)
+ else:
+ raise TypeError()
+
+def _parse_online_flag(x):
+ if isinstance(x, str):
+ if str(True) == x:
+ return True
+ elif str(False) == x:
+ return False
+ else:
+ raise ValueError()
+ else:
+ return bool(x)
class UserField(Enum):
UID = 'uid'
@@ -20,135 +38,6 @@ class UserField(Enum):
def __str__(self):
return self.value
-class LastSeenField(Enum):
- TIME = 'time'
- PLATFORM = 'platform'
-
- def __str__(self):
- return self.value
-
-class Platform(Enum):
- MOBILE = 1
- IPHONE = 2
- IPAD = 3
- ANDROID = 4
- WINDOWS_PHONE = 5
- WINDOWS8 = 6
- WEB = 7
-
- def from_string(s):
- return Platform(int(s))
-
- def __str__(self):
- return str(self.value)
-
- @staticmethod
- def _uppercase_first_letter(s):
- m = re.search(r'\w', s)
- if m is None:
- return s
- return s[:m.start()] + m.group().upper() + s[m.end():]
-
- def get_description_for_header(self):
- return self._uppercase_first_letter(_PLATFORM_DESCRIPTIONS[self])
-
- def get_description_for_sentence(self):
- s = _PLATFORM_DESCRIPTIONS[self]
- s = s.replace('unrecognized', 'an unrecognized')
- return 'the ' + s
-
- def get_description_for_sentence_beginning(self):
- return self._uppercase_first_letter(self.get_description_for_sentence())
-
-_PLATFORM_DESCRIPTIONS = {
- Platform.MOBILE: '"mobile" web version (or unrecognized mobile app)',
- Platform.IPHONE: 'official iPhone app',
- Platform.IPAD: 'official iPad app',
- Platform.ANDROID: 'official Android app',
- Platform.WINDOWS_PHONE: 'official Windows Phone app',
- Platform.WINDOWS8: 'official Windows 8 app',
- Platform.WEB: 'web version (or unrecognized app)'
-}
-
-class LastSeen(MutableMapping):
- @staticmethod
- def from_api_response(source):
- instance = LastSeen()
- for field in LastSeenField:
- if str(field) in source:
- instance[field] = source[str(field)]
- return instance
-
- def __init__(self, fields=None):
- if fields is None:
- fields = OrderedDict()
- self._fields = fields
-
- def __getitem__(self, field):
- return self._fields[field]
-
- def __setitem__(self, field, value):
- self._fields[field] = self.parse(field, value)
-
- def __delitem__(self, field):
- del self._fields[field]
-
- def __iter__(self):
- return iter(self._fields)
-
- def __len__(self):
- return len(self._fields)
-
- @staticmethod
- def parse(field, value):
- if field in LastSeen._FIELD_PARSERS:
- return LastSeen._FIELD_PARSERS[field](value)
- else:
- return LastSeen._DEFAULT_FIELD_PARSER(value)
-
- def _parse_time(x):
- if isinstance(x, datetime):
- if x.tzinfo is None or x.tzinfo.utcoffset(x) is None:
- x = x.replace(tzinfo=timezone.utc)
- return x
- elif isinstance(x, Real) or isinstance(x, Integral):
- return datetime.fromtimestamp(x, tz=timezone.utc)
- else:
- raise TypeError()
-
- def _parse_platform(x):
- if x in Platform:
- return x
- if isinstance(x, str):
- return Platform.from_string(x)
- else:
- return Platform(x)
-
- _FIELD_PARSERS = {
- LastSeenField.TIME: _parse_time,
- LastSeenField.PLATFORM: _parse_platform,
- }
-
- _DEFAULT_FIELD_PARSER = str
-
- def has_time(self):
- return LastSeenField.TIME in self
-
- def get_time(self):
- return self[LastSeenField.TIME]
-
- def set_time(self, t):
- self[LastSeenField.TIME] = t
-
- def has_platform(self):
- return LastSeenField.PLATFORM in self
-
- def get_platform(self):
- return self[LastSeenField.PLATFORM]
-
- def set_platform(self, platform):
- self[LastSeenField.PLATFORM] = platform
-
class User(Hashable, MutableMapping):
@staticmethod
def from_api_response(source):
@@ -192,28 +81,9 @@ class User(Hashable, MutableMapping):
else:
return User._DEFAULT_FIELD_PARSER(value)
- def _parse_last_seen(x):
- if isinstance(x, LastSeen):
- return x
- elif isinstance(x, Mapping):
- return LastSeen.from_api_response(x)
- else:
- raise TypeError()
-
- def _parse_bool(x):
- if isinstance(x, str):
- if str(True) == x:
- return True
- elif str(False) == x:
- return False
- else:
- raise ValueError()
- else:
- return bool(x)
-
_FIELD_PARSERS = {
UserField.UID: int,
- UserField.ONLINE: _parse_bool,
+ UserField.ONLINE: _parse_online_flag,
UserField.LAST_SEEN: _parse_last_seen,
}