Don't override __class__ on LinkCompressed or PromotedLink. Fixes a class of especially annoying bugs

This commit is contained in:
ketralnis
2008-12-10 11:18:09 -08:00
parent 8bcdf103ba
commit 8a27ada22e
10 changed files with 57 additions and 41 deletions

View File

@@ -146,11 +146,13 @@ class ListingController(RedditController):
@staticmethod
def builder_wrapper(thing):
if c.user.pref_compress and isinstance(thing, Link):
thing.__class__ = LinkCompressed
thing.score_fmt = Score.points
w = Wrapped(thing)
return Wrapped(thing)
if c.user.pref_compress and isinstance(thing, Link):
w.render_class = LinkCompressed
w.score_fmt = Score.points
return w
def GET_listing(self, **env):
return self.build_listing(**env)
@@ -443,8 +445,8 @@ class MessageController(ListingController):
if isinstance(thing, Comment):
p = thing.make_permalink_slow()
f = thing._fullname
thing.__class__ = Message
w = Wrapped(thing)
w.render_class = Message
w.to_id = c.user._id
w.subject = 'comment reply'
w.was_comment = True

View File

@@ -306,12 +306,6 @@ def validate_css(string):
return parsed,report
def builder_wrapper(thing):
if c.user.pref_compress and isinstance(thing, Link):
thing.__class__ = LinkCompressed
thing.score_fmt = Score.points
return Wrapped(thing)
def find_preview_comments(sr):
comments = Comment._query(Comment.c.sr_id == c.site._id,
limit=25, data=True)
@@ -336,6 +330,7 @@ def find_preview_links(sr):
def rendered_link(id, res, links, media, compress):
from pylons.controllers.util import abort
from r2.controllers import ListingController
try:
render_style = c.render_style
@@ -347,7 +342,7 @@ def rendered_link(id, res, links, media, compress):
c.user.pref_media = media
b = IDBuilder([l._fullname for l in links],
num = 1, wrap = builder_wrapper)
num = 1, wrap = ListingController.builder_wrapper)
l = LinkListing(b, nextprev=False,
show_nums=True).listing().render(style='html')
res._update(id, innerHTML=l)

View File

@@ -47,11 +47,14 @@ class tp_manager:
self.templates[key] = handler
def get(self, thing, style, cache = True):
if not isinstance(thing, type(object)):
thing = thing.__class__
style = style.lower()
top_key = (thing.__class__.__name__.lower(), style)
top_key = (thing.__name__.lower(), style)
template = None
for cls in inspect.getmro(thing.__class__):
for cls in inspect.getmro(thing):
name = cls.__name__.lower()
key = (name, style)
if not self.templates.has_key(key):

View File

@@ -121,8 +121,8 @@ def get_promoted_slow():
def promote_builder_wrapper(alternative_wrapper):
def wrapper(thing):
if isinstance(thing, Link) and thing.promoted:
thing.__class__ = PromotedLink
w = Wrapped(thing)
w.render_class = PromotedLink
w.rowstyle = 'promoted link'
return w

View File

@@ -34,6 +34,9 @@ class Wrapped(object):
for k, v in context.iteritems():
setattr(self, k, v)
if self.__class__ == Wrapped and lookups:
self.render_class = lookups[0].__class__
def __getattr__(self, attr):
#print "GETATTR: " + str(attr)
#one would think this would never happen
@@ -60,14 +63,13 @@ class Wrapped(object):
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, self.lookups)
def template(self, style = 'html'):
from r2.config.templates import tpm
from pylons import g
debug = g.template_debug
template = None
if self.__class__ == Wrapped:
for lookup in self.lookups:
for lookup in self.lookups + (self.render_class,):
try:
template = tpm.get(lookup, style, cache = not debug)
except AttributeError:

View File

@@ -101,7 +101,8 @@ class Builder(object):
for item in items:
w = self.wrap(item)
wrapped.append(w)
types.setdefault(item.__class__, []).append(w)
types.setdefault(w.render_class, []).append(w)
#TODO pull the author stuff into add_props for links and
#comments and messages?

View File

@@ -184,11 +184,12 @@ class Link(Thing, Printable):
return True
def cache_key(self, wrapped):
@staticmethod
def cache_key(wrapped):
if c.user_is_admin:
return False
s = (str(i) for i in (self._fullname,
s = (str(i) for i in (wrapped._fullname,
bool(c.user_is_loggedin),
wrapped.subreddit == c.site,
c.user.pref_newwindow,
@@ -302,6 +303,11 @@ class Link(Thing, Printable):
when possible. """
return Subreddit._byID(self.sr_id, True, return_dict = False)
# Note that there are no instances of PromotedLink or LinkCompressed,
# so overriding their methods here will not change their behaviour
# (except for add_props). These classes are used to override the
# render_class on a Wrapped to change the template used for rendering
class PromotedLink(Link):
_nodb = True
@@ -334,8 +340,6 @@ class PromotedLink(Link):
# keep the template from trying to read it
item.promoted_by = None
class LinkCompressed(Link):
_nodb = True
@@ -408,14 +412,15 @@ class Comment(Thing, Printable):
def keep_item(self, wrapped):
return True
def cache_key(self, wrapped):
@staticmethod
def cache_key(wrapped):
if c.user_is_admin:
return False
s = (str(i) for i in (c.profilepage,
self._fullname,
wrapped._fullname,
bool(c.user_is_loggedin),
c.focal_comment == self._id36,
c.focal_comment == wrapped._id36,
request.host,
c.cname,
wrapped.author == c.user,
@@ -507,7 +512,8 @@ class MoreComments(object):
author = None
margin = 0
def cache_key(self, item):
@staticmethod
def cache_key(item):
return False
def __init__(self, link, depth, parent=None):
@@ -578,9 +584,10 @@ class Message(Thing, Printable):
else:
item.new = False
item.score_fmt = Score.none
def cache_key(self, wrapped):
@staticmethod
def cache_key(wrapped):
#warning: inbox/sent messages
#comments as messages
return False

View File

@@ -61,7 +61,7 @@ class Listing(object):
fullnames = {}
for i in self.builder.item_iter(builder_items):
rs = c.render_style
key = i.cache_key(i)
key = i.render_class.cache_key(i)
if key:
fullnames[key + rs + c.lang] = i

View File

@@ -248,11 +248,12 @@ class Subreddit(Thing, Printable):
item.score_fmt = Score.subscribers
#TODO: make this work
def cache_key(self, wrapped):
@staticmethod
def cache_key(wrapped):
if c.user_is_admin:
return False
s = (str(i) for i in (self._fullname,
s = (str(i) for i in (wrapped._fullname,
bool(c.user_is_loggedin),
wrapped.subscriber,
wrapped.moderator,

View File

@@ -48,16 +48,21 @@ ${self.RenderPrintable()}
</%def>
<%def name="RenderPrintable()">
<% fullname = thing._fullname %>
<% cls = thing.lookups[0].__class__.__name__.lower() %>
<%
if thing.show_spam:
rowclass = thing.rowstyle + " spam"
elif thing.show_reports:
rowclass = thing.rowstyle + " reported"
else:
rowclass = thing.rowstyle
%>
<%
fullname = thing._fullname
if hasattr(thing, 'render_class'):
cls = thing.render_class
else:
cls = thing.lookups[0].__class__
cls = cls.__name__.lower()
if thing.show_spam:
rowclass = thing.rowstyle + " spam"
elif thing.show_reports:
rowclass = thing.rowstyle + " reported"
else:
rowclass = thing.rowstyle
%>
<div id="thingrow_${fullname}" class="${rowclass} ${cls}" $display>
<p id="pre_${fullname}">
${self.ParentDiv()}