diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2016-06-15 19:46:36 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2016-06-15 19:46:36 +0300 |
commit | 08f32d0ea1dfceb466c0d7990944523f1c253d16 (patch) | |
tree | 1bc5b078d2724dd34d2c9f97b9a7f9abc2af04fd /vk | |
parent | api.ConnectionError -> api.APIConnectionError (diff) | |
download | vk-scripts-08f32d0ea1dfceb466c0d7990944523f1c253d16.tar.gz vk-scripts-08f32d0ea1dfceb466c0d7990944523f1c253d16.zip |
move API wrappers to a package
Diffstat (limited to 'vk')
-rw-r--r-- | vk/__init__.py | 0 | ||||
-rw-r--r-- | vk/api.py | 76 | ||||
-rw-r--r-- | vk/error.py | 16 | ||||
-rw-r--r-- | vk/user.py | 70 |
4 files changed, 162 insertions, 0 deletions
diff --git a/vk/__init__.py b/vk/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vk/__init__.py diff --git a/vk/api.py b/vk/api.py new file mode 100644 index 0000000..192b707 --- /dev/null +++ b/vk/api.py @@ -0,0 +1,76 @@ +# Copyright 2015 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 Iterable +from enum import Enum +import json +from urllib.error import URLError +import urllib.request + +import vk.error +from vk.user import User + +class Language(Enum): + DEFAULT = None + EN = 'en' + + def __str__(self): + return self.value + +class Method(Enum): + USERS_GET = 'users.get' + FRIENDS_GET = 'friends.get' + + def __str__(self): + return self.value + +class API: + def __init__(self, lang=Language.DEFAULT): + self.lang = lang + + def _lang_is_specified(self): + return self.lang != Language.DEFAULT + + def _format_method_params(self, **kwargs): + params = '&'.join(map(lambda k: '{}={}'.format(k, kwargs[k]), kwargs)) + if self._lang_is_specified(): + if params: + params += '&' + params += 'lang={}'.format(self.lang) + return params + + def _build_method_url(self, method, **kwargs): + return 'https://api.vk.com/method/{}?{}'.format( + method, self._format_method_params(**kwargs)) + + def _call_method(self, method, **kwargs): + url = self._build_method_url(method, **kwargs) + try: + with urllib.request.urlopen(url) as request: + response = json.loads(request.read().decode()) + if 'response' not in response: + raise vk.error.InvalidResponseError(response) + return response['response'] + except URLError: + raise vk.error.ConnectionError() + + @staticmethod + def _format_param_values(xs): + if isinstance(xs, str): + return xs + if isinstance(xs, Iterable): + return ','.join(map(str, xs)) + return str(xs) + + def users_get(self, user_ids, fields=()): + return map(User, self._call_method( + Method.USERS_GET, + user_ids=self._format_param_values(user_ids), + fields=self._format_param_values(fields))) + + def friends_get(self, user_id, fields=()): + return map(User, self._call_method( + Method.FRIENDS_GET, + user_id=str(user_id), + fields=self._format_param_values(fields))) diff --git a/vk/error.py b/vk/error.py new file mode 100644 index 0000000..b80db4e --- /dev/null +++ b/vk/error.py @@ -0,0 +1,16 @@ +# Copyright 2016 Egor Tensin <Egor.Tensin@gmail.com> +# This file is licensed under the terms of the MIT License. +# See LICENSE.txt for details. + +class APIError(RuntimeError): + pass + +class InvalidResponseError(APIError): + def __init__(self, response): + self.response = response + + def __str__(self): + return str(self.response) + +class ConnectionError(APIError): + pass diff --git a/vk/user.py b/vk/user.py new file mode 100644 index 0000000..397d902 --- /dev/null +++ b/vk/user.py @@ -0,0 +1,70 @@ +# 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 datetime import datetime +from enum import Enum + +class Field(Enum): + UID = 'uid' + FIRST_NAME = 'first_name' + LAST_NAME = 'last_name' + SCREEN_NAME = 'screen_name' + ONLINE = 'online' + LAST_SEEN = 'last_seen' + + def __str__(self): + return self.value + +class User: + def __init__(self, impl): + self._impl = impl + + def __iter__(self): + return iter(self._impl) + + def __getitem__(self, field): + if isinstance(field, Field): + field = field.value + return self._impl[field] + + def __contains__(self, field): + if isinstance(field, Field): + field = field.value + return field in self._impl + + def get_uid(self): + return self._impl[Field.UID.value] + + def get_first_name(self): + return self._impl[Field.FIRST_NAME.value] + + def get_last_name(self): + return self._impl[Field.LAST_NAME.value] + + def has_last_name(self): + return Field.LAST_NAME.value in self._impl and self.get_last_name() + + def has_screen_name(self): + return Field.SCREEN_NAME.value in self._impl + + def get_screen_name(self): + if self.has_screen_name(): + return self._impl[Field.SCREEN_NAME.value] + else: + return 'id' + str(self.get_uid()) + + def is_online(self): + return self._impl[Field.ONLINE.value] + + def get_last_seen(self): + return datetime.fromtimestamp(self._impl[Field.LAST_SEEN.value]['time']) + + def __str__(self): + return repr(self._impl) + + def __hash__(self): + return hash(self.get_uid()) + + def __eq__(self, other): + return self.get_uid() == other.get_uid() |