Skip to content

Commit ddad2d0

Browse files
committed
Merge pull request ozgur#80 from clustree/master
Add python 3.4 support
2 parents 49eeb55 + aa76e20 commit ddad2d0

File tree

5 files changed

+54
-35
lines changed

5 files changed

+54
-35
lines changed

examples/http_api.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
__author__ = 'Samuel Marks <[email protected]>'
22
__version__ = '0.1.0'
33

4-
from SocketServer import ThreadingTCPServer
5-
from SimpleHTTPServer import SimpleHTTPRequestHandler
4+
try:
5+
from urllib.parse import urlparse
6+
except ImportError:
7+
from urlparse import urlparse
8+
9+
from socketserver import ThreadingTCPServer
10+
from http.server import SimpleHTTPRequestHandler
11+
612
from webbrowser import open_new_tab
713
from json import dumps
8-
from urlparse import urlparse
914
from os import environ
10-
from types import NoneType
15+
1116

1217
from linkedin.linkedin import LinkedInAuthentication, LinkedInApplication, PERMISSIONS
1318

@@ -38,35 +43,35 @@ def json_headers(self, status_code=200):
3843

3944
def do_GET(self):
4045
parsedurl = urlparse(self.path)
41-
authed = type(liw.authentication.token) is not NoneType
46+
authed = liw.authentication.token is not None
4247

4348
if parsedurl.path == '/code':
4449
self.json_headers()
4550

4651
liw.authentication.authorization_code = params_to_d(self.path).get('code')
4752
self.wfile.write(dumps({'access_token': liw.authentication.get_access_token(),
48-
'routes': filter(lambda d: not d.startswith('_'), dir(liw.application))}))
53+
'routes': list(filter(lambda d: not d.startswith('_'), dir(liw.application)))}).encode('utf8'))
4954
elif parsedurl.path == '/routes':
5055
self.json_headers()
5156

52-
self.wfile.write(dumps({'routes': filter(lambda d: not d.startswith('_'), dir(liw.application))}))
57+
self.wfile.write(dumps({'routes': list(filter(lambda d: not d.startswith('_'), dir(liw.application)))}).encode('utf8'))
5358
elif not authed:
5459
self.json_headers()
5560

5661
if not globals()['run_already']:
5762
open_new_tab(liw.authentication.authorization_url)
5863
globals()['run_already'] = True
59-
self.wfile.write(dumps({'path': self.path, 'authed': type(liw.authentication.token) is NoneType}))
64+
self.wfile.write(dumps({'path': self.path, 'authed': type(liw.authentication.token) is None}).encode('utf8'))
6065
elif authed and len(parsedurl.path) and parsedurl.path[1:] in dir(liw.application):
6166
self.json_headers()
62-
self.wfile.write(dumps(getattr(liw.application, parsedurl.path[1:])()))
67+
self.wfile.write(dumps(getattr(liw.application, parsedurl.path[1:])()).encode('utf8'))
6368
else:
6469
self.json_headers(501)
65-
self.wfile.write(dumps({'error': 'NotImplemented'}))
70+
self.wfile.write(dumps({'error': 'NotImplemented'}).encode('utf8'))
6671

6772

6873
if __name__ == '__main__':
6974
httpd = ThreadingTCPServer(('localhost', PORT), CustomHandler)
7075

71-
print 'Server started on port:', PORT
76+
print('Server started on port:{}'.format(PORT))
7277
httpd.serve_forever()

linkedin/linkedin.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
23
import contextlib
34
import hashlib
45
import random
5-
import urllib
6+
7+
try:
8+
from urllib.parse import quote, quote_plus
9+
except ImportError:
10+
from urllib import quote, quote_plus
611

712
import requests
813
from requests_oauthlib import OAuth1
@@ -93,7 +98,7 @@ def authorization_url(self):
9398
'redirect_uri': self.redirect_uri}
9499
# urlencode uses quote_plus when encoding the query string so,
95100
# we ought to be encoding the qs by on our own.
96-
qsl = ['%s=%s' % (urllib.quote(k), urllib.quote(v)) for k, v in qd.items()]
101+
qsl = ['%s=%s' % (quote(k), quote(v)) for k, v in qd.items()]
97102
return '%s?%s' % (self.AUTHORIZATION_URL, '&'.join(qsl))
98103

99104
@property
@@ -102,7 +107,8 @@ def last_error(self):
102107

103108
def _make_new_state(self):
104109
return hashlib.md5(
105-
'%s%s' % (random.randrange(0, 2 ** 63), self.secret)).hexdigest()
110+
'{}{}'.format(random.randrange(0, 2 ** 63), self.secret).encode("utf8")
111+
).hexdigest()
106112

107113
def get_access_token(self, timeout=60):
108114
assert self.authorization_code, 'You must first get the authorization code'
@@ -174,7 +180,7 @@ def get_profile(self, member_id=None, member_url=None, selectors=None,
174180
else:
175181
url = '%s/id=%s' % (ENDPOINTS.PEOPLE, str(member_id))
176182
elif member_url:
177-
url = '%s/url=%s' % (ENDPOINTS.PEOPLE, urllib.quote_plus(member_url))
183+
url = '%s/url=%s' % (ENDPOINTS.PEOPLE, quote_plus(member_url))
178184
else:
179185
url = '%s/~' % ENDPOINTS.PEOPLE
180186
if selectors:
@@ -200,7 +206,7 @@ def get_picture_urls(self, member_id=None, member_url=None,
200206
url = '%s/id=%s/picture-urls::(original)' % (ENDPOINTS.PEOPLE, str(member_id))
201207
elif member_url:
202208
url = '%s/url=%s/picture-urls::(original)' % (ENDPOINTS.PEOPLE,
203-
urllib.quote_plus(member_url))
209+
quote_plus(member_url))
204210
else:
205211
url = '%s/~/picture-urls::(original)' % ENDPOINTS.PEOPLE
206212

@@ -214,7 +220,7 @@ def get_connections(self, member_id=None, member_url=None, selectors=None,
214220
url = '%s/id=%s/connections' % (ENDPOINTS.PEOPLE, str(member_id))
215221
elif member_url:
216222
url = '%s/url=%s/connections' % (ENDPOINTS.PEOPLE,
217-
urllib.quote_plus(member_url))
223+
quote_plus(member_url))
218224
else:
219225
url = '%s/~/connections' % ENDPOINTS.PEOPLE
220226
if selectors:
@@ -230,7 +236,7 @@ def get_memberships(self, member_id=None, member_url=None, group_id=None,
230236
url = '%s/id=%s/group-memberships' % (ENDPOINTS.PEOPLE, str(member_id))
231237
elif member_url:
232238
url = '%s/url=%s/group-memberships' % (ENDPOINTS.PEOPLE,
233-
urllib.quote_plus(member_url))
239+
quote_plus(member_url))
234240
else:
235241
url = '%s/~/group-memberships' % ENDPOINTS.PEOPLE
236242

@@ -307,7 +313,7 @@ def like_post(self, post_id, action):
307313
url = '%s/%s/relation-to-viewer/is-liked' % (ENDPOINTS.POSTS, str(post_id))
308314
try:
309315
self.make_request('PUT', url, data=json.dumps(action))
310-
except (requests.ConnectionError, requests.HTTPError), error:
316+
except (requests.ConnectionError, requests.HTTPError) as error:
311317
raise LinkedInError(error.message)
312318
else:
313319
return True
@@ -319,7 +325,7 @@ def comment_post(self, post_id, comment):
319325
url = '%s/%s/comments' % (ENDPOINTS.POSTS, str(post_id))
320326
try:
321327
self.make_request('POST', url, data=json.dumps(post))
322-
except (requests.ConnectionError, requests.HTTPError), error:
328+
except (requests.ConnectionError, requests.HTTPError) as error:
323329
raise LinkedInError(error.message)
324330
else:
325331
return True

linkedin/utils.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
# -*- coding: utf-8 -*-
22
import requests
33
from .exceptions import LinkedInError, get_exception_for_error_code
4-
5-
try:
6-
from cStringIO import StringIO
7-
except ImportError:
8-
from StringIO import StringIO
4+
import sys
5+
from io import StringIO
96

107
try:
118
import simplejson as json
@@ -16,6 +13,22 @@
1613
import json
1714

1815

16+
if sys.version_info < (3,):
17+
import __builtin__
18+
19+
def to_utf8(x):
20+
return __builtin__.unicode(x)
21+
22+
def to_string(x):
23+
return str(x)
24+
else:
25+
def to_utf8(x):
26+
return x
27+
28+
def to_string(x):
29+
return x
30+
31+
1932
def enum(enum_type='enum', base_classes=None, methods=None, **attrs):
2033
"""
2134
Generates a enumeration with the given attributes.
@@ -31,21 +44,13 @@ def __init__(instance, *args, **kwargs):
3144
methods = {}
3245

3346
base_classes = base_classes + (object,)
34-
for k, v in methods.iteritems():
47+
for k, v in methods.items():
3548
methods[k] = classmethod(v)
3649

3750
attrs['enums'] = attrs.copy()
3851
methods.update(attrs)
3952
methods['__init__'] = __init__
40-
return type(enum_type, base_classes, methods)
41-
42-
43-
def to_utf8(st):
44-
if isinstance(st, unicode):
45-
return st.encode('utf-8')
46-
else:
47-
return bytes(st)
48-
53+
return type(to_string(enum_type), base_classes, methods)
4954

5055
def raise_for_error(response):
5156
try:

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
future==0.14.3
12
requests
23
requests_oauthlib

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
'License :: OSI Approved :: MIT License',
2424
'Operating System :: OS Independent',
2525
'Programming Language :: Python :: 2.7',
26+
'Programming Language :: Python :: 3',
27+
'Programming Language :: Python :: 3.4',
2628
'Natural Language :: English',
2729
],
2830
keywords='linkedin python',

0 commit comments

Comments
 (0)