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
.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
):
43 def _get_callback(self
):
44 return 'http://' + self
.domain
+ reverse('flattr-token')
47 def request(self
, url
, data
=None):
48 headers
= {'Content-Type': 'application/json'}
50 if url
== self
.OAUTH_TOKEN_URL
:
51 # Inject username and password into the request URL
52 url
= utils
.url_add_authentication(url
, settings
.FLATTR_KEY
,
53 settings
.FLATTR_SECRET
)
54 elif self
.user
.settings
.get('flattr_token', ''):
55 headers
['Authorization'] = 'Bearer ' + self
.user
.get_wksetting(FLATTR_TOKEN
)
58 data
= json
.dumps(data
)
61 response
= utils
.urlopen(url
, headers
, data
)
62 except urllib2
.HTTPError
, error
:
63 return {'_gpodder_statuscode': error
.getcode()}
64 except urllib2
.URLError
, error
:
65 return {'_gpodder_no_connection': False}
67 if response
.getcode() == 200:
68 return json
.loads(response
.read())
70 return {'_gpodder_statuscode': response
.getcode()}
72 def get_auth_url(self
):
73 return self
.AUTH_URL_TEMPLATE
% {
74 'client_id': settings
.FLATTR_KEY
,
75 'redirect_uri': self
._get
_callback
(),
79 return bool(self
.user
.get_wksetting(FLATTR_TOKEN
))
81 def process_retrieved_code(self
, url
):
82 url_parsed
= urlparse
.urlparse(url
)
83 query
= urlparse
.parse_qs(url_parsed
.query
)
86 code
= query
['code'][0]
87 token
= self
._request
_access
_token
(code
)
92 def _request_access_token(self
, code
):
93 request_url
= 'https://flattr.com/oauth/token'
97 'grant_type': 'authorization_code',
98 'redirect_uri': self
._get
_callback
(),
101 content
= self
.request(self
.OAUTH_TOKEN_URL
, data
=params
)
102 return content
.get('access_token', '')
105 def get_thing_info(self
, payment_url
):
106 """Get information about a Thing on Flattr
108 Return a tuple (flattrs, flattred):
110 flattrs ... The number of Flattrs this thing received
111 flattred ... True if this user already flattred this thing
113 if not self
.user
.get_wksetting(FLATTR_TOKEN
):
116 quote_url
= urllib
.quote_plus(utils
.sanitize_encoding(payment_url
))
117 url
= self
.THING_INFO_URL_TEMPLATE
% {'url': quote_url
}
118 data
= self
.request(url
)
119 return (int(data
.get('flattrs', 0)), bool(data
.get('flattred', False)))
122 def get_auth_username(self
):
123 if not self
.user
.get_wksetting(FLATTR_TOKEN
):
126 data
= self
.request(self
.USER_INFO_URL
)
127 return data
.get('username', '')
130 def flattr_url(self
, payment_url
):
131 """Flattr an object given its Flattr payment URL
133 Returns a tuple (success, message):
135 success ... True if the item was Flattr'd
136 message ... The success or error message
142 content
= self
.request(self
.FLATTR_URL
, data
=params
)
144 if '_gpodder_statuscode' in content
:
145 status_code
= content
['_gpodder_statuscode']
146 if status_code
== 401:
147 return (False, _('Not enough means to flattr'))
148 elif status_code
== 404:
149 return (False, _('Item does not exist on Flattr'))
150 elif status_code
== 403:
151 return (False, _('Already flattred or own item'))
153 return (False, _('Invalid request'))
155 if '_gpodder_no_connection' in content
:
156 return (False, _('No internet connection'))
158 return (True, content
.get('description', _('No description')))
161 def get_autosubmit_url(self
, thing
):
162 """ returns the auto-submit URL for the given FlattrThing """
164 publish_username
= self
.user
.get_wksetting(FLATTR_USERNAME
)
166 if not publish_username
:
169 URL_TEMPLATE
= 'https://flattr.com/submit/auto?user_id=%s' % (publish_username
,)
172 raise ValueError('Thing must at least have an url')
174 optional_args
= set(thing
._fields
) - set(['url'])
176 args
= [('url', self
.domain
+ thing
.url
)]
177 args
+= [(arg
, getattr(thing
, arg
, None)) for arg
in optional_args
]
178 args
= filter(lambda (k
, v
): v
, args
) # filter out empty arguments
180 args_str
= urllib
.urlencode(args
)
182 autosubmit
= URL_TEMPLATE
+ '&' + args_str
187 # A thing that can be flattred by other Flattr users
188 FlattrThing
= namedtuple('FlattrThing', 'url title description language tags ' +