mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-27 03:00:12 -04:00
Gilding: add support for gilding submissions
This commit is contained in:
@@ -3764,21 +3764,21 @@ class ApiController(RedditController):
|
||||
|
||||
@json_validate(VUser(),
|
||||
VModhash(),
|
||||
comment=VByName("comment", thing_cls=Comment))
|
||||
def POST_generate_payment_blob(self, responder, comment):
|
||||
if not comment:
|
||||
thing=VByName("thing"))
|
||||
def POST_generate_payment_blob(self, responder, thing):
|
||||
if not thing:
|
||||
abort(400, "Bad Request")
|
||||
|
||||
if comment._deleted:
|
||||
if thing._deleted:
|
||||
abort(403, "Forbidden")
|
||||
|
||||
comment_sr = Subreddit._byID(comment.sr_id, data=True)
|
||||
if (not comment_sr.can_view(c.user) or
|
||||
not comment_sr.allow_comment_gilding):
|
||||
thing_sr = Subreddit._byID(thing.sr_id, data=True)
|
||||
if (not thing_sr.can_view(c.user) or
|
||||
not thing_sr.allow_gilding):
|
||||
abort(403, "Forbidden")
|
||||
|
||||
try:
|
||||
recipient = Account._byID(comment.author_id, data=True)
|
||||
recipient = Account._byID(thing.author_id, data=True)
|
||||
except NotFound:
|
||||
self.abort404()
|
||||
|
||||
@@ -3793,7 +3793,7 @@ class ApiController(RedditController):
|
||||
signed=False,
|
||||
recipient=recipient.name,
|
||||
giftmessage=None,
|
||||
comment=comment._fullname,
|
||||
thing=thing._fullname,
|
||||
))
|
||||
|
||||
@validate(srnames=VPrintable("srnames", max_length=2100))
|
||||
|
||||
@@ -1422,25 +1422,35 @@ class FormsController(RedditController):
|
||||
if not payment_blob['goldtype'] == 'gift':
|
||||
self.abort404()
|
||||
|
||||
comment = payment_blob['comment']
|
||||
if (not comment or
|
||||
comment._deleted or
|
||||
not comment.subreddit_slow.can_view(c.user)):
|
||||
recipient = payment_blob['recipient']
|
||||
thing = payment_blob.get('thing')
|
||||
if not thing:
|
||||
thing = payment_blob['comment']
|
||||
if (not thing or
|
||||
thing._deleted or
|
||||
not thing.subreddit_slow.can_view(c.user)):
|
||||
self.abort404()
|
||||
|
||||
recipient = payment_blob['recipient']
|
||||
summary = strings.gold_summary_comment_page
|
||||
if isinstance(thing, Comment):
|
||||
summary = strings.gold_summary_gilding_page_comment
|
||||
else:
|
||||
summary = strings.gold_summary_gilding_page_link
|
||||
summary = summary % {'recipient': recipient.name}
|
||||
months = 1
|
||||
price = g.gold_month_price * months
|
||||
|
||||
if isinstance(thing, Comment):
|
||||
desc = thing.body
|
||||
else:
|
||||
desc = thing.markdown_link_slow()
|
||||
|
||||
content = CreditGild(
|
||||
summary=summary,
|
||||
price=price,
|
||||
months=months,
|
||||
stripe_key=g.STRIPE_PUBLIC_KEY,
|
||||
passthrough=passthrough,
|
||||
comment=comment,
|
||||
description=desc,
|
||||
period=None,
|
||||
)
|
||||
|
||||
@@ -1457,17 +1467,18 @@ class FormsController(RedditController):
|
||||
# variables below are just for gifts
|
||||
signed=VBoolean("signed"),
|
||||
recipient_name=VPrintable("recipient", max_length=50),
|
||||
comment=VByName("comment", thing_cls=Comment),
|
||||
thing=VByName("thing"),
|
||||
giftmessage=VLength("giftmessage", 10000))
|
||||
def GET_gold(self, goldtype, period, months,
|
||||
signed, recipient_name, giftmessage, comment):
|
||||
signed, recipient_name, giftmessage, thing):
|
||||
|
||||
if comment:
|
||||
comment_sr = Subreddit._byID(comment.sr_id, data=True)
|
||||
if (comment._deleted or comment._spam or
|
||||
not comment_sr.can_view(c.user) or
|
||||
not comment_sr.allow_comment_gilding):
|
||||
comment = None
|
||||
if thing:
|
||||
thing_sr = Subreddit._byID(thing.sr_id, data=True)
|
||||
if (thing._deleted or
|
||||
thing._spam or
|
||||
not thing_sr.can_view(c.user) or
|
||||
not thing_sr.allow_gilding):
|
||||
thing = None
|
||||
|
||||
start_over = False
|
||||
recipient = None
|
||||
@@ -1483,10 +1494,10 @@ class FormsController(RedditController):
|
||||
if months is None or months < 1:
|
||||
start_over = True
|
||||
|
||||
if comment:
|
||||
recipient = Account._byID(comment.author_id, data=True)
|
||||
if thing:
|
||||
recipient = Account._byID(thing.author_id, data=True)
|
||||
if recipient._deleted:
|
||||
comment = None
|
||||
thing = None
|
||||
recipient = None
|
||||
start_over = True
|
||||
else:
|
||||
@@ -1515,8 +1526,8 @@ class FormsController(RedditController):
|
||||
payment_blob["signed"] = signed
|
||||
payment_blob["recipient"] = recipient.name
|
||||
payment_blob["giftmessage"] = _force_utf8(giftmessage)
|
||||
if comment:
|
||||
payment_blob["comment"] = comment._fullname
|
||||
if thing:
|
||||
payment_blob["thing"] = thing._fullname
|
||||
|
||||
passthrough = generate_blob(payment_blob)
|
||||
|
||||
@@ -1525,7 +1536,7 @@ class FormsController(RedditController):
|
||||
content=GoldPayment(goldtype, period, months,
|
||||
signed, recipient,
|
||||
giftmessage, passthrough,
|
||||
comment)
|
||||
thing)
|
||||
).render()
|
||||
|
||||
@validate(VUser())
|
||||
|
||||
@@ -62,7 +62,8 @@ from r2.models import (
|
||||
create_gift_gold,
|
||||
create_gold_code,
|
||||
get_discounted_price,
|
||||
make_comment_gold_message,
|
||||
Link,
|
||||
make_gold_message,
|
||||
NotFound,
|
||||
retrieve_gold_transaction,
|
||||
send_system_message,
|
||||
@@ -225,14 +226,15 @@ def months_and_days_from_pennies(pennies, discount=False):
|
||||
days = 31 * months
|
||||
return (months, days)
|
||||
|
||||
def send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id):
|
||||
def send_gift(buyer, recipient, months, days, signed, giftmessage,
|
||||
thing_fullname):
|
||||
admintools.engolden(recipient, days)
|
||||
|
||||
if comment_id:
|
||||
comment = Thing._by_fullname(comment_id, data=True)
|
||||
comment._gild(buyer)
|
||||
if thing_fullname:
|
||||
thing = Thing._by_fullname(thing_fullname, data=True)
|
||||
thing._gild(buyer)
|
||||
else:
|
||||
comment = None
|
||||
thing = None
|
||||
|
||||
if signed:
|
||||
sender = buyer.name
|
||||
@@ -248,17 +250,20 @@ def send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id):
|
||||
else:
|
||||
amount = "%d months" % months
|
||||
|
||||
if not comment:
|
||||
if not thing:
|
||||
subject = _('Let there be gold! %s just sent you reddit gold!') % sender
|
||||
message = strings.youve_got_gold % dict(sender=md_sender, amount=amount)
|
||||
|
||||
if giftmessage and giftmessage.strip():
|
||||
message += "\n\n" + strings.giftgold_note + giftmessage + '\n\n----'
|
||||
else:
|
||||
subject = _('Your comment has been gilded!')
|
||||
message = strings.youve_got_comment_gold % dict(
|
||||
url=comment.make_permalink_slow(),
|
||||
)
|
||||
url = thing.make_permalink_slow()
|
||||
if isinstance(thing, Comment):
|
||||
subject = _('Your comment has been gilded!')
|
||||
message = strings.youve_been_gilded_comment % {'url': url}
|
||||
else:
|
||||
subject = _('Your submission has been gilded!')
|
||||
message = strings.youve_been_gilded_link % {'url': url}
|
||||
|
||||
message += '\n\n' + strings.gold_benefits_msg
|
||||
if g.lounge_reddit:
|
||||
@@ -272,7 +277,7 @@ def send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id):
|
||||
g.log.error('send_gift: could not send system message')
|
||||
|
||||
g.log.info("%s gifted %s to %s" % (buyer.name, amount, recipient.name))
|
||||
return comment
|
||||
return thing
|
||||
|
||||
|
||||
def send_gold_code(buyer, months, days,
|
||||
@@ -354,9 +359,9 @@ class IpnController(RedditController):
|
||||
c.user._commit()
|
||||
|
||||
if payment_blob["goldtype"] == "gift":
|
||||
comment_id = payment_blob.get("comment")
|
||||
comment = send_gift(c.user, recipient, months, days, signed,
|
||||
giftmessage, comment_id)
|
||||
thing_fullname = payment_blob.get("thing")
|
||||
thing = send_gift(c.user, recipient, months, days, signed,
|
||||
giftmessage, thing_fullname)
|
||||
form.set_html(".status", _("the gold has been delivered!"))
|
||||
else:
|
||||
try:
|
||||
@@ -368,7 +373,7 @@ class IpnController(RedditController):
|
||||
"for assistance.")
|
||||
% {'email': g.goldthanks_email})
|
||||
return
|
||||
comment = None
|
||||
thing = None
|
||||
form.set_html(".status",
|
||||
_("the gift code has been messaged to you!"))
|
||||
|
||||
@@ -380,10 +385,9 @@ class IpnController(RedditController):
|
||||
payment_blob["status"] = "processed"
|
||||
g.hardcache.set(blob_key, payment_blob, 86400 * 30)
|
||||
|
||||
if comment:
|
||||
gilding_message = make_comment_gold_message(comment,
|
||||
user_gilded=True)
|
||||
jquery.gild_comment(comment_id, gilding_message, comment.gildings)
|
||||
if thing:
|
||||
gilding_message = make_gold_message(thing, user_gilded=True)
|
||||
jquery.gild_thing(thing_fullname, gilding_message, thing.gildings)
|
||||
|
||||
@textresponse(paypal_secret = VPrintable('secret', 50),
|
||||
payment_status = VPrintable('payment_status', 20),
|
||||
@@ -527,8 +531,9 @@ class IpnController(RedditController):
|
||||
% (recipient_name, custom))
|
||||
signed = payment_blob.get("signed", False)
|
||||
giftmessage = _force_unicode(payment_blob.get("giftmessage", ""))
|
||||
comment_id = payment_blob.get("comment")
|
||||
send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id)
|
||||
thing_fullname = payment_blob.get("thing")
|
||||
send_gift(buyer, recipient, months, days, signed, giftmessage,
|
||||
thing_fullname)
|
||||
instagift = True
|
||||
subject = _("Thanks for giving the gift of reddit gold!")
|
||||
message = _("Your classy gift to %s has been delivered.\n\n"
|
||||
@@ -576,7 +581,7 @@ class Webhook(object):
|
||||
def __init__(self, passthrough=None, transaction_id=None, subscr_id=None,
|
||||
pennies=None, months=None, payer_email='', payer_id='',
|
||||
goldtype=None, buyer=None, recipient=None, signed=False,
|
||||
giftmessage=None, comment=None):
|
||||
giftmessage=None, thing=None):
|
||||
self.passthrough = passthrough
|
||||
self.transaction_id = transaction_id
|
||||
self.subscr_id = subscr_id
|
||||
@@ -589,7 +594,7 @@ class Webhook(object):
|
||||
self.recipient = recipient
|
||||
self.signed = signed
|
||||
self.giftmessage = giftmessage
|
||||
self.comment = comment
|
||||
self.thing = thing
|
||||
|
||||
def load_blob(self):
|
||||
payment_blob = validate_blob(self.passthrough)
|
||||
@@ -598,8 +603,8 @@ class Webhook(object):
|
||||
self.recipient = payment_blob.get('recipient')
|
||||
self.signed = payment_blob.get('signed', False)
|
||||
self.giftmessage = payment_blob.get('giftmessage')
|
||||
comment = payment_blob.get('comment')
|
||||
self.comment = comment._fullname if comment else None
|
||||
thing = payment_blob.get('thing')
|
||||
self.thing = thing._fullname if thing else None
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s: transaction %s>' % (self.__class__.__name__, self.transaction_id)
|
||||
@@ -720,7 +725,7 @@ class GoldPaymentController(RedditController):
|
||||
recipient = webhook.recipient
|
||||
signed = webhook.signed
|
||||
giftmessage = webhook.giftmessage
|
||||
comment = webhook.comment
|
||||
thing = webhook.thing
|
||||
|
||||
gold_recipient = recipient or buyer
|
||||
with gold_lock(gold_recipient):
|
||||
@@ -753,7 +758,7 @@ class GoldPaymentController(RedditController):
|
||||
|
||||
elif goldtype == 'gift':
|
||||
send_gift(buyer, recipient, months, days, signed, giftmessage,
|
||||
comment)
|
||||
thing)
|
||||
subject = "thanks for giving reddit gold!"
|
||||
message = "Your gift to %s has been delivered." % recipient.name
|
||||
|
||||
@@ -1183,12 +1188,12 @@ def validate_blob(custom):
|
||||
ret['recipient'] = recipient
|
||||
except NotFound:
|
||||
raise GoldException('bad recipient')
|
||||
comment_fullname = payment_blob.get('comment', None)
|
||||
if comment_fullname:
|
||||
thing_fullname = payment_blob.get('thing', None)
|
||||
if thing_fullname:
|
||||
try:
|
||||
ret['comment'] = Comment._by_fullname(comment_fullname)
|
||||
ret['thing'] = Thing._by_fullname(thing_fullname)
|
||||
except NotFound:
|
||||
raise GoldException('bad comment')
|
||||
raise GoldException('bad thing')
|
||||
ret['signed'] = payment_blob.get('signed', False)
|
||||
giftmessage = payment_blob.get('giftmessage')
|
||||
giftmessage = _force_unicode(giftmessage) if giftmessage else None
|
||||
|
||||
@@ -520,8 +520,8 @@ class UserController(ListingController):
|
||||
elif (self.where == 'gilded' and
|
||||
(c.user == self.vuser or c.user_is_admin)):
|
||||
path = '/user/%s/gilded/' % self.vuser.name
|
||||
buttons = [NavButton(_("my posts"), dest='/'),
|
||||
NavButton(_("posts gilded by me"), dest='/given')]
|
||||
buttons = [NavButton(_("gildings received"), dest='/'),
|
||||
NavButton(_("gildings given"), dest='/given')]
|
||||
res.append(NavMenu(buttons, base_path=path, type='flatlist'))
|
||||
|
||||
return res
|
||||
@@ -530,14 +530,14 @@ class UserController(ListingController):
|
||||
titles = {'overview': _("overview for %(user)s"),
|
||||
'comments': _("comments by %(user)s"),
|
||||
'submitted': _("submitted by %(user)s"),
|
||||
'gilded': _("gilded comments by %(user)s"),
|
||||
'gilded': _("gilded by %(user)s"),
|
||||
'liked': _("liked by %(user)s"),
|
||||
'disliked': _("disliked by %(user)s"),
|
||||
'saved': _("saved by %(user)s"),
|
||||
'hidden': _("hidden by %(user)s"),
|
||||
'promoted': _("promoted by %(user)s")}
|
||||
if self.where == 'gilded' and self.show == 'given':
|
||||
return _("comments gilded by %(user)s") % {'user': self.vuser.name}
|
||||
return _("gildings given by %(user)s") % {'user': self.vuser.name}
|
||||
|
||||
title = titles.get(self.where, _('profile for %(user)s')) \
|
||||
% dict(user = self.vuser.name, site = c.site.name)
|
||||
@@ -598,7 +598,7 @@ class UserController(ListingController):
|
||||
if self.show == 'given':
|
||||
q = queries.get_user_gildings(self.vuser)
|
||||
else:
|
||||
q = queries.get_gilded_user_comments(self.vuser)
|
||||
q = queries.get_gilded_user(self.vuser)
|
||||
|
||||
elif self.where in ('liked', 'disliked'):
|
||||
sup.set_sup_header(self.vuser, self.where)
|
||||
@@ -1306,7 +1306,7 @@ class UserListListingController(ListingController):
|
||||
return self.build_listing(**kw)
|
||||
|
||||
class GildedController(ListingController):
|
||||
title_text = _("gilded comments")
|
||||
title_text = _("gilded")
|
||||
|
||||
def keep_fn(self):
|
||||
def keep(item):
|
||||
@@ -1315,7 +1315,7 @@ class GildedController(ListingController):
|
||||
|
||||
def query(self):
|
||||
try:
|
||||
return c.site.get_gilded_comments()
|
||||
return c.site.get_gilded()
|
||||
except NotImplementedError:
|
||||
abort(404)
|
||||
|
||||
|
||||
@@ -797,18 +797,60 @@ def get_all_gilded_comments():
|
||||
return
|
||||
|
||||
|
||||
@cached_query(SubredditQueryCache, sort=[desc("date")], filter_fn=filter_thing)
|
||||
def get_all_gilded_links():
|
||||
return
|
||||
|
||||
|
||||
@merged_cached_query
|
||||
def get_all_gilded():
|
||||
return [get_all_gilded_comments(), get_all_gilded_links()]
|
||||
|
||||
|
||||
@cached_query(SubredditQueryCache, sort=[desc("date")], filter_fn=filter_thing)
|
||||
def get_gilded_comments(sr_id):
|
||||
return
|
||||
|
||||
|
||||
@cached_query(SubredditQueryCache, sort=[desc("date")], filter_fn=filter_thing)
|
||||
def get_gilded_links(sr_id):
|
||||
return
|
||||
|
||||
|
||||
@merged_cached_query
|
||||
def get_gilded(sr_ids):
|
||||
queries = [get_gilded_links, get_gilded_comments]
|
||||
return [query(sr_id)
|
||||
for sr_id, query in itertools.product(tup(sr_ids), queries)]
|
||||
|
||||
|
||||
@cached_query(UserQueryCache, sort=[desc("date")], filter_fn=filter_thing)
|
||||
def get_gilded_user_comments(user_id):
|
||||
return
|
||||
|
||||
|
||||
@cached_query(UserQueryCache, sort=[desc("date")], filter_fn=filter_thing)
|
||||
def get_gilded_user_links(user_id):
|
||||
return
|
||||
|
||||
|
||||
@merged_cached_query
|
||||
def get_gilded_users(user_ids):
|
||||
queries = [get_gilded_user_links, get_gilded_user_comments]
|
||||
return [query(user_id)
|
||||
for user_id, query in itertools.product(tup(user_ids), queries)]
|
||||
|
||||
|
||||
@cached_query(UserQueryCache, sort=[desc("date")], filter_fn=filter_thing)
|
||||
def get_user_gildings(user_id):
|
||||
return
|
||||
|
||||
|
||||
@merged_cached_query
|
||||
def get_gilded_user(user):
|
||||
return [get_gilded_user_comments(user), get_gilded_user_links(user)]
|
||||
|
||||
|
||||
def add_queries(queries, insert_items=None, delete_items=None, foreground=False):
|
||||
"""Adds multiple queries to the query queue. If insert_items or
|
||||
delete_items is specified, the query may not need to be
|
||||
|
||||
@@ -409,6 +409,7 @@ class LinkJsonTemplate(ThingJsonTemplate):
|
||||
domain="domain",
|
||||
downs="downvotes",
|
||||
edited="editted",
|
||||
gilded="gildings",
|
||||
hidden="hidden",
|
||||
is_self="is_self",
|
||||
likes="likes",
|
||||
|
||||
@@ -247,17 +247,30 @@ class Reddit(Templated):
|
||||
and not is_api() and not self.show_wiki_actions):
|
||||
# insert some form templates for js to use
|
||||
# TODO: move these to client side templates
|
||||
gold = GoldPayment("gift",
|
||||
"monthly",
|
||||
months=1,
|
||||
signed=False,
|
||||
recipient="",
|
||||
giftmessage=None,
|
||||
passthrough=None,
|
||||
comment=None,
|
||||
clone_template=True,
|
||||
)
|
||||
self._content = PaneStack([ShareLink(), content, gold])
|
||||
gold_link = GoldPayment("gift",
|
||||
"monthly",
|
||||
months=1,
|
||||
signed=False,
|
||||
recipient="",
|
||||
giftmessage=None,
|
||||
passthrough=None,
|
||||
thing=None,
|
||||
clone_template=True,
|
||||
thing_type="link",
|
||||
)
|
||||
gold_comment = GoldPayment("gift",
|
||||
"monthly",
|
||||
months=1,
|
||||
signed=False,
|
||||
recipient="",
|
||||
giftmessage=None,
|
||||
passthrough=None,
|
||||
thing=None,
|
||||
clone_template=True,
|
||||
thing_type="comment",
|
||||
)
|
||||
self._content = PaneStack([ShareLink(), content,
|
||||
gold_comment, gold_link])
|
||||
else:
|
||||
self._content = content
|
||||
|
||||
@@ -2184,9 +2197,10 @@ class Gold(Templated):
|
||||
|
||||
class GoldPayment(Templated):
|
||||
def __init__(self, goldtype, period, months, signed,
|
||||
recipient, giftmessage, passthrough, comment,
|
||||
clone_template=False):
|
||||
recipient, giftmessage, passthrough, thing,
|
||||
clone_template=False, thing_type=None):
|
||||
pay_from_creddits = False
|
||||
desc = None
|
||||
|
||||
if period == "monthly" or 1 <= months < 12:
|
||||
unit_price = g.gold_month_price
|
||||
@@ -2267,9 +2281,17 @@ class GoldPayment(Templated):
|
||||
amount=Score.somethings(months, "month"))
|
||||
elif goldtype == "gift":
|
||||
if clone_template:
|
||||
format = strings.gold_summary_comment_gift
|
||||
elif comment:
|
||||
format = strings.gold_summary_comment_page
|
||||
if thing_type == "comment":
|
||||
format = strings.gold_summary_gilding_comment
|
||||
elif thing_type == "link":
|
||||
format = strings.gold_summary_gilding_link
|
||||
elif thing:
|
||||
if isinstance(thing, Comment):
|
||||
format = strings.gold_summary_gilding_page_comment
|
||||
desc = thing.body
|
||||
else:
|
||||
format = strings.gold_summary_gilding_page_link
|
||||
desc = thing.markdown_link_slow()
|
||||
elif signed:
|
||||
format = strings.gold_summary_signed_gift
|
||||
else:
|
||||
@@ -2298,7 +2320,8 @@ class GoldPayment(Templated):
|
||||
summary=summary, giftmessage=giftmessage,
|
||||
pay_from_creddits=pay_from_creddits,
|
||||
passthrough=passthrough,
|
||||
comment=comment, clone_template=clone_template,
|
||||
thing=thing, clone_template=clone_template,
|
||||
description=desc, thing_type=thing_type,
|
||||
paypal_buttonid=paypal_buttonid,
|
||||
stripe_key=stripe_key,
|
||||
coinbase_button_id=coinbase_button_id)
|
||||
@@ -2340,7 +2363,7 @@ class GoldSubscription(Templated):
|
||||
Templated.__init__(self)
|
||||
|
||||
class CreditGild(Templated):
|
||||
"""Page for credit card payments for comment gilding."""
|
||||
"""Page for credit card payments for gilding."""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ class PrintableButtons(Styled):
|
||||
show_delete = False, show_report = True,
|
||||
show_distinguish = False, show_marknsfw = False,
|
||||
show_unmarknsfw = False, is_link=False,
|
||||
show_flair = False, show_rescrape=False, **kw):
|
||||
show_flair=False, show_rescrape=False,
|
||||
show_givegold=False, **kw):
|
||||
show_ignore = thing.show_reports
|
||||
approval_checkmark = getattr(thing, "approval_checkmark", None)
|
||||
show_approve = (thing.show_spam or show_ignore or
|
||||
@@ -59,6 +60,7 @@ class PrintableButtons(Styled):
|
||||
show_unmarknsfw = show_unmarknsfw,
|
||||
show_flair = show_flair,
|
||||
show_rescrape=show_rescrape,
|
||||
show_givegold=show_givegold,
|
||||
**kw)
|
||||
|
||||
class BanButtons(PrintableButtons):
|
||||
@@ -88,6 +90,7 @@ class LinkButtons(PrintableButtons):
|
||||
if (not thing.is_self and
|
||||
not (thing.has_thumbnail or thing.media_object)):
|
||||
show_rescrape = True
|
||||
show_givegold = thing.can_gild and (c.permalink_page or c.profilepage)
|
||||
|
||||
# do we show the delete button?
|
||||
show_delete = is_author and delete and not thing._deleted
|
||||
@@ -133,6 +136,7 @@ class LinkButtons(PrintableButtons):
|
||||
show_unmarknsfw = show_unmarknsfw,
|
||||
show_flair = thing.can_flair,
|
||||
show_rescrape=show_rescrape,
|
||||
show_givegold=show_givegold,
|
||||
show_comments = comments,
|
||||
# promotion
|
||||
promoted = thing.promoted,
|
||||
@@ -148,28 +152,13 @@ class CommentButtons(PrintableButtons):
|
||||
# do we show the delete button?
|
||||
show_delete = is_author and delete and not thing._deleted
|
||||
|
||||
can_gild = (
|
||||
# you can't gild your own comment
|
||||
not is_author
|
||||
# no point in showing the button for things you've already gilded
|
||||
and not thing.user_gilded
|
||||
# this is a way of checking if the user is logged in that works
|
||||
# both within CommentPane instances and without. e.g. CommentPane
|
||||
# explicitly sets user_is_loggedin = False but can_reply is
|
||||
# correct. while on user overviews, you can't reply but will get
|
||||
# the correct value for user_is_loggedin
|
||||
and (c.user_is_loggedin or thing.can_reply)
|
||||
# ick, if the author deleted their account we shouldn't waste gold
|
||||
and not thing.author._deleted
|
||||
# some subreddits can have gilding disabled
|
||||
and thing.subreddit.allow_comment_gilding
|
||||
)
|
||||
|
||||
show_distinguish = (is_author and
|
||||
(thing.can_ban or # Moderator distinguish
|
||||
c.user.employee or # Admin distinguish
|
||||
c.user_special_distinguish))
|
||||
|
||||
show_givegold = thing.can_gild
|
||||
|
||||
PrintableButtons.__init__(self, "commentbuttons", thing,
|
||||
is_author = is_author,
|
||||
profilepage = c.profilepage,
|
||||
@@ -182,10 +171,11 @@ class CommentButtons(PrintableButtons):
|
||||
deleted = thing.deleted,
|
||||
parent_permalink = thing.parent_permalink,
|
||||
can_reply = thing.can_reply,
|
||||
can_gild=can_gild,
|
||||
show_report = show_report,
|
||||
show_distinguish = show_distinguish,
|
||||
show_delete = show_delete)
|
||||
show_delete = show_delete,
|
||||
show_givegold=show_givegold,
|
||||
)
|
||||
|
||||
class MessageButtons(PrintableButtons):
|
||||
def __init__(self, thing, delete = False, report = True):
|
||||
|
||||
@@ -144,15 +144,18 @@ string_dict = dict(
|
||||
over_comment_limit_gold = _("Sorry, the maximum number of comments is %d."),
|
||||
youve_got_gold = _("%(sender)s just gifted you %(amount)s of reddit gold!"),
|
||||
giftgold_note = _("Here's a note that was included:\n\n----\n\n"),
|
||||
youve_got_comment_gold = _("Another user liked [your comment](%(url)s) so much that they gilded it, giving you reddit gold.\n\n"),
|
||||
youve_been_gilded_comment = _("Another user liked [your comment](%(url)s) so much that they gilded it, giving you reddit gold.\n\n"),
|
||||
youve_been_gilded_link = _("Another user liked [your submission](%(url)s) so much that they gilded it, giving you reddit gold.\n\n"),
|
||||
gold_summary_autorenew = _("You're about to set up an ongoing, autorenewing subscription to reddit gold for yourself (%(user)s)."),
|
||||
gold_summary_onetime = _("You're about to make a one-time purchase of %(amount)s of reddit gold for yourself (%(user)s)."),
|
||||
gold_summary_creddits = _("You're about to purchase %(amount)s of reddit gold creddits. They work like gift certificates: each creddit you have will allow you to give one month of reddit gold to someone else."),
|
||||
gold_summary_gift_code = _("You're about to purchase %(amount)s of reddit gold in the form of a gift code. The recipient (or you) will be able to claim the code to redeem that gold to their account."),
|
||||
gold_summary_signed_gift = _("You're about to give %(amount)s of reddit gold to %(recipient)s, who will be told that it came from you."),
|
||||
gold_summary_anonymous_gift = _("You're about to give %(amount)s of reddit gold to %(recipient)s. It will be an anonymous gift."),
|
||||
gold_summary_comment_gift = _("Want to say thanks to *%(recipient)s* for this comment? Give them a month of [reddit gold](/gold/about)."),
|
||||
gold_summary_comment_page = _("Give *%(recipient)s* a month of [reddit gold](/gold/about) for this comment:"),
|
||||
gold_summary_gilding_comment = _("Want to say thanks to *%(recipient)s* for this comment? Give them a month of [reddit gold](/gold/about)."),
|
||||
gold_summary_gilding_link = _("Want to say thanks to *%(recipient)s* for this submission? Give them a month of [reddit gold](/gold/about)."),
|
||||
gold_summary_gilding_page_comment = _("Give *%(recipient)s* a month of [reddit gold](/gold/about) for this comment:"),
|
||||
gold_summary_gilding_page_link = _("Give *%(recipient)s* a month of [reddit gold](/gold/about) for this submission:"),
|
||||
unvotable_message = _("sorry, this has been archived and can no longer be voted on"),
|
||||
account_activity_blurb = _("This page shows a history of recent activity on your account. If you notice unusual activity, you should change your password immediately. Location information is guessed from your computer's IP address and may be wildly wrong, especially for visits from mobile devices. Note: due to a bug, private-use addresses (starting with 10.) sometimes show up erroneously in this list after regular use of the site."),
|
||||
your_current_ip_is = _("You are currently accessing reddit from this IP address: %(address)s."),
|
||||
|
||||
@@ -22,12 +22,15 @@
|
||||
|
||||
from r2.lib.db.tdb_sql import make_metadata, index_str, create_table
|
||||
|
||||
import json
|
||||
import pytz
|
||||
import uuid
|
||||
|
||||
from pycassa import NotFoundException
|
||||
from pycassa.system_manager import INT_TYPE, UTF8_TYPE
|
||||
from pycassa.util import convert_uuid_to_time
|
||||
from pylons import g, c
|
||||
from pylons.i18n import _
|
||||
from pylons.i18n import _, ungettext
|
||||
from datetime import datetime
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.exc import IntegrityError, OperationalError
|
||||
@@ -42,7 +45,7 @@ from random import choice
|
||||
from time import time
|
||||
|
||||
from r2.lib.db import tdb_cassandra
|
||||
from r2.lib.db.tdb_cassandra import NotFound
|
||||
from r2.lib.db.tdb_cassandra import NotFound, view_of
|
||||
from r2.models import Account
|
||||
from r2.models.subreddit import Frontpage
|
||||
from r2.models.wiki import WikiPage
|
||||
@@ -127,6 +130,107 @@ class GoldRevenueGoalByDate(object):
|
||||
return None
|
||||
|
||||
|
||||
class GildedCommentsByAccount(tdb_cassandra.DenormalizedRelation):
|
||||
_use_db = True
|
||||
_last_modified_name = 'Gilding'
|
||||
_views = []
|
||||
|
||||
@classmethod
|
||||
def value_for(cls, thing1, thing2):
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
def gild(cls, user, thing):
|
||||
cls.create(user, [thing])
|
||||
|
||||
|
||||
class GildedLinksByAccount(tdb_cassandra.DenormalizedRelation):
|
||||
_use_db = True
|
||||
_last_modified_name = 'Gilding'
|
||||
_views = []
|
||||
|
||||
@classmethod
|
||||
def value_for(cls, thing1, thing2):
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
def gild(cls, user, thing):
|
||||
cls.create(user, [thing])
|
||||
|
||||
|
||||
@view_of(GildedCommentsByAccount)
|
||||
@view_of(GildedLinksByAccount)
|
||||
class GildingsByThing(tdb_cassandra.View):
|
||||
_use_db = True
|
||||
_extra_schema_creation_args = {
|
||||
"key_validation_class": tdb_cassandra.UTF8_TYPE,
|
||||
"column_name_class": tdb_cassandra.UTF8_TYPE,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_gilder_ids(cls, thing):
|
||||
columns = cls.get_time_sorted_columns(thing._fullname)
|
||||
return [int(account_id, 36) for account_id in columns.iterkeys()]
|
||||
|
||||
@classmethod
|
||||
def create(cls, user, things):
|
||||
for thing in things:
|
||||
cls._set_values(thing._fullname, {user._id36: ""})
|
||||
|
||||
@classmethod
|
||||
def delete(cls, user, things):
|
||||
# gildings cannot be undone
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@view_of(GildedCommentsByAccount)
|
||||
@view_of(GildedLinksByAccount)
|
||||
class GildingsByDay(tdb_cassandra.View):
|
||||
_use_db = True
|
||||
_compare_with = tdb_cassandra.TIME_UUID_TYPE
|
||||
_extra_schema_creation_args = {
|
||||
"key_validation_class": tdb_cassandra.ASCII_TYPE,
|
||||
"column_name_class": tdb_cassandra.TIME_UUID_TYPE,
|
||||
"default_validation_class": tdb_cassandra.UTF8_TYPE,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _rowkey(date):
|
||||
return date.strftime("%Y-%m-%d")
|
||||
|
||||
@classmethod
|
||||
def get_gildings(cls, date):
|
||||
key = cls._rowkey(date)
|
||||
columns = cls.get_time_sorted_columns(key)
|
||||
gildings = []
|
||||
for name, json_blob in columns.iteritems():
|
||||
timestamp = convert_uuid_to_time(name)
|
||||
date = datetime.utcfromtimestamp(timestamp).replace(tzinfo=g.tz)
|
||||
|
||||
gilding = json.loads(json_blob)
|
||||
gilding["date"] = date
|
||||
gilding["user"] = int(gilding["user"], 36)
|
||||
gildings.append(gilding)
|
||||
return gildings
|
||||
|
||||
@classmethod
|
||||
def create(cls, user, things):
|
||||
key = cls._rowkey(datetime.now(g.tz))
|
||||
|
||||
columns = {}
|
||||
for thing in things:
|
||||
columns[uuid.uuid1()] = json.dumps({
|
||||
"user": user._id36,
|
||||
"thing": thing._fullname,
|
||||
})
|
||||
cls._set_values(key, columns)
|
||||
|
||||
@classmethod
|
||||
def delete(cls, user, things):
|
||||
# gildings cannot be undone
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def create_unclaimed_gold (trans_id, payer_email, paying_id,
|
||||
pennies, days, secret, date,
|
||||
subscr_id = None):
|
||||
@@ -404,3 +508,73 @@ def get_discounted_price(gold_price):
|
||||
discount = float(getattr(g, 'BTC_DISCOUNT', '0'))
|
||||
price = (gold_price.pennies * (1 - discount)) / 100.
|
||||
return GoldPrice("%.2f" % price)
|
||||
|
||||
|
||||
def make_gold_message(thing, user_gilded):
|
||||
from r2.models import Comment
|
||||
|
||||
if thing.gildings == 0 or thing._spam or thing._deleted:
|
||||
return None
|
||||
|
||||
author = Account._byID(thing.author_id, data=True)
|
||||
if not author._deleted:
|
||||
author_name = author.name
|
||||
else:
|
||||
author_name = _("[deleted]")
|
||||
|
||||
if c.user_is_loggedin and thing.author_id == c.user._id:
|
||||
if isinstance(thing, Comment):
|
||||
gilded_message = ungettext(
|
||||
"a redditor gifted you a month of reddit gold for this "
|
||||
"comment.",
|
||||
"redditors have gifted you %(months)d months of reddit gold "
|
||||
"for this comment.",
|
||||
thing.gildings
|
||||
)
|
||||
else:
|
||||
gilded_message = ungettext(
|
||||
"a redditor gifted you a month of reddit gold for this "
|
||||
"submission.",
|
||||
"redditors have gifted you %(months)d months of reddit gold "
|
||||
"for this submission.",
|
||||
thing.gildings
|
||||
)
|
||||
elif user_gilded:
|
||||
if isinstance(thing, Comment):
|
||||
gilded_message = ungettext(
|
||||
"you have gifted reddit gold to %(recipient)s for this "
|
||||
"comment.",
|
||||
"you and other redditors have gifted %(months)d months of "
|
||||
"reddit gold to %(recipient)s for this comment.",
|
||||
thing.gildings
|
||||
)
|
||||
else:
|
||||
gilded_message = ungettext(
|
||||
"you have gifted reddit gold to %(recipient)s for this "
|
||||
"submission.",
|
||||
"you and other redditors have gifted %(months)d months of "
|
||||
"reddit gold to %(recipient)s for this submission.",
|
||||
thing.gildings
|
||||
)
|
||||
else:
|
||||
if isinstance(thing, Comment):
|
||||
gilded_message = ungettext(
|
||||
"a redditor has gifted reddit gold to %(recipient)s for this "
|
||||
"comment.",
|
||||
"redditors have gifted %(months)d months of reddit gold to "
|
||||
"%(recipient)s for this comment.",
|
||||
thing.gildings
|
||||
)
|
||||
else:
|
||||
gilded_message = ungettext(
|
||||
"a redditor has gifted reddit gold to %(recipient)s for this "
|
||||
"submission.",
|
||||
"redditors have gifted %(months)d months of reddit gold to "
|
||||
"%(recipient)s for this submission.",
|
||||
thing.gildings
|
||||
)
|
||||
|
||||
return gilded_message % dict(
|
||||
recipient=author_name,
|
||||
months=thing.gildings,
|
||||
)
|
||||
|
||||
@@ -45,26 +45,28 @@ from r2.lib.strings import strings, Score
|
||||
from r2.lib.db import tdb_cassandra
|
||||
from r2.lib.db.tdb_cassandra import NotFoundException, view_of
|
||||
from r2.lib.utils import sanitize_url
|
||||
from r2.models.gold import (
|
||||
GildedCommentsByAccount,
|
||||
GildedLinksByAccount,
|
||||
make_gold_message,
|
||||
)
|
||||
from r2.models.subreddit import MultiReddit
|
||||
from r2.models.query_cache import CachedQueryMutator
|
||||
from r2.models.promo import PROMOTE_STATUS, get_promote_srid
|
||||
|
||||
from pylons import c, g, request
|
||||
from pylons.i18n import ungettext, _
|
||||
from pylons.i18n import _
|
||||
from datetime import datetime, timedelta
|
||||
from hashlib import md5
|
||||
from pycassa.util import convert_uuid_to_time
|
||||
|
||||
import random, re
|
||||
import json
|
||||
import uuid
|
||||
|
||||
class LinkExists(Exception): pass
|
||||
|
||||
# defining types
|
||||
class Link(Thing, Printable):
|
||||
_data_int_props = Thing._data_int_props + (
|
||||
'num_comments', 'reported', 'comment_tree_id')
|
||||
'num_comments', 'reported', 'comment_tree_id', 'gildings')
|
||||
_defaults = dict(is_self=False,
|
||||
over_18=False,
|
||||
over_18_override=False,
|
||||
@@ -87,6 +89,7 @@ class Link(Thing, Printable):
|
||||
contest_mode=False,
|
||||
skip_commentstree_q="",
|
||||
ignore_reports=False,
|
||||
gildings=0,
|
||||
)
|
||||
_essentials = ('sr_id', 'author_id')
|
||||
_nsfw = re.compile(r"\bnsfw\b", re.I)
|
||||
@@ -299,6 +302,28 @@ class Link(Thing, Printable):
|
||||
return self.make_permalink(self.subreddit_slow,
|
||||
force_domain=force_domain)
|
||||
|
||||
def markdown_link_slow(self):
|
||||
return "[%s](%s)" % (self.title.decode('utf-8'),
|
||||
self.make_permalink_slow())
|
||||
|
||||
def _gild(self, user):
|
||||
now = datetime.now(g.tz)
|
||||
|
||||
self._incr("gildings")
|
||||
|
||||
GildedLinksByAccount.gild(user, self)
|
||||
|
||||
from r2.lib.db import queries
|
||||
with CachedQueryMutator() as m:
|
||||
gilding = utils.Storage(thing=self, date=now)
|
||||
m.insert(queries.get_all_gilded_links(), [gilding])
|
||||
m.insert(queries.get_gilded_links(self.sr_id), [gilding])
|
||||
m.insert(queries.get_gilded_user_links(self.author_id),
|
||||
[gilding])
|
||||
m.insert(queries.get_user_gildings(user), [gilding])
|
||||
|
||||
hooks.get_hook('link.gild').call(link=self, gilder=user)
|
||||
|
||||
@staticmethod
|
||||
def _should_expunge_selftext(link):
|
||||
verdict = getattr(link, "verdict", "")
|
||||
@@ -347,6 +372,13 @@ class Link(Thing, Printable):
|
||||
for ban in bans_for_domain_parts(urls)}
|
||||
|
||||
if user_is_loggedin:
|
||||
gilded = [thing for thing in wrapped if thing.gildings > 0]
|
||||
try:
|
||||
user_gildings = GildedLinksByAccount.fast_query(user, gilded)
|
||||
except tdb_cassandra.TRANSIENT_EXCEPTIONS as e:
|
||||
g.log.warning("Cassandra gilding lookup failed: %r", e)
|
||||
user_gildings = {}
|
||||
|
||||
try:
|
||||
saved = LinkSavesByAccount.fast_query(user, wrapped)
|
||||
hidden = LinkHidesByAccount.fast_query(user, wrapped)
|
||||
@@ -421,13 +453,29 @@ class Link(Thing, Printable):
|
||||
item.urlprefix = ''
|
||||
|
||||
if user_is_loggedin:
|
||||
item.user_gilded = (user, item) in user_gildings
|
||||
item.saved = (user, item) in saved
|
||||
item.hidden = (user, item) in hidden
|
||||
item.visited = (user, item) in visited
|
||||
|
||||
else:
|
||||
item.user_gilded = False
|
||||
item.saved = item.hidden = item.visited = False
|
||||
|
||||
item.gilded_message = make_gold_message(item, item.user_gilded)
|
||||
item.can_gild = (
|
||||
c.user_is_loggedin and
|
||||
# you can't gild your own submission
|
||||
not (item.author and
|
||||
item.author._id == user._id) and
|
||||
# no point in showing the button for things you've already gilded
|
||||
not item.user_gilded and
|
||||
# ick, if the author deleted their account we shouldn't waste gold
|
||||
not item.author._deleted and
|
||||
# some subreddits can have gilding disabled
|
||||
item.subreddit.allow_gilding
|
||||
)
|
||||
|
||||
item.num = None
|
||||
item.permalink = item.make_permalink(item.subreddit)
|
||||
if item.is_self:
|
||||
@@ -700,45 +748,6 @@ class PromotedLink(Link):
|
||||
Printable.add_props(user, wrapped)
|
||||
|
||||
|
||||
def make_comment_gold_message(comment, user_gilded):
|
||||
if comment.gildings == 0 or comment._spam or comment._deleted:
|
||||
return None
|
||||
|
||||
author = Account._byID(comment.author_id, data=True)
|
||||
if not author._deleted:
|
||||
author_name = author.name
|
||||
else:
|
||||
author_name = _("[deleted]")
|
||||
|
||||
if c.user_is_loggedin and comment.author_id == c.user._id:
|
||||
gilded_message = ungettext(
|
||||
"a redditor gifted you a month of reddit gold for this comment.",
|
||||
"redditors have gifted you %(months)d months of reddit gold for "
|
||||
"this comment.",
|
||||
comment.gildings
|
||||
)
|
||||
elif user_gilded:
|
||||
gilded_message = ungettext(
|
||||
"you have gifted reddit gold to %(recipient)s for this comment.",
|
||||
"you and other redditors have gifted %(months)d months of "
|
||||
"reddit gold to %(recipient)s for this comment.",
|
||||
comment.gildings
|
||||
)
|
||||
else:
|
||||
gilded_message = ungettext(
|
||||
"a redditor has gifted reddit gold to %(recipient)s for this "
|
||||
"comment.",
|
||||
"redditors have gifted %(months)d months of reddit gold to "
|
||||
"%(recipient)s for this comment.",
|
||||
comment.gildings
|
||||
)
|
||||
|
||||
return gilded_message % dict(
|
||||
recipient=author_name,
|
||||
months=comment.gildings,
|
||||
)
|
||||
|
||||
|
||||
class Comment(Thing, Printable):
|
||||
_data_int_props = Thing._data_int_props + ('reported', 'gildings')
|
||||
_defaults = dict(reported=0,
|
||||
@@ -882,7 +891,7 @@ class Comment(Thing, Printable):
|
||||
|
||||
self._incr("gildings")
|
||||
|
||||
GildedCommentsByAccount.gild_comment(user, self)
|
||||
GildedCommentsByAccount.gild(user, self)
|
||||
|
||||
from r2.lib.db import queries
|
||||
with CachedQueryMutator() as m:
|
||||
@@ -976,10 +985,9 @@ class Comment(Thing, Printable):
|
||||
now = datetime.now(g.tz)
|
||||
|
||||
if user_is_loggedin:
|
||||
gilded = [comment for comment in wrapped if comment.gildings > 0]
|
||||
gilded = [thing for thing in wrapped if thing.gildings > 0]
|
||||
try:
|
||||
user_gildings = GildedCommentsByAccount.fast_query(user,
|
||||
gilded)
|
||||
user_gildings = GildedCommentsByAccount.fast_query(user, gilded)
|
||||
except tdb_cassandra.TRANSIENT_EXCEPTIONS as e:
|
||||
g.log.warning("Cassandra gilding lookup failed: %r", e)
|
||||
user_gildings = {}
|
||||
@@ -1038,8 +1046,26 @@ class Comment(Thing, Printable):
|
||||
else:
|
||||
item.user_gilded = False
|
||||
item.saved = False
|
||||
item.gilded_message = make_comment_gold_message(item,
|
||||
item.user_gilded)
|
||||
item.gilded_message = make_gold_message(item, item.user_gilded)
|
||||
|
||||
item.can_gild = (
|
||||
# this is a way of checking if the user is logged in that works
|
||||
# both within CommentPane instances and without. e.g. CommentPane
|
||||
# explicitly sets user_is_loggedin = False but can_reply is
|
||||
# correct. while on user overviews, you can't reply but will get
|
||||
# the correct value for user_is_loggedin
|
||||
(c.user_is_loggedin or getattr(item, "can_reply", True)) and
|
||||
# you can't gild your own comment
|
||||
not (c.user_is_loggedin and
|
||||
item.author and
|
||||
item.author._id == user._id) and
|
||||
# no point in showing the button for things you've already gilded
|
||||
not item.user_gilded and
|
||||
# ick, if the author deleted their account we shouldn't waste gold
|
||||
not item.author._deleted and
|
||||
# some subreddits can have gilding disabled
|
||||
item.subreddit.allow_gilding
|
||||
)
|
||||
|
||||
# not deleted on profile pages,
|
||||
# deleted if spam and not author or admin
|
||||
@@ -1537,91 +1563,6 @@ class Message(Thing, Printable):
|
||||
return True
|
||||
|
||||
|
||||
class GildedCommentsByAccount(tdb_cassandra.DenormalizedRelation):
|
||||
_use_db = True
|
||||
_last_modified_name = 'Gilding'
|
||||
_views = []
|
||||
|
||||
@classmethod
|
||||
def value_for(cls, thing1, thing2):
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
def gild_comment(cls, user, comment):
|
||||
cls.create(user, [comment])
|
||||
|
||||
|
||||
@view_of(GildedCommentsByAccount)
|
||||
class GildingsByThing(tdb_cassandra.View):
|
||||
_use_db = True
|
||||
_extra_schema_creation_args = {
|
||||
"key_validation_class": tdb_cassandra.UTF8_TYPE,
|
||||
"column_name_class": tdb_cassandra.UTF8_TYPE,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_gilder_ids(cls, thing):
|
||||
columns = cls.get_time_sorted_columns(thing._fullname)
|
||||
return [int(account_id, 36) for account_id in columns.iterkeys()]
|
||||
|
||||
@classmethod
|
||||
def create(cls, user, things):
|
||||
for thing in things:
|
||||
cls._set_values(thing._fullname, {user._id36: ""})
|
||||
|
||||
@classmethod
|
||||
def delete(cls, user, things):
|
||||
# gildings cannot be undone
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@view_of(GildedCommentsByAccount)
|
||||
class GildingsByDay(tdb_cassandra.View):
|
||||
_use_db = True
|
||||
_compare_with = tdb_cassandra.TIME_UUID_TYPE
|
||||
_extra_schema_creation_args = {
|
||||
"key_validation_class": tdb_cassandra.ASCII_TYPE,
|
||||
"column_name_class": tdb_cassandra.TIME_UUID_TYPE,
|
||||
"default_validation_class": tdb_cassandra.UTF8_TYPE,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _rowkey(date):
|
||||
return date.strftime("%Y-%m-%d")
|
||||
|
||||
@classmethod
|
||||
def get_gildings(cls, date):
|
||||
key = cls._rowkey(date)
|
||||
columns = cls.get_time_sorted_columns(key)
|
||||
gildings = []
|
||||
for name, json_blob in columns.iteritems():
|
||||
timestamp = convert_uuid_to_time(name)
|
||||
date = datetime.utcfromtimestamp(timestamp).replace(tzinfo=g.tz)
|
||||
|
||||
gilding = json.loads(json_blob)
|
||||
gilding["date"] = date
|
||||
gilding["user"] = int(gilding["user"], 36)
|
||||
gildings.append(gilding)
|
||||
return gildings
|
||||
|
||||
@classmethod
|
||||
def create(cls, user, things):
|
||||
key = cls._rowkey(datetime.now(g.tz))
|
||||
|
||||
columns = {}
|
||||
for thing in things:
|
||||
columns[uuid.uuid1()] = json.dumps({
|
||||
"user": user._id36,
|
||||
"thing": thing._fullname,
|
||||
})
|
||||
cls._set_values(key, columns)
|
||||
|
||||
@classmethod
|
||||
def delete(cls, user, things):
|
||||
# gildings cannot be undone
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class _SaveHideByAccount(tdb_cassandra.DenormalizedRelation):
|
||||
@classmethod
|
||||
def value_for(cls, thing1, thing2):
|
||||
|
||||
@@ -141,9 +141,9 @@ class BaseSite(object):
|
||||
from r2.lib.db import queries
|
||||
return queries.get_sr_comments(self)
|
||||
|
||||
def get_gilded_comments(self):
|
||||
def get_gilded(self):
|
||||
from r2.lib.db import queries
|
||||
return queries.get_gilded_comments(self)
|
||||
return queries.get_gilded(self._id)
|
||||
|
||||
@classmethod
|
||||
def get_modactions(cls, srs, mod=None, action=None):
|
||||
@@ -205,7 +205,7 @@ class Subreddit(Thing, Printable, BaseSite):
|
||||
prev_description_id="",
|
||||
prev_submit_text_id="",
|
||||
prev_public_description_id="",
|
||||
allow_comment_gilding=True,
|
||||
allow_gilding=True,
|
||||
hide_subscribers=False,
|
||||
public_traffic=False,
|
||||
spam_links='high',
|
||||
@@ -929,7 +929,7 @@ class FakeSubreddit(BaseSite):
|
||||
from r2.lib.db import queries
|
||||
return queries.get_all_comments()
|
||||
|
||||
def get_gilded_comments(self):
|
||||
def get_gilded(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def spammy(self):
|
||||
@@ -1006,19 +1006,16 @@ class FriendsSR(FakeSubreddit):
|
||||
for friend in friends]
|
||||
return queries.MergedCachedResults(crs)
|
||||
|
||||
def get_gilded_comments(self):
|
||||
from r2.lib.db.queries import get_gilded_user_comments
|
||||
|
||||
def get_gilded(self):
|
||||
from r2.lib.db.queries import get_gilded_users
|
||||
if not c.user_is_loggedin:
|
||||
raise UserRequiredException
|
||||
|
||||
friends = self.get_important_friends(c.user._id)
|
||||
|
||||
if not friends:
|
||||
return []
|
||||
|
||||
queries = [get_gilded_user_comments(user_id) for user_id in friends]
|
||||
return MergedCachedQuery(queries)
|
||||
return get_gilded_users(friends)
|
||||
|
||||
|
||||
class AllSR(FakeSubreddit):
|
||||
@@ -1047,9 +1044,9 @@ class AllSR(FakeSubreddit):
|
||||
from r2.lib.db import queries
|
||||
return queries.get_all_comments()
|
||||
|
||||
def get_gilded_comments(self):
|
||||
def get_gilded(self):
|
||||
from r2.lib.db import queries
|
||||
return queries.get_all_gilded_comments()
|
||||
return queries.get_all_gilded()
|
||||
|
||||
|
||||
class AllMinus(AllSR):
|
||||
@@ -1196,11 +1193,9 @@ class DefaultSR(_DefaultSR):
|
||||
results = [get_sr_comments(sr) for sr in srs]
|
||||
return merge_results(*results)
|
||||
|
||||
def get_gilded_comments(self):
|
||||
from r2.lib.db.queries import get_gilded_comments
|
||||
srs = Subreddit.user_subreddits(c.user)
|
||||
queries = [get_gilded_comments(sr_id) for sr_id in srs]
|
||||
return MergedCachedQuery(queries)
|
||||
def get_gilded(self):
|
||||
from r2.lib.db.queries import get_gilded
|
||||
return get_gilded(Subreddit.user_subreddits(c.user))
|
||||
|
||||
|
||||
class MultiReddit(FakeSubreddit):
|
||||
@@ -1267,10 +1262,9 @@ class MultiReddit(FakeSubreddit):
|
||||
results = [get_sr_comments(sr) for sr in srs]
|
||||
return merge_results(*results)
|
||||
|
||||
def get_gilded_comments(self):
|
||||
from r2.lib.db.queries import get_gilded_comments
|
||||
queries = [get_gilded_comments(sr_id) for sr_id in self.kept_sr_ids]
|
||||
return MergedCachedQuery(queries)
|
||||
def get_gilded(self):
|
||||
from r2.lib.db.queries import get_gilded
|
||||
return get_gilded(self.kept_sr_ids)
|
||||
|
||||
|
||||
class TooManySubredditsError(Exception):
|
||||
|
||||
@@ -303,14 +303,14 @@ body[orient="landscape"] > #topbar > h1 { margin-left: -125px; width: 250px; }
|
||||
|
||||
.comment.collapsed .tagline { margin-left: 20px; font-style: italcs; color: #AAA; }
|
||||
|
||||
/** comment gilding */
|
||||
.gilded-comment-icon { position: relative; display: inline-block; margin: 0 0 -15px 8px; top: -8px; color: #99895F; font-size: .9em; vertical-align: middle; }
|
||||
/** gilding */
|
||||
.gilded-icon { position: relative; display: inline-block; margin: 0 0 -15px 8px; top: -8px; color: #99895F; font-size: .9em; vertical-align: middle; }
|
||||
|
||||
.gilded-comment-icon:before { display: inline-block; content: ''; background-image: url(../gold-coin.png); /* SPRITE */ background-repeat: no-repeat; height: 14px; width: 13px; margin-right: 2px; vertical-align: -3px; }
|
||||
.gilded-icon:before { display: inline-block; content: ''; background-image: url(../gold-coin.png); /* SPRITE */ background-repeat: no-repeat; height: 14px; width: 13px; margin-right: 2px; vertical-align: -3px; }
|
||||
|
||||
.user-gilded > .entry .gilded-comment-icon:before { width: 23px; }
|
||||
.user-gilded > .entry .gilded-icon:before { width: 23px; }
|
||||
|
||||
body.post-under-6h-old .gilded-comment-icon { opacity: .55; }
|
||||
body.post-under-6h-old .gilded-icon { opacity: .55; }
|
||||
|
||||
/** messages and inbox */
|
||||
.message { background: white; position: relative; border: 1px solid #d9d9d9; margin: 10px; -webkit-border-radius: 8px; -moz-border-radius: 8px; -ms-border-radius: 8px; -o-border-radius: 8px; border-radius: 8px; padding: 5px; }
|
||||
|
||||
@@ -887,8 +887,8 @@ padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
/** comment gilding */
|
||||
.gilded-comment-icon {
|
||||
/** gilding */
|
||||
.gilded-icon {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin: 0 0 -15px 8px;
|
||||
@@ -898,7 +898,7 @@ padding: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.gilded-comment-icon:before {
|
||||
.gilded-icon:before {
|
||||
display: inline-block;
|
||||
content: '';
|
||||
background-image: url(../gold-coin.png); /* SPRITE */
|
||||
@@ -909,11 +909,11 @@ padding: 5px;
|
||||
vertical-align: -3px;
|
||||
}
|
||||
|
||||
.user-gilded > .entry .gilded-comment-icon:before {
|
||||
.user-gilded > .entry .gilded-icon:before {
|
||||
width: 23px;
|
||||
}
|
||||
|
||||
body.post-under-6h-old .gilded-comment-icon {
|
||||
body.post-under-6h-old .gilded-icon {
|
||||
opacity: .55;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.gilded-comment-icon {
|
||||
.gilded-icon {
|
||||
background: url(gold-coin.png) no-repeat;
|
||||
padding-left: 15px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.user-gilded > .entry .gilded-comment-icon {
|
||||
.user-gilded > .entry .gilded-icon {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
@@ -6018,7 +6018,7 @@ dd { margin-left: 20px; }
|
||||
.icon-menu .reddit-contributors:before,
|
||||
.icon-menu .reddit-modqueue:before,
|
||||
.giftgold a:before,
|
||||
.gilded-comments-link a:before,
|
||||
.gilded-link a:before,
|
||||
.infobar.gold:before,
|
||||
.gold-form h1.goldgift:before,
|
||||
.users-online:before,
|
||||
@@ -6350,17 +6350,17 @@ body:not(.gold) .allminus-link {
|
||||
font-size: 1.15em;
|
||||
}
|
||||
|
||||
.gilded-comments-link {
|
||||
.gilded-link {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.gilded-comments-link a {
|
||||
.gilded-link a {
|
||||
color: #9a7d2e;
|
||||
font-weight: bold;
|
||||
font-size: 1.15em;
|
||||
}
|
||||
|
||||
.gilded-comments-link a:before {
|
||||
.gilded-link a:before {
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
margin: 0 6px 0 1px;
|
||||
@@ -6544,7 +6544,7 @@ body:not(.gold) .allminus-link {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.gold-form.cloneable {
|
||||
.gold-form.cloneable-link, .gold-form.cloneable-comment {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -6572,8 +6572,8 @@ body:not(.gold) .allminus-link {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.comment .gold-form {
|
||||
margin: 0 0 10px 4px;
|
||||
.thing .gold-form {
|
||||
margin: 10px 0 10px 4px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
@@ -7588,7 +7588,7 @@ table.diff {font-size: small;}
|
||||
.diff_chg {background-color:yellow}
|
||||
.diff_sub {background-color:lightcoral}
|
||||
|
||||
.gilded-comment-icon {
|
||||
.gilded-icon {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin: 0 0 -15px 8px;
|
||||
@@ -7598,7 +7598,7 @@ table.diff {font-size: small;}
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.gilded-comment-icon:before {
|
||||
.gilded-icon:before {
|
||||
display: inline-block;
|
||||
content: '';
|
||||
background-image: url(../gold-coin.png); /* SPRITE */
|
||||
@@ -7609,11 +7609,11 @@ table.diff {font-size: small;}
|
||||
vertical-align: -3px;
|
||||
}
|
||||
|
||||
.user-gilded > .entry .gilded-comment-icon:before {
|
||||
.user-gilded > .entry .gilded-icon:before {
|
||||
width: 23px;
|
||||
}
|
||||
|
||||
body.post-under-6h-old .gilded-comment-icon {
|
||||
body.post-under-6h-old .gilded-icon {
|
||||
opacity: .55;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ r.gold = {
|
||||
$('div.content').on(
|
||||
'click',
|
||||
'a.give-gold, .gold-payment .close-button',
|
||||
$.proxy(this, '_toggleCommentGoldForm')
|
||||
$.proxy(this, '_toggleThingGoldForm')
|
||||
)
|
||||
|
||||
$('.stripe-gold').click(function(){
|
||||
@@ -21,11 +21,11 @@ r.gold = {
|
||||
})
|
||||
},
|
||||
|
||||
_toggleCommentGoldForm: function (e) {
|
||||
_toggleThingGoldForm: function (e) {
|
||||
var $link = $(e.target),
|
||||
$thing = $link.thing(),
|
||||
commentId = $link.thing_id(),
|
||||
formId = 'gold_form_' + commentId,
|
||||
thingFullname = $link.thing_id(),
|
||||
formId = 'gold_form_' + thingFullname,
|
||||
oldForm = $('#' + formId)
|
||||
|
||||
if ($thing.hasClass('user-gilded') ||
|
||||
@@ -47,12 +47,18 @@ r.gold = {
|
||||
this._googleCheckoutAnalyticsLoaded = true
|
||||
}
|
||||
|
||||
var form = $('.gold-form.cloneable:first').clone(),
|
||||
if ($thing.hasClass('link')) {
|
||||
var cloneClass = 'cloneable-link'
|
||||
} else {
|
||||
var cloneClass = 'cloneable-comment'
|
||||
}
|
||||
|
||||
var form = $('.gold-form.' + cloneClass + ':first').clone(),
|
||||
authorName = $link.thing().find('.entry .author:first').text(),
|
||||
passthroughs = form.find('.passthrough'),
|
||||
cbBaseUrl = form.find('[name="cbbaseurl"]').val()
|
||||
|
||||
form.removeClass('cloneable')
|
||||
form.removeClass(cloneClass)
|
||||
.attr('id', formId)
|
||||
.find('p:first-child em').text(authorName).end()
|
||||
.find('button').attr('disabled', '')
|
||||
@@ -66,7 +72,7 @@ r.gold = {
|
||||
form.find('button').addClass('disabled')
|
||||
}, 200)
|
||||
|
||||
$.request('generate_payment_blob.json', {comment: commentId}, function (token) {
|
||||
$.request('generate_payment_blob.json', {thing: thingFullname}, function (token) {
|
||||
clearTimeout(workingTimer)
|
||||
form.removeClass('working')
|
||||
passthroughs.val(token)
|
||||
@@ -78,18 +84,18 @@ r.gold = {
|
||||
return false
|
||||
},
|
||||
|
||||
gildComment: function (comment_id, new_title, specified_gilding_count) {
|
||||
var comment = $('.id-' + comment_id)
|
||||
gildThing: function (thing_fullname, new_title, specified_gilding_count) {
|
||||
var thing = $('.id-' + thing_fullname)
|
||||
|
||||
if (!comment.length) {
|
||||
console.log("couldn't gild comment " + comment_id)
|
||||
if (!thing.length) {
|
||||
console.log("couldn't gild thing " + thing_fullname)
|
||||
return
|
||||
}
|
||||
|
||||
var tagline = comment.children('.entry').find('p.tagline'),
|
||||
icon = tagline.find('.gilded-comment-icon')
|
||||
var tagline = thing.children('.entry').find('p.tagline'),
|
||||
icon = tagline.find('.gilded-icon')
|
||||
|
||||
// when a comment is gilded interactively, we need to increment the
|
||||
// when a thing is gilded interactively, we need to increment the
|
||||
// gilding count displayed by the UI. however, when gildings are
|
||||
// instantiated from a cached comment page via thingupdater, we can't
|
||||
// simply increment the gilding count because we do not know if the
|
||||
@@ -104,10 +110,10 @@ r.gold = {
|
||||
gilding_count++
|
||||
}
|
||||
|
||||
comment.addClass('gilded user-gilded')
|
||||
thing.addClass('gilded user-gilded')
|
||||
if (!icon.length) {
|
||||
icon = $('<span>')
|
||||
.addClass('gilded-comment-icon')
|
||||
.addClass('gilded-icon')
|
||||
tagline.append(icon)
|
||||
}
|
||||
icon
|
||||
@@ -117,7 +123,7 @@ r.gold = {
|
||||
icon.text('x' + gilding_count)
|
||||
}
|
||||
|
||||
comment.children('.entry').find('.give-gold').parent().remove()
|
||||
thing.children('.entry').find('.give-gold').parent().remove()
|
||||
},
|
||||
|
||||
tokenThenPost: function (dest) {
|
||||
@@ -199,8 +205,8 @@ r.gold = {
|
||||
};
|
||||
|
||||
(function($) {
|
||||
$.gild_comment = function (comment_id, new_title) {
|
||||
r.gold.gildComment(comment_id, new_title)
|
||||
$('#gold_form_' + comment_id).fadeOut(400)
|
||||
$.gild_thing = function (thing_fullname, new_title) {
|
||||
r.gold.gildThing(thing_fullname, new_title)
|
||||
$('#gold_form_' + thing_fullname).fadeOut(400)
|
||||
}
|
||||
})(jQuery)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
%endif
|
||||
|
||||
%if not thing.gilding_listing:
|
||||
<div class="gilded-comments-link">
|
||||
<a href="/r/all/comments/gilded">${_("See gilded comments")}</a>
|
||||
<div class="gilded-link">
|
||||
<a href="/r/all/gilded">${_("See gilded comments and submissions")}</a>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
## thing.timesince is a cache stub
|
||||
${unsafe(_("%(timeago)s ago") % dict(timeago=thing.timesince))}
|
||||
% if thing.gilded_message:
|
||||
<span class="gilded-comment-icon" title="${thing.gilded_message}" data-count="${thing.gildings}">
|
||||
<span class="gilded-icon" title="${thing.gilded_message}" data-count="${thing.gildings}">
|
||||
% if thing.gildings > 1:
|
||||
x${thing.gildings}
|
||||
% endif
|
||||
|
||||
@@ -124,15 +124,7 @@ ${parent.collapsed()}
|
||||
${edited(thing, thing.lastedited)}
|
||||
%endif
|
||||
|
||||
% if thing.gilded_message:
|
||||
<a href="${thing.subreddit_path}gilded">
|
||||
<span class="gilded-comment-icon" title="${thing.gilded_message}" data-count="${thing.gildings}">
|
||||
% if thing.gildings > 1:
|
||||
x${thing.gildings}
|
||||
% endif
|
||||
</span>
|
||||
</a>
|
||||
% endif
|
||||
${self.gildings()}
|
||||
|
||||
%if collapse:
|
||||
<a href="#" class="expand"
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="roundfield-content">
|
||||
${unsafe(safemarkdown(thing.summary, wrap=False))}
|
||||
<div class="giftmessage">
|
||||
${unsafe(safemarkdown(thing.comment.body))}
|
||||
${unsafe(safemarkdown(thing.description))}
|
||||
</div>
|
||||
${stripe_form(display=True)}
|
||||
</div>
|
||||
|
||||
@@ -25,9 +25,16 @@
|
||||
<%
|
||||
from r2.lib.filters import unsafe, safemarkdown
|
||||
from r2.lib.template_helpers import static
|
||||
|
||||
clone_class = ''
|
||||
if thing.clone_template:
|
||||
if thing.thing_type == 'comment':
|
||||
clone_class = 'cloneable-comment'
|
||||
else:
|
||||
clone_class = 'cloneable-link'
|
||||
%>
|
||||
|
||||
<div class="gold-form gold-payment ${'cloneable' if thing.clone_template else ''}">
|
||||
<div class="gold-form gold-payment ${clone_class}">
|
||||
<div class="roundfield">
|
||||
% if thing.clone_template:
|
||||
<button class="close-button">${_('close')}</button>
|
||||
@@ -35,9 +42,9 @@
|
||||
<img src="${static('reddit_gold-70.png')}" class="gold-logo">
|
||||
<div class="roundfield-content">
|
||||
${unsafe(safemarkdown(thing.summary, wrap=False))}
|
||||
%if thing.comment and not thing.clone_template:
|
||||
%if thing.thing and not thing.clone_template:
|
||||
<div class="giftmessage">
|
||||
${unsafe(safemarkdown(thing.comment.body))}
|
||||
${unsafe(safemarkdown(thing.description))}
|
||||
</div>
|
||||
%endif
|
||||
|
||||
|
||||
@@ -216,6 +216,9 @@ ${parent.thing_data_attributes(what)} data-ups="${what.upvotes}" data-downs="${w
|
||||
author=WrappedUser(thing.author, thing.attribs, thing).render(),
|
||||
lastedited=capture(edited, thing, thing.lastedited)
|
||||
))}
|
||||
%if c.permalink_page or c.profilepage:
|
||||
${self.gildings()}
|
||||
%endif
|
||||
%if thing.stickied:
|
||||
 - <span class="stickied-tagline" title="selected by this subreddit's moderators">stickied post</span>
|
||||
%endif
|
||||
|
||||
@@ -54,6 +54,18 @@ ${self.RenderPrintable()}
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
<%def name="gildings()">
|
||||
% if thing.gilded_message:
|
||||
<a href="${thing.subreddit_path}gilded">
|
||||
<span class="gilded-icon" title="${thing.gilded_message}" data-count="${thing.gildings}">
|
||||
% if thing.gildings > 1:
|
||||
x${thing.gildings}
|
||||
% endif
|
||||
</span>
|
||||
</a>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="thing_css_class(what)">
|
||||
<%
|
||||
cssclass = "thing"
|
||||
|
||||
@@ -122,6 +122,17 @@
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
<%def name="give_gold()">
|
||||
% if thing.show_givegold:
|
||||
<li>
|
||||
<a href="/gold?goldtype=gift&months=1&thing=${thing.thing._fullname}"
|
||||
title="${_("give reddit gold in appreciation of this post.")}"
|
||||
class="give-gold login-required"
|
||||
>${_("give gold")}</a>
|
||||
</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="ignore_reports_toggle(thing)">
|
||||
<%
|
||||
label = _("ignore reports")
|
||||
@@ -202,6 +213,7 @@
|
||||
%endif
|
||||
|
||||
${self.distinguish()}
|
||||
${self.give_gold()}
|
||||
${self.banbuttons()}
|
||||
%if thing.promoted is not None:
|
||||
%if thing.user_is_sponsor or thing.is_author:
|
||||
@@ -295,14 +307,7 @@
|
||||
%endif
|
||||
${self.banbuttons()}
|
||||
${self.distinguish()}
|
||||
% if thing.can_gild:
|
||||
<li>
|
||||
<a href="/gold?goldtype=gift&months=1&comment=${thing.thing._fullname}"
|
||||
title="${_("give reddit gold in appreciation of this comment.")}"
|
||||
class="give-gold login-required"
|
||||
>${_("give gold")}</a>
|
||||
</li>
|
||||
% endif
|
||||
${self.give_gold()}
|
||||
%if not thing.profilepage and thing.can_reply:
|
||||
<li>
|
||||
${self.simple_button(_("reply {verb}"), "reply")}
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
$.map(friends, show_friend);
|
||||
|
||||
var gildings = ${unsafe(simplejson.dumps(thing.gildings))};
|
||||
for (var gilded_comment in gildings) {
|
||||
var gilding_data = gildings[gilded_comment];
|
||||
r.gold.gildComment(gilded_comment, gilding_data[0], gilding_data[1]);
|
||||
for (var gilded_thing in gildings) {
|
||||
var gilding_data = gildings[gilded_thing];
|
||||
r.gold.gildThing(gilded_thing, gilding_data[0], gilding_data[1]);
|
||||
}
|
||||
|
||||
var saves = ${unsafe(simplejson.dumps(list(thing.saves)))};
|
||||
|
||||
Reference in New Issue
Block a user