Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implementing instagram-javascript-sdk

  • Loading branch information...
commit c9bb260bb9e3cbceba86fea4b05549e855d74a2d 1 parent a899d74
@shayne shayne authored
View
5 instadrop/handlers.py
@@ -18,7 +18,10 @@ def get(self):
if profile and profile.fully_connected():
self.render_template("connected.html")
else:
- self.render_template("not_connected.html", {"profile": profile})
+ self.render_template("not_connected.html", {
+ "profile": profile,
+ "client_id": settings.INSTAGRAM_CONFIG["client_id"]
+ })
class ConnectHandler(webapp.RequestHandler):
View
32 instadrop/templates/not_connected.html
@@ -32,8 +32,38 @@
{% else %}
<h1>
Sound good? Let's get started. <br />
- <a href="/instagram/auth">Connect your Instagram account</a>
+ <a href="javascript:;" onclick="do_login();">Connect your Instagram account</a>
</h1>
+ <div id="ig-root"></div>
+ <script>
+ function do_login() {
+ IG.login(function (response) {
+ if (response.code) {
+ document.location = '/instagram/callback?code=' + response.code;
+ } else if (response.session) {
+ document.location = '/instagram/load_user?ig_user_id=' + response.session.id;
+ }
+ }, {
+ response_type: 'code',
+ scope: ['comments','likes', 'relationships']
+ });
+ }
+
+ window.igAsyncInit = function() {
+ IG.init({
+ client_id: '{{ client_id }}',
+ logging: true,
+ check_status: false
+ });
+ };
+
+ (function() {
+ var e = document.createElement('script'); e.async = true;
+ e.src = document.location.protocol +
+ '//github.com/Instagram/instagram-javascript-sdk/raw/master/ig-min.js';
+ document.getElementById('ig-root').appendChild(e);
+ }());
+ </script>
{% endif %}
</div>
</body>
View
33 instagram/handlers.py
@@ -58,6 +58,39 @@ def get(self):
self.redirect("/connect")
+class InstagramLoadUser(webapp.RequestHandler):
+ def get(self):
+ ig_user_id = self.request.get("ig_user_id")
+
+ if not ig_user_id:
+ self.redirect("/connect")
+
+ instagram_client = InstagramAPI(**settings.INSTAGRAM_CONFIG)
+
+ access_token = instagram_client.exchange_user_id_for_access_token(ig_user_id)
+
+ instagram_client = InstagramAPI(access_token = access_token)
+
+ user = instagram_client.user("self")
+
+ profiles = Profile.all()
+ profiles.filter("ig_user_id = ", user.id)
+ profile = (profiles.get() or Profile())
+
+ profile.full_name = (user.full_name or user.username)
+ profile.ig_user_id = user.id
+ profile.ig_username = user.username
+ profile.ig_access_token = access_token
+ profile.put()
+
+ cookieutil = LilCookies(self, settings.COOKIE_SECRET)
+ cookieutil.set_secure_cookie(
+ name = "ig_user_id",
+ value = user.id,
+ expires_days = 365)
+
+ self.redirect("/")
+
class InstagramSubscribe(webapp.RequestHandler):
def get(self):
View
32 instagram/instagram/oauth2.py
@@ -22,7 +22,7 @@ class OAuth2API(object):
protocol = "https"
# override with 'Instagram', etc
api_name = "Generic API"
-
+
def __init__(self, client_id=None, client_secret=None, access_token=None, redirect_uri=None):
self.client_id = client_id
self.client_secret = client_secret
@@ -32,7 +32,7 @@ def __init__(self, client_id=None, client_secret=None, access_token=None, redire
def get_authorize_url(self, scope=None):
req = OAuth2AuthExchangeRequest(self)
return req.get_authorize_url(scope = scope)
-
+
def get_authorize_login_url(self, scope=None):
""" scope should be a tuple or list of requested scope access levels """
req = OAuth2AuthExchangeRequest(self)
@@ -42,6 +42,10 @@ def exchange_code_for_access_token(self, code):
req = OAuth2AuthExchangeRequest(self)
return req.exchange_for_access_token(code = code)
+ def exchange_user_id_for_access_token(self, user_id):
+ req = OAuth2AuthExchangeRequest(self)
+ return req.exchange_for_access_token(user_id = user_id)
+
def exchange_xauth_login_for_access_token(self, username, password, scope=None):
""" scope should be a tuple or list of requested scope access levels """
req = OAuth2AuthExchangeRequest(self)
@@ -63,7 +67,7 @@ def _url_for_authorize(self, scope=None):
url_params = urllib.urlencode(client_params)
return "%s?%s" % (self.api.authorize_url, url_params)
- def _data_for_exchange(self, code=None, username=None, password=None, scope=None):
+ def _data_for_exchange(self, code=None, username=None, password=None, scope=None, user_id=None):
client_params = {
"client_id": self.api.client_id,
"client_secret": self.api.client_secret,
@@ -73,11 +77,13 @@ def _data_for_exchange(self, code=None, username=None, password=None, scope=None
if code:
client_params.update(code=code)
elif username and password:
- client_params.update(username = username,
+ client_params.update(username = username,
password = password,
grant_type = "password")
if scope:
client_params.update(scope = ' '.join(scope))
+ elif user_id:
+ client_params.update(user_id = user_id)
return urllib.urlencode(client_params)
def get_authorize_url(self, scope=None):
@@ -93,8 +99,8 @@ def get_authorize_login_url(self, scope=None):
redirected_to = response['content-location']
return redirected_to
- def exchange_for_access_token(self, code=None, username=None, password=None, scope=None):
- data = self._data_for_exchange(code, username, password, scope = scope)
+ def exchange_for_access_token(self, code=None, username=None, password=None, scope=None, user_id=None):
+ data = self._data_for_exchange(code, username, password, scope = scope, user_id = user_id)
http_object = Http()
url = self.api.access_token_url
response, content = http_object.request(url, method="POST", body=data)
@@ -113,10 +119,10 @@ def url_for_get(self, path, parameters):
def get_request(self, path, **kwargs):
return self.make_request(self.prepare_request("GET", path, kwargs))
-
+
def post_request(self, path, **kwargs):
return self.make_request(self.prepare_request("POST", path, kwargs))
-
+
def _full_url(self, path):
return "%s://%s%s%s%s" % (self.api.protocol, self.api.host, self.api.base_path, path, self._auth_query())
@@ -135,7 +141,7 @@ def _auth_query(self):
def _post_body(self, params):
return urllib.urlencode(params)
-
+
def _encode_multipart(params, files):
boundary = "MuL7Ip4rt80uND4rYF0o"
@@ -146,7 +152,7 @@ def encode_field(field_name):
return ("--" + boundary,
'Content-Disposition: form-data; name="%s"' % (field_name),
"", str(params[field_name]))
-
+
def encode_file(field_name):
file_name, file_handle = files[field_name]
return ("--" + boundary,
@@ -161,10 +167,10 @@ def encode_file(field_name):
lines.extend(encode_file(field))
lines.extend(("--%s--" % (boundary), ""))
body = "\r\n".join (lines)
-
+
headers = {"Content-Type": "multipart/form-data; boundary=" + boundary,
"Content-Length": str(len(body))}
-
+
return body, headers
def prepare_request(self, method, path, params):
@@ -174,7 +180,7 @@ def prepare_request(self, method, path, params):
if not params.get('files'):
if method == "POST":
body = self._post_body(params)
- headers = {'Content-type': 'application/x-www-form-urlencoded'}
+ headers = {'Content-type': 'application/x-www-form-urlencoded'}
url = self._full_url(path)
else:
url = self._full_url_with_params(path, params)
View
3  main.py
@@ -9,7 +9,7 @@
from instadrop.handlers import WelcomeHandler, ConnectHandler
from instagram.handlers import (InstagramAuth, InstagramCallback, \
InstagramSubscribe, InstagramPushCallback, \
- InstagramDisconnect)
+ InstagramDisconnect, InstagramLoadUser)
from dropbox.handlers import DropboxAuth, DropboxCallback, DropboxDisconnect
@@ -24,6 +24,7 @@
("/instagram/subscribe", InstagramSubscribe),
("/instagram/push_callback", InstagramPushCallback),
("/instagram/disconnect", InstagramDisconnect),
+ ("/instagram/load_user", InstagramLoadUser),
("/dropbox/auth", DropboxAuth),
("/dropbox/callback", DropboxCallback),
("/dropbox/disconnect", DropboxDisconnect)], debug=True)
Please sign in to comment.
Something went wrong with that request. Please try again.