Show More
@@ -38,17 +38,17 b' from kallithea.lib.auth import HasPermis' | |||||
38 | from kallithea.lib.diffs import BIN_FILENODE, CHMOD_FILENODE, DEL_FILENODE, MOD_FILENODE, NEW_FILENODE, RENAMED_FILENODE |
|
38 | from kallithea.lib.diffs import BIN_FILENODE, CHMOD_FILENODE, DEL_FILENODE, MOD_FILENODE, NEW_FILENODE, RENAMED_FILENODE | |
39 | from kallithea.lib.markup_renderer import url_re |
|
39 | from kallithea.lib.markup_renderer import url_re | |
40 | from kallithea.lib.pygmentsutils import get_custom_lexer |
|
40 | from kallithea.lib.pygmentsutils import get_custom_lexer | |
41 |
from kallithea.lib.utils2 import ( |
|
41 | from kallithea.lib.utils2 import (AttributeDict, age, asbool, credentials_filter, fmt_date, link_to_ref, safe_bytes, safe_int, safe_str, shorter, | |
42 |
|
|
42 | time_to_datetime) | |
43 | from kallithea.lib.vcs.backends.base import BaseChangeset, EmptyChangeset |
|
43 | from kallithea.lib.vcs.backends.base import BaseChangeset, EmptyChangeset | |
44 | from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError |
|
44 | from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError | |
45 | #============================================================================== |
|
45 | #============================================================================== | |
46 | # SCM FILTERS available via h. |
|
46 | # SCM FILTERS available via h. | |
47 | #============================================================================== |
|
47 | #============================================================================== | |
48 | from kallithea.lib.vcs.utils import author_email, author_name |
|
48 | from kallithea.lib.vcs.utils import author_email, author_name | |
49 |
from kallithea.lib.webutils import (HTML, Option, canonical_url, checkbox, chop_at, end_form, escape, form, format_byte_size, hidden, |
|
49 | from kallithea.lib.webutils import (HTML, MENTIONS_REGEX, Option, canonical_url, checkbox, chop_at, end_form, escape, form, format_byte_size, hidden, | |
50 |
link_to, literal, password, pop_flash_messages, radio, reset, safeid, select, |
|
50 | html_escape, js, jshtml, link_to, literal, password, pop_flash_messages, radio, reset, safeid, select, | |
51 | session_csrf_secret_token, submit, text, textarea, truncate, url, wrap_paragraphs) |
|
51 | session_csrf_secret_name, session_csrf_secret_token, submit, text, textarea, truncate, url, wrap_paragraphs) | |
52 | from kallithea.model import db |
|
52 | from kallithea.model import db | |
53 | from kallithea.model.changeset_status import ChangesetStatusModel |
|
53 | from kallithea.model.changeset_status import ChangesetStatusModel | |
54 |
|
54 |
@@ -36,7 +36,7 b' import markdown as markdown_mod' | |||||
36 | from docutils.core import publish_parts |
|
36 | from docutils.core import publish_parts | |
37 | from docutils.parsers.rst import directives |
|
37 | from docutils.parsers.rst import directives | |
38 |
|
38 | |||
39 |
from kallithea.lib |
|
39 | from kallithea.lib import webutils | |
40 |
|
40 | |||
41 |
|
41 | |||
42 | log = logging.getLogger(__name__) |
|
42 | log = logging.getLogger(__name__) | |
@@ -242,5 +242,5 b' class MarkupRenderer(object):' | |||||
242 | def wrapp(match_obj): |
|
242 | def wrapp(match_obj): | |
243 | uname = match_obj.groups()[0] |
|
243 | uname = match_obj.groups()[0] | |
244 | return r'\ **@%(uname)s**\ ' % {'uname': uname} |
|
244 | return r'\ **@%(uname)s**\ ' % {'uname': uname} | |
245 | mention_hl = MENTIONS_REGEX.sub(wrapp, source).strip() |
|
245 | mention_hl = webutils.MENTIONS_REGEX.sub(wrapp, source).strip() | |
246 | return cls.rst(mention_hl) |
|
246 | return cls.rst(mention_hl) |
@@ -36,8 +36,9 b' import mercurial.error' | |||||
36 | import mercurial.ui |
|
36 | import mercurial.ui | |
37 |
|
37 | |||
38 | import kallithea.lib.conf |
|
38 | import kallithea.lib.conf | |
|
39 | from kallithea.lib import webutils | |||
39 | from kallithea.lib.exceptions import InvalidCloneUriException |
|
40 | from kallithea.lib.exceptions import InvalidCloneUriException | |
40 |
from kallithea.lib.utils2 import ascii_bytes, aslist, |
|
41 | from kallithea.lib.utils2 import ascii_bytes, aslist, safe_bytes, safe_str | |
41 | from kallithea.lib.vcs.backends.git.repository import GitRepository |
|
42 | from kallithea.lib.vcs.backends.git.repository import GitRepository | |
42 | from kallithea.lib.vcs.backends.hg.repository import MercurialRepository |
|
43 | from kallithea.lib.vcs.backends.hg.repository import MercurialRepository | |
43 | from kallithea.lib.vcs.conf import settings |
|
44 | from kallithea.lib.vcs.conf import settings | |
@@ -494,7 +495,7 b' def load_extensions(root_path):' | |||||
494 | def extract_mentioned_users(text): |
|
495 | def extract_mentioned_users(text): | |
495 | """ Returns set of actual database Users @mentioned in given text. """ |
|
496 | """ Returns set of actual database Users @mentioned in given text. """ | |
496 | result = set() |
|
497 | result = set() | |
497 | for name in extract_mentioned_usernames(text): |
|
498 | for name in webutils.extract_mentioned_usernames(text): | |
498 | user = db.User.get_by_username(name, case_insensitive=True) |
|
499 | user = db.User.get_by_username(name, case_insensitive=True) | |
499 | if user is not None and not user.is_default_user: |
|
500 | if user is not None and not user.is_default_user: | |
500 | result.add(user) |
|
501 | result.add(user) |
@@ -422,22 +422,6 b' def time_to_datetime(tm):' | |||||
422 | return datetime.datetime.fromtimestamp(tm) |
|
422 | return datetime.datetime.fromtimestamp(tm) | |
423 |
|
423 | |||
424 |
|
424 | |||
425 | # Must match regexp in kallithea/public/js/base.js MentionsAutoComplete() |
|
|||
426 | # Check char before @ - it must not look like we are in an email addresses. |
|
|||
427 | # Matching is greedy so we don't have to look beyond the end. |
|
|||
428 | MENTIONS_REGEX = re.compile(r'(?:^|(?<=[^a-zA-Z0-9]))@([a-zA-Z0-9][-_.a-zA-Z0-9]*[a-zA-Z0-9])') |
|
|||
429 |
|
||||
430 |
|
||||
431 | def extract_mentioned_usernames(text): |
|
|||
432 | r""" |
|
|||
433 | Returns list of (possible) usernames @mentioned in given text. |
|
|||
434 |
|
||||
435 | >>> extract_mentioned_usernames('@1-2.a_X,@1234 not@not @ddd@not @n @ee @ff @gg, @gg;@hh @n\n@zz,') |
|
|||
436 | ['1-2.a_X', '1234', 'ddd', 'ee', 'ff', 'gg', 'gg', 'hh', 'zz'] |
|
|||
437 | """ |
|
|||
438 | return MENTIONS_REGEX.findall(text) |
|
|||
439 |
|
||||
440 |
|
||||
441 | class AttributeDict(dict): |
|
425 | class AttributeDict(dict): | |
442 | def __getattr__(self, attr): |
|
426 | def __getattr__(self, attr): | |
443 | return self.get(attr, None) |
|
427 | return self.get(attr, None) |
@@ -23,6 +23,7 b' imported anywhere - just like the global' | |||||
23 | import json |
|
23 | import json | |
24 | import logging |
|
24 | import logging | |
25 | import random |
|
25 | import random | |
|
26 | import re | |||
26 |
|
27 | |||
27 | from tg import request, session |
|
28 | from tg import request, session | |
28 | from webhelpers2.html import HTML, escape, literal |
|
29 | from webhelpers2.html import HTML, escape, literal | |
@@ -306,3 +307,19 b' def jshtml(val):' | |||||
306 | better to escape too much than too little. |
|
307 | better to escape too much than too little. | |
307 | """ |
|
308 | """ | |
308 | return js(escape(val)) |
|
309 | return js(escape(val)) | |
|
310 | ||||
|
311 | ||||
|
312 | # Must match regexp in kallithea/public/js/base.js MentionsAutoComplete() | |||
|
313 | # Check char before @ - it must not look like we are in an email addresses. | |||
|
314 | # Matching is greedy so we don't have to look beyond the end. | |||
|
315 | MENTIONS_REGEX = re.compile(r'(?:^|(?<=[^a-zA-Z0-9]))@([a-zA-Z0-9][-_.a-zA-Z0-9]*[a-zA-Z0-9])') | |||
|
316 | ||||
|
317 | ||||
|
318 | def extract_mentioned_usernames(text): | |||
|
319 | r""" | |||
|
320 | Returns list of (possible) usernames @mentioned in given text. | |||
|
321 | ||||
|
322 | >>> extract_mentioned_usernames('@1-2.a_X,@1234 not@not @ddd@not @n @ee @ff @gg, @gg;@hh @n\n@zz,') | |||
|
323 | ['1-2.a_X', '1234', 'ddd', 'ee', 'ff', 'gg', 'gg', 'hh', 'zz'] | |||
|
324 | """ | |||
|
325 | return MENTIONS_REGEX.findall(text) |
@@ -111,7 +111,7 b' class TestLibs(base.TestController):' | |||||
111 | assert asbool(str_bool) == expected |
|
111 | assert asbool(str_bool) == expected | |
112 |
|
112 | |||
113 | def test_mention_extractor(self): |
|
113 | def test_mention_extractor(self): | |
114 |
from kallithea.lib.utils |
|
114 | from kallithea.lib.webutils import extract_mentioned_usernames | |
115 | sample = ( |
|
115 | sample = ( | |
116 | "@first hi there @world here's my email username@example.com " |
|
116 | "@first hi there @world here's my email username@example.com " | |
117 | "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three " |
|
117 | "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three " |
General Comments 0
You need to be logged in to leave comments.
Login now