# Copyright 2009-2010 Joshua Roesslein
# See LICENSE for details.
-from tweepy.error import TweepError
+from __future__ import absolute_import, print_function
+
from tweepy.utils import parse_datetime, parse_html_value, parse_a_href
if self._max_id:
return self._max_id
ids = self.ids()
- return max(ids) if ids else None
+ # Max_id is always set to the *smallest* id, minus one, in the set
+ return (min(ids) - 1) if ids else None
@property
def since_id(self):
if self._since_id:
return self._since_id
ids = self.ids()
- return min(ids) if ids else None
+ # Since_id is always set to the *greatest* id in the set
+ return max(ids) if ids else None
def ids(self):
return [item.id for item in self if hasattr(item, 'id')]
+
class Model(object):
def __init__(self, api=None):
@classmethod
def parse_list(cls, api, json_list):
- """Parse a list of JSON objects into a result set of model instances."""
+ """
+ Parse a list of JSON objects into
+ a result set of model instances.
+ """
results = ResultSet()
for obj in json_list:
if obj:
return results
def __repr__(self):
- state = ['%s=%s' % (k, repr(v)) for (k,v) in vars(self).items()]
+ state = ['%s=%s' % (k, repr(v)) for (k, v) in vars(self).items()]
return '%s(%s)' % (self.__class__.__name__, ', '.join(state))
@classmethod
def parse(cls, api, json):
status = cls(api)
- for k, v in json.items():
-
- # Hack by guyrt to fix unicode issues, which we do *not* want to teach.
- if isinstance(v, basestring):
- v = v.encode('ascii', errors='ignore')
+ # I'm not proud. Blame billg.
+ import sys
+ json['text'] = str(json['text'].encode(sys.stdout.encoding, 'replace'))[2:-1]
+ if 'user' in json:
+ json['user']['screen_name'] = str(json['user']['screen_name'].encode(sys.stdout.encoding, 'replace'))[2:-1]
+
+ setattr(status, '_json', json)
+ for k, v in json.items():
if k == 'user':
user_model = getattr(api.parser.model_factory, 'user') if api else User
user = user_model.parse(api, v)
def favorite(self):
return self._api.create_favorite(self.id)
+ def __eq__(self, other):
+ if isinstance(other, Status):
+ return self.id == other.id
+
+ return NotImplemented
+
+ def __ne__(self, other):
+ result = self == other
+
+ if result is NotImplemented:
+ return result
+
+ return not result
+
class User(Model):
@classmethod
def parse(cls, api, json):
user = cls(api)
+ setattr(user, '_json', json)
for k, v in json.items():
if k == 'created_at':
setattr(user, k, parse_datetime(v))
self.following = False
def lists_memberships(self, *args, **kargs):
- return self._api.lists_memberships(user=self.screen_name, *args, **kargs)
+ return self._api.lists_memberships(user=self.screen_name,
+ *args,
+ **kargs)
def lists_subscriptions(self, *args, **kargs):
- return self._api.lists_subscriptions(user=self.screen_name, *args, **kargs)
+ return self._api.lists_subscriptions(user=self.screen_name,
+ *args,
+ **kargs)
def lists(self, *args, **kargs):
- return self._api.lists_all(user=self.screen_name, *args, **kargs)
+ return self._api.lists_all(user=self.screen_name,
+ *args,
+ **kargs)
def followers_ids(self, *args, **kargs):
- return self._api.followers_ids(user_id=self.id, *args, **kargs)
+ return self._api.followers_ids(user_id=self.id,
+ *args,
+ **kargs)
class DirectMessage(Model):
@classmethod
def parse(cls, api, json):
metadata = json['search_metadata']
- results = SearchResults(metadata.get('max_id'), metadata.get('since_id'))
+ results = SearchResults()
results.refresh_url = metadata.get('refresh_url')
results.completed_in = metadata.get('completed_in')
results.query = metadata.get('query')
results.count = metadata.get('count')
results.next_results = metadata.get('next_results')
+ status_model = getattr(api.parser.model_factory, 'status') if api else Status
+
for status in json['statuses']:
- results.append(Status.parse(api, status))
+ results.append(status_model.parse(api, status))
return results
@classmethod
def parse(cls, api, json):
lst = List(api)
- for k,v in json.items():
+ for k, v in json.items():
if k == 'user':
setattr(lst, k, User.parse(api, v))
elif k == 'created_at':
return self._api.destroy_list(self.slug)
def timeline(self, **kargs):
- return self._api.list_timeline(self.user.screen_name, self.slug, **kargs)
+ return self._api.list_timeline(self.user.screen_name,
+ self.slug,
+ **kargs)
def add_member(self, id):
return self._api.add_list_member(self.slug, id)
return self._api.remove_list_member(self.slug, id)
def members(self, **kargs):
- return self._api.list_members(self.user.screen_name, self.slug, **kargs)
+ return self._api.list_members(self.user.screen_name,
+ self.slug,
+ **kargs)
def is_member(self, id):
- return self._api.is_list_member(self.user.screen_name, self.slug, id)
+ return self._api.is_list_member(self.user.screen_name,
+ self.slug,
+ id)
def subscribe(self):
return self._api.subscribe_list(self.user.screen_name, self.slug)
return self._api.unsubscribe_list(self.user.screen_name, self.slug)
def subscribers(self, **kargs):
- return self._api.list_subscribers(self.user.screen_name, self.slug, **kargs)
+ return self._api.list_subscribers(self.user.screen_name,
+ self.slug,
+ **kargs)
def is_subscribed(self, id):
- return self._api.is_subscribed_list(self.user.screen_name, self.slug, id)
+ return self._api.is_subscribed_list(self.user.screen_name,
+ self.slug,
+ id)
+
class Relation(Model):
@classmethod
def parse(cls, api, json):
result = cls(api)
- for k,v in json.items():
+ for k, v in json.items():
if k == 'value' and json['kind'] in ['Tweet', 'LookedupStatus']:
setattr(result, k, Status.parse(api, v))
elif k == 'results':
setattr(result, k, v)
return result
+
class Relationship(Model):
@classmethod
def parse(cls, api, json):
result = cls(api)
- for k,v in json.items():
+ for k, v in json.items():
if k == 'connections':
setattr(result, 'is_following', 'following' in v)
setattr(result, 'is_followed_by', 'followed_by' in v)
setattr(result, k, v)
return result
+
class JSONModel(Model):
@classmethod
results.append(cls.parse(api, obj))
return results
+
+class Media(Model):
+
+ @classmethod
+ def parse(cls, api, json):
+ media = cls(api)
+ for k, v in json.items():
+ setattr(media, k, v)
+ return media
+
+
class ModelFactory(object):
"""
Used by parsers for creating instances
list = List
relation = Relation
relationship = Relationship
+ media = Media
json = JSONModel
ids = IDModel
place = Place
bounding_box = BoundingBox
-