diff options
Diffstat (limited to 'tinder.py')
-rw-r--r-- | tinder.py | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/tinder.py b/tinder.py new file mode 100644 index 0000000..aaa94a4 --- /dev/null +++ b/tinder.py @@ -0,0 +1,180 @@ + +import json +import requests +from time import time + +from profile import TinderProfile + + +# +# References: +# - Tinder API documentation (https://gist.github.com/rtt/10403467) +# - pynder (https://github.com/charliewolf/pynder) +# + + +class TinderLoginError(Exception): + pass + + +class InitializationError(Exception): + pass + + +class RequestError(Exception): + pass + + +class ProcessingError(Exception): + pass + + +API_BASE = 'https://api.gotinder.com' + + +class TinderAPI(object): + + def __init__(self, fb_id, fb_token): + """Create a new Tinder interface.""" + + headers = { + "Content-Type": "application/json; charset=utf-8", + "User-Agent": "Tinder Android Version 6.4.1", + "Host": API_BASE, + "os_version": "1935", + "app-version": "371", + "platform": "android", + "Accept-Encoding": "gzip" + } + + self._session = requests.Session() + self._session.headers.update(headers) + + self._auth(fb_id, fb_token) + + + def _url(self, path): + """Build a full URL to resources.""" + + return API_BASE + path + + + def _auth(self, fb_id, fb_token): + """Authenticate with Tinder services.""" + + params = { + "facebook_id": fb_id, + "facebook_token": fb_token + } + + params = json.dumps(params) + + response = self._session.post(self._url('/auth'), data=params) + + response = json.loads(response.content.decode('utf-8')) + + if 'token' not in response: + raise TinderLoginError() + + self._token = response['token'] + self._session.headers.update({"X-Auth-Token": str(response['token'])}) + + + def get_auth_token(self): + """Provide the Tider authentication token.""" + + if not hasattr(self, '_token'): + raise TinderInitializationError() + + return self._token + + + def _request(self, method, url, data={}): + """Perform a request to Tinder's services in a generic way.""" + + if not hasattr(self, '_token'): + raise TinderInitializationError() + + result = self._session.request(method, self._url(url), data=json.dumps(data)) + + while result.status_code == 429: + blocker = threading.Event() + blocker.wait(0.01) + result = self._session.request(method, self._url(url), data=data) + + if result.status_code != 200: + raise RequestError(result.status_code) + + return result.json() + + + def _get(self, url): + """Perform a GET request.""" + + return self._request("get", url) + + + def _post(self, url, data={}): + """Perform a POST request.""" + + return self._request("post", url, data=data) + + + def _meta(self): + """Get meta information about the current Tinder user.""" + + return self._get("/meta") + + + def get_remaining_likes(self): + """Provide the number of remaining likes for the current Tinder user.""" + + meta_dct = self._meta() + + return meta_dct['rating']['likes_remaining'] + + + def get_recommendations(self, limit=10): + """Get a fresh list of Tinder profiles.""" + + new = [] + + data = self._post("/user/recs", data={"limit": limit}) + + for d in data['results']: + if not d["_id"].startswith("tinder_rate_limited_id_"): + profile = TinderProfile(d) + new.append(profile) + + return new + + + def get_info(self, uid): + """Get information about a given Tinder user.""" + + data = self._get("/user/" + uid) + + if 'results' in data: + profile = TinderProfile(data['results']) + else: + profile = None + + return profile + + + def like(self, uid): + """Like a Tinder profile.""" + + self._get('/like/%s' % uid) + + if data['status'] != 200: + raise ProcessingError() + + + def dislike(self, uid): + """Dislike a Tinder profile.""" + + data = self._get('/pass/%s' % uid) + + if data['status'] != 200: + raise ProcessingError() |