stuppid_bot

Untitled

Jan 3rd, 2015
368
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.47 KB | None | 0 0
  1. import os
  2. import re
  3. import time
  4. import requests
  5. from urllib.parse import urlparse
  6.  
  7. __author__ = "Sergey Sergeev <[email protected]>"
  8. __license__ = "GNU General Public License v. 3"
  9.  
  10. class VkClient(object):
  11.     """Класс для работы с API Вконтакте.
  12.    
  13.    Методы API Вконтакте можно вызывать в нативном виде:
  14.    
  15.        <object VkClient>.users.get(user_id=1)
  16.          
  17.    Параметры можно паредать в виде словаря:
  18.    
  19.        <object VkClient>.users.get({'user_id': 1})
  20.        
  21.    Оба варианта анологичны такой записи:
  22.    
  23.        <object VkClient>.api('users.get', {'user_id': 1})
  24.        
  25.    См.: http://vk.com/dev/methods
  26.    """  
  27.     def __init__(self, apiVersion=None, accessToken=None, apiDelay=None):
  28.         """Конструктор.
  29.        :param apiVersion: Версия API Вконтакте. Об актуальной версии можно
  30.            узнать тут <http://vk.com/dev>.
  31.        
  32.        :param accessToken: Токен полученный при авторизации.
  33.          
  34.        :param apiDelay: Принудительная задержка возвращения результата
  35.            выполения метода API. Для приложений есть лимиты обращения к API
  36.            в секунду <http://vk.com/dev/api_requests>.
  37.        """
  38.         self.apiVersion = apiVersion
  39.         self.accessToken = accessToken
  40.         self.apiDelay = apiDelay
  41.         self.session = requests.session()
  42.  
  43.     def api(self, method, params=None):
  44.         """Отправляет запрос к API.
  45.        
  46.        :param method: Имя метода.
  47.        :param params: - словарь, необязательный. Параметры запроса.
  48.        :return: Значение поля `response`.
  49.        """
  50.         params = dict(params) or {}
  51.  
  52.         if self.accessToken and not 'access_token' in params:
  53.             params['access_token'] = self.accessToken
  54.  
  55.         if self.apiVersion and not 'v' in params:
  56.             params['v'] = self.apiVersion
  57.  
  58.         if self.apiDelay:
  59.             time.sleep(self.apiDelay)
  60.  
  61.         u = 'https://api.vk.com/method/{}'.format(method)  
  62.         r = self.session.post(u, params).json()
  63.  
  64.         if 'error' in r:
  65.             details = r['error']
  66.             error = VkError(details['error_msg'], details['error_code'],
  67.                             method, params, details.get('captcha_img'),
  68.                             details.get('captcha_sid'),
  69.                             details.get('redirect_uri'))
  70.  
  71.             if error.code == 14:
  72.                 return self.captchaHandler(error)
  73.             elif error.code == 17:
  74.                 return self.validationHandler(error)
  75.  
  76.             raise error
  77.  
  78.         return r['response']
  79.    
  80.     def execute(self, code, **kw):
  81.         kw['code'] = code
  82.         return self.api('execute', kw)
  83.  
  84.     def captchaHandler(self, error):
  85.         raise error
  86.  
  87.     def validationHandler(self, error):
  88.         raise error
  89.  
  90.     def upload(self, url, files):
  91.         """Загружает файлы на сервер.
  92.        
  93.        :param url: Адрес сервера для загрузки файлов.
  94.        :param files: Словарь, где "имя поля" => "путь до файла"(может быть
  95.            ссылкой). Так же можно передавать кортеж или список вида
  96.            ("имя файла", "содержимое"). На сервере проверяется расширение
  97.            файла, mime тип не учитывается(поэтому клиентом он не передается).
  98.            Проверяются сигнатуры файлов
  99.            <http://en.wikipedia.org/wiki/List_of_file_signatures> при
  100.            загрузке изображений.
  101.        """
  102.         files = dict(files)
  103.  
  104.         for k, v in files.items():
  105.             if not isinstance(v, str):
  106.                 continue
  107.  
  108.             filename = v  
  109.              
  110.             if re.match('(?i)https?://', filename):
  111.                 content = self.session.get(filename).content
  112.                 # http://example.com/path/to/file?query -> path/to/file
  113.                 filename = urlparse(filename).path
  114.             else:
  115.                 content = open(filename, 'rb').read()
  116.                
  117.             # path/to/file -> file
  118.             filename = os.path.basename(filename)
  119.             files[k] = (filename, content)
  120.  
  121.         r = self.session.post(url, files=files).json()
  122.  
  123.         if 'error' in r:
  124.             raise VkError(r['error'])
  125.  
  126.         return r
  127.    
  128.     def uploadWallPhoto(self, photo, group_id=None):
  129.         """Метод для тестирования загрузки фото на стену."""
  130.         args = {'group_id': group_id} if group_id else {}
  131.         u = self.photos.getWallUploadServer(args)['upload_url']
  132.         r = self.upload(u, {'photo': photo})
  133.         photos = self.photos.saveWallPhoto(r)
  134.         # return "photo{owner_id}_{id}".format(**photos[0])
  135.         return photos
  136.    
  137.     # Комплексные методы вида <namespace>.<method>.
  138.     def __getattr__(self, name):
  139.         if re.match('[a-z]+$', name):
  140.             return ComplexMethod(self, name)
  141.    
  142. class ComplexMethod(object):
  143.     def __init__(self, client, prefix):
  144.         self._client = client
  145.         self._prefix = prefix
  146.        
  147.     def __getattr__(self, name):
  148.         def wrapper(*arg, **kw):
  149.             if len(arg) == 1 and isinstance(arg[0], dict):
  150.                 dict.update(arg[0], kw)
  151.                 kw = arg[0]
  152.  
  153.             return self._client.api(self._prefix + '.' + name, kw)
  154.        
  155.         # Имена методов должны быть в camelCase.
  156.         if re.match('[a-z]+([A-Z][a-z]+)*$', name):
  157.             return wrapper
  158.        
  159. class VkError(Exception):
  160.     def __init__(self, message=None, code=-1, method=None, params=None,
  161.                  captchaImg=None, captchaSid=None, redirectUri=None):      
  162.         Exception.__init__(self, message)
  163.         self.code = code
  164.         self.message = message
  165.         self.method = method
  166.         self.params = params
  167.         self.captchaSid = captchaSid
  168.         self.captchaImg = captchaImg
  169.         self.redirectUri = redirectUri
Advertisement
Add Comment
Please, Sign In to add comment