mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-05 03:00:15 -04:00
The 'share' link can now share with reddit users via PM.
From /r/ideasfortheadmins http://redd.it/z5d0y
This commit is contained in:
@@ -65,6 +65,7 @@ from r2.lib.search import SearchQuery
|
||||
from r2.controllers.oauth2 import OAuth2ResourceController, require_oauth2_scope
|
||||
from r2.lib.system_messages import notify_user_added
|
||||
from r2.controllers.ipn import generate_blob
|
||||
from r2.lib.template_helpers import add_sr, get_domain
|
||||
|
||||
from r2.models import wiki
|
||||
from r2.lib.merge import ConflictException
|
||||
@@ -1090,12 +1091,13 @@ class ApiController(RedditController, OAuth2ResourceController):
|
||||
VRatelimit(rate_user = True, rate_ip = True,
|
||||
prefix = "rate_share_"),
|
||||
share_from = VLength('share_from', max_length = 100),
|
||||
emails = ValidEmails("share_to"),
|
||||
emails = ValidEmailsOrExistingUnames("share_to"),
|
||||
reply_to = ValidEmails("replyto", num = 1),
|
||||
message = VLength("message", max_length = 1000),
|
||||
thing = VByName('parent'))
|
||||
thing = VByName('parent'),
|
||||
ip = ValidIP())
|
||||
def POST_share(self, shareform, jquery, emails, thing, share_from, reply_to,
|
||||
message):
|
||||
message, ip):
|
||||
|
||||
# remove the ratelimit error if the user's karma is high
|
||||
sr = thing.subreddit_slow
|
||||
@@ -1123,6 +1125,7 @@ class ApiController(RedditController, OAuth2ResourceController):
|
||||
elif shareform.has_errors("ratelimit", errors.RATELIMIT):
|
||||
pass
|
||||
else:
|
||||
emails, users = emails
|
||||
c.user.add_share_emails(emails)
|
||||
c.user._commit()
|
||||
link = jquery.things(thing._fullname)
|
||||
@@ -1130,10 +1133,54 @@ class ApiController(RedditController, OAuth2ResourceController):
|
||||
shareform.html("<div class='clearleft'></div>"
|
||||
"<p class='error'>%s</p>" %
|
||||
_("your link has been shared."))
|
||||
|
||||
|
||||
# Set up the parts that are common between e-mail and PMs
|
||||
urlparts = (get_domain(cname=c.cname, subreddit=False),
|
||||
thing._id36)
|
||||
url = "http://%s/tb/%s" % urlparts
|
||||
|
||||
if message:
|
||||
message = message + "\n\n"
|
||||
else:
|
||||
message = ""
|
||||
message = message + '\n%s\n\n%s\n\n' % (thing.title,url)
|
||||
|
||||
# Deliberately not translating this, as it'd be in the
|
||||
# sender's language
|
||||
if thing.num_comments:
|
||||
count = ("There are currently %(num_comments)s comments on " +
|
||||
"this link. You can view them here:")
|
||||
if thing.num_comments == 1:
|
||||
count = ("There is currently %(num_comments)s comment " +
|
||||
"on this link. You can view it here:")
|
||||
|
||||
numcom = count % {'num_comments':thing.num_comments}
|
||||
message = message + "%s\n\n" % numcom
|
||||
else:
|
||||
message = message + "You can leave a comment here:\n\n"
|
||||
|
||||
url = add_sr(thing.make_permalink_slow(), force_hostname=True)
|
||||
message = message + url
|
||||
|
||||
# E-mail everyone
|
||||
emailer.share(thing, emails, from_name = share_from or "",
|
||||
body = message or "", reply_to = reply_to or "")
|
||||
|
||||
# Send the PMs
|
||||
subject = "%s has shared a link with you!" % c.user.name
|
||||
# Prepend this subject to the message - we're repeating ourselves
|
||||
# because it looks very abrupt without it.
|
||||
message = "%s\n\n%s" % (subject,message)
|
||||
|
||||
for target in users:
|
||||
|
||||
m, inbox_rel = Message._new(c.user, target, subject,
|
||||
message, ip)
|
||||
# Queue up this PM
|
||||
amqp.add_item('new_message', m._fullname)
|
||||
|
||||
queries.new_message(m, inbox_rel)
|
||||
|
||||
#set the ratelimiter
|
||||
if should_ratelimit:
|
||||
VRatelimit.ratelimit(rate_user=True, rate_ip = True,
|
||||
|
||||
@@ -1488,6 +1488,70 @@ class ValidEmails(Validator):
|
||||
# return single email if one is expected, list otherwise
|
||||
return list(emails)[0] if self.num == 1 else emails
|
||||
|
||||
class ValidEmailsOrExistingUnames(Validator):
|
||||
"""Validates a list of mixed email addresses and usernames passed in
|
||||
as a string, delineated by whitespace, ',' or ';'. Validates total
|
||||
quantity too while we're at it. Returns a tuple of the form
|
||||
(e-mail addresses, user account objects)"""
|
||||
|
||||
def __init__(self, param, num=20, **kw):
|
||||
self.num = num
|
||||
Validator.__init__(self, param=param, **kw)
|
||||
|
||||
def run(self, items):
|
||||
# Use ValidEmails separator to break the list up
|
||||
everything = set(ValidEmails.separator.findall(items) if items else [])
|
||||
|
||||
# Use ValidEmails regex to divide the list into e-mail and other
|
||||
emails = set(e for e in everything if ValidEmails.email_re.match(e))
|
||||
failures = everything - emails
|
||||
|
||||
# Run the rest of the validator against the e-mails list
|
||||
ve = ValidEmails(self.param, self.num)
|
||||
if len(emails) > 0:
|
||||
ve.run(", ".join(emails))
|
||||
|
||||
# ValidEmails will add to c.errors for us, so do nothing if that fails
|
||||
# Elsewise, on with the users
|
||||
if not ve.has_errors:
|
||||
users = set() # set of accounts
|
||||
validusers = set() # set of usernames to subtract from failures
|
||||
|
||||
# Now steal from VExistingUname:
|
||||
for uname in failures:
|
||||
check = uname
|
||||
if re.match('/u/', uname):
|
||||
check = check[3:]
|
||||
veu = VExistingUname(check)
|
||||
account = veu.run(check)
|
||||
if account:
|
||||
validusers.add(uname)
|
||||
users.add(account)
|
||||
|
||||
# We're fine if all our failures turned out to be valid users
|
||||
if len(users) == len(failures):
|
||||
# ValidEmails checked to see if there were too many addresses,
|
||||
# check to see if there's enough left-over space for users
|
||||
remaining = self.num - len(emails)
|
||||
if len(users) > remaining:
|
||||
if self.num == 1:
|
||||
# We only wanted one, and we got it as an e-mail,
|
||||
# so complain.
|
||||
self.set_error(errors.BAD_EMAILS,
|
||||
{"emails": '"%s"' % items})
|
||||
else:
|
||||
# Too many total
|
||||
self.set_error(errors.TOO_MANY_EMAILS,
|
||||
{"num": self.num})
|
||||
elif len(users) + len(emails) == 0:
|
||||
self.set_error(errors.NO_EMAILS)
|
||||
else:
|
||||
# It's all good!
|
||||
return (emails, users)
|
||||
else:
|
||||
failures = failures - validusers
|
||||
self.set_error(errors.BAD_EMAILS,
|
||||
{'emails': ', '.join(failures)})
|
||||
|
||||
class VCnameDomain(Validator):
|
||||
domain_re = re.compile(r'\A([\w\-_]+\.)+[\w]+\Z')
|
||||
|
||||
@@ -21,18 +21,9 @@
|
||||
###############################################################################
|
||||
|
||||
<%! from r2.lib.template_helpers import get_domain%>
|
||||
%if not thing.body:
|
||||
${thing.username} from http://${get_domain(cname = c.cname, subreddit = False)}/ has shared a link with you.
|
||||
%else:
|
||||
|
||||
${thing.body}
|
||||
%endif
|
||||
|
||||
"${thing.link.title}"
|
||||
http://${get_domain(cname = c.cname, subreddit = False)}/tb/${thing.link._id36}
|
||||
|
||||
<% from r2.lib.strings import strings, plurals %>${ungettext("There is currently %(num_comments)s on this link. You can view it here:", "There are currently %(num_comments)s on this link. You can view them here:", thing.link.num_comments) % dict(num_comments = strings.number_label % dict(num=thing.link.num_comments, thing=plurals.N_comments(thing.link.num_comments)))}
|
||||
|
||||
<% from r2.lib.template_helpers import add_sr %>${add_sr(thing.link.make_permalink_slow(), force_hostname = True)}
|
||||
|
||||
___
|
||||
If you would not like to receive emails from reddit.com in the future, visit http://${g.domain}/mail/optout?x=${thing.msg_hash}
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
<td>
|
||||
<textarea id="message_${thing.link_name}"
|
||||
name="message" rows="4" cols="40">
|
||||
${_("%(user)s from http://%(site)s/ has shared a link with you.") % dict(user = c.user.name, site=c.site.domain if c.cname and hasattr(c.site, 'domain') else g.domain)}
|
||||
</textarea>
|
||||
</td>
|
||||
<td class="message-errors">
|
||||
|
||||
Reference in New Issue
Block a user