Browse files

Questions work for the most part.

Added str() and unicode() for most models. Refactored some stuff in Site.
Added rate limit information - use the tuple Site.rate_limit. Don't use
the other property - it's wrong.
  • Loading branch information...
lucjon committed May 23, 2010
1 parent 2d68026 commit d3bf0e8548d719a3f4321e316cb392f989a0e651
Showing with 81 additions and 15 deletions.
  1. +73 −15
  2. +8 −0
@@ -121,11 +121,17 @@ class Answer(JSONModel):
def _extend(self, json, site): = json.answer_id
self.comments = site.build_from_snippet(json.comments, Comment) if ('comment' in json._params_ and json._params_['comment']) else StackExchangeLazySequence(Comment, None, site, json.answer_comments_url, self._up('comments'))
if not hasattr(json, '_params_'):
comment = False
comment = ('comment' in json._params_ and json._params_['comment'])
self.comments = site.build_from_snippet(json.comments, Comment) if comment else StackExchangeLazySequence(Comment, None, site, json.answer_comments_url, self._up('comments'))
self._question, self._owner = None, None
self.owner_id = json.owner['user_id']
self.owner_info = tuple(json.owner.values())
if hasattr(json, 'owner'):
self.owner_id = json.owner['user_id']
self.owner_info = tuple(json.owner.values())
self.creation_date =
@@ -139,8 +145,32 @@ def _extend(self, json, site):
question = property(lambda self: self._question if self._question is not None else
owner = property(lambda self: self._owner if self._owner is not None else
class Question(object):
def __unicode__(self):
return u'Answer %d [%s]' % (, self.title)
def __str__(self):
return str(unicode(self))
class Question(JSONModel):
transfer = ('tags', 'favorite_count', 'up_vote_count', 'down_vote_count', 'view_count', 'score', 'community_owned', 'title', 'body')
def _extend(self, json, site): = json.question_id
self.timeline = LazyTimeline(self, json.question_timeline_url, self._up('timeline'))
self.comments_url = json.question_comments_url
self.comments = StackExchangeLazySequence(Comment, None, site, self.comments_url, self._up('comments'))
self.answers_url = json.question_answers_url
self.answers = [Answer(x, site) for x in json.answers]
self.owner_id = json.owner['user_id']
self.owner = User.partial(lambda self:, site, {
'id': self.owner_id,
'user_type': UserType.from_string(json.owner['user_type']),
'display_name': json.owner['display_name'],
'reputation': json.owner['reputation'],
'email_hash': json.owner['email_hash']})
class Comment(JSONModel):
transfer = ('post_id', 'score', 'edit_count', 'body')
@@ -171,6 +201,11 @@ def get_post(self):
elif self.post_type == PostType.Answer:
def __unicode__(self):
return u'Comment ' + str(
def __str__(self):
return str(unicode(self))
##### Users ####
@@ -219,14 +254,23 @@ def _extend(self, json, site):
self.reputation_detail = StackExchangeLazySequence(RepChange, None, site, json.user_reputation_url, self._up('reputation_detail'))
self.vote_counts = (self.up_vote_count, self.down_vote_count)
self.badge_counts_t = (json.badge_counts['gold'], json.badge_counts['silver'], json.badge_counts['bronze'])
gold = json.badge_counts['gold'] if 'gold' in json.badge_counts else 0
silver = json.badge_counts['silver'] if 'silver' in json.badge_counts else 0
bronze = json.badge_counts['bronze'] if 'bronze' in json.badge_counts else 0
self.badge_counts_t = (gold, silver, bronze)
self.badge_counts = {
BadgeType.Gold: json.badge_counts['gold'],
BadgeType.Silver: json.badge_counts['silver'],
BadgeType.Bronze: json.badge_counts['bronze']
BadgeType.Gold: gold,
BadgeType.Silver: silver,
BadgeType.Bronze: bronze
self.gold_badges, self.silver_badges, self.bronze_badges = self.badge_counts_t
self.badge_total = reduce(operator.add, self.badge_counts_t)
def __unicode__(self):
return 'User %d [%s]' % (, self.display_name)
def __str__(self):
return str(unicode(self))
class Site(object):
@@ -242,6 +286,7 @@ def __init__(self, domain, app_key=None):
User: 'users/%s',
Answer: 'answers/%s',
Comment: 'comments/%s',
Question: 'questions/%s',
def _request(self, to, params):
@@ -265,6 +310,11 @@ def _request(self, to, params):
conn = urllib2.urlopen(url)
dump = json.load(conn)
info =
self.rate_limit = (int(info.getheader('X-RateLimit-Current')), int(info.getheader('X-RateLimit-Max')))
self.requests_left = self.rate_limit[1] - self.rate_limit[0]
return dump
@@ -296,28 +346,36 @@ def build(self, url, typ, collection, kw={}):
def build_from_snippet(self, json, typ):
return StackExchangeResultSet([typ(x, self) for x in json])
def _get(self, typ, ids, coll, kw):
root = self.URL_Roots[typ] % ';'.join([str(x) for x in ids])
return, typ, coll, kw)
def user(self, nid, **kw):
"""Retrieves an object representing the user with the ID `nid`."""
u, = self.users((nid,), **kw)
return u
def users(self, ids, **kw):
"""Retrieves a list of the users with the IDs specified in the `ids' parameter."""
root = self.URL_Roots[User] % ';'.join([str(x) for x in ids])
return, User, 'users', kw)
return self._get(User, ids, 'users', kw)
def answer(self, nid, **kw):
a, = self.answers((nid,), **kw)
return a
def answers(self, ids, **kw):
root = self.URL_Roots[Answer] % ';'.join([str(x) for x in ids])
return, Answer, 'answers', kw)
return self._get(Answer, ids, 'answers', kw)
def comment(self, nid, **kw):
c, = self.comments((nid,), **kw)
return c
def comments(self, ids, **kw):
root = self.URL_Roots[Comment] % ';'.join([str(x) for x in ids])
return, Comment, 'comments', kw)
return self._get(Comment, ids, 'comments', kw)
def question(self, nid, **kw):
q, = self.questions((nid,), **kw)
return q
def questions(self, ids, **kw):
return self._get(Question, ids, 'questions', kw)
@@ -11,3 +11,11 @@
print 'Downloading user information for user #150...'
user = site.user(150)
print repr(user)
## 2.) Get question #4 150
print 'Downloading question #4...'
question = site.question(4)
print repr(question)
## f.) Print rate info
print '-> Finished. (requests, total) = %s' % repr(site.rate_limit)

0 comments on commit d3bf0e8

Please sign in to comment.