Created
March 24, 2016 19:01
-
-
Save Daiver/5b06c77aaad975938f48 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cookielib | |
import urllib2 | |
import json | |
from urllib import urlencode | |
from urlparse import urlparse | |
from HTMLParser import HTMLParser | |
import os | |
import pickle | |
import getpass | |
class FormParser(HTMLParser): | |
def __init__(self): | |
HTMLParser.__init__(self) | |
self.url = None | |
self.params = {} | |
self.in_form = False | |
self.form_parsed = False | |
self.method = "GET" | |
def handle_starttag(self, tag, attrs): | |
tag = tag.lower() | |
if tag == "form": | |
if self.form_parsed: | |
raise RuntimeError("Second form on page") | |
if self.in_form: | |
raise RuntimeError("Already in form") | |
self.in_form = True | |
if not self.in_form: | |
return | |
attrs = dict((name.lower(), value) for name, value in attrs) | |
if tag == "form": | |
self.url = attrs["action"] | |
if "method" in attrs: | |
self.method = attrs["method"] | |
elif tag == "input" and "type" in attrs and "name" in attrs: | |
if attrs["type"] in ["hidden", "text", "password"]: | |
self.params[attrs["name"]] = attrs["value"] if "value" in attrs else "" | |
def handle_endtag(self, tag): | |
tag = tag.lower() | |
if tag == "form": | |
if not self.in_form: | |
raise RuntimeError("Unexpected end of <form>") | |
self.in_form = False | |
self.form_parsed = True | |
def auth(email, password, client_id, scope): | |
def split_key_value(kv_pair): | |
kv = kv_pair.split("=") | |
return kv[0], kv[1] | |
# Authorization form | |
def auth_user(email, password, client_id, scope, opener): | |
response = opener.open( | |
"http://oauth.vk.com/oauth/authorize?" + \ | |
"redirect_uri=http://oauth.vk.com/blank.html&response_type=token&" + \ | |
"client_id=%s&scope=%s&display=wap" % (client_id, ",".join(scope)) | |
) | |
doc = response.read() | |
parser = FormParser() | |
parser.feed(doc) | |
parser.close() | |
if not parser.form_parsed or parser.url is None or "pass" not in parser.params or \ | |
"email" not in parser.params: | |
raise RuntimeError("Something wrong") | |
parser.params["email"] = email | |
parser.params["pass"] = password | |
if parser.method in ["POST", "post"]: | |
response = opener.open(parser.url, urllib.urlencode(parser.params)) | |
else: | |
print parser.method | |
raise NotImplementedError("Method '%s'" % params.method) | |
return response.read(), response.geturl() | |
# Permission request form | |
def give_access(doc, opener): | |
parser = FormParser() | |
parser.feed(doc) | |
parser.close() | |
if not parser.form_parsed or parser.url is None: | |
raise RuntimeError("Something wrong") | |
if parser.method == "POST": | |
response = opener.open(parser.url, urllib.urlencode(parser.params)) | |
else: | |
raise NotImplementedError("Method '%s'" % params.method) | |
return response.geturl() | |
if not isinstance(scope, list): | |
scope = [scope] | |
opener = urllib2.build_opener( | |
urllib2.HTTPCookieProcessor(cookielib.CookieJar()), | |
urllib2.HTTPRedirectHandler()) | |
doc, url = auth_user(email, password, client_id, scope, opener) | |
if urlparse(url).path != "/blank.html": | |
# Need to give access to requested scope | |
url = give_access(doc, opener) | |
if urlparse(url).path != "/blank.html": | |
raise RuntimeError("Expected success here") | |
answer = dict(split_key_value(kv_pair) for kv_pair in urlparse(url).fragment.split("&")) | |
if "access_token" not in answer or "user_id" not in answer: | |
raise RuntimeError("Missing some values in answer") | |
return answer["access_token"], answer["user_id"] | |
def call_api(method, params, token): | |
params.append(("access_token", token)) | |
url = "https://api.vk.com/method/%s?%s" % (method, urlencode(params)) | |
#print url | |
ansewer = json.loads(urllib2.urlopen(url).read()) | |
if 'response' in ansewer: | |
return ansewer["response"] | |
return None | |
def inputAuthData(): | |
email = raw_input("Email: ") | |
password = getpass.getpass() | |
return email, password | |
def authByInputOrDump(appId, fname): | |
if os.path.exists(fname): | |
f = open(fname) | |
res = pickle.load(f) | |
f.close() | |
return res | |
email, password = inputAuthData() | |
token, uid = auth(email, password, appId, '') | |
f = open(fname, 'w') | |
pickle.dump((token, uid), f) | |
f.close() | |
return (token, uid) | |
if __name__ == '__main__': | |
appId = "appId" | |
token, uid = authByInputOrDump(appId, 'auth.dump') | |
print token, uid | |
print call_api("friends.get", | |
[ | |
('user_id', uid) | |
], token) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment