Skip to content

Instantly share code, notes, and snippets.

@Daiver
Created March 24, 2016 19:01
Show Gist options
  • Save Daiver/5b06c77aaad975938f48 to your computer and use it in GitHub Desktop.
Save Daiver/5b06c77aaad975938f48 to your computer and use it in GitHub Desktop.
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