Subreddit settings: Use subreddit multi for related subreddits

Use a multi to manage a subreddit's related subreddits.
This commit is contained in:
Florence Yeun
2015-03-10 12:45:47 -07:00
parent 81c184e7a4
commit efce256abb
5 changed files with 65 additions and 14 deletions

View File

@@ -2500,7 +2500,7 @@ class ApiController(RedditController):
pass
elif form.has_errors('comment_score_hide_mins', errors.BAD_NUMBER):
pass
elif form.has_errors('related_subreddits',
elif form.has_errors('related_subreddits', errors.SUBREDDIT_NOEXIST,
errors.BAD_SR_NAME, errors.TOO_MANY_SUBREDDITS):
pass
elif form.has_errors('hide_ads', errors.GOLD_ONLY_SR_REQUIRED):

View File

@@ -299,10 +299,6 @@ class SubredditJsonTemplate(ThingJsonTemplate):
if thing.community_rules:
return thing.community_rules.split('\n')
return []
elif attr == 'related_subreddits':
if thing.related_subreddits:
return thing.related_subreddits.split('\n')
return []
else:
return ThingJsonTemplate.thing_attr(self, thing, attr)
@@ -1133,6 +1129,9 @@ class SubredditSettingsTemplate(ThingJsonTemplate):
def thing_attr(self, thing, attr):
if attr.startswith('site.') and thing.site:
return getattr(thing.site, attr[5:])
if attr == 'related_subreddits':
# string used for form input
return '\n'.join(thing.related_subreddits)
return ThingJsonTemplate.thing_attr(self, thing, attr)
def raw_data(self, thing):

View File

@@ -2766,11 +2766,11 @@ class VSubredditList(Validator):
def run(self, subreddits):
if not subreddits:
return ''
return []
# extract subreddit name if path provided
subreddits = [sr_path_rx.sub('\g<name>', sr.strip())
for sr in subreddits.lower().splitlines()]
for sr in subreddits.lower().strip().splitlines() if sr]
for name in subreddits:
valid_name = Subreddit.is_valid_name(
@@ -2778,14 +2778,19 @@ class VSubredditList(Validator):
if not valid_name:
return self.set_error(errors.BAD_SR_NAME, code=400)
# unique nonempty subreddits, preserve order
subreddits = list(OrderedDict.fromkeys([''] + subreddits))[1:]
unique_srs = set(subreddits)
if len(subreddits) > self.limit:
if subreddits:
valid_srs = set(Subreddit._by_name(subreddits).keys())
if unique_srs - valid_srs:
return self.set_error(errors.SUBREDDIT_NOEXIST, code=400)
if len(unique_srs) > self.limit:
return self.set_error(
errors.TOO_MANY_SUBREDDITS, {'max': self.limit}, code=400)
return '\n'.join(subreddits)
# return list of subreddit names as entered
return subreddits
def param_docs(self):
return {

View File

@@ -261,10 +261,16 @@ class Subreddit(Thing, Printable, BaseSite):
banner_img='',
banner_size=None,
community_rules='',
related_subreddits='',
key_color='',
hide_ads=False,
)
# special attributes that shouldn't set Thing data attributes because they
# have special setters that set other data attributes
_derived_attrs = (
'related_subreddits',
)
_essentials = ('type', 'name', 'lang')
_data_int_props = Thing._data_int_props + ('mod_actions', 'reported',
'wiki_edit_karma', 'wiki_edit_age',
@@ -316,6 +322,12 @@ class Subreddit(Thing, Printable, BaseSite):
('#0079d3', N_('alien blue')),
])
def __setattr__(self, attr, val, make_dirty=True):
if attr in self._derived_attrs:
object.__setattr__(self, attr, val)
else:
Thing.__setattr__(self, attr, val, make_dirty=make_dirty)
# note: for purposely unrenderable reddits (like promos) set author_id = -1
@classmethod
def _new(cls, name, title, author_id, ip, lang = g.lang, type = 'public',
@@ -557,6 +569,40 @@ class Subreddit(Thing, Printable, BaseSite):
def hide_contributors(self):
return self.type in {'employees_only', 'gold_only'}
@property
def _related_multipath(self):
return '/r/%s/m/related' % self.name.lower()
@property
def related_subreddits(self):
try:
multi = LabeledMulti._byID(self._related_multipath)
except tdb_cassandra.NotFound:
multi = None
return [sr.name for sr in multi.srs] if multi else []
@related_subreddits.setter
def related_subreddits(self, related_subreddits):
try:
multi = LabeledMulti._byID(self._related_multipath)
except tdb_cassandra.NotFound:
if not related_subreddits:
return
multi = LabeledMulti.create(self._related_multipath, self)
if related_subreddits:
srs = Subreddit._by_name(related_subreddits)
try:
sr_props = {srs[sr_name]: {} for sr_name in related_subreddits}
except KeyError as e:
raise NotFound, 'Subreddit %s' % e.args[0]
multi.clear_srs()
multi.add_srs(sr_props)
multi._commit()
else:
multi.delete()
def get_accounts_active(self):
fuzzed = False
count = AccountsActiveBySR.get_count(self)

View File

@@ -478,7 +478,7 @@ try participating in other communities on reddit for a little while first before
<a href=""></a>
<button class="remove-sr" onclick="remove_related_sr(this.parentNode)">${_('remove')}</button>
</li>
%for sr in thing.site.related_subreddits.split('\n'):
%for sr in thing.site.related_subreddits:
%if sr:
<li data-name="${sr.lower()}">
<a href="/r/${sr}">/r/${sr}</a>
@@ -493,10 +493,11 @@ try participating in other communities on reddit for a little while first before
</form>
%endif
<textarea id="related_subreddits" name="related_subreddits" style="display:none;">
${keep_space(thing.site.related_subreddits)}
${keep_space('\n'.join(thing.site.related_subreddits))}
</textarea>
${error_field("BAD_SR_NAME", "related_subreddits")}
${error_field("TOO_MANY_SUBREDDITS", "related_subreddits")}
${error_field("SUBREDDIT_NOEXIST", "related_subreddits")}
<script type="text/javascript">
function add_related_sr(form) {
$('.SUBREDDIT_NOEXIST.field-sr').hide();