diff options
author | Byron <byroncorrales@gmail.com> | 2011-09-27 14:53:50 -0600 |
---|---|---|
committer | Byron <byroncorrales@gmail.com> | 2011-09-27 14:53:50 -0600 |
commit | 640ccca72ee78dd9876e235d930b7ee393f42017 (patch) | |
tree | 9ae7470e5f6f5946bf7f8b9832e2c856622668e5 | |
parent | 8b0363c4b3613415bb887f25bfdf1b540208a222 (diff) | |
parent | b208c5648d4fbf810b65283db4a6eae151839570 (diff) | |
download | askbot-640ccca72ee78dd9876e235d930b7ee393f42017.tar.gz askbot-640ccca72ee78dd9876e235d930b7ee393f42017.tar.bz2 askbot-640ccca72ee78dd9876e235d930b7ee393f42017.zip |
Merge branch 'master' of https://github.com/ASKBOT/askbot-devel
-rw-r--r-- | askbot/__init__.py | 2 | ||||
-rw-r--r-- | askbot/conf/markup.py | 80 | ||||
-rw-r--r-- | askbot/doc/source/changelog.rst | 13 | ||||
-rw-r--r-- | askbot/doc/source/contributors.rst | 1 | ||||
-rw-r--r-- | askbot/skins/default/templates/user_profile/user_moderate.html | 28 | ||||
-rw-r--r-- | askbot/utils/markup.py | 67 |
6 files changed, 174 insertions, 17 deletions
diff --git a/askbot/__init__.py b/askbot/__init__.py index 8133c74f..5ced4ca1 100644 --- a/askbot/__init__.py +++ b/askbot/__init__.py @@ -9,7 +9,7 @@ import smtplib import sys import logging -VERSION = (0, 7, 22) +VERSION = (0, 7, 23) #necessary for interoperability of django and coffin try: diff --git a/askbot/conf/markup.py b/askbot/conf/markup.py index 026c5536..e4202f05 100644 --- a/askbot/conf/markup.py +++ b/askbot/conf/markup.py @@ -4,17 +4,34 @@ Settings that modify processing of user text input from askbot.conf.settings_wrapper import settings from askbot.deps.livesettings import ConfigurationGroup -from askbot.deps.livesettings import BooleanValue, StringValue +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( 'MARKUP', _('Markup formatting') ) +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)): + re.compile(regex_list[i].strip()) + return args[1] + + except Exception: + # The regex is invalid, so we overwrite it with empty string + return "" + + settings.register( BooleanValue( MARKUP, @@ -63,3 +80,60 @@ settings.register( default = '' ) ) + + +settings.register( + 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( + MARKUP, + 'AUTO_LINK_PATTERNS', + description=_('Regexes to detect the link patterns'), + help_text=_( + '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 = '' + ) + ) + +settings.register( + LongStringValue( + MARKUP, + 'AUTO_LINK_URLS', + description=_('URLs for autolinking'), + help_text=_( + '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' + ' 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 c40f08c1..33a0199c 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -1,8 +1,13 @@ Changes in Askbot ================= -Development version -------------------- +Development version (not released yet) +-------------------------------------- +* Added annotations for the meanings of user levels on the "moderation" page. (Jishnu) +* 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) * Greeting for anonymous users is shown only once (Rag Sagar) * Added support for Akismet spam detection service (Adolfo Fitoria) @@ -11,8 +16,8 @@ Development version * Allowed logging in with password and email in the place of login name (Evgeny) * Added config settings allowing adjust license information (Evgeny) -0.7.22 (Current Version) ------------------------- +0.7.22 +------ * Media resource revision is now incremented automatically any time when media is updated (Adolfo Fitoria, Evgeny Fadeev) * First user automatically becomes site administrator (Adolfo Fitoria) diff --git a/askbot/doc/source/contributors.rst b/askbot/doc/source/contributors.rst index 35c02be1..fb8d9690 100644 --- a/askbot/doc/source/contributors.rst +++ b/askbot/doc/source/contributors.rst @@ -15,6 +15,7 @@ Programming and documentation * Andy Knotts * Benoit Lavine (with Windriver Software, Inc.) * Jeff Madynski +* `Jishnu <http://thecodecracker.com/>`_ * `Hrishi <https://github.com/stultus>`_ * Andrei Mamoutkine * Ramiro Morales (with Machinalis) diff --git a/askbot/skins/default/templates/user_profile/user_moderate.html b/askbot/skins/default/templates/user_profile/user_moderate.html index 563026a4..b2f350df 100644 --- a/askbot/skins/default/templates/user_profile/user_moderate.html +++ b/askbot/skins/default/templates/user_profile/user_moderate.html @@ -15,6 +15,8 @@ <table class="form-as-table"> {{ change_user_status_form.as_table() }} </table> + <p id="id_user_status_info"> + </p> <input type="submit" class="submit" name="change_status" value="{% trans %}Save{% endtrans %}" /> </form> {% endif %} @@ -64,3 +66,29 @@ </form> {% endif %} {% endblock %} +{% block endjs %} + <script type="text/javascript" > + $("#id_user_status_info").hide(); + $("#id_user_status").change(function () { + var optionValue = $(this).attr('value'); + if (optionValue == "d") { + $('#id_user_status_info').html("{% trans %}Administrators have privileges of normal users, but in addition they can assign/revoke any status to any user, and are exempt from the reputation limits.{% endtrans %}"); + $('#id_user_status_info').show('slow'); + } else if (optionValue == "m"){ + $('#id_user_status_info').html("{% trans %}Moderators have the same privileges as administrators, but cannot add or remove user status of 'moderator' or 'administrator'.{% endtrans %}"); + $('#id_user_status_info').show('slow'); + } else if (optionValue == "a"){ + $('#id_user_status_info').html("{% trans %}'Approved' status means the same as regular user.{% endtrans %}"); + $('#id_user_status_info').show('slow'); + } else if (optionValue == "s"){ + $('#id_user_status_info').html("{% trans %}Suspended users can only edit or delete their own posts.{% endtrans %}"); + $('#id_user_status_info').show('slow'); + } else if (optionValue == "b"){ + $('#id_user_status_info').html("{% trans %}Blocked users can only login and send feedback to the site administrators.{% endtrans %}"); + $('#id_user_status_info').show('slow'); + } else { + $('#id_user_status_info').hide('slow'); + } + }) + </script> +{% endblock %} diff --git a/askbot/utils/markup.py b/askbot/utils/markup.py index acb8d03d..60bde9a0 100644 --- a/askbot/utils/markup.py +++ b/askbot/utils/markup.py @@ -1,8 +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\.&%\$\-]+)*@)*((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\.\,\?\'\\\+&%\$#\=~_\-]+))*))") @@ -10,7 +15,10 @@ LINK_PATTERNS = [ (URL_RE, r'\1'), ] + 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: @@ -22,6 +30,30 @@ def get_parser(): #pip install -e git+git://github.com/andryuha/python-markdown2.git extras.append('video') + if askbot_settings.ENABLE_AUTO_LINKING: + 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? + #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.critical( + "Number of autolink patterns didn't match the number " + "of url templates, fix this by visiting" + settings_url) + return Markdown( html4tags=True, extras=extras, @@ -30,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: @@ -50,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 @@ -68,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) @@ -81,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: |