diff --git a/pynder/api.py b/pynder/api.py index ecb9de0..e9f9140 100644 --- a/pynder/api.py +++ b/pynder/api.py @@ -23,7 +23,8 @@ def _full_url(self, url): return constants.API_BASE + url def auth(self, facebook_id, facebook_token): - data = {"facebook_id": str(facebook_id), "facebook_token": facebook_token} + data = {"facebook_id": str(facebook_id), + "facebook_token": facebook_token} result = self._session.post( self._full_url('/auth'), json=data, proxies=self._proxies).json() if 'token' not in result: @@ -65,10 +66,10 @@ def meta(self): def add_profile_photo(self, fbid, x_dist, y_dist, x_offset, y_offset): data = { - "transmit": "fb", - "assets": [{"id": str(fbid), "xdistance_percent": float(x_dist), "ydistance_percent": float(y_dist), - "xoffset_percent": float(x_offset), "yoffset_percent": float(y_offset)}] - } + "transmit": "fb", + "assets": [{"id": str(fbid), "xdistance_percent": float(x_dist), "ydistance_percent": float(y_dist), + "xoffset_percent": float(x_offset), "yoffset_percent": float(y_offset)}] + } return self._request("post", constants.CONTENT_BASE + "/media", data=data) @@ -90,7 +91,10 @@ def update_profile(self, profile): return self._post("/profile", profile) def like(self, user): - return self._get("/like/{}".format(user)) + ans = self._get("/like/{}".format(user)) + if 'rate_limited_until' in ans: + raise errors.RequestError('Like limit exceeded') + return ans def dislike(self, user): return self._get("/pass/{}".format(user)) diff --git a/pynder/models/user.py b/pynder/models/user.py index 05c8407..d722ebc 100644 --- a/pynder/models/user.py +++ b/pynder/models/user.py @@ -1,13 +1,14 @@ import itertools import datetime import dateutil.parser -import six +from future.utils import python_2_unicode_compatible from pynder.models.base import Model from pynder.constants import GENDER_MAP, SIMPLE_FIELDS, VALID_PHOTO_SIZES from pynder.models.message import Message +@python_2_unicode_compatible class User(Model): def __init__(self, data, session): @@ -23,13 +24,21 @@ def __init__(self, data, session): self.schools = {} self.jobs = [] try: - self.schools.update({school["id"]: school["name"] for school in data['schools'] if 'id' in school and 'name' in school}) - self.jobs.extend(["%s @ %s" % (job["title"]["name"], job["company"]["name"]) for job in data['jobs'] if 'title' in job and 'company' in job]) - self.jobs.extend(["%s" % (job["company"]["name"],) for job in data['jobs'] if 'title' not in job and 'company' in job]) - self.jobs.extend(["%s" % (job["title"]["name"],) for job in data['jobs'] if 'title' in job and 'company' not in job]) + self.schools.update({school["id"]: school["name"] + for school in data['schools'] if 'id' in school and 'name' in school}) + self.jobs.extend(["%s @ %s" % (job["title"]["name"], job["company"]["name"]) + for job in data['jobs'] if 'title' in job and 'company' in job]) + self.jobs.extend(["%s" % (job["company"]["name"],) + for job in data['jobs'] if 'title' not in job and 'company' in job]) + self.jobs.extend(["%s" % (job["title"]["name"],) + for job in data['jobs'] if 'title' in job and 'company' not in job]) except (ValueError, KeyError): pass + def reload(self): + data = self._session._api.user_info(self.id) + return User(data['results'], self._session) + @property def instagram_username(self): if "instagram" in self._data: @@ -89,14 +98,14 @@ def age(self): def share_link(self): return self._session._api.share(self.id)['link'] - def __unicode__(self): - return u"{n} ({a})".format(n=self.name, a=self.age) - def __str__(self): - return six.text_type(self).encode('utf-8') + return u"{n} ({a})".format(n=self.name, a=self.age) def __repr__(self): - return repr(self.name) + fmt = "User(name={n!r}, age={a}, id={i!r})" + return fmt.format(n=self.name, + a=self.age, + i=self.id) def report(self, cause, text=""): return self._session._api.report(self.id, cause, text) @@ -128,7 +137,7 @@ def __init__(self, match, _session): self.id = match["_id"] self.user, self.messages = None, [] self.match_date = datetime.datetime.strptime( - match["created_date"], "%Y-%m-%dT%H:%M:%S.%fZ" + match["created_date"], "%Y-%m-%dT%H:%M:%S.%fZ" ) if 'person' in match: user_data = _session._api.user_info( diff --git a/pynder/session.py b/pynder/session.py index 8669bb8..694def6 100644 --- a/pynder/session.py +++ b/pynder/session.py @@ -1,5 +1,4 @@ from time import time -from cached_property import cached_property import pynder.api as api from pynder.errors import InitializationError, RecsTimeout @@ -10,17 +9,22 @@ class Session(object): def __init__(self, facebook_token=None, XAuthToken=None, proxies=None, facebook_id=None): if facebook_token is None and XAuthToken is None: - raise InitializationError("Either XAuth or facebook token must be set") + raise InitializationError( + "Either XAuth or facebook token must be set") self._api = api.TinderAPI(XAuthToken, proxies) # perform authentication if XAuthToken is None: self._api.auth(facebook_id, facebook_token) - @cached_property + @property def profile(self): return Profile(self._api.profile(), self._api) + def user_from_id(self, id): + data = self._api.user_info(id) + return User(data['results'], self) + def nearby_users(self, limit=10): while True: response = self._api.recs(limit) @@ -74,7 +78,8 @@ def can_like_in(self): Return the number of seconds before being allowed to issue likes """ now = int(time()) - limited_until = self._api.meta()['rating'].get('rate_limited_until', now) + limited_until = self._api.meta()['rating'].get( + 'rate_limited_until', now) return limited_until / 1000 - now @property