summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-09-26 18:29:40 -0300
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-09-26 18:33:28 -0300
commit56b83e94717bd46b8d1fb9c638bbad044ea28f88 (patch)
treeaf0bf1a499178a088d1d67300e16e068b0d3d4d6
parent10ff7a37e1403f96f73918b6b30a51da1f56a654 (diff)
downloadaskbot-56b83e94717bd46b8d1fb9c638bbad044ea28f88.tar.gz
askbot-56b83e94717bd46b8d1fb9c638bbad044ea28f88.tar.bz2
askbot-56b83e94717bd46b8d1fb9c638bbad044ea28f88.zip
pylinted markup.py files in askbot/conf and askbot/utils
-rw-r--r--askbot/conf/markup.py87
-rw-r--r--askbot/doc/source/changelog.rst4
-rw-r--r--askbot/utils/markup.py71
3 files changed, 96 insertions, 66 deletions
diff --git a/askbot/conf/markup.py b/askbot/conf/markup.py
index 077c2d9f..e4202f05 100644
--- a/askbot/conf/markup.py
+++ b/askbot/conf/markup.py
@@ -6,9 +6,7 @@ from askbot.conf.settings_wrapper import settings
from askbot.deps.livesettings import ConfigurationGroup
from askbot.deps.livesettings import BooleanValue, StringValue, LongStringValue
from django.utils.translation import ugettext as _
-import askbot
from askbot import const
-import os
import re
MARKUP = ConfigurationGroup(
@@ -16,27 +14,20 @@ MARKUP = ConfigurationGroup(
_('Markup formatting')
)
-AUTOLINK = ConfigurationGroup(
- 'AUTOLINK',
- _('Auto link a pattern to an URL')
-
-)
-
def regex_settings_validation(*args):
"""
Validate the regular expressions
-
"""
try:
new_value = args[1]
regex_list = new_value.split('\n')
- for i in range(0,len(regex_list)):
+ for i in range(0, len(regex_list)):
re.compile(regex_list[i].strip())
return args[1]
- except Exception, e:
+ except Exception:
# The regex is invalid, so we overwrite it with empty string
return ""
@@ -92,34 +83,36 @@ settings.register(
settings.register(
- BooleanValue(
- AUTOLINK,
- 'ENABLE_AUTO_LINKING',
- description=_('Enable autolinking a specifc pattern'),
- help_text=_(
- 'If you enable this feature, '
- 'the application will be able to '
- 'detect patterns and auto link to URLs'
- ),
-
- default = False
- )
- )
+ BooleanValue(
+ MARKUP,
+ 'ENABLE_AUTO_LINKING',
+ description=_('Enable autolinking with specific patterns'),
+ help_text=_(
+ 'If you enable this feature, '
+ 'the application will be able to '
+ 'detect patterns and auto link to URLs'
+ ),
+ default = False
+ )
+)
settings.register(
LongStringValue(
- AUTOLINK,
- 'PATTERN',
- description=_('Regex to detect the pattern'),
+ MARKUP,
+ 'AUTO_LINK_PATTERNS',
+ description=_('Regexes to detect the link patterns'),
help_text=_(
- ' Enter valid regular expressions to'
- ' detect patterns. If you want to auto'
- ' link more than one key terms enter them'
- ' line by line. For example to'
- ' detect a bug pattern like #rhbz 637402'
- ' you will have use the following regex #rhbz\s(\d+)'
- ),
+ 'Enter valid regular expressions for the patters,'
+ ' one per line.'
+ ' For example to'
+ ' detect a bug pattern like #bug123,'
+ ' use the following regex: #bug(\d+). The numbers'
+ ' captured by the pattern in the parentheses will'
+ ' be transferred to the link url template.'
+ ' Please look up more information about regular'
+ ' expressions elsewhere.'
+ ),
update_callback=regex_settings_validation,
default = ''
)
@@ -127,20 +120,20 @@ settings.register(
settings.register(
LongStringValue(
- AUTOLINK,
- 'AUTO_LINK_URL',
- description=_('URL for autolinking'),
+ MARKUP,
+ 'AUTO_LINK_URLS',
+ description=_('URLs for autolinking'),
help_text=_(
- ' The regex to detect pattern #rhbz 637402'
- ' is #rhbz\s(\d+), If you want to auto link it to the actual bug'
- ' then the autolink URL should be entered here. Example URL can be'
+ 'Here, please enter url templates for the patterns'
+ ' entered in the previous setting, also one entry per line.'
+ ' <strong>Make sure that number of lines in this setting'
+ ' and the previous one are the same</strong>'
+ ' For example template'
' https://bugzilla.redhat.com/show_bug.cgi?id=\\1'
- ' where \\1 is the saved match (bugid) from the regular expression.'
- ' Multiple URLs should be entered in separate lines.'
- ' The URL entered in first line'
- ' will be used to auto link the first pattern or key term'
- ),
+ ' together with the pattern shown above'
+ ' and the entry in the post #123'
+ ' will produce link to the bug 123 in the redhat bug tracker.'
+ ),
default = ''
- )
)
-
+)
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst
index 7bbd734c..04062dc2 100644
--- a/askbot/doc/source/changelog.rst
+++ b/askbot/doc/source/changelog.rst
@@ -1,6 +1,10 @@
Changes in Askbot
=================
+Development version (not released yet)
+--------------------------------------
+* Auto-link patterns - e.g. to bug databases - are configurable from settings. (Arun SAG)
+
0.7.23 (Current Version)
-------------------
* Greeting for anonymuos users can be changed from live settings (Hrishi)
diff --git a/askbot/utils/markup.py b/askbot/utils/markup.py
index 3b16a5b2..60bde9a0 100644
--- a/askbot/utils/markup.py
+++ b/askbot/utils/markup.py
@@ -1,9 +1,13 @@
+"""methods that make parsing of post inputs possible,
+handling of markdown and additional syntax rules -
+such as optional link patterns, video embedding and
+Twitter-style @mentions"""
+
import re
import logging
from askbot import const
from askbot.conf import settings as askbot_settings
from markdown2 import Markdown
-
#url taken from http://regexlib.com/REDetails.aspx?regexp_id=501 by Brian Bothwell
URL_RE = re.compile("((?<!(href|.src|data)=['\"])((http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&amp;%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&amp;%\$#\=~_\-]+))*))")
@@ -13,6 +17,8 @@ LINK_PATTERNS = [
def get_parser():
+ """returns an instance of configured ``markdown2`` parser
+ """
extras = ['link-patterns', 'video']
if askbot_settings.ENABLE_MATHJAX or \
askbot_settings.MARKUP_CODE_FRIENDLY:
@@ -25,18 +31,28 @@ def get_parser():
extras.append('video')
if askbot_settings.ENABLE_AUTO_LINKING:
- pattern_list = askbot_settings.PATTERN.split('\n')
- url_list = askbot_settings.AUTO_LINK_URL.split('\n')
+ pattern_list = askbot_settings.AUTO_LINK_PATTERNS.split('\n')
+ url_list = askbot_settings.AUTO_LINK_URLS.split('\n')
+ pairs = zip(pattern_list, url_list)#always takes equal number of items
+ for item in pairs:
+ LINK_PATTERNS.append(
+ (
+ re.compile(item[0]),
+ item[1].strip()
+ )
+ )
- # Check whether we have matching links for all key terms, Other wise we ignore the key terms
- # May be we should do this test in update_callback?
- if len(pattern_list) == len(url_list):
- for i in range(0,len(pattern_list)):
- LINK_PATTERNS.append((re.compile(pattern_list[i].strip()),url_list[i].strip()))
- else:
+ #Check whether we have matching links for all key terms,
+ #Other wise we ignore the key terms
+ #May be we should do this test in update_callback?
+ #looks like this might be a defect of livesettings
+ #as there seems to be no way
+ #to validate entries that depend on each other
+ if len(pattern_list) != len(url_list):
settings_url = askbot_settings.APP_URL+'/settings/AUTOLINK/'
- logging.debug("Number of keyterms didn't match the number of links, fix this by visiting" + settings_url)
-
+ logging.critical(
+ "Number of autolink patterns didn't match the number "
+ "of url templates, fix this by visiting" + settings_url)
return Markdown(
html4tags=True,
@@ -46,18 +62,23 @@ def get_parser():
def format_mention_in_html(mentioned_user):
+ """formats mention as url to the user profile"""
url = mentioned_user.get_profile_url()
username = mentioned_user.username
return '<a href="%s">@%s</a>' % (url, username)
def extract_first_matching_mentioned_author(text, anticipated_authors):
+ """matches beginning of ``text`` string with the names
+ of ``anticipated_authors`` - list of user objects.
+ Returns upon first match the first matched user object
+ and the remainder of the ``text`` that is left unmatched"""
if len(text) == 0:
return None, ''
- for a in anticipated_authors:
- if text.lower().startswith(a.username.lower()):
- ulen = len(a.username)
+ for author in anticipated_authors:
+ if text.lower().startswith(author.username.lower()):
+ ulen = len(author.username)
if len(text) == ulen:
text = ''
elif text[ulen] in const.TWITTER_STYLE_MENTION_TERMINATION_CHARS:
@@ -66,17 +87,24 @@ def extract_first_matching_mentioned_author(text, anticipated_authors):
#near miss, here we could insert a warning that perhaps
#a termination character is needed
continue
- return a, text
+ return author, text
return None, text
def extract_mentioned_name_seeds(text):
+ """Returns list of strings that
+ follow the '@' symbols in the text.
+ The strings will be 10 characters long,
+ or shorter, if the subsequent character
+ is one of the list accepted to be termination
+ characters.
+ """
extra_name_seeds = set()
while '@' in text:
pos = text.index('@')
text = text[pos+1:]#chop off prefix
name_seed = ''
- for c in text:
- if c in const.TWITTER_STYLE_MENTION_TERMINATION_CHARS:
+ for char in text:
+ if char in const.TWITTER_STYLE_MENTION_TERMINATION_CHARS:
extra_name_seeds.add(name_seed)
name_seed = ''
break
@@ -84,12 +112,12 @@ def extract_mentioned_name_seeds(text):
extra_name_seeds.add(name_seed)
name_seed = ''
break
- if c == '@':
+ if char == '@':
if len(name_seed) > 0:
extra_name_seeds.add(name_seed)
name_seed = ''
break
- name_seed += c
+ name_seed += char
if len(name_seed) > 0:
#in case we run off the end of text
extra_name_seeds.add(name_seed)
@@ -97,6 +125,11 @@ def extract_mentioned_name_seeds(text):
return extra_name_seeds
def mentionize_text(text, anticipated_authors):
+ """Returns a tuple of two items:
+ * modified text where @mentions are
+ replaced with urls to the corresponding user profiles
+ * list of users whose names matched the @mentions
+ """
output = ''
mentioned_authors = list()
while '@' in text: