Commits

edanm committed 167a6e7

Fixed gzip-compression to (hopefully) work for both gzipped and not)

Comments (0)

Files changed (4)

 glob:*.pyc
 glob:*.orig
 glob:stack2blog/settings.py
-glob:stack2blog/settings.py.dist
 glob:*@*

stack2blog/settings.py

-# Django settings for stack2blog project.
-from settings_yuvalcomp import *

stack2blog/settings_edancomp.py

+from base_settings import *
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME   = 'e:/Projects/Web/Stack2Blog/db/db.sqlite'
+DATABASE_USER = ''             # Not used with sqlite3.
+DATABASE_PASSWORD = ''         # Not used with sqlite3.
+DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
+DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = 'e:/Projects/Web/Stack2Blog/site_media/'

stack2blog/stack2blogapp/stackexchange.py

 #### Hack, because I can't be bothered to fix my mistaking JSON's output for an object not a dict
 # Attrib: Eli Bendersky, http://stackoverflow.com/questions/1305532/convert-python-dict-to-object/1305663#1305663
 class DictObject:
-    def __init__(self, entries): 
+    def __init__(self, entries):
         self.__dict__.update(entries)
 
 class StackExchangeError(Exception):
 	def __new__(cls, items, page, pagesize, build_info):
 		cls.page, cls.pagesize, cls.build_info = page, pagesize, build_info
 		return tuple.__new__(cls, items)
-	
+
 	def reload(self):
 		"""Refreshes the data in the resultset with fresh API data. Note that this doesn't work with extended resultsets."""
 		# kind of a cheat, but oh well
 		new_params[4] = new_params[4].copy()
 		new_params[4]['page'] = page
 		return new_params[0].build(*new_params[1:])
-	
+
 	def fetch_extended(self, page):
 		"""Returns a new resultset containing data from this resultset AND from the specified page."""
 		next = self.fetch_page(page)
 	def fetch_next(self):
 		"""Returns the resultset of the data in the next page."""
 		return self.fetch_page(self.page + 1)
-	
+
 	def extend_next(self):
 		"""Returns a new resultset containing data from this resultset AND from the next page."""
 		return self.fetch_extended(self.page + 1)
 		self.url = url
 		self.fetch_callback = fetch
 		self.collection = collection if collection != None else self._collection(url)
-	
+
 	def _collection(self, c):
 		return c.split('/')[-1]
 
 			return self.count
 		else:
 			raise NeedsAwokenError(self)
-	
+
 	def fetch(self):
 		"""Fetch, from the API, the data this sequence is meant to hold."""
 
 				raise ValueError('Supplied fetch callback did not return a usable value.')
 		else:
 			return False
-	
+
 	# Allows the easy creation of updateable, partial classes
 	@classmethod
 	def partial(cls, fetch_callback, site, populate):
 		"""Creates a partial description of the API object, with the proviso that the full set of data can be fetched later."""
 
 		model = cls({}, site, True)
-		
+
 		for k, v in populate.iteritems():
 			setattr(model, k, v)
 
 			self.last_activity_date = datetime.date.fromtimestamp(json.last_activity_date)
 
 		self.votes = (self.up_vote_count, self.down_vote_count)
-	
+
 	question = property(lambda self: self._question if self._question is not None else self.site.question(self.question_id))
 	owner = property(lambda self: self._owner if self._owner is not None else self.site.user(self.owner_id))
 
 
 		if hasattr(json, 'owner'):
 			self.owner_id = json.owner['user_id']
-	
+
 			owner_dict = json.owner
 			owner_dict['id'] = self.owner_id
 			del owner_dict['user_id']
 			owner_dict['user_type'] = UserType.from_string(owner_dict['user_type'])
-	
+
 			self.owner = User.partial(lambda self: self.site.user(self.id), site, owner_dict)
 
 class Comment(JSONModel):
 	transfer = ('post_id', 'score', 'edit_count', 'body')
 	def _extend(self, json, site):
 		self.id = json.comment_id
-		
+
 		self.creation_date = datetime.date.fromtimestamp(json.creation_date)
 		self.owner_id = json.owner['owner_id'] if 'owner_id' in json.owner else json.owner['user_id']
 		self.owner = User.partial(lambda self: self.site.user(self.id), site, {
-			'id': self.owner_id, 
+			'id': self.owner_id,
 			'user_type': Enumeration.from_string(json.owner['user_type'], UserType),
 			'display_name': json.owner['display_name'],
 			'reputation': json.owner['reputation'],
 			'email_hash': json.owner['email_hash']})
-		
+
 		if hasattr(json, 'reply_to'):
 			self.reply_to_user_id = json.reply_to['user_id']
 			self.reply_to = User.partial(lambda self: self.site.user(self.id), site, {
 				'display_name': json.reply_to['display_name'],
 				'reputation': json.reply_to['reputation'],
 				'email_hash': json.reply_to['email_hash']})
-		
+
 		self.post_type = PostType.from_string(json.post_type)
 	def get_post(self):
 		if self.post_type == PostType.Question:
 			return self.site.question(self.post_id)
 		elif self.post_type == PostType.Answer:
 			return self.site.answer(self.post_id)
-	
+
 	def __unicode__(self):
 		return u'Comment ' + str(self.id)
 	def __str__(self):
 	def _extend(self, json, site):
 		self.id = json.badge_id
 		self.recipients = StackExchangeLazySequence(User, None, site, json.badges_recipients_url, self._up('recipients'))
-	
+
 	def __str__(self):
 		return self.name
 
 		self.timeline_type = TimelineEventType.from_string(json.timeline_type)
 		self.post_type = PostType.from_string(json.post_type)
 		self.creation_date = datetime.date.fromtimestamp(json.creation_date)
-	
+
 class TimelineEventType(Enumeration):
 	"""Denotes the type of a timeline event."""
 	_map = {'askoranswered': 'AskOrAnswered'}
 		}
 		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.id, self.display_name)
 	def __str__(self):
 
 		self.include_body = False
 		self.include_comments = False
-	
+
 	URL_Roots = {
 		User: 'users/%s',
 		Badge: 'badges/%s',
 		Comment: 'comments/%s',
 		Question: 'questions/%s',
 	}
-	
+
 	def _request(self, to, params):
 		url = 'http://' + self.domain + '/' + self.api_version + '/' + to
 
 			url += ('?' if not '?' in url else '&') + 'key=' + self.app_key
 
 		try:
+
+			# TODO: This is a temp fix to get things working if the server decides to gzip-encode.
 			conn = urllib2.urlopen(url)
-			dump = json.load(conn)
+			data = conn.read()
+
+			try:
+			    from cStringIO import StringIO
+			    from gzip import GzipFile
+			    data2 = GzipFile('', 'r', 0, StringIO(data)).read()
+			    data = StringIO(data2)
+			except:
+				# This is not a gzipped file, just keep going.
+			    #print "decompress error %s" % err
+			    pass
+
+			dump = json.load(data)
+
 
 			info = conn.info()
 			self.rate_limit = (int(info.getheader('X-RateLimit-Current')), int(info.getheader('X-RateLimit-Max')))
 			return dump
 		except urllib2.URLError, e:
 			raise StackExchangeError(e)
-	
+
 	def be_inclusive(self):
 		"""Include the body and comments of a post, where appropriate, by default."""
 
 			kw['comments'] = str(self.include_comments)
 
 		json = self._request(url, kw)
-		
+
 		if 'page' in json:
 			# we have a paginated resultset
 			page = json['page']
 			pagesize = json['pagesize']
 			items = []
-	
+
 			# create strongly-typed objects from the JSON items
 			for json_item in json[collection]:
 				json_item['_params_'] = kw	# convenient access to the kw hash
 		else:
 			# this isn't a paginated resultset (unlikely, but possible - eg badges)
 			return tuple([typ(x, self) for x in json[collection]])
-	
+
 	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 self.build(root, typ, coll, kw)
 
 		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."""
 		return self._get(User, ids, 'users', kw)
 
 		a, = self.answers((nid,), **kw)
 		return a
-	
+
 	def answers(self, ids, **kw):
 		"""Retrieves a set of the answers with the IDs specified in the 'ids' parameter."""
 		return self._get(Answer, ids, 'answers', kw)
 		"""Retrieves an object representing a comment with the ID `nid`."""
 		c, = self.comments((nid,), **kw)
 		return c
-	
+
 	def comments(self, ids, **kw):
 		"""Retrieves a set of the comments with the IDs specified in the 'ids' parameter."""
 		return self._get(Comment, ids, 'comments', kw)
-	
+
 	def question(self, nid, **kw):
 		"""Retrieves an object representing a question with the ID `nid`. Note that an answer ID can not be specified -
 unlike on the actual site, you will receive an error rather than a redirect to the actual question."""
 		q, = self.questions((nid,), **kw)
 		return q
-	
+
 	def questions(self, ids, **kw):
 		"""Retrieves a set of the comments with the IDs specified in the 'ids' parameter."""
 		return self._get(Question, ids, 'questions', kw)
-	
+
 	def recent_questions(self, **kw):
 		"""Returns the set of the most recent questions on the site, by last activity."""
 		return self.build('questions', Question, 'questions', kw)
-	
+
 	def users_with_badge(self, bid, **kw):
 		"""Returns the set of all the users who have been awarded the badge with the ID 'bid'."""
 		return self.build('badges/' + str(bid), User, 'users', kw)
-	
+
 	def all_badges(self, **kw):
 		"""Returns the set of all the badges which can be awarded on the site, excluding those which are awarded for specific tags."""
 		return self.build('badges', Badge, 'badges', kw)
-	
+
 	def badges(self, ids, **kw):
 		"""Returns information on the badges with the IDs specified in the 'ids' parameter."""
 		return self._get(Badge, ids, 'badges', kw)
 		"""Returns an object representing the badge with the ID 'nid'."""
 		b, = self.badges((nid,), kw)
 		return b
-	
+
 	def all_tag_badges(self, **kw):
 		"""Returns the set of all the tag-based badges: those which are awarded for performance on a specific tag."""
 		return self.build('badges/tags', Badge, 'badges', kw)
-	
+
 	def all_tags(self, **kw):
 		return self.build('tags', Tag, 'tags', kw)
-	
+
 	def stats(self, **kw):
 		return self.build('stats', Statistics, 'statistics', kw)[0]