Created
August 17, 2014 20:30
-
-
Save charlierm/4647526c9068130e64b0 to your computer and use it in GitHub Desktop.
Tinder automatcher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Queue | |
import threading | |
import tinderClient | |
import json | |
import logging | |
logging.basicConfig(level=logging.DEBUG) | |
PRODUCER_THREADS = 5 | |
CONSUMER_THREADS = 10 | |
""" | |
Get the access token from this URL. | |
https://www.facebook.com/dialog/oauth?client_id=464891386855067&redirect_uri=https://www.facebook.com/connect/login_success.html | |
""" | |
fb = { | |
'facebook_token': "ACCESS_TOKEN", | |
'facebook_id': "712920247" | |
} | |
location = { | |
'lat': 'LAT', | |
'lon': 'LONG' | |
} | |
t = tinderClient.tinderClient(fb, location=location) | |
r = t.post_ping() | |
q = Queue.Queue() | |
def producer(pid): | |
""" | |
Gets tinder matches and adds them to queue | |
""" | |
logging.info("Producer {} started".format(pid)) | |
while True: | |
try: | |
results = t.get_recs() | |
for result in results['results']: | |
q.put(result) | |
logging.debug(u'Match added to queue: {}'.format(result[u'name'])) | |
logging.info('{} Matches added to queue'.format(len(results['results']))) | |
except Exception as e: | |
logging.info("No results remaining to add to queue") | |
break | |
def consumer(cid): | |
""" | |
Pulls matches off queue and matches them. | |
""" | |
logging.info("Consumer {} started".format(cid)) | |
while True: | |
try: | |
match = q.get(block=True, timeout=5) | |
t.get_like(match['_id']) | |
logging.debug(u"Match liked: {}".format(match[u'name'])) | |
except Queue.Empty as e: | |
logging.info("Queue is empty - stopping thread") | |
break | |
threads = [] | |
#Start Producers | |
for i in range(0, PRODUCER_THREADS): | |
thread = threading.Thread(target=producer, args=(i,)) | |
threads.append(thread) | |
#Start Consumers | |
for i in range(0, CONSUMER_THREADS): | |
thread = threading.Thread(target=consumer, args=(i,)) | |
threads.append(thread) | |
#Start and join all threads | |
[x.start() for x in threads] | |
[x.join() for x in threads] | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import json, urllib2, datetime, string | |
class tinderClient(): | |
tinderApi = "https://api.gotinder.com/" | |
timeOut = 3 | |
token = None | |
location = None | |
headers = None | |
authHeaders = None | |
lastUrl = None | |
lastError = None | |
appVersion = None | |
osVersion = None | |
def __init__(self, token, location = {'lat': '48.856614', 'lon': '2.352222'}, tinderVersion='3.0.4', iosVersion = '7.1'): | |
self.version(tinderVersion, iosVersion) | |
self.authHeaders = { | |
'Accept-Language': 'fr;q=1, en;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5', | |
'User-Agent': 'Tinder/'+tinderVersion+' (iPhone; iOS '+iosVersion+'; Scale/2.00)', | |
'os_version': self.osVersion, | |
'Accept': '*/*', | |
'platform': 'ios', | |
'Connection': 'keep-alive', | |
'app_version': self.appVersion, | |
'Accept-Encoding': 'gzip, deflate' | |
} | |
try: | |
if (isinstance(token, str)): | |
try: | |
self.token = self.auth(json.loads(token))['token'] | |
except: | |
self.token = token | |
else: | |
self.token = self.auth(token)['token'] | |
except: | |
self.errorLogger('Auth', 'Error while getting authentication token') | |
self.location = location | |
self.headers = self.authHeaders | |
self.headers['X-Auth-Token'] = self.token | |
self.headers['Authorization'] = 'Token token="%s"' % (self.token) | |
"""The GET method for the client | |
Used for: recs, user, like, pass""" | |
def get(self, uri): | |
headers = self.headers | |
url = self.lastUrl = self.url(uri) | |
try: | |
r = urllib2.Request(url, headers=headers) | |
return json.loads(urllib2.urlopen(r, timeout=self.timeOut).read()) | |
except urllib2.HTTPError, e: | |
return self.errorLogger('HTTP', e.code) | |
except urllib2.URLError, e: | |
return self.errorLogger('URL', e.code) | |
except Exception: | |
import traceback | |
return self.errorLogger('generic', traceback.format_exc()) | |
"""The POST method for the client | |
Used for: auth, ping, update""" | |
def post(self, uri, data): | |
if (uri == 'auth'): | |
headers = self.authHeaders | |
else: | |
headers = self.headers | |
headers['Content-Type'] = 'application/json; charset=utf-8' | |
data = json.dumps(data) | |
url = self.lastUrl = self.url(uri) | |
try: | |
r = urllib2.Request(url, data=data, headers=headers) | |
return json.loads(urllib2.urlopen(r, timeout=self.timeOut).read()) | |
except urllib2.HTTPError, e: | |
return self.errorLogger('HTTP', e.code) | |
except urllib2.URLError, e: | |
return self.errorLogger('URL', e.code) | |
except Exception: | |
import traceback | |
return self.errorLogger('generic', traceback.format_exc()) | |
"""Authentication method of the client | |
Better not to call it directly unless you know what you're doing | |
Is called upon __init__ to get the auth token""" | |
def auth(self, fbToken): | |
return self.post('auth', fbToken) | |
"""Returns user's Tinder profile""" | |
def get_profile(self): | |
return self.get('profile') | |
"""Updates user's settings | |
Variables: | |
distance_filter: [2,160] | |
gender: [0,1] (male, female) | |
age_filter_min: 18 | |
age_filter_max: 1000 | |
gender_filter: [-1, 0, 1] (males & females, males, females) | |
bio: String""" | |
def post_profile(self, data): | |
return self.post('profile', data) | |
"""Returns nearby users | |
Error messages: | |
recs timeout: did not find nearby users quick enough | |
recs exhausted: no more users nearby right now""" | |
def get_recs(self): | |
return self.get('user/recs') | |
"""Pings Tinder's servers | |
Also used to pass the geolocation""" | |
def post_ping(self): | |
return self.post('user/ping', self.location) | |
"""Gives last updates since lastActivty (matches, messages, ...) | |
If lastActivty is invalid (0 or 1 for instance) it will give you all updates""" | |
def post_updates(self, lastActivity = None): | |
if lastActivity is None: | |
lastActivity = datetime.datetime.utcnow().isoformat() | |
data = {'last_activity_date': lastActivity} | |
return self.post('updates', data) | |
"""Likes uid | |
Returns match: true/false""" | |
def get_like(self, uid): | |
return self.get('like/%s' % (uid)) | |
"""Dislikes uid""" | |
def get_pass(self, uid): | |
return self.get('pass/%s' % (uid)) | |
"""Gets all informations for user uid""" | |
def get_user(self, uid): | |
return self.get('user/%s' % (uid)) | |
"""Formats the API's url""" | |
def url(self,u): | |
return "%s%s" % (self.tinderApi, u) | |
"""Unicode to UTF8 used to debug in console""" | |
def uniutf(t): | |
return t.encode('utf-8') | |
"""Sends a ping with lat and lon as geolocation | |
If you "move" too quick Tinder will notice it""" | |
def updateLocation(self, lat, lon): | |
self.location['lat'] = lat | |
self.location['lon'] = lon | |
return self.post_ping() | |
"""Catches errors and returns them | |
Last error also stored in self.lastError""" | |
def errorLogger(self, Etype, data): | |
e = {'error': 1, 'type': Etype, 'errorData': data, 'url': self.lastUrl, 'headers': self.headers} | |
e = self.lastError = json.dumps(e) | |
return e | |
"""Formats Tinder's and iOS's version correctly for headers | |
Example Tinder version: 3.0.4 | |
Example iOS version: 7.1""" | |
def version(self, tinder, ios): | |
tV = string.split(tinder, '.') | |
self.appVersion = tV[0] | |
tI = filter(None, string.split(ios, '.')) | |
tL = (5 - (len(tI) -1)) | |
self.osVersion = tI[0] + ('0' * ((tL/len('0'))+1))[:tL] + ''.join(tI[1:len(tI)]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment