Commit ec2678a5 by Chris Rossi Committed by Diana Huang

Refactor LinkedIn API code to common location for reuse.

parent dc9c52d7
import hashlib
import json
import urllib2
import urlparse
import uuid
from django.conf import settings
from django.core.management.base import CommandError
from ...models import LinkedInToken
class LinkedinAPI(object):
"""
Encapsulates the LinkedIn API.
"""
def __init__(self):
config = getattr(settings, "LINKEDIN_API", None)
if not config:
raise CommandError("LINKEDIN_API is not configured")
self.config = config
try:
self.tokens = LinkedInToken.objects.get()
except LinkedInToken.DoesNotExist:
self.tokens = None
self.state = str(uuid.uuid4())
def http_error(error, message):
print "!!ERROR!!"
print error
print error.read()
raise CommandError(message)
def authorization_url(self):
config = self.config
return ("https://www.linkedin.com/uas/oauth2/authorization"
"?response_type=code"
"&client_id=%s&state=%s&redirect_uri=%s" % (
config['CLIENT_ID'], self.state, config['REDIRECT_URI']))
def get_authorization_code(self, redirect):
query = urlparse.parse_qs(urlparse.urlparse(redirect).query)
assert query['state'][0] == self.state, (query['state'][0], self.state)
return query['code'][0]
def get_access_token(self, code):
config = self.config
url = ("https://www.linkedin.com/uas/oauth2/accessToken"
"?grant_type=authorization_code"
"&code=%s&redirect_uri=%s&client_id=%s&client_secret=%s" % (
code, config['REDIRECT_URI'], config['CLIENT_ID'],
config['CLIENT_SECRET']))
try:
response = urllib2.urlopen(url).read()
except urllib2.HTTPError, error:
self.http_error(error, "Unable to retrieve access token")
access_token = json.loads(response)['access_token']
try:
tokens = LinkedInToken.objects.get()
tokens.access_token = access_token
tokens.authorization_code = code
except LinkedInToken.DoesNotExist:
tokens = LinkedInToken(access_token=access_token)
tokens.save()
self.tokens = tokens
return access_token
def batch(self, emails):
"""
Get the LinkedIn status for a batch of emails.
"""
if self.tokens is None:
raise CommandError(
"You must log in to LinkedIn in order to use this script. "
"Please use the 'login' command to log in to LinkedIn.")
def md5(email):
"Compute md5 hash for an email address."
hash = hashlib.md5()
hash.update(email)
return hash.hexdigest()
hashes = ','.join(("email-hash=" + md5(email) for email in emails))
url = "https://api.linkedin.com/v1/people::(%s):(id)" % hashes
url += "?oauth2_access_token=%s" % self.tokens.access_token
try:
response = urllib2.urlopen(url).read()
except urllib2.HTTPError, error:
print "!!ERROR!!"
print error
print error.read()
raise CommandError("Unable to access People API")
return (True for email in emails)
...@@ -13,6 +13,7 @@ from django.utils import timezone ...@@ -13,6 +13,7 @@ from django.utils import timezone
from optparse import make_option from optparse import make_option
from ...models import LinkedIn from ...models import LinkedIn
from .api import LinkedinAPI
FRIDAY = 4 FRIDAY = 4
...@@ -112,15 +113,3 @@ class Command(BaseCommand): ...@@ -112,15 +113,3 @@ class Command(BaseCommand):
do_batch(batch) do_batch(batch)
except StopIteration: except StopIteration:
pass pass
class LinkedinAPI(object):
"""
Encapsulates the LinkedIn API.
"""
def batch(self, emails):
"""
Get the LinkedIn status for a batch of emails.
"""
return (True for email in emails)
""" """
Log into LinkedIn API. Log into LinkedIn API.
""" """
import json from django.core.management.base import BaseCommand
import urllib2
import urlparse
import uuid
from django.conf import settings from .api import LinkedinAPI
from django.core.management.base import BaseCommand, CommandError
from ...models import LinkedInTokens
class Command(BaseCommand): class Command(BaseCommand):
...@@ -25,48 +19,13 @@ class Command(BaseCommand): ...@@ -25,48 +19,13 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
""" """
""" """
api = getattr(settings, "LINKEDIN_API", None) api = LinkedinAPI()
if not api:
raise CommandError("LINKEDIN_API is not configured")
state = str(uuid.uuid4())
url = ("https://www.linkedin.com/uas/oauth2/authorization"
"?response_type=code"
"&client_id=%s&state=%s&redirect_uri=%s" % (
api['CLIENT_ID'], state, api['REDIRECT_URI']))
print "Let's log into your LinkedIn account." print "Let's log into your LinkedIn account."
print "Start by visiting this url:" print "Start by visiting this url:"
print url print api.authorization_url()
print print
print "Within 30 seconds of logging in, enter the full URL of the " print "Within 30 seconds of logging in, enter the full URL of the "
print "webpage you were redirected to: " print "webpage you were redirected to: "
redirect = raw_input() redirect = raw_input()
query = urlparse.parse_qs(urlparse.urlparse(redirect).query) code = api.get_authorization_code(redirect)
assert query['state'][0] == state, (query['state'][0], state) api.get_access_token(code)
code = query['code'][0]
url = ("https://www.linkedin.com/uas/oauth2/accessToken"
"?grant_type=authorization_code"
"&code=%s&redirect_uri=%s&client_id=%s&client_secret=%s" % (
code, api['REDIRECT_URI'], api['CLIENT_ID'],
api['CLIENT_SECRET']))
try:
response = urllib2.urlopen(url).read()
except urllib2.HTTPError, error:
print "!!ERROR!!"
print error
print error.read()
raise CommandError("Unable to retrieve access token")
access_token = json.loads(response)['access_token']
try:
tokens = LinkedInTokens.objects.get()
tokens.access_token = access_token
tokens.authorization_code = code
except LinkedInTokens.DoesNotExist:
tokens = LinkedInTokens(
access_token=access_token,
authorization_code=code)
tokens.save()
...@@ -14,10 +14,9 @@ class LinkedIn(models.Model): ...@@ -14,10 +14,9 @@ class LinkedIn(models.Model):
emailed_courses = models.TextField(default="[]") # JSON list of course ids emailed_courses = models.TextField(default="[]") # JSON list of course ids
class LinkedInTokens(models.Model): class LinkedInToken(models.Model):
""" """
For storing access token and authorization code after logging in to For storing access token and authorization code after logging in to
LinkedIn. LinkedIn.
""" """
access_token = models.CharField(max_length=255) access_token = models.CharField(max_length=255)
authorization_code = models.CharField(max_length=255)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment