Mercurial > kallithea
changeset 5877:ba5fee3879c8
utils: improve extract_mentioned_users usefulness
Previously, extract_mentioned_users performed a regex search, converted
to a set to remove duplicates, converted that set back into a list, and
sorted the list on username, ignoring case. Every single caller of the
function then promptly took the carefully pruned and sorted result and
put it back into a set, rendering the entire exercise pointless.
In addition, every caller also resolved the usernames to database User
objects.
In this changeset, extract_mentioned_users is changed to return a set
of database User objects directly. A new extract_mentioned_usernames
function, which does only username extraction, is kept for the sole
purpose of providing a more testable interface (no database needed).
Bonus feature: The new extract_mentioned_users will prune non-existent
users, as well as the DEFAULT user. This means it is no longer possible
to @mention (and send notifications to) the DEFAULT user.
author | Søren Løvborg <sorenl@unity3d.com> |
---|---|
date | Wed, 06 Apr 2016 14:50:47 +0200 |
parents | ea02c8b2b529 |
children | 1658beb26ff9 |
files | kallithea/lib/utils2.py kallithea/model/comment.py kallithea/model/pull_request.py kallithea/tests/other/test_libs.py |
diffstat | 4 files changed, 23 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/lib/utils2.py Tue Apr 19 17:58:21 2016 +0200 +++ b/kallithea/lib/utils2.py Wed Apr 06 14:50:47 2016 +0200 @@ -572,25 +572,30 @@ return return datetime.datetime.fromtimestamp(tm) + # Must match regexp in kallithea/public/js/base.js MentionsAutoComplete() # Check char before @ - it must not look like we are in an email addresses. # Matching is greedy so we don't have to look beyond the end. MENTIONS_REGEX = re.compile(r'(?:^|(?<=[^a-zA-Z0-9]))@([a-zA-Z0-9][-_.a-zA-Z0-9]*[a-zA-Z0-9])') -def extract_mentioned_users(s): +def extract_mentioned_usernames(text): r""" - Returns unique usernames from given string s that have @mention + Returns list of (possible) usernames @mentioned in given text. - :param s: string to get mentions - - >>> extract_mentioned_users('@1-2.a_X,@1234 not@not @ddd@not @n @ee @ff @gg, @gg;@hh @n\n@zz,') + >>> extract_mentioned_usernames('@1-2.a_X,@1234 not@not @ddd@not @n @ee @ff @gg, @gg;@hh @n\n@zz,') ['1-2.a_X', '1234', 'ddd', 'ee', 'ff', 'gg', 'hh', 'zz'] """ - usrs = set() - for username in MENTIONS_REGEX.findall(s): - usrs.add(username) + return MENTIONS_REGEX.findall(text) - return sorted(list(usrs), key=lambda k: k.lower()) +def extract_mentioned_users(text): + """ Returns set of actual database Users @mentioned in given text. """ + from kallithea.model.db import User + result = set() + for name in extract_mentioned_usernames(text): + user = User.get_by_username(name, case_insensitive=True) + if user is not None and user.username != User.DEFAULT_USER: + result.add(user) + return result class AttributeDict(dict):
--- a/kallithea/model/comment.py Tue Apr 19 17:58:21 2016 +0200 +++ b/kallithea/model/comment.py Wed Apr 06 14:50:47 2016 +0200 @@ -51,14 +51,6 @@ def __get_pull_request(self, pull_request): return self._get_instance(PullRequest, pull_request) - def _extract_mentions(self, s): - user_objects = [] - for username in extract_mentioned_users(s): - user_obj = User.get_by_username(username, case_insensitive=True) - if user_obj: - user_objects.append(user_obj) - return user_objects - def _get_notification_data(self, repo, comment, user, comment_text, line_no=None, revision=None, pull_request=None, status_change=None, closing_pr=False): @@ -210,8 +202,7 @@ email_kwargs=email_kwargs, ) - mention_recipients = set(self._extract_mentions(body)) \ - .difference(recipients) + mention_recipients = extract_mentioned_users(body).difference(recipients) if mention_recipients: email_kwargs['is_mention'] = True subj = _('[Mention]') + ' ' + subj
--- a/kallithea/model/pull_request.py Tue Apr 19 17:58:21 2016 +0200 +++ b/kallithea/model/pull_request.py Wed Apr 06 14:50:47 2016 +0200 @@ -35,7 +35,7 @@ from kallithea.lib.exceptions import UserInvalidException from kallithea.model import BaseModel from kallithea.model.db import PullRequest, PullRequestReviewers, Notification, \ - ChangesetStatus, User + ChangesetStatus from kallithea.model.notification import NotificationModel from kallithea.lib.utils2 import extract_mentioned_users, safe_unicode @@ -109,8 +109,7 @@ pull_request=new ) - mention_recipients = set(User.get_by_username(username, case_insensitive=True) - for username in extract_mentioned_users(new.description)) + mention_recipients = extract_mentioned_users(new.description) self.__add_reviewers(created_by_user, new, reviewers, mention_recipients) return new @@ -163,7 +162,6 @@ email_kwargs=email_kwargs) if mention_recipients: - mention_recipients.discard(None) mention_recipients.difference_update(reviewers) if mention_recipients: email_kwargs['is_mention'] = True @@ -174,10 +172,8 @@ email_kwargs=email_kwargs) def mention_from_description(self, user, pr, old_description=''): - mention_recipients = set(User.get_by_username(username, case_insensitive=True) - for username in extract_mentioned_users(pr.description)) - mention_recipients.difference_update(User.get_by_username(username, case_insensitive=True) - for username in extract_mentioned_users(old_description)) + mention_recipients = (extract_mentioned_users(pr.description) - + extract_mentioned_users(old_description)) log.debug("Mentioning %s", mention_recipients) self.__add_reviewers(user, pr, [], mention_recipients)
--- a/kallithea/tests/other/test_libs.py Tue Apr 19 17:58:21 2016 +0200 +++ b/kallithea/tests/other/test_libs.py Wed Apr 06 14:50:47 2016 +0200 @@ -102,7 +102,7 @@ self.assertEqual(str2bool(str_bool), expected) def test_mention_extractor(self): - from kallithea.lib.utils2 import extract_mentioned_users + from kallithea.lib.utils2 import extract_mentioned_usernames sample = ( "@first hi there @world here's my email username@example.com " "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three " @@ -111,10 +111,10 @@ "user.dot hej ! not-needed maril@example.com" ) - s = sorted([ + expected = set([ '2one_more22', 'first', 'lukaszb', 'one', 'one_more22', 'UPPER', 'cAmEL', 'john', - 'marian.user', 'marco-polo', 'marco_polo', 'world'], key=lambda k: k.lower()) - self.assertEqual(s, extract_mentioned_users(sample)) + 'marian.user', 'marco-polo', 'marco_polo', 'world']) + self.assertEqual(expected, set(extract_mentioned_usernames(sample))) @parameterized.expand([ (dict(), u'just now'),