Advertisement
stuppid_bot

Untitled

Nov 30th, 2014
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.13 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import re
  4. import sys
  5. import json
  6. import time
  7. import uuid
  8. import urllib
  9. import urllib2
  10. import mimetypes
  11.  
  12. class VKError(Exception):
  13.     pass
  14.  
  15. class VKValidationError(VKError):
  16.     pass
  17.  
  18. class VKCaptchaError(VKError):
  19.     pass
  20.  
  21. class VKAuthError(VKError):
  22.     def __init__(self, t, d):
  23.         super(VKAuthError, self).__init__("%s: %s" % (t, d))
  24.         self.type=t
  25.  
  26. class VKApiError(VKError):
  27.     def __init__(self, c, d):
  28.         super(VKApiError, self).__init__("[%s] %s" % (c, d))
  29.         self.code=c
  30.  
  31. class VKAgent(object):
  32.     def __init__(self, access_token=None, user_id=None,
  33.         expires=None, api_version=5.25, lang=None, user_agent="VKAgent"):
  34.         self.access_token=access_token
  35.         self.user_id=user_id
  36.         self.expires=expires
  37.         self.api_version=api_version
  38.         self.lang=lang
  39.         self.user_agent=user_agent
  40.  
  41.     def login(self, username, password, client_id=3140623,
  42.         client_secret='VeWdmVclDCtn6ihuP1nt', scope=''):
  43.         u"Прямая авторизация."
  44.         params={
  45.             'username': username,
  46.             'password': password,
  47.             'client_id': client_id,
  48.             'client_secret': client_secret,
  49.             'scope': scope,
  50.             'grant_type': 'password',
  51.             'test_redirect_uri': 1,
  52.         }
  53.         self.auth('token', params)
  54.  
  55.     def api(self, method, params):
  56.         u"Вызывает метод API Вконтакте."
  57.         params=dict(params)
  58.         if not 'access_token' in params and self.access_token:
  59.             params['access_token']=self.access_token
  60.         if not 'lang' in params and self.lang:
  61.             params['lang']=self.lang
  62.         if not 'v' in params:
  63.             params['v']=self.api_version
  64.         return self.raw_api(method, params)
  65.  
  66.     def auth(self, action, params):
  67.         url='https://oauth.vk.com/' + action
  68.         r=self.post(url, params)
  69.         if 'error' in r:
  70.             if 'need_validation' == r['error']:
  71.                 self.validate(r['redirect_uri'])
  72.             elif 'need_captcha' == r['error']:
  73.                 self.captcha_params(params, r['captcha_img'], r['captcha_sid'])
  74.             else:
  75.                 raise VKAuthError(r['error'], r['error_description'])
  76.             return self.auth(action, params)
  77.         self.access_token = r['access_token']
  78.         self.user_id = r.get('user_id')
  79.         if r['expires_in']:
  80.             self.expires = r['expires_in'] + time.time()
  81.  
  82.     def raw_api(self, method, params):
  83.         url='https://api.vk.com/method/' + method
  84.         r=self.post(url, params)
  85.         if 'response' in r:
  86.             return r['response']
  87.         error=r['error']
  88.         if error['error_code'] == 14:
  89.             self.captcha_params(params, error['captcha_img'], error['captcha_sid'])
  90.         elif error['error_code'] == 17:
  91.             self.validate(error['redirect_uri'])
  92.         else:
  93.             raise VKApiError(error['error_code'], error['error_msg'])
  94.         self.raw_api(method, params)
  95.  
  96.     def post(self, url, params):
  97.         params=self.encode_params(params)
  98.         headers={'Content-Type': 'application/x-www-form-urlencoded'}
  99.         return self.get_json(url, params, headers)
  100.  
  101.     def upload(self, url, files):
  102.         u"Загружает файлы."
  103.         lines=[]
  104.         boundary=uuid.uuid4().hex
  105.         content_type='application/octet-stream'
  106.         for k, v in files.items():
  107.             if re.match('(?i)https?://', v, re.I):
  108.                 r=self.fetch(v)
  109.                 content_type=r.headers.get('content-type', content_type)
  110.                 data=r.read()
  111.             else:
  112.                 f=open(v, 'rb')
  113.                 data=f.read()
  114.                 f.close()
  115.                 ending=os.path.splitext(v)[1]
  116.                 content_type=mimetypes.types_map.get(ending, content_type)
  117.                 v=v.encode(sys.getfilesystemencoding())
  118.             lines.extend([
  119.                 '--' + boundary,
  120.                 'Content-Disposition: form-data; name="' + k +\
  121.                 '"; filename="' + os.path.basename(v) + '"',
  122.                 'Content-Type: ' + content_type,
  123.                 '',
  124.                 data
  125.             ])
  126.         lines.extend([
  127.             '--' + boundary + '--',
  128.             ''
  129.         ])
  130.         data='\r\n'.join(lines)
  131.         headers={'Content-Type': 'multipart/form-data; boundary=' + boundary}
  132.         return self.exec_url(url, data, headers)
  133.  
  134.     def fetch(self, url, data=None, headers={}):
  135.         url=str(url) # bugfix
  136.         _headers={'User-Agent': self.user_agent}
  137.         _headers.update(headers)
  138.         r=urllib2.Request(url, data, _headers)
  139.         try:
  140.             r=urllib2.urlopen(r)
  141.         except urllib2.HTTPError as r:
  142.             pass
  143.         return r
  144.  
  145.     def get_content(self, url, headers={}):
  146.         return self.fetch(url, None, headers).read()
  147.  
  148.     def get_json(self, url, data=None, headers={}):
  149.         j=self.fetch(url, data, headers).read()
  150.         try:
  151.             j=json.loads(j)
  152.         except:
  153.             # некоторые методы отдают данные в windows-1251 вместо utf-8
  154.             j=json.loads(j, 'windows-1251')
  155.         return j
  156.  
  157.     # !Неудачное имя метода.
  158.     def exec_url(self, url, data=None, headers={}):
  159.         u"""
  160.        Возвращает response, либо бросает исключение, если в ответе есть
  161.        поле error.
  162.        """
  163.         r = self.get_json(url, data, headers)
  164.         if 'error' in r:
  165.             raise VKError(r['error'])
  166.         return r
  167.  
  168.     def encode_params(self, params):
  169.         params=dict(params)
  170.         for k, v in params.items():
  171.             if type(v) == unicode:
  172.                 params[k]=v.encode('utf-8')
  173.         return urllib.urlencode(params)
  174.  
  175.     def get_captcha_key(self, url):
  176.         u"Возвращает значение капчи."
  177.         print url
  178.         raise VKCaptchaError('Captcha needed.')
  179.  
  180.     def captcha_params(self, params, url, sid):
  181.         u"Добавляет парамерты капчи."
  182.         params['captcha_sid']=sid
  183.         params['captcha_key']=self.get_captcha_key(url)
  184.  
  185.     def validate(self, url):
  186.         u"""
  187.        Осуществляет автоматическую валидацию пользователя при заходе из
  188.        подозрительного места.
  189.        """
  190.         s=self.get_content(url)
  191.         m=re.search(r'/security_check\?[^"]+', s)
  192.         if m:
  193.             u='https://oauth.vk.com' + m.group(0)
  194.             r=self.fetch(u)
  195.             if r.geturl() == 'https://oauth.vk.com/blank.html?success=1':
  196.                 return
  197.         raise VKValidationError('Validation failed.')
  198.  
  199. ###############################################################################
  200.  
  201. if __name__ == '__main__':
  202.     from account import *
  203.     vk=VKAgent()
  204.     vk.login(username, password)
  205.     api=vk.api
  206.     sl=time.sleep
  207.     # 35 запросов в секунду ~0.03
  208.     for i in range(20):
  209.         api('wall.post', dict(message="Тест %s" % (i + 1)))
  210.         sl(0.1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement