1 # -*- coding: utf-8 -*-
4 # based on flattr.py from gPodder by Bernd Schlapsi <brot@gmx.info>
10 from collections
import namedtuple
12 from django
.conf
import settings
13 from django
.core
.urlresolvers
import reverse
15 from mygpo
.core
.json
import json
16 from mygpo
.users
.settings
import FLATTR_TOKEN
, FLATTR_USERNAME
17 from mygpo
import utils
18 from django
.utils
.translation
import ugettext
as _
22 """ a Flattr client """
25 OAUTH_BASE
= 'https://flattr.com/oauth'
26 AUTH_URL_TEMPLATE
= (OAUTH_BASE
+ '/authorize?scope=flattr&' +
27 'response_type=code&client_id=%(client_id)s&' +
28 'redirect_uri=%(redirect_uri)s')
29 OAUTH_TOKEN_URL
= OAUTH_BASE
+ '/token'
32 API_BASE
= 'https://api.flattr.com/rest/v2'
33 USER_INFO_URL
= API_BASE
+ '/user'
34 FLATTR_URL
= API_BASE
+ '/flattr'
35 THING_INFO_URL_TEMPLATE
= API_BASE
+ '/things/lookup/?url=%(url)s'
38 def __init__(self
, user
, domain
, is_secure
):
41 self
.is_secure
= is_secure
44 def _get_callback(self
):
45 return 'http{s}://{domain}{callback}'.format(
46 s
='s' if self
.is_secure
else '',
48 callback
=reverse('flattr-token'))
51 def request(self
, url
, data
=None):
52 headers
= {'Content-Type': 'application/json'}
54 if url
== self
.OAUTH_TOKEN_URL
:
55 # Inject username and password into the request URL
56 url
= utils
.url_add_authentication(url
, settings
.FLATTR_KEY
,
57 settings
.FLATTR_SECRET
)
58 elif self
.user
.profile
.settings
.get_setting('flattr_token', ''):
59 headers
['Authorization'] = 'Bearer ' + self
.user
.profile
.settings
.get_wksetting(FLATTR_TOKEN
)
62 data
= json
.dumps(data
)
65 response
= utils
.urlopen(url
, headers
, data
)
66 except urllib2
.HTTPError
, error
:
67 return {'_gpodder_statuscode': error
.getcode()}
68 except urllib2
.URLError
, error
:
69 return {'_gpodder_no_connection': False}
71 if response
.getcode() == 200:
72 return json
.loads(response
.read())
74 return {'_gpodder_statuscode': response
.getcode()}
76 def get_auth_url(self
):
77 return self
.AUTH_URL_TEMPLATE
% {
78 'client_id': settings
.FLATTR_KEY
,
79 'redirect_uri': self
._get
_callback
(),
83 return bool(self
.user
.profile
.settings
.get_wksetting(FLATTR_TOKEN
))
85 def process_retrieved_code(self
, url
):
86 url_parsed
= urlparse
.urlparse(url
)
87 query
= urlparse
.parse_qs(url_parsed
.query
)
90 code
= query
['code'][0]
91 token
= self
._request
_access
_token
(code
)
96 def _request_access_token(self
, code
):
97 request_url
= 'https://flattr.com/oauth/token'
101 'grant_type': 'authorization_code',
102 'redirect_uri': self
._get
_callback
(),
105 content
= self
.request(self
.OAUTH_TOKEN_URL
, data
=params
)
106 return content
.get('access_token', '')
109 def get_thing_info(self
, payment_url
):
110 """Get information about a Thing on Flattr
112 Return a tuple (flattrs, flattred):
114 flattrs ... The number of Flattrs this thing received
115 flattred ... True if this user already flattred this thing
117 if not self
.user
.profile
.settings
.get_wksetting(FLATTR_TOKEN
):
120 quote_url
= urllib
.quote_plus(utils
.sanitize_encoding(payment_url
))
121 url
= self
.THING_INFO_URL_TEMPLATE
% {'url': quote_url
}
122 data
= self
.request(url
)
123 return (int(data
.get('flattrs', 0)), bool(data
.get('flattred', False)))
126 def get_auth_username(self
):
127 if not self
.user
.profile
.settings
.get_wksetting(FLATTR_TOKEN
):
130 data
= self
.request(self
.USER_INFO_URL
)
131 return data
.get('username', '')
134 def flattr_url(self
, payment_url
):
135 """Flattr an object given its Flattr payment URL
137 Returns a tuple (success, message):
139 success ... True if the item was Flattr'd
140 message ... The success or error message
146 content
= self
.request(self
.FLATTR_URL
, data
=params
)
148 if '_gpodder_statuscode' in content
:
149 status_code
= content
['_gpodder_statuscode']
150 if status_code
== 401:
151 return (False, _('Not enough means to flattr'))
152 elif status_code
== 404:
153 return (False, _('Item does not exist on Flattr'))
154 elif status_code
== 403:
155 return (False, _('Already flattred or own item'))
157 return (False, _('Invalid request'))
159 if '_gpodder_no_connection' in content
:
160 return (False, _('No internet connection'))
162 return (True, content
.get('description', _('No description')))
165 def get_autosubmit_url(self
, thing
):
166 """ returns the auto-submit URL for the given FlattrThing """
168 publish_username
= self
.user
.profile
.settings
.get_wksetting(FLATTR_USERNAME
)
170 if not publish_username
:
173 URL_TEMPLATE
= 'https://flattr.com/submit/auto?user_id=%s' % (publish_username
,)
176 raise ValueError('Thing must at least have an url')
178 optional_args
= set(thing
._fields
) - set(['url'])
180 args
= [(u
'url', self
.domain
+ thing
.url
)]
181 args
+= [(arg
, getattr(thing
, arg
, None)) for arg
in optional_args
]
182 args
= filter(lambda (k
, v
): v
, args
) # filter out empty arguments
184 # TODO: check encoding
185 args
= [(k
, v
.encode('utf-8')) for (k
, v
) in args
]
187 args_str
= urllib
.urlencode(args
)
189 autosubmit
= URL_TEMPLATE
+ '&' + args_str
194 # A thing that can be flattred by other Flattr users
195 FlattrThing
= namedtuple('FlattrThing', 'url title description language tags ' +