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
):
43 def _get_callback(self
):
44 return 'https://' + 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
= [(u
'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 # TODO: check encoding
181 args
= [(k
, v
.encode('utf-8')) for (k
, v
) in args
]
183 args_str
= urllib
.urlencode(args
)
185 autosubmit
= URL_TEMPLATE
+ '&' + args_str
190 # A thing that can be flattred by other Flattr users
191 FlattrThing
= namedtuple('FlattrThing', 'url title description language tags ' +