+import threading
+
+
class RequestHolder(object):
- def __init__(self):
- self.request = None
+ _requests = threading.local()
+
+ @property
+ def request(self):
+ return self._requests.request
+
+ @request.setter
+ def request(self, value):
+ self._requests.request = value
-REQUEST_HOLDER = RequestHolder()
\ No newline at end of file
+REQUEST_HOLDER = RequestHolder()
from django.utils.translation import ugettext as _
from forum.models.action import ActionProxy
from forum.models import Comment, Question, Answer, NodeRevision
-import logging
+from forum import settings, REQUEST_HOLDER
+
+from django.contrib import messages
class NodeEditAction(ActionProxy):
def create_revision_data(self, initial=False, **data):
question.save()
self.node = question
- self.user.message_set.create(message=self.describe(self.user))
+ messages.info(REQUEST_HOLDER.request, self.describe(self.user))
def describe(self, viewer=None):
return _("%(user)s asked %(question)s") % {
def process_action(self):
self.node.question.reset_answer_count_cache()
- self.user.message_set.create(message=self.describe(self.user))
+ messages.info(REQUEST_HOLDER.request, self.describe(self.user))
def describe(self, viewer=None):
from django.db.models import F
from forum.models.action import ActionProxy
from forum.models import Award, Badge, ValidationHash, User
-from forum import settings
+from forum import settings, REQUEST_HOLDER
from forum.settings import APP_SHORT_NAME
from forum.utils.mail import send_template_email
+from django.contrib import messages
+
class UserJoinsAction(ActionProxy):
verb = _("joined")
message=_("Congratulations, you have been awarded an extra %s reputation points.") % self._value +
'<br />%s' % self.extra.get('message', _('Thank you')))
else:
- self._affected.message_set.create(
- message=_("You have been penalized in %s reputation points.") % self._value +
+ messages.info(REQUEST_HOLDER.request, _("You have penalized %s in %s reputation points.") % (self._affected, self._value) +
'<br />%s' % self.extra.get('message', ''))
def describe(self, viewer=None):
self.repute(self._affected, self._value)
self.repute(self.user, -self._value)
-
self._affected.message_set.create(
message=_("Congratulations, you have been awarded an extra %(points)s reputation %(points_label)s on <a href=\"%(answer_url)s\">this</a> answer.") % {
'points': self._value,
def auth_processor(request):
if hasattr(request, 'user'):
user = request.user
- if user.is_authenticated():
- messages = user.message_set.all()
- else:
- messages = None
else:
from django.contrib.auth.models import AnonymousUser
user = AnonymousUser()
- messages = None
from django.core.context_processors import PermWrapper
return {
'user': user,
- 'messages': messages,
'perms': PermWrapper(user),
}
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
from forum import settings
-from django.http import str_to_unicode
from forum.models import User
from forum.modules import call_all_handlers
import urllib
def clean_next(next):
if next is None:
return DEFAULT_NEXT
- next = str_to_unicode(urllib.unquote(next), 'utf-8')
+ next = urllib.unquote(next)
+ if not isinstance(next, unicode):
+ next = unicode(next, 'utf-8')
next = next.strip()
if next.startswith('/'):
return next
class Meta:
model = SubscriptionSettings
+ fields = ['enable_notifications', 'member_joins', 'new_question', 'new_question_watched_tags', 'subscribed_questions']
class UserPreferencesForm(forms.Form):
sticky_sorts = forms.BooleanField(required=False, initial=False)
-from forum.user_messages import create_message
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.core.exceptions import ObjectDoesNotExist
+from django.contrib import messages
from forum.settings import EMAIL_HOST, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, \
APP_URL
# We do not want to repeat ourselves. If the message already exists in the message list, we're not going to
# add it. That's why first of all we're going the check if it is there.
- try:
- # If the message doesn't exist in the RelatedManager ObjectsDoesNotExist is going to be raised.
- request.user.message_set.all().get(message=msg)
- except ObjectDoesNotExist:
- # Let's create the message.
- request.user.message_set.create(message=msg)
- except:
- pass
+ if msg not in [m.message for m in messages.api.get_messages(request)]:
+ messages.info(request, msg)
def check_app_url(self, request):
# We consider the APP_URL setting not configured if it contains only the protocol
# We do not want to repeat ourselves. If the message already exists in the message list, we're not going to
# add it. That's why first of all we're going the check if it is there.
- try:
- # If the message doesn't exist in the RelatedManager ObjectsDoesNotExist is going to be raised.
- request.user.message_set.all().get(message=msg)
- except ObjectDoesNotExist:
- # Let's create the message.
- request.user.message_set.create(message=msg)
- except:
- pass
+ if msg not in [m.message for m in messages.api.get_messages(request)]:
+ messages.info(request, msg)
from django.http import HttpResponseRedirect, HttpResponse
from forum.forms import get_next_url
from django.utils.translation import ugettext as _
-from forum.user_messages import create_message, get_and_delete_messages
from forum import settings
from django.core.urlresolvers import reverse
import logging
+from django.contrib import messages
+
class AnonymousMessageManager(object):
def __init__(self,request):
self.request = request
def process_request(self, request):
if not request.user.is_authenticated():
request.user.__deepcopy__ = dummy_deepcopy #plug on deepcopy which may be called by django db "driver"
- request.user.message_set = AnonymousMessageManager(request) #here request is linked to anon user
- request.user.get_and_delete_messages = request.user.message_set.get_and_delete
#also set the first greeting one time per session only
if 'greeting_set' not in request.session:
# If the store greeting in cookie setting is activated make sure that the greeting_set cookies isn't set
if (settings.STORE_GREETING_IN_COOKIE and not request.COOKIES.has_key('greeting_set')) or \
not settings.STORE_GREETING_IN_COOKIE:
- request.user.message_set.create(message=msg)
+ messages.info(request, msg)
if settings.STORE_GREETING_IN_COOKIE:
request.COOKIES.set(key='greeting_set', value=True)
from django.http import HttpResponseRedirect
from forum.forms import get_next_url
import logging
+from django.contrib import messages
+
class CancelActionMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
if 'cancel' in request.REQUEST:
msg = getattr(view_func,'CANCEL_MESSAGE')
except AttributeError:
msg = 'action canceled'
- request.user.message_set.create(message=msg)
+ messages.info(request, msg)
return HttpResponseRedirect(get_next_url(request))
else:
return None
class ActionManager(CachedManager):
use_for_related_fields = True
- def get_query_set(self):
+ def get_queryset(self):
qs = ActionQuerySet(self.model)
if self.model is not Action:
class CachedManager(models.Manager):
use_for_related_fields = True
- def get_query_set(self):
+ def get_queryset(self):
return CachedQuerySet(self.model)
def get_or_create(self, *args, **kwargs):
cls.add_to_class("reset_%s_cache" % name, reset_cache)
-class BaseMetaClass(models.Model.__metaclass__):
+class BaseMetaClass(type(models.Model)):
to_denormalize = []
def __new__(cls, *args, **kwargs):
class NodeManager(CachedManager):
use_for_related_fields = True
- def get_query_set(self):
+ def get_queryset(self):
qs = NodeQuerySet(self.model)
# If the node is an answer, question or comment we filter the Node model by type
class ActiveTagManager(CachedManager):
use_for_related_fields = True
- def get_query_set(self):
- return super(ActiveTagManager, self).get_query_set().exclude(used_count__lt=1)
+ def get_queryset(self):
+ return super(ActiveTagManager, self).get_queryset().exclude(used_count__lt=1)
class Tag(BaseModel):
name = models.CharField(max_length=255, unique=True)
sub_settings = SubscriptionSettings(user=self)
sub_settings.save()
- def get_messages(self):
- messages = []
- for m in self.message_set.all():
- messages.append(m.message)
- return messages
-
- def delete_messages(self):
- self.message_set.all().delete()
-
@models.permalink
def get_profile_url(self):
keyword_arguments = {
raise
return value
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection, prepared=False):
if value is not None and not isinstance(value, PickledObject):
if type(value).__name__ in self.markable_types and not (isinstance(value, basestring) and len(value
) > MAX_MARKABLE_STRING_LENGTH):
try:
all.append(__import__('%s.%s' % (m.__name__, script_name), globals(), locals(), [m.__name__]))
- except ImportError, e:
- #print repr(type(e)) + m.__name__ + ":" + str(e)
- pass
- except:
- import traceback
- msg = "Error importing %s from module %s: \n %s" % (
- script_name, m, traceback.format_exc()
- )
- logging.error(msg)
+ except Exception, e:
+ if isinstance(e, ImportError) and str(e).endswith(script_name):
+ continue
+ logging.exception("Error importing %s from module %s", script_name, m)
return all
from django.forms.widgets import Textarea
from django.utils.translation import ugettext_lazy as _
from django.conf import settings as djsettings
-from django.utils.version import get_svn_revision
+from django.utils.version import get_git_changeset
from forum.modules import get_modules_script_implementations
OSQA_VERSION = "Development Build"
-SVN_REVISION = get_svn_revision(djsettings.SITE_SRC_ROOT)
+VCS_REVISION = get_git_changeset()
# We'll have to keep in mind this variable on every release.
-if SVN_REVISION == u'SVN-unknown':
- SVN_REVISION = u'SVN-1000'
+if VCS_REVISION == u'SVN-unknown':
+ VCS_REVISION = u'SVN-1000'
MAINTAINANCE_MODE = Setting('MAINTAINANCE_MODE', None)
FORCE_SCRIPT_NAME = djsettings.FORCE_SCRIPT_NAME
OSQA_SKIN = djsettings.OSQA_DEFAULT_SKIN
LANGUAGE_CODE = djsettings.LANGUAGE_CODE
-ADMIN_MEDIA_PREFIX = djsettings.ADMIN_MEDIA_PREFIX
ONLINE_USERS = Setting('ONLINE_USERS', {})
-import os.path\r
-\r
-from base import Setting, SettingSet\r
-from forms import ImageFormWidget\r
-\r
-from django.utils.translation import ugettext_lazy as _\r
-from django.forms.widgets import Textarea\r
-\r
-BASIC_SET = SettingSet('basic', _('Basic settings'), _("The basic settings for your application"), 1)\r
-\r
-APP_LOGO = Setting('APP_LOGO', '/upfiles/logo.png', BASIC_SET, dict(\r
-label = _("Application logo"),\r
-help_text = _("Your site main logo."),\r
-widget=ImageFormWidget))\r
-\r
-APP_FAVICON = Setting('APP_FAVICON', '/m/default/media/images/favicon.ico', BASIC_SET, dict(\r
-label = _("Favicon"),\r
-help_text = _("Your site favicon."),\r
-widget=ImageFormWidget))\r
-\r
-APP_TITLE = Setting('APP_TITLE', u'OSQA: Open Source Q&A Forum', BASIC_SET, dict(\r
-label = _("Application title"),\r
-help_text = _("The title of your application that will show in the browsers title bar")))\r
-\r
-APP_SHORT_NAME = Setting(u'APP_SHORT_NAME', 'OSQA', BASIC_SET, dict(\r
-label = _("Application short name"),\r
-help_text = "The short name for your application that will show up in many places."))\r
-\r
-APP_KEYWORDS = Setting('APP_KEYWORDS', u'OSQA,CNPROG,forum,community', BASIC_SET, dict(\r
-label = _("Application keywords"),\r
-help_text = _("The meta keywords that will be available through the HTML meta tags.")))\r
-\r
-APP_DESCRIPTION = Setting('APP_DESCRIPTION', u'Ask and answer questions.', BASIC_SET, dict(\r
-label = _("Application description"),\r
-help_text = _("The description of your application"),\r
-widget=Textarea))\r
-\r
-APP_COPYRIGHT = Setting('APP_COPYRIGHT', u'Copyright OSQA, 2010. Some rights reserved under creative commons license.', BASIC_SET, dict(\r
-label = _("Copyright notice"),\r
-help_text = _("The copyright notice visible at the footer of your page.")))\r
-\r
-SUPPORT_URL = Setting('SUPPORT_URL', '', BASIC_SET, dict(\r
-label = _("Support URL"),\r
-help_text = _("The URL provided for users to get support. It can be http: or mailto: or whatever your preferred support scheme is."),\r
-required=False))\r
-\r
-CONTACT_URL = Setting('CONTACT_URL', '', BASIC_SET, dict(\r
-label = _("Contact URL"),\r
-help_text = _("The URL provided for users to contact you. It can be http: or mailto: or whatever your preferred contact scheme is."),\r
-required=False))\r
-\r
-\r
+import os.path
+
+from base import Setting, SettingSet
+from forms import ImageFormWidget
+
+from django.utils.translation import ugettext_lazy as _
+from django.forms.widgets import Textarea
+
+BASIC_SET = SettingSet('basic', _('Basic settings'), _("The basic settings for your application"), 1)
+
+APP_LOGO = Setting('APP_LOGO', '/upfiles/logo.png', BASIC_SET, dict(
+label = _("Application logo"),
+help_text = _("Your site main logo."),
+widget=ImageFormWidget))
+
+APP_FAVICON = Setting('APP_FAVICON', '/m/default/media/images/favicon.ico', BASIC_SET, dict(
+label = _("Favicon"),
+help_text = _("Your site favicon."),
+widget=ImageFormWidget))
+
+APP_TITLE = Setting('APP_TITLE', u'OSQA: Open Source Q&A Forum', BASIC_SET, dict(
+label = _("Application title"),
+help_text = _("The title of your application that will show in the browsers title bar")))
+
+APP_SHORT_NAME = Setting(u'APP_SHORT_NAME', 'OSQA', BASIC_SET, dict(
+label = _("Application short name"),
+help_text = "The short name for your application that will show up in many places."))
+
+APP_KEYWORDS = Setting('APP_KEYWORDS', u'OSQA,CNPROG,forum,community', BASIC_SET, dict(
+label = _("Application keywords"),
+help_text = _("The meta keywords that will be available through the HTML meta tags.")))
+
+APP_DESCRIPTION = Setting('APP_DESCRIPTION', u'Ask and answer questions.', BASIC_SET, dict(
+label = _("Application description"),
+help_text = _("The description of your application"),
+widget=Textarea))
+
+APP_COPYRIGHT = Setting('APP_COPYRIGHT', u'Copyright OSQA, 2010. Some rights reserved under creative commons license.', BASIC_SET, dict(
+label = _("Copyright notice"),
+help_text = _("The copyright notice visible at the footer of your page.")))
+
+SUPPORT_URL = Setting('SUPPORT_URL', '', BASIC_SET, dict(
+label = _("Support URL"),
+help_text = _("The URL provided for users to get support. It can be http: or mailto: or whatever your preferred support scheme is."),
+required=False))
+
+CONTACT_URL = Setting('CONTACT_URL', '', BASIC_SET, dict(
+label = _("Contact URL"),
+help_text = _("The URL provided for users to contact you. It can be http: or mailto: or whatever your preferred contact scheme is."),
+required=False))
+
+
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-from django.forms.widgets import PasswordInput\r
-from django.forms.widgets import RadioSelect\r
-from forms import TestEmailSettingsWidget\r
-\r
-EMAIL_SET = SettingSet('email', _('Email settings'), _("Email server and other email related settings."), 50)\r
-\r
-TEST_EMAIL_SETTINGS = Setting('TEST_EMAIL_SETTINGS', '', EMAIL_SET, dict(\r
-label = _("E-Mail settings test"),\r
-help_text = _("Test the current E-Mail configuration."),\r
-required=False,\r
-widget=TestEmailSettingsWidget))\r
-\r
-EMAIL_HOST = Setting('EMAIL_HOST', '', EMAIL_SET, dict(\r
-label = _("Email Server"),\r
-help_text = _("The SMTP server through which your application will be sending emails."),\r
-required=False))\r
-\r
-EMAIL_PORT = Setting('EMAIL_PORT', 25, EMAIL_SET, dict(\r
-label = _("Email Port"),\r
-help_text = _("The port on which your SMTP server is listening to. Usually this is 25, but can be something else."),\r
-required=False))\r
-\r
-EMAIL_HOST_USER = Setting('EMAIL_HOST_USER', '', EMAIL_SET, dict(\r
-label = _("Email User"),\r
-help_text = _("The username for your SMTP connection."),\r
-required=False))\r
-\r
-EMAIL_HOST_PASSWORD = Setting('EMAIL_HOST_PASSWORD', '', EMAIL_SET, dict(\r
-label = _("Email Password"),\r
-help_text = _("The password for your SMTP connection."),\r
-required=False,\r
-widget=PasswordInput(render_value=True)))\r
-\r
-EMAIL_USE_TLS = Setting('EMAIL_USE_TLS', False, EMAIL_SET, dict(\r
-label = _("Use TLS"),\r
-help_text = _("Whether to use TLS for authentication with your SMTP server."),\r
-required=False))\r
-\r
-DEFAULT_FROM_EMAIL = Setting('DEFAULT_FROM_EMAIL', '', EMAIL_SET, dict(\r
-label = _("Site 'from' Email Address"),\r
-help_text = _("The address that will show up on the 'from' field on emails sent by your website."),\r
-required=False))\r
-\r
-DEFAULT_REPLY_TO_EMAIL = Setting('DEFAULT_REPLY_TO_EMAIL', '', EMAIL_SET, dict(\r
-label = _("Site 'reply-to' Email Address"),\r
-help_text = _("The address that will show up on the 'reply-to' field on emails sent by your website."),\r
-required=False))\r
-\r
-EMAIL_SUBJECT_PREFIX = Setting('EMAIL_SUBJECT_PREFIX', '', EMAIL_SET, dict(\r
-label = _("Email Subject Prefix"),\r
-help_text = _("Every email sent through your website will have the subject prefixed by this string. It's usually a good idea to have such a prefix so your users can easily set up a filter on their email clients."),\r
-required=False))\r
-\r
-EMAIL_FOOTER_TEXT = Setting(u'EMAIL_FOOTER_TEXT', '', EMAIL_SET, dict(\r
-label = _("Email Footer Text"),\r
-help_text = _("Email footer text, usually \"CAN SPAM\" compliance, or the physical address of the organization running the website. See <a href=\"http://en.wikipedia.org/wiki/CAN-SPAM_Act_of_2003\">this Wikipedia article</a> for more info."),\r
-required=False))\r
-\r
-EMAIL_BORDER_COLOR = Setting('EMAIL_BORDER_COLOR', '#e5ebf8', EMAIL_SET, dict(\r
-label = _("Email Border Color"),\r
-help_text = _("The outter border color of the email base template"),\r
-required=False))\r
-\r
-EMAIL_PARAGRAPH_STYLE = Setting('EMAIL_PARAGRAPH_STYLE', "color:#333333;font-family:'helvetica neue', arial, Helvetica, sans-serif;line-height:18px;font-size:14px;margin-top:10px;", EMAIL_SET, dict(\r
-label = _("Email Paragraph Style"),\r
-help_text = _("A valid css string to be used to style email paragraphs (the P tag)."),\r
-required=False))\r
-\r
-EMAIL_ANCHOR_STYLE = Setting('EMAIL_ANCHOR_STYLE', "text-decoration:none;color:#3060a8;font-weight:bold;", EMAIL_SET, dict(\r
-label = _("Email Link Style"),\r
-help_text = _("A valid css string to be used to style email links (the A tag)."),\r
-required=False))\r
-\r
-SEND_DIGEST_ONLY_TO_ACTIVE_USERS = Setting('SEND_DIGEST_ONLY_TO_ACTIVE_USERS', True, EMAIL_SET, dict(\r
-label = _("Send digest only to active users"),\r
-help_text = _("If checked the daily digest won't be sent to users that have been suspended."),\r
-required=False))\r
-\r
-SEND_DIGEST_ONLY_TO_VALIDATED_USERS = Setting('SEND_DIGEST_ONLY_TO_VALIDATED_USERS', True, EMAIL_SET, dict(\r
-label = _("Send digest only to validated users"),\r
-help_text = _("If checked the daily digest won't be sent to users that haven't validated their emails."),\r
-required=False))\r
-\r
-EMAIL_DIGEST_FLAG = Setting('EMAIL_DIGEST_FLAG', None)\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+from django.forms.widgets import PasswordInput
+from django.forms.widgets import RadioSelect
+from forms import TestEmailSettingsWidget
+
+EMAIL_SET = SettingSet('email', _('Email settings'), _("Email server and other email related settings."), 50)
+
+TEST_EMAIL_SETTINGS = Setting('TEST_EMAIL_SETTINGS', '', EMAIL_SET, dict(
+label = _("E-Mail settings test"),
+help_text = _("Test the current E-Mail configuration."),
+required=False,
+widget=TestEmailSettingsWidget))
+
+EMAIL_HOST = Setting('EMAIL_HOST', '', EMAIL_SET, dict(
+label = _("Email Server"),
+help_text = _("The SMTP server through which your application will be sending emails."),
+required=False))
+
+EMAIL_PORT = Setting('EMAIL_PORT', 25, EMAIL_SET, dict(
+label = _("Email Port"),
+help_text = _("The port on which your SMTP server is listening to. Usually this is 25, but can be something else."),
+required=False))
+
+EMAIL_HOST_USER = Setting('EMAIL_HOST_USER', '', EMAIL_SET, dict(
+label = _("Email User"),
+help_text = _("The username for your SMTP connection."),
+required=False))
+
+EMAIL_HOST_PASSWORD = Setting('EMAIL_HOST_PASSWORD', '', EMAIL_SET, dict(
+label = _("Email Password"),
+help_text = _("The password for your SMTP connection."),
+required=False,
+widget=PasswordInput(render_value=True)))
+
+EMAIL_USE_TLS = Setting('EMAIL_USE_TLS', False, EMAIL_SET, dict(
+label = _("Use TLS"),
+help_text = _("Whether to use TLS for authentication with your SMTP server."),
+required=False))
+
+DEFAULT_FROM_EMAIL = Setting('DEFAULT_FROM_EMAIL', '', EMAIL_SET, dict(
+label = _("Site 'from' Email Address"),
+help_text = _("The address that will show up on the 'from' field on emails sent by your website."),
+required=False))
+
+DEFAULT_REPLY_TO_EMAIL = Setting('DEFAULT_REPLY_TO_EMAIL', '', EMAIL_SET, dict(
+label = _("Site 'reply-to' Email Address"),
+help_text = _("The address that will show up on the 'reply-to' field on emails sent by your website."),
+required=False))
+
+EMAIL_SUBJECT_PREFIX = Setting('EMAIL_SUBJECT_PREFIX', '', EMAIL_SET, dict(
+label = _("Email Subject Prefix"),
+help_text = _("Every email sent through your website will have the subject prefixed by this string. It's usually a good idea to have such a prefix so your users can easily set up a filter on their email clients."),
+required=False))
+
+EMAIL_FOOTER_TEXT = Setting(u'EMAIL_FOOTER_TEXT', '', EMAIL_SET, dict(
+label = _("Email Footer Text"),
+help_text = _("Email footer text, usually \"CAN SPAM\" compliance, or the physical address of the organization running the website. See <a href=\"http://en.wikipedia.org/wiki/CAN-SPAM_Act_of_2003\">this Wikipedia article</a> for more info."),
+required=False))
+
+EMAIL_BORDER_COLOR = Setting('EMAIL_BORDER_COLOR', '#e5ebf8', EMAIL_SET, dict(
+label = _("Email Border Color"),
+help_text = _("The outter border color of the email base template"),
+required=False))
+
+EMAIL_PARAGRAPH_STYLE = Setting('EMAIL_PARAGRAPH_STYLE', "color:#333333;font-family:'helvetica neue', arial, Helvetica, sans-serif;line-height:18px;font-size:14px;margin-top:10px;", EMAIL_SET, dict(
+label = _("Email Paragraph Style"),
+help_text = _("A valid css string to be used to style email paragraphs (the P tag)."),
+required=False))
+
+EMAIL_ANCHOR_STYLE = Setting('EMAIL_ANCHOR_STYLE', "text-decoration:none;color:#3060a8;font-weight:bold;", EMAIL_SET, dict(
+label = _("Email Link Style"),
+help_text = _("A valid css string to be used to style email links (the A tag)."),
+required=False))
+
+SEND_DIGEST_ONLY_TO_ACTIVE_USERS = Setting('SEND_DIGEST_ONLY_TO_ACTIVE_USERS', True, EMAIL_SET, dict(
+label = _("Send digest only to active users"),
+help_text = _("If checked the daily digest won't be sent to users that have been suspended."),
+required=False))
+
+SEND_DIGEST_ONLY_TO_VALIDATED_USERS = Setting('SEND_DIGEST_ONLY_TO_VALIDATED_USERS', True, EMAIL_SET, dict(
+label = _("Send digest only to validated users"),
+help_text = _("If checked the daily digest won't be sent to users that haven't validated their emails."),
+required=False))
+
+EMAIL_DIGEST_FLAG = Setting('EMAIL_DIGEST_FLAG', None)
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-EXT_KEYS_SET = SettingSet('extkeys', _('External Keys'), _("Keys for various external providers that your application may optionally use."), 100)\r
-\r
-GOOGLE_SITEMAP_CODE = Setting('GOOGLE_SITEMAP_CODE', '', EXT_KEYS_SET, dict(\r
-label = _("Google sitemap code"),\r
-help_text = _("This is the code you get when you register your site at <a href='https://www.google.com/webmasters/tools/'>Google webmaster central</a>."),\r
-required=False))\r
-\r
-GOOGLE_ANALYTICS_KEY = Setting('GOOGLE_ANALYTICS_KEY', '', EXT_KEYS_SET, dict(\r
-label = _("Google analytics key"),\r
-help_text = _("Your Google analytics key. You can get one at the <a href='http://www.google.com/analytics/'>Google analytics official website</a>"),\r
-required=False))\r
-\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+EXT_KEYS_SET = SettingSet('extkeys', _('External Keys'), _("Keys for various external providers that your application may optionally use."), 100)
+
+GOOGLE_SITEMAP_CODE = Setting('GOOGLE_SITEMAP_CODE', '', EXT_KEYS_SET, dict(
+label = _("Google sitemap code"),
+help_text = _("This is the code you get when you register your site at <a href='https://www.google.com/webmasters/tools/'>Google webmaster central</a>."),
+required=False))
+
+GOOGLE_ANALYTICS_KEY = Setting('GOOGLE_ANALYTICS_KEY', '', EXT_KEYS_SET, dict(
+label = _("Google analytics key"),
+help_text = _("Your Google analytics key. You can get one at the <a href='http://www.google.com/analytics/'>Google analytics official website</a>"),
+required=False))
+
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-MIN_REP_SET = SettingSet('minrep', _('Minimum reputation config'), _("Configure the minimum reputation required to perform certain actions on your site."), 300)\r
-\r
-CAPTCHA_IF_REP_LESS_THAN = Setting('CAPTCHA_IF_REP_LESS_THAN', 0, MIN_REP_SET, dict(\r
-label = _("Show captcha if user with less reputation than"),\r
-help_text = _("If the user has less reputation, captcha is used to when adding new content.")))\r
-\r
-REP_TO_VOTE_UP = Setting('REP_TO_VOTE_UP', 15, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to vote up"),\r
-help_text = _("The minimum reputation an user must have to be allowed to vote up.")))\r
-\r
-REP_TO_VOTE_DOWN = Setting('REP_TO_VOTE_DOWN', 100, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to vote down"),\r
-help_text = _("The minimum reputation an user must have to be allowed to vote down.")))\r
-\r
-REP_TO_FLAG = Setting('REP_TO_FLAG', 15, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to flag a post"),\r
-help_text = _("The minimum reputation an user must have to be allowed to flag a post.")))\r
-\r
-REP_TO_COMMENT = Setting('REP_TO_COMMENT', 50, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to comment"),\r
-help_text = _("The minimum reputation an user must have to be allowed to comment a post.")))\r
-\r
-REP_TO_LIKE_COMMENT = Setting('REP_TO_LIKE_COMMENT', 15, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to like a comment"),\r
-help_text = _("The minimum reputation an user must have to be allowed to \"like\" a comment.")))\r
-\r
-REP_TO_UPLOAD = Setting('REP_TO_UPLOAD', 60, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to upload"),\r
-help_text = _("The minimum reputation an user must have to be allowed to upload a file.")))\r
-\r
-REP_TO_CREATE_TAGS = Setting('REP_TO_CREATE_TAGS', 250, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to create tags"),\r
-help_text = _("The minimum reputation an user must have to be allowed to create new tags.")))\r
-\r
-REP_TO_CLOSE_OWN = Setting('REP_TO_CLOSE_OWN', 250, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to close own question"),\r
-help_text = _("The minimum reputation an user must have to be allowed to close his own question.")))\r
-\r
-UNIFY_PERMISSIONS_TO_CLOSE_AND_REOPEN = Setting('UNIFY_PERMISSIONS_TO_CLOSE_AND_REOPEN', True, MIN_REP_SET, dict(\r
-label = _("Unify close and reopen permissions"),\r
-help_text = _("If checked the same permissions as the ones to close question will be required to reopen it."),\r
-required=False))\r
-\r
-REP_TO_REOPEN_OWN = Setting('REP_TO_REOPEN_OWN', 500, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to reopen own question"),\r
-help_text = _("The minimum reputation an user must have to be allowed to reopen his own question.")))\r
-\r
-REP_TO_RETAG = Setting('REP_TO_RETAG', 500, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to retag others questions"),\r
-help_text = _("The minimum reputation an user must have to be allowed to retag others questions.")))\r
-\r
-REP_TO_EDIT_WIKI = Setting('REP_TO_EDIT_WIKI', 750, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to edit wiki posts"),\r
-help_text = _("The minimum reputation an user must have to be allowed to edit community wiki posts.")))\r
-\r
-REP_TO_WIKIFY = Setting('REP_TO_WIKIFY', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to mark post as community wiki"),\r
-help_text = _("The minimum reputation an user must have to be allowed to mark a post as community wiki.")))\r
-\r
-REP_TO_EDIT_OTHERS = Setting('REP_TO_EDIT_OTHERS', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to edit others posts"),\r
-help_text = _("The minimum reputation an user must have to be allowed to edit others posts.")))\r
-\r
-REP_TO_CLOSE_OTHERS = Setting('REP_TO_CLOSE_OTHERS', 3000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to close others posts"),\r
-help_text = _("The minimum reputation an user must have to be allowed to close others posts.")))\r
-\r
-REP_TO_DELETE_COMMENTS = Setting('REP_TO_DELETE_COMMENTS', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to delete comments"),\r
-help_text = _("The minimum reputation an user must have to be allowed to delete comments.")))\r
-\r
-REP_TO_CONVERT_TO_COMMENT = Setting('REP_TO_CONVERT_TO_COMMENT', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to convert answers to comment"),\r
-help_text = _("The minimum reputation an user must have to be allowed to convert an answer into a comment.")))\r
-\r
-REP_TO_CONVERT_COMMENTS_TO_ANSWERS = Setting('REP_TO_CONVERT_COMMENTS_TO_ANSWERS', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to convert comments to answers"),\r
-help_text = _("The minimum reputation an user must have to be allowed to convert comments into an answer.")))\r
-\r
-REP_TO_CONVERT_TO_QUESTION = Setting('REP_TO_CONVERT_TO_QUESTION', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to convert answers to questions"),\r
-help_text = _("The minimum reputation an user must have to be allowed to convert an answer into a question.")))\r
-\r
-REP_TO_VIEW_FLAGS = Setting('REP_TO_VIEW_FLAGS', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to view offensive flags"),\r
-help_text = _("The minimum reputation an user must have to view offensive flags.")))\r
-\r
-#REP_TO_DISABLE_NOFOLLOW = Setting('REP_TO_DISABLE_NOFOLLOW', 2000, MIN_REP_SET, dict(\r
-#label = _("Minimum reputation to disable nofollow"),\r
-#help_text = _("""\r
-#The minimum reputation an user must have to be allowed to disable the nofollow attribute of a post link.\r
-#""")))\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+MIN_REP_SET = SettingSet('minrep', _('Minimum reputation config'), _("Configure the minimum reputation required to perform certain actions on your site."), 300)
+
+CAPTCHA_IF_REP_LESS_THAN = Setting('CAPTCHA_IF_REP_LESS_THAN', 0, MIN_REP_SET, dict(
+label = _("Show captcha if user with less reputation than"),
+help_text = _("If the user has less reputation, captcha is used to when adding new content.")))
+
+REP_TO_VOTE_UP = Setting('REP_TO_VOTE_UP', 15, MIN_REP_SET, dict(
+label = _("Minimum reputation to vote up"),
+help_text = _("The minimum reputation an user must have to be allowed to vote up.")))
+
+REP_TO_VOTE_DOWN = Setting('REP_TO_VOTE_DOWN', 100, MIN_REP_SET, dict(
+label = _("Minimum reputation to vote down"),
+help_text = _("The minimum reputation an user must have to be allowed to vote down.")))
+
+REP_TO_FLAG = Setting('REP_TO_FLAG', 15, MIN_REP_SET, dict(
+label = _("Minimum reputation to flag a post"),
+help_text = _("The minimum reputation an user must have to be allowed to flag a post.")))
+
+REP_TO_COMMENT = Setting('REP_TO_COMMENT', 50, MIN_REP_SET, dict(
+label = _("Minimum reputation to comment"),
+help_text = _("The minimum reputation an user must have to be allowed to comment a post.")))
+
+REP_TO_LIKE_COMMENT = Setting('REP_TO_LIKE_COMMENT', 15, MIN_REP_SET, dict(
+label = _("Minimum reputation to like a comment"),
+help_text = _("The minimum reputation an user must have to be allowed to \"like\" a comment.")))
+
+REP_TO_UPLOAD = Setting('REP_TO_UPLOAD', 60, MIN_REP_SET, dict(
+label = _("Minimum reputation to upload"),
+help_text = _("The minimum reputation an user must have to be allowed to upload a file.")))
+
+REP_TO_CREATE_TAGS = Setting('REP_TO_CREATE_TAGS', 250, MIN_REP_SET, dict(
+label = _("Minimum reputation to create tags"),
+help_text = _("The minimum reputation an user must have to be allowed to create new tags.")))
+
+REP_TO_CLOSE_OWN = Setting('REP_TO_CLOSE_OWN', 250, MIN_REP_SET, dict(
+label = _("Minimum reputation to close own question"),
+help_text = _("The minimum reputation an user must have to be allowed to close his own question.")))
+
+UNIFY_PERMISSIONS_TO_CLOSE_AND_REOPEN = Setting('UNIFY_PERMISSIONS_TO_CLOSE_AND_REOPEN', True, MIN_REP_SET, dict(
+label = _("Unify close and reopen permissions"),
+help_text = _("If checked the same permissions as the ones to close question will be required to reopen it."),
+required=False))
+
+REP_TO_REOPEN_OWN = Setting('REP_TO_REOPEN_OWN', 500, MIN_REP_SET, dict(
+label = _("Minimum reputation to reopen own question"),
+help_text = _("The minimum reputation an user must have to be allowed to reopen his own question.")))
+
+REP_TO_RETAG = Setting('REP_TO_RETAG', 500, MIN_REP_SET, dict(
+label = _("Minimum reputation to retag others questions"),
+help_text = _("The minimum reputation an user must have to be allowed to retag others questions.")))
+
+REP_TO_EDIT_WIKI = Setting('REP_TO_EDIT_WIKI', 750, MIN_REP_SET, dict(
+label = _("Minimum reputation to edit wiki posts"),
+help_text = _("The minimum reputation an user must have to be allowed to edit community wiki posts.")))
+
+REP_TO_WIKIFY = Setting('REP_TO_WIKIFY', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to mark post as community wiki"),
+help_text = _("The minimum reputation an user must have to be allowed to mark a post as community wiki.")))
+
+REP_TO_EDIT_OTHERS = Setting('REP_TO_EDIT_OTHERS', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to edit others posts"),
+help_text = _("The minimum reputation an user must have to be allowed to edit others posts.")))
+
+REP_TO_CLOSE_OTHERS = Setting('REP_TO_CLOSE_OTHERS', 3000, MIN_REP_SET, dict(
+label = _("Minimum reputation to close others posts"),
+help_text = _("The minimum reputation an user must have to be allowed to close others posts.")))
+
+REP_TO_DELETE_COMMENTS = Setting('REP_TO_DELETE_COMMENTS', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to delete comments"),
+help_text = _("The minimum reputation an user must have to be allowed to delete comments.")))
+
+REP_TO_CONVERT_TO_COMMENT = Setting('REP_TO_CONVERT_TO_COMMENT', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to convert answers to comment"),
+help_text = _("The minimum reputation an user must have to be allowed to convert an answer into a comment.")))
+
+REP_TO_CONVERT_COMMENTS_TO_ANSWERS = Setting('REP_TO_CONVERT_COMMENTS_TO_ANSWERS', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to convert comments to answers"),
+help_text = _("The minimum reputation an user must have to be allowed to convert comments into an answer.")))
+
+REP_TO_CONVERT_TO_QUESTION = Setting('REP_TO_CONVERT_TO_QUESTION', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to convert answers to questions"),
+help_text = _("The minimum reputation an user must have to be allowed to convert an answer into a question.")))
+
+REP_TO_VIEW_FLAGS = Setting('REP_TO_VIEW_FLAGS', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to view offensive flags"),
+help_text = _("The minimum reputation an user must have to view offensive flags.")))
+
+#REP_TO_DISABLE_NOFOLLOW = Setting('REP_TO_DISABLE_NOFOLLOW', 2000, MIN_REP_SET, dict(
+#label = _("Minimum reputation to disable nofollow"),
+#help_text = _("""
+#The minimum reputation an user must have to be allowed to disable the nofollow attribute of a post link.
+#""")))
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-REP_GAIN_SET = SettingSet('repgain', _('Reputation gains and losses config'), _("Configure the reputation points a user may gain or lose upon certain actions."), 200)\r
-\r
-INITIAL_REP = Setting('INITIAL_REP', 1, REP_GAIN_SET, dict(\r
-label = _("Initial reputation"),\r
-help_text = _("The initial reputation an user gets when he first signs in.")))\r
-\r
-MAX_REP_BY_UPVOTE_DAY = Setting('MAX_REP_BY_UPVOTE_DAY', 200, REP_GAIN_SET, dict(\r
-label = "Max rep by up votes / day",\r
-help_text = _("Maximum reputation a user can gain in one day for being upvoted.")))\r
-\r
-REP_GAIN_BY_EMAIL_VALIDATION = Setting('REP_GAIN_BY_EMAIL_VALIDATION', 10, REP_GAIN_SET, dict(\r
-label = _("Rep gain by e-mail validation"),\r
-help_text = _("Reputation a user gains for validating his e-mail.")))\r
-\r
-REP_GAIN_BY_UPVOTED = Setting('REP_GAIN_BY_UPVOTED', 10, REP_GAIN_SET, dict(\r
-label = _("Rep gain by upvoted"),\r
-help_text = _("Reputation a user gains for having one of his posts up voted.")))\r
-\r
-REP_LOST_BY_DOWNVOTED = Setting('REP_LOST_BY_DOWNVOTED', 2, REP_GAIN_SET, dict(\r
-label = _("Rep lost by downvoted"),\r
-help_text = _("Reputation a user loses for having one of his posts down voted.")))\r
-\r
-REP_LOST_BY_DOWNVOTING = Setting('REP_LOST_BY_DOWNVOTING', 1, REP_GAIN_SET, dict(\r
-label = _("Rep lost by downvoting"),\r
-help_text = _("Reputation a user loses for down voting a post.")))\r
-\r
-\r
-REP_GAIN_BY_ACCEPTED = Setting('REP_GAIN_BY_ACCEPTED', 15, REP_GAIN_SET, dict(\r
-label = _("Rep gain by accepted answer"),\r
-help_text = _("Reputation a user gains for having one of his answers accepted.")))\r
-\r
-REP_GAIN_BY_ACCEPTING = Setting('REP_GAIN_BY_ACCEPTING', 2, REP_GAIN_SET, dict(\r
-label = _("Rep gain by accepting answer"),\r
-help_text = _("Reputation a user gains for accepting an answer to one of his questions.")))\r
-\r
-REP_LOST_BY_FLAGGED = Setting('REP_LOST_BY_FLAGGED', 2, REP_GAIN_SET, dict(\r
-label = _("Rep lost by post flagged"),\r
-help_text = _("Reputation a user loses by having one of his posts flagged.")))\r
-\r
-REP_LOST_BY_FLAGGED_3_TIMES = Setting('REP_LOST_BY_FLAGGED_3_TIMES', 30, REP_GAIN_SET, dict(\r
-label = _("Rep lost by post flagged and hidden"),\r
-help_text = _("Reputation a user loses by having the last revision of one of his posts flagged the enough number of times to hide the post.")))\r
-\r
-REP_LOST_BY_FLAGGED_5_TIMES = Setting('REP_LOST_BY_FLAGGED_5_TIMES', 100, REP_GAIN_SET, dict(\r
-label = _("Rep lost by post flagged and deleted"),\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+REP_GAIN_SET = SettingSet('repgain', _('Reputation gains and losses config'), _("Configure the reputation points a user may gain or lose upon certain actions."), 200)
+
+INITIAL_REP = Setting('INITIAL_REP', 1, REP_GAIN_SET, dict(
+label = _("Initial reputation"),
+help_text = _("The initial reputation an user gets when he first signs in.")))
+
+MAX_REP_BY_UPVOTE_DAY = Setting('MAX_REP_BY_UPVOTE_DAY', 200, REP_GAIN_SET, dict(
+label = "Max rep by up votes / day",
+help_text = _("Maximum reputation a user can gain in one day for being upvoted.")))
+
+REP_GAIN_BY_EMAIL_VALIDATION = Setting('REP_GAIN_BY_EMAIL_VALIDATION', 10, REP_GAIN_SET, dict(
+label = _("Rep gain by e-mail validation"),
+help_text = _("Reputation a user gains for validating his e-mail.")))
+
+REP_GAIN_BY_UPVOTED = Setting('REP_GAIN_BY_UPVOTED', 10, REP_GAIN_SET, dict(
+label = _("Rep gain by upvoted"),
+help_text = _("Reputation a user gains for having one of his posts up voted.")))
+
+REP_LOST_BY_DOWNVOTED = Setting('REP_LOST_BY_DOWNVOTED', 2, REP_GAIN_SET, dict(
+label = _("Rep lost by downvoted"),
+help_text = _("Reputation a user loses for having one of his posts down voted.")))
+
+REP_LOST_BY_DOWNVOTING = Setting('REP_LOST_BY_DOWNVOTING', 1, REP_GAIN_SET, dict(
+label = _("Rep lost by downvoting"),
+help_text = _("Reputation a user loses for down voting a post.")))
+
+
+REP_GAIN_BY_ACCEPTED = Setting('REP_GAIN_BY_ACCEPTED', 15, REP_GAIN_SET, dict(
+label = _("Rep gain by accepted answer"),
+help_text = _("Reputation a user gains for having one of his answers accepted.")))
+
+REP_GAIN_BY_ACCEPTING = Setting('REP_GAIN_BY_ACCEPTING', 2, REP_GAIN_SET, dict(
+label = _("Rep gain by accepting answer"),
+help_text = _("Reputation a user gains for accepting an answer to one of his questions.")))
+
+REP_LOST_BY_FLAGGED = Setting('REP_LOST_BY_FLAGGED', 2, REP_GAIN_SET, dict(
+label = _("Rep lost by post flagged"),
+help_text = _("Reputation a user loses by having one of his posts flagged.")))
+
+REP_LOST_BY_FLAGGED_3_TIMES = Setting('REP_LOST_BY_FLAGGED_3_TIMES', 30, REP_GAIN_SET, dict(
+label = _("Rep lost by post flagged and hidden"),
+help_text = _("Reputation a user loses by having the last revision of one of his posts flagged the enough number of times to hide the post.")))
+
+REP_LOST_BY_FLAGGED_5_TIMES = Setting('REP_LOST_BY_FLAGGED_5_TIMES', 100, REP_GAIN_SET, dict(
+label = _("Rep lost by post flagged and deleted"),
help_text = _("Reputation a user loses by having the last revision of one of his posts flagged the enough number of times to delete the post.")))
\ No newline at end of file
-import os.path\r
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-UPLOAD_SET = SettingSet('paths', _('File upload settings'), _("File uploads related settings."), 600)\r
-\r
-UPFILES_FOLDER = Setting('UPFILES_FOLDER', os.path.join(os.path.dirname(os.path.dirname(__file__)),'upfiles'), UPLOAD_SET, dict(\r
-label = _("Uploaded files folder"),\r
-help_text = _("The filesystem path where uploaded files will be stored. Please note that this folder must exist.")))\r
-\r
-UPFILES_ALIAS = Setting('UPFILES_ALIAS', '/upfiles/', UPLOAD_SET, dict(\r
-label = _("Uploaded files alias"),\r
-help_text = _("The url alias for uploaded files. Notice that if you change this setting, you'll need to restart your site.")))\r
-\r
-ALLOW_MAX_FILE_SIZE = Setting('ALLOW_MAX_FILE_SIZE', 2.5, UPLOAD_SET, dict(\r
-label = _("Max file size"),\r
+import os.path
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+UPLOAD_SET = SettingSet('paths', _('File upload settings'), _("File uploads related settings."), 600)
+
+UPFILES_FOLDER = Setting('UPFILES_FOLDER', os.path.join(os.path.dirname(os.path.dirname(__file__)),'upfiles'), UPLOAD_SET, dict(
+label = _("Uploaded files folder"),
+help_text = _("The filesystem path where uploaded files will be stored. Please note that this folder must exist.")))
+
+UPFILES_ALIAS = Setting('UPFILES_ALIAS', '/upfiles/', UPLOAD_SET, dict(
+label = _("Uploaded files alias"),
+help_text = _("The url alias for uploaded files. Notice that if you change this setting, you'll need to restart your site.")))
+
+ALLOW_MAX_FILE_SIZE = Setting('ALLOW_MAX_FILE_SIZE', 2.5, UPLOAD_SET, dict(
+label = _("Max file size"),
help_text = _("The maximum allowed file size for uploads in mb.")))
\ No newline at end of file
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-VOTE_RULES_SET = SettingSet('voting', _('Voting rules'), _("Configure the voting rules on your site."), 400)\r
-\r
-USER_REPUTATION_TO_MAX_VOTES = Setting('USER_REPUTATION_TO_MAX_VOTES', True, VOTE_RULES_SET, dict(\r
-label = _("Add reputation to max votes per day"), required=False,\r
-help_text = _("The user reputation is added to the static MAX_VOTES_PER_DAY option. Users with higher reputation can vote more.")))\r
-\r
-MAX_VOTES_PER_DAY = Setting('MAX_VOTES_PER_DAY', 30, VOTE_RULES_SET, dict(\r
-label = _("Maximum votes per day"),\r
-help_text = _("The maximum number of votes an user can cast per day.")))\r
-\r
-START_WARN_VOTES_LEFT = Setting('START_WARN_VOTES_LEFT', 10, VOTE_RULES_SET, dict(\r
-label = _("Start warning about votes left"),\r
-help_text = _("From how many votes left should an user start to be warned about it.")))\r
-\r
-MAX_FLAGS_PER_DAY = Setting('MAX_FLAGS_PER_DAY', 5, VOTE_RULES_SET, dict(\r
-label = _("Maximum flags per day"),\r
-help_text = _("The maximum number of times an can flag a post per day.")))\r
-\r
-FLAG_COUNT_TO_HIDE_POST = Setting('FLAG_COUNT_TO_HIDE_POST', 3, VOTE_RULES_SET, dict(\r
-label = _("Flag count to hide post"),\r
-help_text = _("How many times a post needs to be flagged to be hidden from the main page.")))\r
-\r
-FLAG_COUNT_TO_DELETE_POST = Setting('FLAG_COUNT_TO_DELETE_POST', 5, VOTE_RULES_SET, dict(\r
-label = _("Flag count to delete post"),\r
-help_text = _("How many times a post needs to be flagged to be deleted.")))\r
-\r
-DENY_UNVOTE_DAYS = Setting('DENY_UNVOTE_DAYS', 1, VOTE_RULES_SET, dict(\r
-label = _("Days to cancel a vote"),\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+VOTE_RULES_SET = SettingSet('voting', _('Voting rules'), _("Configure the voting rules on your site."), 400)
+
+USER_REPUTATION_TO_MAX_VOTES = Setting('USER_REPUTATION_TO_MAX_VOTES', True, VOTE_RULES_SET, dict(
+label = _("Add reputation to max votes per day"), required=False,
+help_text = _("The user reputation is added to the static MAX_VOTES_PER_DAY option. Users with higher reputation can vote more.")))
+
+MAX_VOTES_PER_DAY = Setting('MAX_VOTES_PER_DAY', 30, VOTE_RULES_SET, dict(
+label = _("Maximum votes per day"),
+help_text = _("The maximum number of votes an user can cast per day.")))
+
+START_WARN_VOTES_LEFT = Setting('START_WARN_VOTES_LEFT', 10, VOTE_RULES_SET, dict(
+label = _("Start warning about votes left"),
+help_text = _("From how many votes left should an user start to be warned about it.")))
+
+MAX_FLAGS_PER_DAY = Setting('MAX_FLAGS_PER_DAY', 5, VOTE_RULES_SET, dict(
+label = _("Maximum flags per day"),
+help_text = _("The maximum number of times an can flag a post per day.")))
+
+FLAG_COUNT_TO_HIDE_POST = Setting('FLAG_COUNT_TO_HIDE_POST', 3, VOTE_RULES_SET, dict(
+label = _("Flag count to hide post"),
+help_text = _("How many times a post needs to be flagged to be hidden from the main page.")))
+
+FLAG_COUNT_TO_DELETE_POST = Setting('FLAG_COUNT_TO_DELETE_POST', 5, VOTE_RULES_SET, dict(
+label = _("Flag count to delete post"),
+help_text = _("How many times a post needs to be flagged to be deleted.")))
+
+DENY_UNVOTE_DAYS = Setting('DENY_UNVOTE_DAYS', 1, VOTE_RULES_SET, dict(
+label = _("Days to cancel a vote"),
help_text = _("How many days an user can cancel a vote after he originaly casted it.")))
\ No newline at end of file
-<public:component>\r
-<script type="text/javascript">\r
-\r
-// IE5.5+ PNG Alpha Fix v2.0 Alpha\r
-// (c) 2004-2009 Angus Turnbull http://www.twinhelix.com\r
-\r
-// This is licensed under the GNU LGPL, version 2.1 or later.\r
-// For details, see: http://creativecommons.org/licenses/LGPL/2.1/\r
-\r
-var IEPNGFix = window.IEPNGFix || {};\r
-IEPNGFix.data = IEPNGFix.data || {};\r
-\r
-\r
-// CONFIG: blankImg is the path to blank.gif, *relative to the HTML document*.\r
-// Try either:\r
-// * An absolute path like: '/images/blank.gif'\r
-// * A path relative to this HTC file like: thisFolder + 'blank.gif'\r
-var thisFolder = document.URL.replace(/(\\|\/)[^\\\/]*$/, '/');\r
-IEPNGFix.blankImg = thisFolder + 'blank.gif';\r
-\r
-\r
-IEPNGFix.fix = function(elm, src, t) {\r
- // Applies an image 'src' to an element 'elm' using the DirectX filter.\r
- // If 'src' is null, filter is disabled.\r
- // Disables the 'hook' to prevent infinite recursion on setting BG/src.\r
- // 't' = type, where background tile = 0, background = 1, IMG SRC = 2.\r
-\r
- var h = this.hook.enabled;\r
- this.hook.enabled = 0;\r
-\r
- var f = 'DXImageTransform.Microsoft.AlphaImageLoader';\r
- src = (src || '').replace(/\(/g, '%28').replace(/\)/g, '%29');\r
-\r
- if (\r
- src && !(/IMG|INPUT/.test(elm.nodeName) && (t != 2)) &&\r
- elm.currentStyle.width == 'auto' && elm.currentStyle.height == 'auto'\r
- ) {\r
- if (elm.offsetWidth) {\r
- elm.style.width = elm.offsetWidth + 'px';\r
- }\r
- if (elm.clientHeight) {\r
- elm.style.height = elm.clientHeight + 'px';\r
- }\r
- if (elm.currentStyle.display == 'inline') {\r
- elm.style.display = 'inline-block';\r
- }\r
- }\r
-\r
- if (t == 1) {\r
- elm.style.backgroundImage = 'url("' + this.blankImg + '")';\r
- }\r
- if (t == 2) {\r
- elm.src = this.blankImg;\r
- }\r
-\r
- if (elm.filters[f]) {\r
- elm.filters[f].enabled = src ? true : false;\r
- if (src) {\r
- elm.filters[f].src = src;\r
- }\r
- } else if (src) {\r
- elm.style.filter = 'progid:' + f + '(src="' + src +\r
- '",sizingMethod="' + (t == 2 ? 'scale' : 'crop') + '")';\r
- }\r
-\r
- this.hook.enabled = h;\r
-};\r
-\r
-\r
-IEPNGFix.process = function(elm, init) {\r
- // Checks the onpropertychange event (on first 'init' run, a fake event)\r
- // and calls the filter-applying-functions.\r
-\r
- if (\r
- !/MSIE (5\.5|6)/.test(navigator.userAgent) ||\r
- typeof elm.filters == 'unknown'\r
- ) {\r
- return;\r
- }\r
- if (!this.data[elm.uniqueID]) {\r
- this.data[elm.uniqueID] = {\r
- className: ''\r
- };\r
- }\r
- var data = this.data[elm.uniqueID],\r
- evt = init ? { propertyName: 'src,backgroundImage' } : event,\r
- isSrc = /src/.test(evt.propertyName),\r
- isBg = /backgroundImage/.test(evt.propertyName),\r
- isPos = /width|height|background(Pos|Rep)/.test(evt.propertyName),\r
- isClass = !init && ((elm.className != data.className) &&\r
- (elm.className || data.className));\r
- if (!(isSrc || isBg || isPos || isClass)) {\r
- return;\r
- }\r
- data.className = elm.className;\r
- var blank = this.blankImg.match(/([^\/]+)$/)[1],\r
- eS = elm.style,\r
- eCS = elm.currentStyle;\r
-\r
- // Required for Whatever:hover - erase set BG if className changes.\r
- if (\r
- isClass && (eS.backgroundImage.indexOf('url(') == -1 ||\r
- eS.backgroundImage.indexOf(blank) > -1)\r
- ) {\r
- return setTimeout(function() {\r
- eS.backgroundImage = '';\r
- }, 0);\r
- }\r
-\r
- // Foregrounds.\r
- if (isSrc && elm.src && { IMG: 1, INPUT: 1 }[elm.nodeName]) {\r
- if ((/\.png/i).test(elm.src)) {\r
- if (!elm.oSrc) {\r
- // MM rollover compat\r
- elm.oSrc = elm.src;\r
- }\r
- this.fix(elm, elm.src, 2);\r
- } else if (elm.src.indexOf(blank) == -1) {\r
- this.fix(elm, '');\r
- }\r
- }\r
-\r
- // Backgrounds.\r
- var bgSrc = eCS.backgroundImage || eS.backgroundImage;\r
- if ((bgSrc + elm.src).indexOf(blank) == -1) {\r
- var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);\r
- if (bgPNG) {\r
- if (this.tileBG && !{ IMG: 1, INPUT: 1 }[elm.nodeName]) {\r
- this.tileBG(elm, bgPNG[1]);\r
- this.fix(elm, '', 1);\r
- } else {\r
- if (data.tiles && data.tiles.src) {\r
- this.tileBG(elm, '');\r
- }\r
- this.fix(elm, bgPNG[1], 1);\r
- this.childFix(elm);\r
- }\r
- } else {\r
- if (data.tiles && data.tiles.src) {\r
- this.tileBG(elm, '');\r
- }\r
- this.fix(elm, '');\r
- }\r
- } else if ((isPos || isClass) && data.tiles && data.tiles.src) {\r
- this.tileBG(elm, data.tiles.src);\r
- }\r
-\r
- if (init) {\r
- this.hook.enabled = 1;\r
- elm.attachEvent('onpropertychange', this.hook);\r
- }\r
-};\r
-\r
-\r
-IEPNGFix.childFix = function(elm) {\r
- // "hasLayout" fix for unclickable children inside PNG backgrounds.\r
- var tags = [\r
- 'a',\r
- 'input',\r
- 'select',\r
- 'textarea',\r
- 'button',\r
- 'iframe',\r
- 'object'\r
- ],\r
- t = tags.length,\r
- tFix = [];\r
- while (t--) {\r
- var pFix = elm.all.tags(tags[t]),\r
- e = pFix.length;\r
- while (e--) {\r
- tFix.push(pFix[e]);\r
- }\r
- }\r
- t = tFix.length;\r
- if (t && (/relative|absolute/i).test(elm.currentStyle.position)) {\r
- alert('IEPNGFix: Unclickable children of element:' +\r
- '\n\n<' + elm.nodeName + (elm.id && ' id=' + elm.id) + '>');\r
- }\r
- while (t--) {\r
- if (!(/relative|absolute/i).test(tFix[t].currentStyle.position)) {\r
- tFix[t].style.position = 'relative';\r
- }\r
- }\r
-};\r
-\r
-\r
-IEPNGFix.hook = function() {\r
- if (IEPNGFix.hook.enabled) {\r
- IEPNGFix.process(element, 0);\r
- }\r
-};\r
-\r
-\r
-IEPNGFix.process(element, 1);\r
-\r
-</script>\r
-</public:component>\r
+<public:component>
+<script type="text/javascript">
+
+// IE5.5+ PNG Alpha Fix v2.0 Alpha
+// (c) 2004-2009 Angus Turnbull http://www.twinhelix.com
+
+// This is licensed under the GNU LGPL, version 2.1 or later.
+// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
+
+var IEPNGFix = window.IEPNGFix || {};
+IEPNGFix.data = IEPNGFix.data || {};
+
+
+// CONFIG: blankImg is the path to blank.gif, *relative to the HTML document*.
+// Try either:
+// * An absolute path like: '/images/blank.gif'
+// * A path relative to this HTC file like: thisFolder + 'blank.gif'
+var thisFolder = document.URL.replace(/(\\|\/)[^\\\/]*$/, '/');
+IEPNGFix.blankImg = thisFolder + 'blank.gif';
+
+
+IEPNGFix.fix = function(elm, src, t) {
+ // Applies an image 'src' to an element 'elm' using the DirectX filter.
+ // If 'src' is null, filter is disabled.
+ // Disables the 'hook' to prevent infinite recursion on setting BG/src.
+ // 't' = type, where background tile = 0, background = 1, IMG SRC = 2.
+
+ var h = this.hook.enabled;
+ this.hook.enabled = 0;
+
+ var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
+ src = (src || '').replace(/\(/g, '%28').replace(/\)/g, '%29');
+
+ if (
+ src && !(/IMG|INPUT/.test(elm.nodeName) && (t != 2)) &&
+ elm.currentStyle.width == 'auto' && elm.currentStyle.height == 'auto'
+ ) {
+ if (elm.offsetWidth) {
+ elm.style.width = elm.offsetWidth + 'px';
+ }
+ if (elm.clientHeight) {
+ elm.style.height = elm.clientHeight + 'px';
+ }
+ if (elm.currentStyle.display == 'inline') {
+ elm.style.display = 'inline-block';
+ }
+ }
+
+ if (t == 1) {
+ elm.style.backgroundImage = 'url("' + this.blankImg + '")';
+ }
+ if (t == 2) {
+ elm.src = this.blankImg;
+ }
+
+ if (elm.filters[f]) {
+ elm.filters[f].enabled = src ? true : false;
+ if (src) {
+ elm.filters[f].src = src;
+ }
+ } else if (src) {
+ elm.style.filter = 'progid:' + f + '(src="' + src +
+ '",sizingMethod="' + (t == 2 ? 'scale' : 'crop') + '")';
+ }
+
+ this.hook.enabled = h;
+};
+
+
+IEPNGFix.process = function(elm, init) {
+ // Checks the onpropertychange event (on first 'init' run, a fake event)
+ // and calls the filter-applying-functions.
+
+ if (
+ !/MSIE (5\.5|6)/.test(navigator.userAgent) ||
+ typeof elm.filters == 'unknown'
+ ) {
+ return;
+ }
+ if (!this.data[elm.uniqueID]) {
+ this.data[elm.uniqueID] = {
+ className: ''
+ };
+ }
+ var data = this.data[elm.uniqueID],
+ evt = init ? { propertyName: 'src,backgroundImage' } : event,
+ isSrc = /src/.test(evt.propertyName),
+ isBg = /backgroundImage/.test(evt.propertyName),
+ isPos = /width|height|background(Pos|Rep)/.test(evt.propertyName),
+ isClass = !init && ((elm.className != data.className) &&
+ (elm.className || data.className));
+ if (!(isSrc || isBg || isPos || isClass)) {
+ return;
+ }
+ data.className = elm.className;
+ var blank = this.blankImg.match(/([^\/]+)$/)[1],
+ eS = elm.style,
+ eCS = elm.currentStyle;
+
+ // Required for Whatever:hover - erase set BG if className changes.
+ if (
+ isClass && (eS.backgroundImage.indexOf('url(') == -1 ||
+ eS.backgroundImage.indexOf(blank) > -1)
+ ) {
+ return setTimeout(function() {
+ eS.backgroundImage = '';
+ }, 0);
+ }
+
+ // Foregrounds.
+ if (isSrc && elm.src && { IMG: 1, INPUT: 1 }[elm.nodeName]) {
+ if ((/\.png/i).test(elm.src)) {
+ if (!elm.oSrc) {
+ // MM rollover compat
+ elm.oSrc = elm.src;
+ }
+ this.fix(elm, elm.src, 2);
+ } else if (elm.src.indexOf(blank) == -1) {
+ this.fix(elm, '');
+ }
+ }
+
+ // Backgrounds.
+ var bgSrc = eCS.backgroundImage || eS.backgroundImage;
+ if ((bgSrc + elm.src).indexOf(blank) == -1) {
+ var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);
+ if (bgPNG) {
+ if (this.tileBG && !{ IMG: 1, INPUT: 1 }[elm.nodeName]) {
+ this.tileBG(elm, bgPNG[1]);
+ this.fix(elm, '', 1);
+ } else {
+ if (data.tiles && data.tiles.src) {
+ this.tileBG(elm, '');
+ }
+ this.fix(elm, bgPNG[1], 1);
+ this.childFix(elm);
+ }
+ } else {
+ if (data.tiles && data.tiles.src) {
+ this.tileBG(elm, '');
+ }
+ this.fix(elm, '');
+ }
+ } else if ((isPos || isClass) && data.tiles && data.tiles.src) {
+ this.tileBG(elm, data.tiles.src);
+ }
+
+ if (init) {
+ this.hook.enabled = 1;
+ elm.attachEvent('onpropertychange', this.hook);
+ }
+};
+
+
+IEPNGFix.childFix = function(elm) {
+ // "hasLayout" fix for unclickable children inside PNG backgrounds.
+ var tags = [
+ 'a',
+ 'input',
+ 'select',
+ 'textarea',
+ 'button',
+ 'iframe',
+ 'object'
+ ],
+ t = tags.length,
+ tFix = [];
+ while (t--) {
+ var pFix = elm.all.tags(tags[t]),
+ e = pFix.length;
+ while (e--) {
+ tFix.push(pFix[e]);
+ }
+ }
+ t = tFix.length;
+ if (t && (/relative|absolute/i).test(elm.currentStyle.position)) {
+ alert('IEPNGFix: Unclickable children of element:' +
+ '\n\n<' + elm.nodeName + (elm.id && ' id=' + elm.id) + '>');
+ }
+ while (t--) {
+ if (!(/relative|absolute/i).test(tFix[t].currentStyle.position)) {
+ tFix[t].style.position = 'relative';
+ }
+ }
+};
+
+
+IEPNGFix.hook = function() {
+ if (IEPNGFix.hook.enabled) {
+ IEPNGFix.process(element, 0);
+ }
+};
+
+
+IEPNGFix.process(element, 1);
+
+</script>
+</public:component>
-// IE5.5+ PNG Alpha Fix v2.0 Alpha: Background Tiling Support\r
-// (c) 2008-2009 Angus Turnbull http://www.twinhelix.com\r
-\r
-// This is licensed under the GNU LGPL, version 2.1 or later.\r
-// For details, see: http://creativecommons.org/licenses/LGPL/2.1/\r
-\r
-var IEPNGFix = window.IEPNGFix || {};\r
-\r
-IEPNGFix.tileBG = function(elm, pngSrc, ready) {\r
- // Params: A reference to a DOM element, the PNG src file pathname, and a\r
- // hidden "ready-to-run" passed when called back after image preloading.\r
-\r
- var data = this.data[elm.uniqueID],\r
- elmW = Math.max(elm.clientWidth, elm.scrollWidth),\r
- elmH = Math.max(elm.clientHeight, elm.scrollHeight),\r
- bgX = elm.currentStyle.backgroundPositionX,\r
- bgY = elm.currentStyle.backgroundPositionY,\r
- bgR = elm.currentStyle.backgroundRepeat;\r
-\r
- // Cache of DIVs created per element, and image preloader/data.\r
- if (!data.tiles) {\r
- data.tiles = {\r
- elm: elm,\r
- src: '',\r
- cache: [],\r
- img: new Image(),\r
- old: {}\r
- };\r
- }\r
- var tiles = data.tiles,\r
- pngW = tiles.img.width,\r
- pngH = tiles.img.height;\r
-\r
- if (pngSrc) {\r
- if (!ready && pngSrc != tiles.src) {\r
- // New image? Preload it with a callback to detect dimensions.\r
- tiles.img.onload = function() {\r
- this.onload = null;\r
- IEPNGFix.tileBG(elm, pngSrc, 1);\r
- };\r
- return tiles.img.src = pngSrc;\r
- }\r
- } else {\r
- // No image?\r
- if (tiles.src) ready = 1;\r
- pngW = pngH = 0;\r
- }\r
- tiles.src = pngSrc;\r
-\r
- if (!ready && elmW == tiles.old.w && elmH == tiles.old.h &&\r
- bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r) {\r
- return;\r
- }\r
-\r
- // Convert English and percentage positions to pixels.\r
- var pos = {\r
- top: '0%',\r
- left: '0%',\r
- center: '50%',\r
- bottom: '100%',\r
- right: '100%'\r
- },\r
- x,\r
- y,\r
- pc;\r
- x = pos[bgX] || bgX;\r
- y = pos[bgY] || bgY;\r
- if (pc = x.match(/(\d+)%/)) {\r
- x = Math.round((elmW - pngW) * (parseInt(pc[1]) / 100));\r
- }\r
- if (pc = y.match(/(\d+)%/)) {\r
- y = Math.round((elmH - pngH) * (parseInt(pc[1]) / 100));\r
- }\r
- x = parseInt(x);\r
- y = parseInt(y);\r
-\r
- // Handle backgroundRepeat.\r
- var repeatX = { 'repeat': 1, 'repeat-x': 1 }[bgR],\r
- repeatY = { 'repeat': 1, 'repeat-y': 1 }[bgR];\r
- if (repeatX) {\r
- x %= pngW;\r
- if (x > 0) x -= pngW;\r
- }\r
- if (repeatY) {\r
- y %= pngH;\r
- if (y > 0) y -= pngH;\r
- }\r
-\r
- // Go!\r
- this.hook.enabled = 0;\r
- if (!({ relative: 1, absolute: 1 }[elm.currentStyle.position])) {\r
- elm.style.position = 'relative';\r
- }\r
- var count = 0,\r
- xPos,\r
- maxX = repeatX ? elmW : x + 0.1,\r
- yPos,\r
- maxY = repeatY ? elmH : y + 0.1,\r
- d,\r
- s,\r
- isNew;\r
- if (pngW && pngH) {\r
- for (xPos = x; xPos < maxX; xPos += pngW) {\r
- for (yPos = y; yPos < maxY; yPos += pngH) {\r
- isNew = 0;\r
- if (!tiles.cache[count]) {\r
- tiles.cache[count] = document.createElement('div');\r
- isNew = 1;\r
- }\r
- var clipR = Math.max(0, xPos + pngW > elmW ? elmW - xPos : pngW),\r
- clipB = Math.max(0, yPos + pngH > elmH ? elmH - yPos : pngH);\r
- d = tiles.cache[count];\r
- s = d.style;\r
- s.behavior = 'none';\r
- s.left = (xPos - parseInt(elm.currentStyle.paddingLeft)) + 'px';\r
- s.top = yPos + 'px';\r
- s.width = clipR + 'px';\r
- s.height = clipB + 'px';\r
- s.clip = 'rect(' +\r
- (yPos < 0 ? 0 - yPos : 0) + 'px,' +\r
- clipR + 'px,' +\r
- clipB + 'px,' +\r
- (xPos < 0 ? 0 - xPos : 0) + 'px)';\r
- s.display = 'block';\r
- if (isNew) {\r
- s.position = 'absolute';\r
- s.zIndex = -999;\r
- if (elm.firstChild) {\r
- elm.insertBefore(d, elm.firstChild);\r
- } else {\r
- elm.appendChild(d);\r
- }\r
- }\r
- this.fix(d, pngSrc, 0);\r
- count++;\r
- }\r
- }\r
- }\r
- while (count < tiles.cache.length) {\r
- this.fix(tiles.cache[count], '', 0);\r
- tiles.cache[count++].style.display = 'none';\r
- }\r
-\r
- this.hook.enabled = 1;\r
-\r
- // Cache so updates are infrequent.\r
- tiles.old = {\r
- w: elmW,\r
- h: elmH,\r
- x: bgX,\r
- y: bgY,\r
- r: bgR\r
- };\r
-};\r
-\r
-\r
-IEPNGFix.update = function() {\r
- // Update all PNG backgrounds.\r
- for (var i in IEPNGFix.data) {\r
- var t = IEPNGFix.data[i].tiles;\r
- if (t && t.elm && t.src) {\r
- IEPNGFix.tileBG(t.elm, t.src);\r
- }\r
- }\r
-};\r
-IEPNGFix.update.timer = 0;\r
-\r
-if (window.attachEvent && !window.opera) {\r
- window.attachEvent('onresize', function() {\r
- clearTimeout(IEPNGFix.update.timer);\r
- IEPNGFix.update.timer = setTimeout(IEPNGFix.update, 100);\r
- });\r
-}\r
+// IE5.5+ PNG Alpha Fix v2.0 Alpha: Background Tiling Support
+// (c) 2008-2009 Angus Turnbull http://www.twinhelix.com
+
+// This is licensed under the GNU LGPL, version 2.1 or later.
+// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
+
+var IEPNGFix = window.IEPNGFix || {};
+
+IEPNGFix.tileBG = function(elm, pngSrc, ready) {
+ // Params: A reference to a DOM element, the PNG src file pathname, and a
+ // hidden "ready-to-run" passed when called back after image preloading.
+
+ var data = this.data[elm.uniqueID],
+ elmW = Math.max(elm.clientWidth, elm.scrollWidth),
+ elmH = Math.max(elm.clientHeight, elm.scrollHeight),
+ bgX = elm.currentStyle.backgroundPositionX,
+ bgY = elm.currentStyle.backgroundPositionY,
+ bgR = elm.currentStyle.backgroundRepeat;
+
+ // Cache of DIVs created per element, and image preloader/data.
+ if (!data.tiles) {
+ data.tiles = {
+ elm: elm,
+ src: '',
+ cache: [],
+ img: new Image(),
+ old: {}
+ };
+ }
+ var tiles = data.tiles,
+ pngW = tiles.img.width,
+ pngH = tiles.img.height;
+
+ if (pngSrc) {
+ if (!ready && pngSrc != tiles.src) {
+ // New image? Preload it with a callback to detect dimensions.
+ tiles.img.onload = function() {
+ this.onload = null;
+ IEPNGFix.tileBG(elm, pngSrc, 1);
+ };
+ return tiles.img.src = pngSrc;
+ }
+ } else {
+ // No image?
+ if (tiles.src) ready = 1;
+ pngW = pngH = 0;
+ }
+ tiles.src = pngSrc;
+
+ if (!ready && elmW == tiles.old.w && elmH == tiles.old.h &&
+ bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r) {
+ return;
+ }
+
+ // Convert English and percentage positions to pixels.
+ var pos = {
+ top: '0%',
+ left: '0%',
+ center: '50%',
+ bottom: '100%',
+ right: '100%'
+ },
+ x,
+ y,
+ pc;
+ x = pos[bgX] || bgX;
+ y = pos[bgY] || bgY;
+ if (pc = x.match(/(\d+)%/)) {
+ x = Math.round((elmW - pngW) * (parseInt(pc[1]) / 100));
+ }
+ if (pc = y.match(/(\d+)%/)) {
+ y = Math.round((elmH - pngH) * (parseInt(pc[1]) / 100));
+ }
+ x = parseInt(x);
+ y = parseInt(y);
+
+ // Handle backgroundRepeat.
+ var repeatX = { 'repeat': 1, 'repeat-x': 1 }[bgR],
+ repeatY = { 'repeat': 1, 'repeat-y': 1 }[bgR];
+ if (repeatX) {
+ x %= pngW;
+ if (x > 0) x -= pngW;
+ }
+ if (repeatY) {
+ y %= pngH;
+ if (y > 0) y -= pngH;
+ }
+
+ // Go!
+ this.hook.enabled = 0;
+ if (!({ relative: 1, absolute: 1 }[elm.currentStyle.position])) {
+ elm.style.position = 'relative';
+ }
+ var count = 0,
+ xPos,
+ maxX = repeatX ? elmW : x + 0.1,
+ yPos,
+ maxY = repeatY ? elmH : y + 0.1,
+ d,
+ s,
+ isNew;
+ if (pngW && pngH) {
+ for (xPos = x; xPos < maxX; xPos += pngW) {
+ for (yPos = y; yPos < maxY; yPos += pngH) {
+ isNew = 0;
+ if (!tiles.cache[count]) {
+ tiles.cache[count] = document.createElement('div');
+ isNew = 1;
+ }
+ var clipR = Math.max(0, xPos + pngW > elmW ? elmW - xPos : pngW),
+ clipB = Math.max(0, yPos + pngH > elmH ? elmH - yPos : pngH);
+ d = tiles.cache[count];
+ s = d.style;
+ s.behavior = 'none';
+ s.left = (xPos - parseInt(elm.currentStyle.paddingLeft)) + 'px';
+ s.top = yPos + 'px';
+ s.width = clipR + 'px';
+ s.height = clipB + 'px';
+ s.clip = 'rect(' +
+ (yPos < 0 ? 0 - yPos : 0) + 'px,' +
+ clipR + 'px,' +
+ clipB + 'px,' +
+ (xPos < 0 ? 0 - xPos : 0) + 'px)';
+ s.display = 'block';
+ if (isNew) {
+ s.position = 'absolute';
+ s.zIndex = -999;
+ if (elm.firstChild) {
+ elm.insertBefore(d, elm.firstChild);
+ } else {
+ elm.appendChild(d);
+ }
+ }
+ this.fix(d, pngSrc, 0);
+ count++;
+ }
+ }
+ }
+ while (count < tiles.cache.length) {
+ this.fix(tiles.cache[count], '', 0);
+ tiles.cache[count++].style.display = 'none';
+ }
+
+ this.hook.enabled = 1;
+
+ // Cache so updates are infrequent.
+ tiles.old = {
+ w: elmW,
+ h: elmH,
+ x: bgX,
+ y: bgY,
+ r: bgR
+ };
+};
+
+
+IEPNGFix.update = function() {
+ // Update all PNG backgrounds.
+ for (var i in IEPNGFix.data) {
+ var t = IEPNGFix.data[i].tiles;
+ if (t && t.elm && t.src) {
+ IEPNGFix.tileBG(t.elm, t.src);
+ }
+ }
+};
+IEPNGFix.update.timer = 0;
+
+if (window.attachEvent && !window.opera) {
+ window.attachEvent('onresize', function() {
+ clearTimeout(IEPNGFix.update.timer);
+ IEPNGFix.update.timer = setTimeout(IEPNGFix.update, 100);
+ });
+}
-/*\r
- *\r
- * Copyright (c) 2010 C. F., Wong (<a href="http://cloudgen.w0ng.hk">Cloudgen Examplet Store</a>)\r
- * Licensed under the MIT License:\r
- * http://www.opensource.org/licenses/mit-license.php\r
- *\r
- */\r
-(function(k,e,i,j){k.fn.caret=function(b,l){var a,c,f=this[0],d=k.browser.msie;if(typeof b==="object"&&typeof b.start==="number"&&typeof b.end==="number"){a=b.start;c=b.end}else if(typeof b==="number"&&typeof l==="number"){a=b;c=l}else if(typeof b==="string")if((a=f.value.indexOf(b))>-1)c=a+b[e];else a=null;else if(Object.prototype.toString.call(b)==="[object RegExp]"){b=b.exec(f.value);if(b!=null){a=b.index;c=a+b[0][e]}}if(typeof a!="undefined"){if(d){d=this[0].createTextRange();d.collapse(true);\r
-d.moveStart("character",a);d.moveEnd("character",c-a);d.select()}else{this[0].selectionStart=a;this[0].selectionEnd=c}this[0].focus();return this}else{if(d){c=document.selection;if(this[0].tagName.toLowerCase()!="textarea"){d=this.val();a=c[i]()[j]();a.moveEnd("character",d[e]);var g=a.text==""?d[e]:d.lastIndexOf(a.text);a=c[i]()[j]();a.moveStart("character",-d[e]);var h=a.text[e]}else{a=c[i]();c=a[j]();c.moveToElementText(this[0]);c.setEndPoint("EndToEnd",a);g=c.text[e]-a.text[e];h=g+a.text[e]}}else{g=\r
+/*
+ *
+ * Copyright (c) 2010 C. F., Wong (<a href="http://cloudgen.w0ng.hk">Cloudgen Examplet Store</a>)
+ * Licensed under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+(function(k,e,i,j){k.fn.caret=function(b,l){var a,c,f=this[0],d=k.browser.msie;if(typeof b==="object"&&typeof b.start==="number"&&typeof b.end==="number"){a=b.start;c=b.end}else if(typeof b==="number"&&typeof l==="number"){a=b;c=l}else if(typeof b==="string")if((a=f.value.indexOf(b))>-1)c=a+b[e];else a=null;else if(Object.prototype.toString.call(b)==="[object RegExp]"){b=b.exec(f.value);if(b!=null){a=b.index;c=a+b[0][e]}}if(typeof a!="undefined"){if(d){d=this[0].createTextRange();d.collapse(true);
+d.moveStart("character",a);d.moveEnd("character",c-a);d.select()}else{this[0].selectionStart=a;this[0].selectionEnd=c}this[0].focus();return this}else{if(d){c=document.selection;if(this[0].tagName.toLowerCase()!="textarea"){d=this.val();a=c[i]()[j]();a.moveEnd("character",d[e]);var g=a.text==""?d[e]:d.lastIndexOf(a.text);a=c[i]()[j]();a.moveStart("character",-d[e]);var h=a.text[e]}else{a=c[i]();c=a[j]();c.moveToElementText(this[0]);c.setEndPoint("EndToEnd",a);g=c.text[e]-a.text[e];h=g+a.text[e]}}else{g=
f.selectionStart;h=f.selectionEnd}a=f.value.substring(g,h);return{start:g,end:h,text:a,replace:function(m){return f.value.substring(0,g)+m+f.value.substring(h,f.value[e])}}}}})(jQuery,"length","createRange","duplicate");
\ No newline at end of file
-$(function() {\r
- $('.string_list_widget_button').live('click', function() {\r
- $but = $(this);\r
-\r
- if ($but.is('.add')) {\r
- $new = $("<div style=\"display: none;\">" +\r
- "<input style=\"width: 600px;\" type=\"text\" name=\"" + $but.attr('name') + "\" value=\"\" />" +\r
- "<button class=\"string_list_widget_button\">-</button>" +\r
- "</div>");\r
-\r
- $but.before($new);\r
- $new.slideDown('fast');\r
- } else {\r
- $but.parent().slideUp('fast', function() {\r
- $but.parent().remove();\r
- });\r
- }\r
-\r
- return false;\r
- })\r
-\r
- $('.fieldtool').each(function() {\r
- var $link = $(this);\r
- var $input = $link.parent().parent().find('input, textarea');\r
- var name = $input.attr('name')\r
-\r
- if ($link.is('.context')) {\r
- $link.click(function() {\r
- var $contextbox = $('<input type="text" value="' + name + '" />');\r
- $link.replaceWith($contextbox);\r
- });\r
- } else if ($link.is('.default')) {\r
- if ($input.length == 1 && ($input.is('[type=text]') || $input.is('textarea'))) {\r
- $link.click(function() {\r
- $.post(name + '/', function(data) {\r
- $input.val(data);\r
- });\r
- });\r
- } else {\r
- $link.attr('href', name + '/');\r
- }\r
- }\r
- });\r
-\r
- $('.url_field').each(function() {\r
- var $input = $(this);\r
- var $anchor = $input.parent().find('.url_field_anchor');\r
- var app_url = $anchor.attr('href');\r
-\r
- function rewrite_anchor() {\r
- var val = app_url + '/' + $input.val();\r
-\r
- $anchor.attr('href', val);\r
- $anchor.html(val);\r
-\r
- }\r
-\r
- $input.keyup(rewrite_anchor);\r
- rewrite_anchor(); \r
- });\r
-\r
- $('#test_email_settings a.test_button').click(function() {\r
- $('div.test_status').hide('slow')\r
- $('div.ajax_indicator').show('fast')\r
- $.post($(this).attr('href'), function(data) {\r
- $('div.ajax_indicator').hide('fast')\r
- $('div.test_status').html(data)\r
- $('div.test_status').show('slow')\r
- })\r
- })\r
-});\r
-\r
-/*\r
- * Autocomplete - jQuery plugin 1.0.3\r
- *\r
- * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, J�rn Zaefferer\r
- *\r
- * Dual licensed under the MIT and GPL licenses:\r
- * http://www.opensource.org/licenses/mit-license.php\r
- * http://www.gnu.org/licenses/gpl.html\r
- *\r
- */\r
-(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){y.preventDefault();w=true;return false}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multipleSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:""))}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);o=a("<ul/>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass(i.ACTIVE);g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li/>").html(e.highlight(w,m)).addClass(v%2==0?"ac_even":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){o.bgiframe()}}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},emptyList:function(){o&&o.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);\r
+$(function() {
+ $('.string_list_widget_button').live('click', function() {
+ $but = $(this);
+
+ if ($but.is('.add')) {
+ $new = $("<div style=\"display: none;\">" +
+ "<input style=\"width: 600px;\" type=\"text\" name=\"" + $but.attr('name') + "\" value=\"\" />" +
+ "<button class=\"string_list_widget_button\">-</button>" +
+ "</div>");
+
+ $but.before($new);
+ $new.slideDown('fast');
+ } else {
+ $but.parent().slideUp('fast', function() {
+ $but.parent().remove();
+ });
+ }
+
+ return false;
+ })
+
+ $('.fieldtool').each(function() {
+ var $link = $(this);
+ var $input = $link.parent().parent().find('input, textarea');
+ var name = $input.attr('name')
+
+ if ($link.is('.context')) {
+ $link.click(function() {
+ var $contextbox = $('<input type="text" value="' + name + '" />');
+ $link.replaceWith($contextbox);
+ });
+ } else if ($link.is('.default')) {
+ if ($input.length == 1 && ($input.is('[type=text]') || $input.is('textarea'))) {
+ $link.click(function() {
+ $.post(name + '/', function(data) {
+ $input.val(data);
+ });
+ });
+ } else {
+ $link.attr('href', name + '/');
+ }
+ }
+ });
+
+ $('.url_field').each(function() {
+ var $input = $(this);
+ var $anchor = $input.parent().find('.url_field_anchor');
+ var app_url = $anchor.attr('href');
+
+ function rewrite_anchor() {
+ var val = app_url + '/' + $input.val();
+
+ $anchor.attr('href', val);
+ $anchor.html(val);
+
+ }
+
+ $input.keyup(rewrite_anchor);
+ rewrite_anchor();
+ });
+
+ $('#test_email_settings a.test_button').click(function() {
+ $('div.test_status').hide('slow')
+ $('div.ajax_indicator').show('fast')
+ $.post($(this).attr('href'), function(data) {
+ $('div.ajax_indicator').hide('fast')
+ $('div.test_status').html(data)
+ $('div.test_status').show('slow')
+ })
+ })
+});
+
+/*
+ * Autocomplete - jQuery plugin 1.0.3
+ *
+ * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, J�rn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){y.preventDefault();w=true;return false}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multipleSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:""))}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);o=a("<ul/>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass(i.ACTIVE);g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li/>").html(e.highlight(w,m)).addClass(v%2==0?"ac_even":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){o.bgiframe()}}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},emptyList:function(){o&&o.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);
-/**\r
- * We do not want the CSRF protection enabled for the AJAX post requests, it causes only trouble.\r
- * Get the csrftoken cookie and pass it to the X-CSRFToken HTTP request property.\r
- */\r
-\r
-$('html').ajaxSend(function(event, xhr, settings) {\r
- function getCookie(name) {\r
- var cookieValue = null;\r
- if (document.cookie && document.cookie != '') {\r
- var cookies = document.cookie.split(';');\r
- for (var i = 0; i < cookies.length; i++) {\r
- var cookie = jQuery.trim(cookies[i]);\r
- // Does this cookie string begin with the name we want?\r
- if (cookie.substring(0, name.length + 1) == (name + '=')) {\r
- cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\r
- break;\r
- }\r
- }\r
- }\r
- return cookieValue;\r
- }\r
- try {\r
- if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {\r
- // Only send the token to relative URLs i.e. locally.\r
- xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));\r
- }\r
- } catch (e) {}\r
-});\r
-\r
-var response_commands = {\r
- refresh_page: function() {\r
- window.location.reload(true)\r
- },\r
- \r
- update_post_score: function(id, inc) {\r
- var $score_board = $('#post-' + id + '-score');\r
- var current = parseInt($score_board.html())\r
- if (isNaN(current)){\r
- current = 0;\r
- }\r
- $score_board.html(current + inc)\r
- },\r
-\r
- update_user_post_vote: function(id, vote_type) {\r
- var $upvote_button = $('#post-' + id + '-upvote');\r
- var $downvote_button = $('#post-' + id + '-downvote');\r
-\r
- $upvote_button.removeClass('on');\r
- $downvote_button.removeClass('on');\r
-\r
- if (vote_type == 'up') {\r
- $upvote_button.addClass('on');\r
- } else if (vote_type == 'down') {\r
- $downvote_button.addClass('on');\r
- }\r
- },\r
-\r
- update_favorite_count: function(inc) {\r
- var $favorite_count = $('#favorite-count');\r
- var count = parseInt($favorite_count.html());\r
-\r
- if (isNaN(count))\r
- count = 0;\r
-\r
- count += inc;\r
-\r
- if (count == 0)\r
- count = '';\r
-\r
- $favorite_count.html(count);\r
- },\r
-\r
- update_favorite_mark: function(type) {\r
- if (type == 'on') {\r
- $('#favorite-mark').addClass('on');\r
- } else {\r
- $('#favorite-mark').removeClass('on');\r
- }\r
- },\r
-\r
- mark_accepted: function(id) { \r
- var $answer = $('#answer-container-' + id);\r
- $answer.addClass('accepted-answer');\r
- $answer.find('.accept-answer').addClass('on');\r
- $answer.find('.accept-answer').attr('title', $answer.find('.accept-answer').attr('bn:on'));\r
- },\r
-\r
- unmark_accepted: function(id) {\r
- var $answer = $('#answer-container-' + id);\r
- $answer.removeClass('accepted-answer');\r
- $answer.find('.accept-answer').removeClass('on');\r
- $answer.find('.accept-answer').attr('title', $answer.find('.accept-answer').attr('bn:off'));\r
- },\r
-\r
- remove_comment: function(id) {\r
- var $comment = $('#comment-' + id);\r
- $comment.css('background', 'red')\r
- $comment.fadeOut('slow', function() {\r
- $comment.remove(); \r
- });\r
- },\r
-\r
- award_points: function(id) {\r
- alert('ok');\r
- },\r
-\r
- insert_comment: function(post_id, comment_id, comment, username, profile_url, delete_url, edit_url, convert_url, can_convert, show_latest_comments_first) {\r
- var $container = $('#comments-container-' + post_id);\r
- var skeleton = $('#new-comment-skeleton-' + post_id).html().toString();\r
-\r
- skeleton = skeleton.replace(new RegExp('%ID%', 'g'), comment_id)\r
- .replace(new RegExp('%COMMENT%', 'g'), comment)\r
- .replace(new RegExp('%USERNAME%', 'g'), username)\r
- .replace(new RegExp('%PROFILE_URL%', 'g'), profile_url)\r
- .replace(new RegExp('%DELETE_URL%', 'g'), delete_url)\r
- .replace(new RegExp('%EDIT_URL%', 'g'), edit_url)\r
- .replace(new RegExp('%CONVERT_URL%', 'g'), convert_url);\r
- if (show_latest_comments_first) {\r
- $container.prepend(skeleton);\r
- } else {\r
- $container.append(skeleton);\r
- }\r
-\r
- // Show the convert comment to answer tool only if the current comment can be converted\r
- if (can_convert == true) {\r
- $('#comment-' + comment_id + '-convert').show();\r
- }\r
-\r
- $('#comment-' + comment_id).slideDown('slow');\r
- },\r
-\r
- update_comment: function(comment_id, comment_text) {\r
- var $comment = $('#comment-' + comment_id);\r
- $comment.find('.comment-text').html(comment_text);\r
-\r
- $comment.slideDown('slow');\r
- },\r
-\r
- mark_deleted: function(post_type, post_id) {\r
- if (post_type == 'question') {\r
- var $container = $('#question-table');\r
- $container.addClass('deleted');\r
- } else {\r
- var $el = $('#' + post_type + '-container-' + post_id);\r
- $el.addClass('deleted');\r
- }\r
- },\r
-\r
- unmark_deleted: function(post_type, post_id) {\r
- if (post_type == 'answer') {\r
- var $answer = $('#answer-container-' + post_id);\r
- $answer.removeClass('deleted');\r
- } else {\r
- var $container = $('#question-table');\r
- $container.removeClass('deleted');\r
- }\r
- },\r
-\r
- set_subscription_button: function(text) {\r
- $('.subscription_switch').html(text);\r
- },\r
-\r
- set_subscription_status: function(text) {\r
- $('.subscription-status').html(text);\r
- },\r
-\r
- copy_url: function(url) {\r
- }\r
-}\r
-\r
-function show_dialog (extern) {\r
- var default_close_function = function($diag) {\r
- $diag.fadeOut('fast', function() {\r
- $diag.remove();\r
- });\r
- };\r
-\r
- var options = {\r
- extra_class: '',\r
- pos: {\r
- x: ($(window).width() / 2) + $(window).scrollLeft(),\r
- y: ($(window).height() / 2) + $(window).scrollTop()\r
- },\r
- dim: false, \r
- yes_text: messages.ok,\r
- yes_callback: default_close_function,\r
- no_text: messages.cancel,\r
- show_no: false,\r
- close_on_clickoutside: false,\r
- copy: false\r
- }\r
-\r
- $.extend(options, extern);\r
-\r
- var copy_id = '';\r
- if (options.copy) {\r
- copy_id = ' id="copy_clip_button"'\r
- }\r
-\r
- if (options.event != undefined && options.event.pageX != undefined && options.event.pageY != undefined) {\r
- options.pos = {x: options.event.pageX, y: options.event.pageY};\r
- } else if (options.event.currentTarget != undefined) {\r
- var el = jQuery("#" + options.event.currentTarget.id);\r
- var position = el.offset();\r
- options.pos = {\r
- x: position.left,\r
- y: position.top\r
- }\r
- }\r
-\r
- var html = '<div class="dialog ' + options.extra_class + '" style="display: none; z-index: 999;">'\r
- + '<div class="dialog-content">' + options.html + '</div><div class="dialog-buttons">';\r
-\r
- if (options.show_no) {\r
- html += '<button class="dialog-no">' + options.no_text + '</button>';\r
- }\r
-\r
- html += '<button class="dialog-yes"' + copy_id + '>' + options.yes_text + '</button>' + '</div></div>';\r
-\r
- var $dialog = $(html);\r
-\r
- $('body').append($dialog);\r
- var message = $('.dialog-content')[0];\r
- message.style.visibility = "hidden";\r
-\r
- if (options.dim === false) {\r
- $dialog.css({\r
- visibility: 'hidden',\r
- display: 'block'\r
- });\r
-\r
- options.dim = {w: $dialog.width(), h: $dialog.height()};\r
-\r
- $dialog.css({\r
- width: 1,\r
- height: 1,\r
- visibility: 'visible'\r
- });\r
- }\r
-\r
- $dialog.css({\r
- top: options.pos.y,\r
- left: options.pos.x\r
- });\r
- \r
- top_position_change = (options.dim.h / 2)\r
- left_position_change = (options.dim.w / 2)\r
- \r
- new_top_position = options.pos.y - top_position_change\r
- new_left_position = options.pos.x - left_position_change\r
- \r
- if (new_left_position < 0) {\r
- left_position_change = 0\r
- }\r
- if (($(window).scrollTop() - new_top_position) > 0) {\r
- top_position_change = 0\r
- }\r
- if ((options.event.pageY + options.dim.h) > ($(window).height() + $(window).scrollTop())) {\r
- top_position_change = options.dim.h\r
- }\r
- if ((options.event.pageX + options.dim.w) > ($(window).width() + $(window).scrollLeft())) {\r
- left_position_change = options.dim.w\r
- }\r
- \r
- $dialog.animate({\r
- top: "-=" + top_position_change,\r
- left: "-=" + left_position_change,\r
- width: options.dim.w,\r
- height: options.dim.h\r
- }, 200, function() {\r
- message.style.visibility = "visible";\r
- });\r
-\r
- $dialog.find('.dialog-yes').click(function() {\r
- options.yes_callback($dialog);\r
- });\r
-\r
- if (options.hasOwnProperty("no_callback")) {\r
- $dialog.find('.dialog-no:first-child').click(function() {\r
- options.no_callback($dialog);\r
- });\r
- } else {\r
- $dialog.find('.dialog-no:first-child').click(function() {\r
- default_close_function($dialog);\r
- });\r
- }\r
-\r
- if (options.close_on_clickoutside) {\r
- $dialog.one('clickoutside', function() {\r
- default_close_function($dialog);\r
- });\r
- }\r
-\r
- return $dialog;\r
-}\r
-\r
-function show_message(evt, msg, callback) {\r
- var $dialog = show_dialog({\r
- html: msg,\r
- extra_class: 'warning',\r
- event: evt,\r
- yes_callback: function() {\r
- $dialog.fadeOut('fast', function() {\r
- $dialog.remove();\r
- });\r
- if (callback) {\r
- callback();\r
- }\r
- },\r
- close_on_clickoutside: true\r
- });\r
-}\r
-\r
-function load_prompt(evt, el, url) {\r
- $.get(url, function(data) {\r
- var doptions = {\r
- html: data,\r
- extra_class: 'prompt',\r
- yes_callback: function() {\r
- var postvars = {};\r
- $dialog.find('input, textarea, select').each(function() {\r
- postvars[$(this).attr('name')] = $(this).val();\r
- });\r
- $.post(url, postvars, function(data) {\r
- $dialog.fadeOut('fast', function() {\r
- $dialog.remove();\r
- });\r
- process_ajax_response(data, evt);\r
- }, 'json');\r
- },\r
- show_no: true,\r
- copy: false\r
- }\r
-\r
- if (el.hasClass('copy')) {\r
- $.extend(doptions, { yes_text : 'Copy', copy: true});\r
- }\r
-\r
- if (!el.is('.centered')) {\r
- doptions.event = evt;\r
- }\r
-\r
- var $dialog = show_dialog(doptions);\r
- });\r
-}\r
-\r
-function process_ajax_response(data, evt, callback) {\r
- if (!data.success && data['error_message'] != undefined) {\r
- show_message(evt, data.error_message, function() {if (callback) callback(true);});\r
- end_command(false);\r
- }\r
- if (typeof data['commands'] != undefined){\r
- for (var command in data.commands) {\r
- response_commands[command].apply(null, data.commands[command])\r
-\r
-\r
- }\r
-\r
- if (data['message'] != undefined) {\r
- show_message(evt, data.message, function() {if (callback) callback(false);})\r
- } else {\r
- if (callback) callback(false);\r
- }\r
- end_command(true);\r
- }\r
-}\r
-\r
-var running = false;\r
-\r
-function start_command() {\r
- $('body').append($('<div id="command-loader"></div>'));\r
- running = true;\r
-}\r
-\r
-function end_command(success) {\r
- if (success) {\r
- $('#command-loader').addClass('success');\r
- $('#command-loader').fadeOut("slow", function() {\r
- $('#command-loader').remove();\r
- running = false;\r
- });\r
- } else {\r
- $('#command-loader').remove();\r
- running = false;\r
- }\r
-}\r
-\r
-var comment_box_cursor_position = 0;\r
-function canned_comment(post_id, comment) {\r
- textarea = $('#comment-' + post_id + '-form textarea')\r
-\r
- // Get the text from the beginning to the caret\r
- textarea_start = textarea.val().substr(0, comment_box_cursor_position)\r
-\r
- // Get the text from the caret to the end\r
- textarea_end = textarea.val().substr(comment_box_cursor_position, textarea.val().length)\r
-\r
- textarea.val(textarea_start + comment + textarea_end);\r
-}\r
-\r
-$(function() {\r
- $('textarea.commentBox').bind('keydown keyup mousedown mouseup mousemove', function(evt) {\r
- comment_box_cursor_position = $(this).caret().start;\r
- });\r
-\r
- $('textarea.commentBox').blur(function() {\r
- //alert(comment_box_cursor_position);\r
- });\r
-\r
- $('a.ajax-command').live('click', function(evt) {\r
- if (running) return false;\r
-\r
- var el = $(this);\r
-\r
- var ajax_url = el.attr('href')\r
- ajax_url = ajax_url + "?nocache=" + new Date().getTime()\r
-\r
- $('.context-menu-dropdown').slideUp('fast');\r
-\r
- if (el.is('.withprompt')) {\r
- load_prompt(evt, el, ajax_url);\r
- } else if(el.is('.confirm')) {\r
- var doptions = {\r
- html: messages.confirm,\r
- extra_class: 'confirm',\r
- yes_callback: function() {\r
- start_command();\r
- $.getJSON(ajax_url, function(data) {\r
- process_ajax_response(data, evt);\r
- $dialog.fadeOut('fast', function() {\r
- $dialog.remove();\r
- });\r
- });\r
- },\r
- yes_text: messages.yes,\r
- show_no: true,\r
- no_text: messages.no\r
- }\r
-\r
- if (!el.is('.centered')) {\r
- doptions.event = evt;\r
- }\r
- var $dialog = show_dialog(doptions);\r
- } else {\r
- start_command();\r
- $.ajax({\r
- url: ajax_url,\r
- type: "POST",\r
- dataType: "json",\r
- contentType: "application/json; charset=utf-8",\r
- success: function(data) {\r
- process_ajax_response(data, evt);\r
- }\r
- });\r
- }\r
-\r
- return false\r
- });\r
-\r
- $('.context-menu').each(function() {\r
- var $menu = $(this);\r
- var $trigger = $menu.find('.context-menu-trigger');\r
- var $dropdown = $menu.find('.context-menu-dropdown');\r
-\r
- $trigger.click(function() {\r
- $dropdown.slideToggle('fast', function() {\r
- if ($dropdown.is(':visible')) {\r
- $dropdown.one('clickoutside', function() {\r
- if ($dropdown.is(':visible'))\r
- $dropdown.slideUp('fast');\r
- });\r
- }\r
- }); \r
- });\r
- });\r
-\r
- $('div.comment-form-container').each(function() {\r
- var $container = $(this);\r
- var $comment_tools = $container.parent().find('.comment-tools');\r
- var $comments_container = $container.parent().find('.comments-container');\r
- \r
- var $form = $container.find('form');\r
-\r
- if ($form.length) {\r
- var $textarea = $container.find('textarea');\r
- var textarea = $textarea.get(0);\r
- var $button = $container.find('.comment-submit');\r
- var $cancel = $container.find('.comment-cancel');\r
- var $chars_left_message = $container.find('.comments-chars-left-msg');\r
- var $chars_togo_message = $container.find('.comments-chars-togo-msg');\r
- var $chars_counter = $container.find('.comments-char-left-count');\r
-\r
- var $add_comment_link = $comment_tools.find('.add-comment-link');\r
-\r
- var chars_limits = $chars_counter.html().split('|');\r
-\r
- var min_length = parseInt(chars_limits[0]);\r
- var max_length = parseInt(chars_limits[1]);\r
-\r
- var warn_length = max_length - 30;\r
- var current_length = 0;\r
- var comment_in_form = false;\r
- var interval = null;\r
-\r
- var hcheck = !($.browser.msie || $.browser.opera);\r
-\r
- $textarea.css("padding-top", 0).css("padding-bottom", 0).css("resize", "none");\r
- textarea.style.overflow = 'hidden';\r
-\r
-\r
- function cleanup_form() {\r
- $textarea.val('');\r
- $textarea.css('height', 80);\r
- $chars_counter.html(max_length);\r
- $chars_left_message.removeClass('warn');\r
- comment_in_form = false;\r
- current_length = 0;\r
-\r
- $chars_left_message.hide();\r
- $chars_togo_message.show();\r
-\r
- $chars_counter.removeClass('warn');\r
- $chars_counter.html(min_length);\r
- $button.attr("disabled","disabled");\r
-\r
- interval = null;\r
- }\r
-\r
- cleanup_form();\r
-\r
- function process_form_changes() {\r
- var length = $textarea.val().replace(/[ ]{2,}/g," ").length;\r
-\r
- if (current_length == length)\r
- return;\r
-\r
- if (length < warn_length && current_length >= warn_length) {\r
- $chars_counter.removeClass('warn');\r
- } else if (current_length < warn_length && length >= warn_length){\r
- $chars_counter.addClass('warn');\r
- }\r
-\r
- if (length < min_length) {\r
- $chars_left_message.hide();\r
- $chars_togo_message.show();\r
- $chars_counter.html(min_length - length);\r
- } else {\r
- length = $textarea.val().length;\r
- $chars_togo_message.hide();\r
- $chars_left_message.show();\r
- $chars_counter.html(max_length - length);\r
- }\r
-\r
- if (length > max_length || length < min_length) {\r
- $button.attr("disabled","disabled");\r
- } else {\r
- $button.removeAttr("disabled");\r
- }\r
-\r
- var current_height = textarea.style.height;\r
- if (hcheck)\r
- textarea.style.height = "0px";\r
-\r
- var h = Math.max(80, textarea.scrollHeight);\r
- textarea.style.height = current_height;\r
- $textarea.animate({height: h + 'px'}, 50);\r
-\r
- current_length = length;\r
- }\r
-\r
- function show_comment_form() {\r
- $container.slideDown('slow');\r
- $add_comment_link.fadeOut('slow');\r
- $textarea.focus();\r
- interval = window.setInterval(function() {\r
- process_form_changes();\r
- }, 200);\r
- }\r
-\r
- function hide_comment_form() {\r
- if (interval != null) {\r
- window.clearInterval(interval);\r
- interval = null;\r
- }\r
- $container.slideUp('slow');\r
- $add_comment_link.fadeIn('slow');\r
- }\r
-\r
- $add_comment_link.click(function(){\r
- cleanup_form();\r
- show_comment_form();\r
- return false;\r
- });\r
-\r
- $('#' + $comments_container.attr('id') + ' .comment-edit').live('click', function() {\r
- var $link = $(this);\r
- var comment_id = /comment-(\d+)-edit/.exec($link.attr('id'))[1];\r
- var $comment = $('#comment-' + comment_id);\r
-\r
- comment_in_form = comment_id;\r
-\r
- $.get($link.attr('href'), function(data) {\r
- $textarea.val(data);\r
- });\r
-\r
- $comment.slideUp('slow');\r
- show_comment_form();\r
- return false;\r
- });\r
-\r
- $button.click(function(evt) {\r
- if (running) return false;\r
-\r
- var post_data = {\r
- comment: $textarea.val()\r
- }\r
-\r
- if (comment_in_form) {\r
- post_data['id'] = comment_in_form;\r
- }\r
-\r
- start_command();\r
- $.post($form.attr('action'), post_data, function(data) {\r
- process_ajax_response(data, evt, function(error) {\r
- if (!error) {\r
- cleanup_form();\r
- hide_comment_form();\r
- }\r
- });\r
-\r
- }, "json");\r
-\r
- return false;\r
- });\r
-\r
- // Submit comment with CTRL + Enter\r
- $textarea.keydown(function(e) {\r
- if (e.ctrlKey && e.keyCode == 13 && !$button.attr('disabled')) {\r
- // console.log('submit');\r
- $(this).parent().find('input.comment-submit').click();\r
- }\r
- });\r
-\r
- $cancel.click(function(event) {\r
- if (confirm("You will lose all of your changes in this comment. Do you still wish to proceed?")){\r
- if (comment_in_form) {\r
- $comment = $('#comment-' + comment_in_form).slideDown('slow');\r
- }\r
- hide_comment_form();\r
- cleanup_form();\r
- }\r
- return false;\r
- });\r
- }\r
-\r
- $comment_tools.find('.show-all-comments-link').click(function() {\r
- $comments_container.find('.not_top_scorer').slideDown('slow');\r
- $(this).fadeOut('slow');\r
- $comment_tools.find('.comments-showing').fadeOut('slow');\r
- return false;\r
- });\r
- });\r
-\r
- if ($('#editor').length) {\r
- var $editor = $('#editor');\r
- var $previewer = $('#previewer');\r
- var $container = $('#editor-metrics');\r
-\r
- var initial_whitespace_rExp = /^[^A-Za-zА-Яа-я0-9]+/gi;\r
- var non_alphanumerics_rExp = rExp = /[^A-Za-zА-Яа-я0-9]+/gi;\r
- var editor_interval = null;\r
-\r
- $editor.focus(function() {\r
- if (editor_interval == null) {\r
- editor_interval = window.setInterval(function() {\r
- recalc_metrics();\r
- }, 200);\r
- }\r
- });\r
-\r
- function recalc_metrics() {\r
- var text = $previewer.text();\r
-\r
- var char_count = text.length;\r
- var fullStr = text + " ";\r
- var left_trimmedStr = fullStr.replace(initial_whitespace_rExp, "");\r
- var cleanedStr = left_trimmedStr.replace(non_alphanumerics_rExp, " ");\r
- var splitString = cleanedStr.split(" ");\r
- var word_count = splitString.length - 1;\r
-\r
- var metrics = char_count + " " + (char_count == 1 ? messages.character : messages.characters);\r
- metrics += " / " + word_count + " " + (word_count == 1 ? messages.word : messages.words);\r
- $container.html(metrics);\r
- }\r
- }\r
-});\r
-\r
-//var scriptUrl, interestingTags, ignoredTags, tags, $;\r
-function pickedTags(){\r
-\r
- var sendAjax = function(tagname, reason, action, callback){\r
- var url = scriptUrl;\r
- if (action == 'add'){\r
- url += $.i18n._('mark-tag/');\r
- if (reason == 'good'){\r
- url += $.i18n._('interesting/');\r
- }\r
- else {\r
- url += $.i18n._('ignored/');\r
- }\r
- }\r
- else {\r
- url += $.i18n._('unmark-tag/');\r
- }\r
- url = url + tagname + '/';\r
-\r
- var call_settings = {\r
- type:'POST',\r
- url:url,\r
- data: ''\r
- };\r
- if (callback !== false){\r
- call_settings.success = callback;\r
- }\r
- $.ajax(call_settings);\r
- };\r
-\r
-\r
- var unpickTag = function(from_target ,tagname, reason, send_ajax){\r
- //send ajax request to delete tag\r
- var deleteTagLocally = function(){\r
- from_target[tagname].remove();\r
- delete from_target[tagname];\r
- $(".tags.interesting").trigger('contentchanged');\r
- };\r
-\r
- if (send_ajax){\r
- sendAjax(tagname,reason,'remove',deleteTagLocally);\r
- }\r
- else {\r
- deleteTagLocally();\r
- }\r
- };\r
-\r
- var setupTagDeleteEvents = function(obj,tag_store,tagname,reason,send_ajax){\r
- obj.unbind('mouseover').bind('mouseover', function(){\r
- $(this).attr('src', mediaUrl('media/images/close-small-hover.png'));\r
- });\r
- obj.unbind('mouseout').bind('mouseout', function(){\r
- $(this).attr('src', mediaUrl('media/images/close-small-dark.png'));\r
- });\r
- obj.click( function(){\r
- unpickTag(tag_store,tagname,reason,send_ajax);\r
- });\r
- };\r
-\r
- var handlePickedTag = function(obj,reason){\r
- var tagname = $.trim($(obj).prev().attr('value'));\r
- var to_target = interestingTags;\r
- var from_target = ignoredTags;\r
- var to_tag_container;\r
- if (reason == 'bad'){\r
- to_target = ignoredTags;\r
- from_target = interestingTags;\r
- to_tag_container = $('div .tags.ignored');\r
- }\r
- else if (reason != 'good'){\r
- return;\r
- }\r
- else {\r
- to_tag_container = $('div .tags.interesting');\r
- }\r
-\r
- if (tagname in from_target){\r
- unpickTag(from_target,tagname,reason,false);\r
- }\r
-\r
- if (!(tagname in to_target)){\r
- //send ajax request to pick this tag\r
-\r
- sendAjax(tagname,reason,'add',function(){\r
- var new_tag = $('<span></span>');\r
- new_tag.addClass('deletable-tag');\r
- var tag_link = $('<a></a>');\r
- tag_link.attr('rel','tag');\r
- tag_link.attr('href', scriptUrl + $.i18n._('tags/') + tagname + '/');\r
- tag_link.html(tagname);\r
- var del_link = $('<img />');\r
- del_link.addClass('delete-icon');\r
- del_link.attr('src', mediaUrl('media/images/close-small-dark.png'));\r
-\r
- setupTagDeleteEvents(del_link, to_target, tagname, reason, true);\r
-\r
- new_tag.append(tag_link);\r
- new_tag.append(del_link);\r
- to_tag_container.append(new_tag);\r
-\r
- to_target[tagname] = new_tag;\r
-\r
- to_tag_container.trigger('contentchanged');\r
- });\r
- }\r
- };\r
-\r
- var collectPickedTags = function(){\r
- var good_prefix = 'interesting-tag-';\r
- var bad_prefix = 'ignored-tag-';\r
- var good_re = RegExp('^' + good_prefix);\r
- var bad_re = RegExp('^' + bad_prefix);\r
- interestingTags = {};\r
- ignoredTags = {};\r
- $('.deletable-tag').each(\r
- function(i,item){\r
- var item_id = $(item).attr('id');\r
- var tag_name, tag_store;\r
- if (good_re.test(item_id)){\r
- tag_name = item_id.replace(good_prefix,'');\r
- tag_store = interestingTags;\r
- reason = 'good';\r
- }\r
- else if (bad_re.test(item_id)){\r
- tag_name = item_id.replace(bad_prefix,'');\r
- tag_store = ignoredTags;\r
- reason = 'bad';\r
- }\r
- else {\r
- return;\r
- }\r
- tag_store[tag_name] = $(item);\r
- setupTagDeleteEvents($(item).find('img'),tag_store,tag_name,reason,true);\r
- }\r
- );\r
- };\r
-\r
- var setupHideIgnoredQuestionsControl = function(){\r
- $('#hideIgnoredTagsCb').unbind('click').click(function(){\r
- $.ajax({\r
- type: 'POST',\r
- dataType: 'json',\r
- cache: false,\r
- url: scriptUrl + $.i18n._('command/'),\r
- data: {command:'toggle-ignored-questions'}\r
- });\r
- });\r
- };\r
- return {\r
- init: function(){\r
- collectPickedTags();\r
- setupHideIgnoredQuestionsControl();\r
- $("#interestingTagInput, #ignoredTagInput").autocomplete(messages.matching_tags_url, {\r
- minChars: 1,\r
- matchContains: true,\r
- max: 20,\r
- /*multiple: false, - the favorite tags and ignore tags don't let you do multiple tags\r
- multipleSeparator: " "*/\r
-\r
- formatItem: function(row, i, max, value) {\r
- return row[1] + " (" + row[2] + ")";\r
- },\r
-\r
- formatResult: function(row, i, max, value){\r
- return row[1];\r
- }\r
-\r
- });\r
- $("#interestingTagAdd").click(function(){handlePickedTag(this,'good');});\r
- $("#ignoredTagAdd").click(function(){handlePickedTag(this,'bad');});\r
- }\r
- };\r
-}\r
-\r
-Hilite={elementid:"content",exact:true,max_nodes:1000,onload:true,style_name:"hilite",style_name_suffix:true,debug_referrer:""};Hilite.search_engines=[["local","q"],["cnprog\\.","q"],["google\\.","q"],["search\\.yahoo\\.","p"],["search\\.msn\\.","q"],["search\\.live\\.","query"],["search\\.aol\\.","userQuery"],["ask\\.com","q"],["altavista\\.","q"],["feedster\\.","q"],["search\\.lycos\\.","q"],["alltheweb\\.","q"],["technorati\\.com/search/([^\\?/]+)",1],["dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)",1,true]];Hilite.decodeReferrer=function(d){var g=null;var e=new RegExp("");for(var c=0;c<Hilite.search_engines.length;c++){var f=Hilite.search_engines[c];e.compile("^http://(www\\.)?"+f[0],"i");var b=d.match(e);if(b){var a;if(isNaN(f[1])){a=Hilite.decodeReferrerQS(d,f[1])}else{a=b[f[1]+1]}if(a){a=decodeURIComponent(a);if(f.length>2&&f[2]){a=decodeURIComponent(a)}a=a.replace(/\'|"/g,"");a=a.split(/[\s,\+\.]+/);return a}break}}return null};Hilite.decodeReferrerQS=function(f,d){var b=f.indexOf("?");var c;if(b>=0){var a=new String(f.substring(b+1));b=0;c=0;while((b>=0)&&((c=a.indexOf("=",b))>=0)){var e,g;e=a.substring(b,c);b=a.indexOf("&",c)+1;if(e==d){if(b<=0){return a.substring(c+1)}else{return a.substring(c+1,b-1)}}else{if(b<=0){return null}}}}return null};Hilite.hiliteElement=function(f,e){if(!e||f.childNodes.length==0){return}var c=new Array();for(var b=0;b<e.length;b++){e[b]=e[b].toLowerCase();if(Hilite.exact){c.push("\\b"+e[b]+"\\b")}else{c.push(e[b])}}c=new RegExp(c.join("|"),"i");var a={};for(var b=0;b<e.length;b++){if(Hilite.style_name_suffix){a[e[b]]=Hilite.style_name+(b+1)}else{a[e[b]]=Hilite.style_name}}var d=function(m){var j=c.exec(m.data);if(j){var n=j[0];var i="";var h=m.splitText(j.index);var g=h.splitText(n.length);var l=m.ownerDocument.createElement("SPAN");m.parentNode.replaceChild(l,h);l.className=a[n.toLowerCase()];l.appendChild(h);return l}else{return m}};Hilite.walkElements(f.childNodes[0],1,d)};Hilite.hilite=function(){var a=Hilite.debug_referrer?Hilite.debug_referrer:document.referrer;var b=null;a=Hilite.decodeReferrer(a);if(a&&((Hilite.elementid&&(b=document.getElementById(Hilite.elementid)))||(b=document.body))){Hilite.hiliteElement(b,a)}};Hilite.walkElements=function(d,f,e){var a=/^(script|style|textarea)/i;var c=0;while(d&&f>0){c++;if(c>=Hilite.max_nodes){var b=function(){Hilite.walkElements(d,f,e)};setTimeout(b,50);return}if(d.nodeType==1){if(!a.test(d.tagName)&&d.childNodes.length>0){d=d.childNodes[0];f++;continue}}else{if(d.nodeType==3){d=e(d)}}if(d.nextSibling){d=d.nextSibling}else{while(f>0){d=d.parentNode;f--;if(d.nextSibling){d=d.nextSibling;break}}}}};if(Hilite.onload){if(window.attachEvent){window.attachEvent("onload",Hilite.hilite)}else{if(window.addEventListener){window.addEventListener("load",Hilite.hilite,false)}else{var __onload=window.onload;window.onload=function(){Hilite.hilite();__onload()}}}};\r
-\r
-var mediaUrl = function(resource){\r
- return scriptUrl + 'm/' + osqaSkin + '/' + resource;\r
-};\r
-\r
-/*\r
- * jQuery i18n plugin\r
- * @requires jQuery v1.1 or later\r
- *\r
- * Examples at: http://recurser.com/articles/2008/02/21/jquery-i18n-translation-plugin/\r
- * Dual licensed under the MIT and GPL licenses:\r
- * http://www.opensource.org/licenses/mit-license.php\r
- * http://www.gnu.org/licenses/gpl.html\r
- *\r
- * Based on 'javascript i18n that almost doesn't suck' by markos\r
- * http://markos.gaivo.net/blog/?p=100\r
- *\r
- * Revision: $Id$\r
- * Version: 1.0.0 Feb-10-2008\r
- */\r
- (function($) {\r
-/**\r
- * i18n provides a mechanism for translating strings using a jscript dictionary.\r
- *\r
- */\r
-\r
-\r
-/*\r
- * i18n property list\r
- */\r
-$.i18n = {\r
-\r
-/**\r
- * setDictionary()\r
- * Initialise the dictionary and translate nodes\r
- *\r
- * @param property_list i18n_dict : The dictionary to use for translation\r
- */\r
- setDictionary: function(i18n_dict) {\r
- i18n_dict = i18n_dict;\r
- },\r
-\r
-/**\r
- * _()\r
- * The actual translation function. Looks the given string up in the\r
- * dictionary and returns the translation if one exists. If a translation\r
- * is not found, returns the original word\r
- *\r
- * @param string str : The string to translate\r
- * @param property_list params : params for using printf() on the string\r
- * @return string : Translated word\r
- *\r
- */\r
- _: function (str, params) {\r
- var transl = str;\r
- if (i18n_dict&& i18n_dict[str]) {\r
- transl = i18n_dict[str];\r
- }\r
- return this.printf(transl, params);\r
- },\r
-\r
-/**\r
- * toEntity()\r
- * Change non-ASCII characters to entity representation\r
- *\r
- * @param string str : The string to transform\r
- * @return string result : Original string with non-ASCII content converted to entities\r
- *\r
- */\r
- toEntity: function (str) {\r
- var result = '';\r
- for (var i=0;i<str.length; i++) {\r
- if (str.charCodeAt(i) > 128)\r
- result += "&#"+str.charCodeAt(i)+";";\r
- else\r
- result += str.charAt(i);\r
- }\r
- return result;\r
- },\r
-\r
-/**\r
- * stripStr()\r
- *\r
- * @param string str : The string to strip\r
- * @return string result : Stripped string\r
- *\r
- */\r
- stripStr: function(str) {\r
- return str.replace(/^\s*/, "").replace(/\s*$/, "");\r
- },\r
-\r
-/**\r
- * stripStrML()\r
- *\r
- * @param string str : The multi-line string to strip\r
- * @return string result : Stripped string\r
- *\r
- */\r
- stripStrML: function(str) {\r
- // Split because m flag doesn't exist before JS1.5 and we need to\r
- // strip newlines anyway\r
- var parts = str.split('\n');\r
- for (var i=0; i<parts.length; i++)\r
- parts[i] = stripStr(parts[i]);\r
-\r
- // Don't join with empty strings, because it "concats" words\r
- // And strip again\r
- return stripStr(parts.join(" "));\r
- },\r
-\r
-/*\r
- * printf()\r
- * C-printf like function, which substitutes %s with parameters\r
- * given in list. %%s is used to escape %s.\r
- *\r
- * Doesn't work in IE5.0 (splice)\r
- *\r
- * @param string S : string to perform printf on.\r
- * @param string L : Array of arguments for printf()\r
- */\r
- printf: function(S, L) {\r
- if (!L) return S;\r
-\r
- var nS = "";\r
- var tS = S.split("%s");\r
-\r
- for(var i=0; i<L.length; i++) {\r
- if (tS[i].lastIndexOf('%') == tS[i].length-1 && i != L.length-1)\r
- tS[i] += "s"+tS.splice(i+1,1)[0];\r
- nS += tS[i] + L[i];\r
- }\r
- return nS + tS[tS.length-1];\r
- }\r
-\r
-};\r
-\r
-\r
-})(jQuery);\r
-\r
-\r
-//var i18nLang;\r
-var i18nZh = {\r
- 'insufficient privilege':'??????????',\r
- 'cannot pick own answer as best':'??????????????',\r
- 'anonymous users cannot select favorite questions':'?????????????',\r
- 'please login':'??????',\r
- 'anonymous users cannot vote':'????????',\r
- '>15 points requried to upvote':'??+15?????????',\r
- '>100 points required to downvote':'??+100?????????',\r
- 'please see': '??',\r
- 'cannot vote for own posts':'??????????',\r
- 'daily vote cap exhausted':'????????????????',\r
- 'cannot revoke old vote':'??????????????',\r
- 'please confirm offensive':"??????????????????????",\r
- 'anonymous users cannot flag offensive posts':'???????????',\r
- 'cannot flag message as offensive twice':'???????',\r
- 'flag offensive cap exhausted':'?????????????5?\91??\92???',\r
- 'need >15 points to report spam':"??+15??????\91???\92?",\r
- 'confirm delete':"?????/????????",\r
- 'anonymous users cannot delete/undelete':"???????????????",\r
- 'post recovered':"?????????????",\r
- 'post deleted':"????????????",\r
- 'add comment':'????',\r
- 'community karma points':'????',\r
- 'to comment, need':'????',\r
- 'delete this comment':'?????',\r
- 'hide comments':"????",\r
- 'add a comment':"????",\r
- 'comments':"??",\r
- 'confirm delete comment':"?????????",\r
- 'characters':'??',\r
- 'can write':'???',\r
- 'click to close':'???????',\r
- 'loading...':'???...',\r
- 'tags cannot be empty':'???????',\r
- 'tablimits info':"??5????????????20????",\r
- 'content cannot be empty':'???????',\r
- 'content minchars': '????? {0} ???',\r
- 'please enter title':'??????',\r
- 'title minchars':"????? {0} ???",\r
- 'delete':'??',\r
- 'undelete': '??',\r
- 'bold':'??',\r
- 'italic':'??',\r
- 'link':'???',\r
- 'quote':'??',\r
- 'preformatted text':'??',\r
- 'image':'??',\r
- 'numbered list':'??????',\r
- 'bulleted list':'??????',\r
- 'heading':'??',\r
- 'horizontal bar':'???',\r
- 'undo':'??',\r
- 'redo':'??',\r
- 'enter image url':'<b>??????</b></p><p>???<br />http://www.example.com/image.jpg \"????\"',\r
- 'enter url':'<b>??Web??</b></p><p>???<br />http://www.cnprog.com/ \"????\"</p>"',\r
- 'upload image':'?????????'\r
-};\r
-\r
-var i18nEn = {\r
- 'need >15 points to report spam':'need >15 points to report spam ',\r
- '>15 points requried to upvote':'>15 points required to upvote ',\r
- 'tags cannot be empty':'please enter at least one tag',\r
- 'anonymous users cannot vote':'sorry, anonymous users cannot vote ',\r
- 'anonymous users cannot select favorite questions':'sorry, anonymous users cannot select favorite questions ',\r
- 'to comment, need': '(to comment other people\'s posts, karma ',\r
- 'please see':'please see ',\r
- 'community karma points':' or more is necessary) - ',\r
- 'upload image':'Upload image:',\r
- 'enter image url':'enter URL of the image, e.g. http://www.example.com/image.jpg \"image title\"',\r
- 'enter url':'enter Web address, e.g. http://www.example.com \"page title\"',\r
- 'daily vote cap exhausted':'sorry, you\'ve used up todays vote cap',\r
- 'cannot pick own answer as best':'sorry, you cannot accept your own answer',\r
- 'cannot revoke old vote':'sorry, older votes cannot be revoked',\r
- 'please confirm offensive':'are you sure this post is offensive, contains spam, advertising, malicious remarks, etc.?',\r
- 'flag offensive cap exhausted':'sorry, you\'ve used up todays cap of flagging offensive messages ',\r
- 'confirm delete':'are you sure you want to delete this?',\r
- 'anonymous users cannot delete/undelete':'sorry, anonymous users cannot delete or undelete posts',\r
- 'post recovered':'your post is now restored!',\r
- 'post deleted':'your post has been deleted',\r
- 'confirm delete comment':'do you really want to delete this comment?',\r
- 'can write':'have ',\r
- 'tablimits info':'up to 5 tags, no more than 20 characters each',\r
- 'content minchars': 'please enter more than {0} characters',\r
- 'title minchars':"please enter at least {0} characters",\r
- 'characters':'characters left',\r
- 'cannot vote for own posts':'sorry, you cannot vote for your own posts',\r
- 'cannot flag message as offensive twice':'cannot flag message as offensive twice ',\r
- '>100 points required to downvote':'>100 points required to downvote '\r
-};\r
-\r
-var i18nEs = {\r
- 'insufficient privilege':'privilegio insuficiente',\r
- 'cannot pick own answer as best':'no puede escoger su propia respuesta como la mejor',\r
- 'anonymous users cannot select favorite questions':'usuarios anonimos no pueden seleccionar',\r
- 'please login':'por favor inicie sesión',\r
- 'anonymous users cannot vote':'usuarios anónimos no pueden votar',\r
- '>15 points requried to upvote': '>15 puntos requeridos para votar positivamente',\r
- '>100 points required to downvote':'>100 puntos requeridos para votar negativamente',\r
- 'please see': 'por favor vea',\r
- 'cannot vote for own posts':'no se puede votar por sus propias publicaciones',\r
- 'daily vote cap exhausted':'cuota de votos diarios excedida',\r
- 'cannot revoke old vote':'no puede revocar un voto viejo',\r
- 'please confirm offensive':"por favor confirme ofensiva",\r
- 'anonymous users cannot flag offensive posts':'usuarios anónimos no pueden marcar publicaciones como ofensivas',\r
- 'cannot flag message as offensive twice':'no puede marcar mensaje como ofensivo dos veces',\r
- 'flag offensive cap exhausted':'cuota para marcar ofensivas ha sido excedida',\r
- 'need >15 points to report spam':"necesita >15 puntos para reportar spam",\r
- 'confirm delete':"¿Está seguro que desea borrar esto?",\r
- 'anonymous users cannot delete/undelete':"usuarios anónimos no pueden borrar o recuperar publicaciones",\r
- 'post recovered':"publicación recuperada",\r
- 'post deleted':"publicación borrada?",\r
- 'add comment':'agregar comentario',\r
- 'community karma points':'reputación comunitaria',\r
- 'to comment, need':'para comentar, necesita reputación',\r
- 'delete this comment':'borrar este comentario',\r
- 'hide comments':"ocultar comentarios",\r
- 'add a comment':"agregar comentarios",\r
- 'comments':"comentarios",\r
- 'confirm delete comment':"¿Realmente desea borrar este comentario?",\r
- 'characters':'caracteres faltantes',\r
- 'can write':'tiene ',\r
- 'click to close':'haga click para cerrar',\r
- 'loading...':'cargando...',\r
- 'tags cannot be empty':'las etiquetas no pueden estar vacías',\r
- 'tablimits info':"hasta 5 etiquetas de no mas de 20 caracteres cada una",\r
- 'content cannot be empty':'el contenido no puede estar vacío',\r
- 'content minchars': 'por favor introduzca mas de {0} caracteres',\r
- 'please enter title':'por favor ingrese un título',\r
- 'title minchars':"por favor introduzca al menos {0} caracteres",\r
- 'delete':'borrar',\r
- 'undelete': 'recuperar',\r
- 'bold': 'negrita',\r
- 'italic':'cursiva',\r
- 'link':'enlace',\r
- 'quote':'citar',\r
- 'preformatted text':'texto preformateado',\r
- 'image':'imagen',\r
- 'numbered list':'lista numerada',\r
- 'bulleted list':'lista no numerada',\r
- 'heading':'??',\r
- 'horizontal bar':'barra horizontal',\r
- 'undo':'deshacer',\r
- 'redo':'rehacer',\r
- 'enter image url':'introduzca la URL de la imagen, por ejemplo?<br />http://www.example.com/image.jpg \"titulo de imagen\"',\r
- 'enter url':'introduzca direcciones web, ejemplo?<br />http://www.cnprog.com/ \"titulo del enlace\"</p>"',\r
- 'upload image':'cargar imagen?',\r
- 'questions/' : 'preguntas/',\r
- 'vote/' : 'votar/'\r
-};\r
-\r
-var i18n = {\r
- 'en':i18nEn,\r
- 'zh_CN':i18nZh,\r
- 'es':i18nEs\r
-};\r
-\r
-var i18n_dict = i18n[i18nLang];\r
-\r
-/*\r
- jQuery TextAreaResizer plugin\r
- Created on 17th January 2008 by Ryan O'Dell\r
- Version 1.0.4\r
-*/(function($){var textarea,staticOffset;var iLastMousePos=0;var iMin=32;var grip;$.fn.TextAreaResizer=function(){return this.each(function(){textarea=$(this).addClass('processed'),staticOffset=null;$(this).wrap('<div class="resizable-textarea"><span></span></div>').parent().append($('<div class="grippie"></div>').bind("mousedown",{el:this},startDrag));var grippie=$('div.grippie',$(this).parent())[0];grippie.style.marginRight=(grippie.offsetWidth-$(this)[0].offsetWidth)+'px'})};function startDrag(e){textarea=$(e.data.el);textarea.blur();iLastMousePos=mousePosition(e).y;staticOffset=textarea.height()-iLastMousePos;textarea.css('opacity',0.25);$(document).mousemove(performDrag).mouseup(endDrag);return false}function performDrag(e){var iThisMousePos=mousePosition(e).y;var iMousePos=staticOffset+iThisMousePos;if(iLastMousePos>=(iThisMousePos)){iMousePos-=5}iLastMousePos=iThisMousePos;iMousePos=Math.max(iMin,iMousePos);textarea.height(iMousePos+'px');if(iMousePos<iMin){endDrag(e)}return false}function endDrag(e){$(document).unbind('mousemove',performDrag).unbind('mouseup',endDrag);textarea.css('opacity',1);textarea.focus();textarea=null;staticOffset=null;iLastMousePos=0}function mousePosition(e){return{x:e.clientX+document.documentElement.scrollLeft,y:e.clientY+document.documentElement.scrollTop}}})(jQuery);\r
-/*\r
- * Autocomplete - jQuery plugin 1.0.3\r
- *\r
- * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer\r
- *\r
- * Dual licensed under the MIT and GPL licenses:\r
- * http://www.opensource.org/licenses/mit-license.php\r
- * http://www.gnu.org/licenses/gpl.html\r
- *\r
- */\r
-(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){y.preventDefault();w=true;return false}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multipleSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:""))}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);o=a("<ul/>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass(i.ACTIVE);g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li/>").html(e.highlight(w,m)).addClass(v%2==0?"ac_even":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){o.bgiframe()}}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},emptyList:function(){o&&o.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);\r
-\r
-var notify = function() {\r
- var visible = false;\r
- return {\r
- show: function(html) {\r
- if (html) {\r
- $("body").css("margin-top", "2.2em");\r
- $(".notify span").html(html);\r
- }\r
- $(".notify").fadeIn("slow");\r
- visible = true;\r
- },\r
- close: function(doPostback) {\r
- $(".notify").fadeOut("fast");\r
- $("body").css("margin-top", "0");\r
- visible = false;\r
- },\r
- isVisible: function() { return visible; }\r
- };\r
-} ();\r
-\r
-/*\r
- * jQuery outside events - v1.1 - 3/16/2010\r
- * http://benalman.com/projects/jquery-outside-events-plugin/\r
- *\r
- * Copyright (c) 2010 "Cowboy" Ben Alman\r
- * Dual licensed under the MIT and GPL licenses.\r
- * http://benalman.com/about/license/\r
- */\r
-(function($,c,b){$.map("click dblclick mousemove mousedown mouseup mouseover mouseout change select submit keydown keypress keyup".split(" "),function(d){a(d)});a("focusin","focus"+b);a("focusout","blur"+b);$.addOutsideEvent=a;function a(g,e){e=e||g+b;var d=$(),h=g+"."+e+"-special-event";$.event.special[e]={setup:function(){d=d.add(this);if(d.length===1){$(c).bind(h,f)}},teardown:function(){d=d.not(this);if(d.length===0){$(c).unbind(h)}},add:function(i){var j=i.handler;i.handler=function(l,k){l.target=k;j.apply(this,arguments)}}};function f(i){$(d).each(function(){var j=$(this);if(this!==i.target&&!j.has(i.target).length){j.triggerHandler(e,[i.target])}})}}})(jQuery,document,"outside");\r
-\r
-$(document).ready( function(){\r
- pickedTags().init();\r
-\r
- $('input#bnewaccount').click(function() {\r
- $('#bnewaccount').disabled=true;\r
- });\r
-});\r
-\r
-function yourWorkWillBeLost(e) {\r
- if(browserTester('chrome')) {\r
- return "Are you sure you want to leave? Your work will be lost.";\r
- } else if(browserTester('safari')) {\r
- return "Are you sure you want to leave? Your work will be lost.";\r
- } else {\r
- if(!e) e = window.event;\r
- e.cancelBubble = true;\r
- e.returnValue = 'If you leave, your work will be lost.';\r
-\r
- if (e.stopPropagation) {\r
- e.stopPropagation();\r
- e.preventDefault();\r
- }\r
- return e;\r
- }\r
-}\r
-\r
-function browserTester(browserString) {\r
- return navigator.userAgent.toLowerCase().indexOf(browserString) > -1;\r
-}\r
-\r
-// Add missing IE functionality\r
-if (!window.addEventListener) {\r
- if (window.attachEvent) {\r
- window.addEventListener = function (type, listener, useCapture) {\r
- window.attachEvent('on' + type, listener);\r
- };\r
- window.removeEventListener = function (type, listener, useCapture) {\r
- window.detachEvent('on' + type, listener);\r
- };\r
- } else {\r
- window.addEventListener = function (type, listener, useCapture) {\r
- window['on' + type] = listener;\r
- };\r
- window.removeEventListener = function (type, listener, useCapture) {\r
- window['on' + type] = null;\r
- };\r
- }\r
-}\r
+/**
+ * We do not want the CSRF protection enabled for the AJAX post requests, it causes only trouble.
+ * Get the csrftoken cookie and pass it to the X-CSRFToken HTTP request property.
+ */
+
+$('html').ajaxSend(function(event, xhr, settings) {
+ function getCookie(name) {
+ var cookieValue = null;
+ if (document.cookie && document.cookie != '') {
+ var cookies = document.cookie.split(';');
+ for (var i = 0; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+ }
+ try {
+ if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
+ // Only send the token to relative URLs i.e. locally.
+ xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
+ }
+ } catch (e) {}
+});
+
+var response_commands = {
+ refresh_page: function() {
+ window.location.reload(true)
+ },
+
+ update_post_score: function(id, inc) {
+ var $score_board = $('#post-' + id + '-score');
+ var current = parseInt($score_board.html())
+ if (isNaN(current)){
+ current = 0;
+ }
+ $score_board.html(current + inc)
+ },
+
+ update_user_post_vote: function(id, vote_type) {
+ var $upvote_button = $('#post-' + id + '-upvote');
+ var $downvote_button = $('#post-' + id + '-downvote');
+
+ $upvote_button.removeClass('on');
+ $downvote_button.removeClass('on');
+
+ if (vote_type == 'up') {
+ $upvote_button.addClass('on');
+ } else if (vote_type == 'down') {
+ $downvote_button.addClass('on');
+ }
+ },
+
+ update_favorite_count: function(inc) {
+ var $favorite_count = $('#favorite-count');
+ var count = parseInt($favorite_count.html());
+
+ if (isNaN(count))
+ count = 0;
+
+ count += inc;
+
+ if (count == 0)
+ count = '';
+
+ $favorite_count.html(count);
+ },
+
+ update_favorite_mark: function(type) {
+ if (type == 'on') {
+ $('#favorite-mark').addClass('on');
+ } else {
+ $('#favorite-mark').removeClass('on');
+ }
+ },
+
+ mark_accepted: function(id) {
+ var $answer = $('#answer-container-' + id);
+ $answer.addClass('accepted-answer');
+ $answer.find('.accept-answer').addClass('on');
+ $answer.find('.accept-answer').attr('title', $answer.find('.accept-answer').attr('bn:on'));
+ },
+
+ unmark_accepted: function(id) {
+ var $answer = $('#answer-container-' + id);
+ $answer.removeClass('accepted-answer');
+ $answer.find('.accept-answer').removeClass('on');
+ $answer.find('.accept-answer').attr('title', $answer.find('.accept-answer').attr('bn:off'));
+ },
+
+ remove_comment: function(id) {
+ var $comment = $('#comment-' + id);
+ $comment.css('background', 'red')
+ $comment.fadeOut('slow', function() {
+ $comment.remove();
+ });
+ },
+
+ award_points: function(id) {
+ alert('ok');
+ },
+
+ insert_comment: function(post_id, comment_id, comment, username, profile_url, delete_url, edit_url, convert_url, can_convert, show_latest_comments_first) {
+ var $container = $('#comments-container-' + post_id);
+ var skeleton = $('#new-comment-skeleton-' + post_id).html().toString();
+
+ skeleton = skeleton.replace(new RegExp('%ID%', 'g'), comment_id)
+ .replace(new RegExp('%COMMENT%', 'g'), comment)
+ .replace(new RegExp('%USERNAME%', 'g'), username)
+ .replace(new RegExp('%PROFILE_URL%', 'g'), profile_url)
+ .replace(new RegExp('%DELETE_URL%', 'g'), delete_url)
+ .replace(new RegExp('%EDIT_URL%', 'g'), edit_url)
+ .replace(new RegExp('%CONVERT_URL%', 'g'), convert_url);
+ if (show_latest_comments_first) {
+ $container.prepend(skeleton);
+ } else {
+ $container.append(skeleton);
+ }
+
+ // Show the convert comment to answer tool only if the current comment can be converted
+ if (can_convert == true) {
+ $('#comment-' + comment_id + '-convert').show();
+ }
+
+ $('#comment-' + comment_id).slideDown('slow');
+ },
+
+ update_comment: function(comment_id, comment_text) {
+ var $comment = $('#comment-' + comment_id);
+ $comment.find('.comment-text').html(comment_text);
+
+ $comment.slideDown('slow');
+ },
+
+ mark_deleted: function(post_type, post_id) {
+ if (post_type == 'question') {
+ var $container = $('#question-table');
+ $container.addClass('deleted');
+ } else {
+ var $el = $('#' + post_type + '-container-' + post_id);
+ $el.addClass('deleted');
+ }
+ },
+
+ unmark_deleted: function(post_type, post_id) {
+ if (post_type == 'answer') {
+ var $answer = $('#answer-container-' + post_id);
+ $answer.removeClass('deleted');
+ } else {
+ var $container = $('#question-table');
+ $container.removeClass('deleted');
+ }
+ },
+
+ set_subscription_button: function(text) {
+ $('.subscription_switch').html(text);
+ },
+
+ set_subscription_status: function(text) {
+ $('.subscription-status').html(text);
+ },
+
+ copy_url: function(url) {
+ }
+}
+
+function show_dialog (extern) {
+ var default_close_function = function($diag) {
+ $diag.fadeOut('fast', function() {
+ $diag.remove();
+ });
+ };
+
+ var options = {
+ extra_class: '',
+ pos: {
+ x: ($(window).width() / 2) + $(window).scrollLeft(),
+ y: ($(window).height() / 2) + $(window).scrollTop()
+ },
+ dim: false,
+ yes_text: messages.ok,
+ yes_callback: default_close_function,
+ no_text: messages.cancel,
+ show_no: false,
+ close_on_clickoutside: false,
+ copy: false
+ }
+
+ $.extend(options, extern);
+
+ var copy_id = '';
+ if (options.copy) {
+ copy_id = ' id="copy_clip_button"'
+ }
+
+ if (options.event != undefined && options.event.pageX != undefined && options.event.pageY != undefined) {
+ options.pos = {x: options.event.pageX, y: options.event.pageY};
+ } else if (options.event.currentTarget != undefined) {
+ var el = jQuery("#" + options.event.currentTarget.id);
+ var position = el.offset();
+ options.pos = {
+ x: position.left,
+ y: position.top
+ }
+ }
+
+ var html = '<div class="dialog ' + options.extra_class + '" style="display: none; z-index: 999;">'
+ + '<div class="dialog-content">' + options.html + '</div><div class="dialog-buttons">';
+
+ if (options.show_no) {
+ html += '<button class="dialog-no">' + options.no_text + '</button>';
+ }
+
+ html += '<button class="dialog-yes"' + copy_id + '>' + options.yes_text + '</button>' + '</div></div>';
+
+ var $dialog = $(html);
+
+ $('body').append($dialog);
+ var message = $('.dialog-content')[0];
+ message.style.visibility = "hidden";
+
+ if (options.dim === false) {
+ $dialog.css({
+ visibility: 'hidden',
+ display: 'block'
+ });
+
+ options.dim = {w: $dialog.width(), h: $dialog.height()};
+
+ $dialog.css({
+ width: 1,
+ height: 1,
+ visibility: 'visible'
+ });
+ }
+
+ $dialog.css({
+ top: options.pos.y,
+ left: options.pos.x
+ });
+
+ top_position_change = (options.dim.h / 2)
+ left_position_change = (options.dim.w / 2)
+
+ new_top_position = options.pos.y - top_position_change
+ new_left_position = options.pos.x - left_position_change
+
+ if (new_left_position < 0) {
+ left_position_change = 0
+ }
+ if (($(window).scrollTop() - new_top_position) > 0) {
+ top_position_change = 0
+ }
+ if ((options.event.pageY + options.dim.h) > ($(window).height() + $(window).scrollTop())) {
+ top_position_change = options.dim.h
+ }
+ if ((options.event.pageX + options.dim.w) > ($(window).width() + $(window).scrollLeft())) {
+ left_position_change = options.dim.w
+ }
+
+ $dialog.animate({
+ top: "-=" + top_position_change,
+ left: "-=" + left_position_change,
+ width: options.dim.w,
+ height: options.dim.h
+ }, 200, function() {
+ message.style.visibility = "visible";
+ });
+
+ $dialog.find('.dialog-yes').click(function() {
+ options.yes_callback($dialog);
+ });
+
+ if (options.hasOwnProperty("no_callback")) {
+ $dialog.find('.dialog-no:first-child').click(function() {
+ options.no_callback($dialog);
+ });
+ } else {
+ $dialog.find('.dialog-no:first-child').click(function() {
+ default_close_function($dialog);
+ });
+ }
+
+ if (options.close_on_clickoutside) {
+ $dialog.one('clickoutside', function() {
+ default_close_function($dialog);
+ });
+ }
+
+ return $dialog;
+}
+
+function show_message(evt, msg, callback) {
+ var $dialog = show_dialog({
+ html: msg,
+ extra_class: 'warning',
+ event: evt,
+ yes_callback: function() {
+ $dialog.fadeOut('fast', function() {
+ $dialog.remove();
+ });
+ if (callback) {
+ callback();
+ }
+ },
+ close_on_clickoutside: true
+ });
+}
+
+function load_prompt(evt, el, url) {
+ $.get(url, function(data) {
+ var doptions = {
+ html: data,
+ extra_class: 'prompt',
+ yes_callback: function() {
+ var postvars = {};
+ $dialog.find('input, textarea, select').each(function() {
+ postvars[$(this).attr('name')] = $(this).val();
+ });
+ $.post(url, postvars, function(data) {
+ $dialog.fadeOut('fast', function() {
+ $dialog.remove();
+ });
+ process_ajax_response(data, evt);
+ }, 'json');
+ },
+ show_no: true,
+ copy: false
+ }
+
+ if (el.hasClass('copy')) {
+ $.extend(doptions, { yes_text : 'Copy', copy: true});
+ }
+
+ if (!el.is('.centered')) {
+ doptions.event = evt;
+ }
+
+ var $dialog = show_dialog(doptions);
+ });
+}
+
+function process_ajax_response(data, evt, callback) {
+ if (!data.success && data['error_message'] != undefined) {
+ show_message(evt, data.error_message, function() {if (callback) callback(true);});
+ end_command(false);
+ }
+ if (typeof data['commands'] != undefined){
+ for (var command in data.commands) {
+ response_commands[command].apply(null, data.commands[command])
+
+
+ }
+
+ if (data['message'] != undefined) {
+ show_message(evt, data.message, function() {if (callback) callback(false);})
+ } else {
+ if (callback) callback(false);
+ }
+ end_command(true);
+ }
+}
+
+var running = false;
+
+function start_command() {
+ $('body').append($('<div id="command-loader"></div>'));
+ running = true;
+}
+
+function end_command(success) {
+ if (success) {
+ $('#command-loader').addClass('success');
+ $('#command-loader').fadeOut("slow", function() {
+ $('#command-loader').remove();
+ running = false;
+ });
+ } else {
+ $('#command-loader').remove();
+ running = false;
+ }
+}
+
+var comment_box_cursor_position = 0;
+function canned_comment(post_id, comment) {
+ textarea = $('#comment-' + post_id + '-form textarea')
+
+ // Get the text from the beginning to the caret
+ textarea_start = textarea.val().substr(0, comment_box_cursor_position)
+
+ // Get the text from the caret to the end
+ textarea_end = textarea.val().substr(comment_box_cursor_position, textarea.val().length)
+
+ textarea.val(textarea_start + comment + textarea_end);
+}
+
+$(function() {
+ $('textarea.commentBox').bind('keydown keyup mousedown mouseup mousemove', function(evt) {
+ comment_box_cursor_position = $(this).caret().start;
+ });
+
+ $('textarea.commentBox').blur(function() {
+ //alert(comment_box_cursor_position);
+ });
+
+ $('a.ajax-command').live('click', function(evt) {
+ if (running) return false;
+
+ var el = $(this);
+
+ var ajax_url = el.attr('href')
+ ajax_url = ajax_url + "?nocache=" + new Date().getTime()
+
+ $('.context-menu-dropdown').slideUp('fast');
+
+ if (el.is('.withprompt')) {
+ load_prompt(evt, el, ajax_url);
+ } else if(el.is('.confirm')) {
+ var doptions = {
+ html: messages.confirm,
+ extra_class: 'confirm',
+ yes_callback: function() {
+ start_command();
+ $.getJSON(ajax_url, function(data) {
+ process_ajax_response(data, evt);
+ $dialog.fadeOut('fast', function() {
+ $dialog.remove();
+ });
+ });
+ },
+ yes_text: messages.yes,
+ show_no: true,
+ no_text: messages.no
+ }
+
+ if (!el.is('.centered')) {
+ doptions.event = evt;
+ }
+ var $dialog = show_dialog(doptions);
+ } else {
+ start_command();
+ $.ajax({
+ url: ajax_url,
+ type: "POST",
+ dataType: "json",
+ contentType: "application/json; charset=utf-8",
+ success: function(data) {
+ process_ajax_response(data, evt);
+ }
+ });
+ }
+
+ return false
+ });
+
+ $('.context-menu').each(function() {
+ var $menu = $(this);
+ var $trigger = $menu.find('.context-menu-trigger');
+ var $dropdown = $menu.find('.context-menu-dropdown');
+
+ $trigger.click(function() {
+ $dropdown.slideToggle('fast', function() {
+ if ($dropdown.is(':visible')) {
+ $dropdown.one('clickoutside', function() {
+ if ($dropdown.is(':visible'))
+ $dropdown.slideUp('fast');
+ });
+ }
+ });
+ });
+ });
+
+ $('div.comment-form-container').each(function() {
+ var $container = $(this);
+ var $comment_tools = $container.parent().find('.comment-tools');
+ var $comments_container = $container.parent().find('.comments-container');
+
+ var $form = $container.find('form');
+
+ if ($form.length) {
+ var $textarea = $container.find('textarea');
+ var textarea = $textarea.get(0);
+ var $button = $container.find('.comment-submit');
+ var $cancel = $container.find('.comment-cancel');
+ var $chars_left_message = $container.find('.comments-chars-left-msg');
+ var $chars_togo_message = $container.find('.comments-chars-togo-msg');
+ var $chars_counter = $container.find('.comments-char-left-count');
+
+ var $add_comment_link = $comment_tools.find('.add-comment-link');
+
+ var chars_limits = $chars_counter.html().split('|');
+
+ var min_length = parseInt(chars_limits[0]);
+ var max_length = parseInt(chars_limits[1]);
+
+ var warn_length = max_length - 30;
+ var current_length = 0;
+ var comment_in_form = false;
+ var interval = null;
+
+ var hcheck = !($.browser.msie || $.browser.opera);
+
+ $textarea.css("padding-top", 0).css("padding-bottom", 0).css("resize", "none");
+ textarea.style.overflow = 'hidden';
+
+
+ function cleanup_form() {
+ $textarea.val('');
+ $textarea.css('height', 80);
+ $chars_counter.html(max_length);
+ $chars_left_message.removeClass('warn');
+ comment_in_form = false;
+ current_length = 0;
+
+ $chars_left_message.hide();
+ $chars_togo_message.show();
+
+ $chars_counter.removeClass('warn');
+ $chars_counter.html(min_length);
+ $button.attr("disabled","disabled");
+
+ interval = null;
+ }
+
+ cleanup_form();
+
+ function process_form_changes() {
+ var length = $textarea.val().replace(/[ ]{2,}/g," ").length;
+
+ if (current_length == length)
+ return;
+
+ if (length < warn_length && current_length >= warn_length) {
+ $chars_counter.removeClass('warn');
+ } else if (current_length < warn_length && length >= warn_length){
+ $chars_counter.addClass('warn');
+ }
+
+ if (length < min_length) {
+ $chars_left_message.hide();
+ $chars_togo_message.show();
+ $chars_counter.html(min_length - length);
+ } else {
+ length = $textarea.val().length;
+ $chars_togo_message.hide();
+ $chars_left_message.show();
+ $chars_counter.html(max_length - length);
+ }
+
+ if (length > max_length || length < min_length) {
+ $button.attr("disabled","disabled");
+ } else {
+ $button.removeAttr("disabled");
+ }
+
+ var current_height = textarea.style.height;
+ if (hcheck)
+ textarea.style.height = "0px";
+
+ var h = Math.max(80, textarea.scrollHeight);
+ textarea.style.height = current_height;
+ $textarea.animate({height: h + 'px'}, 50);
+
+ current_length = length;
+ }
+
+ function show_comment_form() {
+ $container.slideDown('slow');
+ $add_comment_link.fadeOut('slow');
+ $textarea.focus();
+ interval = window.setInterval(function() {
+ process_form_changes();
+ }, 200);
+ }
+
+ function hide_comment_form() {
+ if (interval != null) {
+ window.clearInterval(interval);
+ interval = null;
+ }
+ $container.slideUp('slow');
+ $add_comment_link.fadeIn('slow');
+ }
+
+ $add_comment_link.click(function(){
+ cleanup_form();
+ show_comment_form();
+ return false;
+ });
+
+ $('#' + $comments_container.attr('id') + ' .comment-edit').live('click', function() {
+ var $link = $(this);
+ var comment_id = /comment-(\d+)-edit/.exec($link.attr('id'))[1];
+ var $comment = $('#comment-' + comment_id);
+
+ comment_in_form = comment_id;
+
+ $.get($link.attr('href'), function(data) {
+ $textarea.val(data);
+ });
+
+ $comment.slideUp('slow');
+ show_comment_form();
+ return false;
+ });
+
+ $button.click(function(evt) {
+ if (running) return false;
+
+ var post_data = {
+ comment: $textarea.val()
+ }
+
+ if (comment_in_form) {
+ post_data['id'] = comment_in_form;
+ }
+
+ start_command();
+ $.post($form.attr('action'), post_data, function(data) {
+ process_ajax_response(data, evt, function(error) {
+ if (!error) {
+ cleanup_form();
+ hide_comment_form();
+ }
+ });
+
+ }, "json");
+
+ return false;
+ });
+
+ // Submit comment with CTRL + Enter
+ $textarea.keydown(function(e) {
+ if (e.ctrlKey && e.keyCode == 13 && !$button.attr('disabled')) {
+ // console.log('submit');
+ $(this).parent().find('input.comment-submit').click();
+ }
+ });
+
+ $cancel.click(function(event) {
+ if (confirm("You will lose all of your changes in this comment. Do you still wish to proceed?")){
+ if (comment_in_form) {
+ $comment = $('#comment-' + comment_in_form).slideDown('slow');
+ }
+ hide_comment_form();
+ cleanup_form();
+ }
+ return false;
+ });
+ }
+
+ $comment_tools.find('.show-all-comments-link').click(function() {
+ $comments_container.find('.not_top_scorer').slideDown('slow');
+ $(this).fadeOut('slow');
+ $comment_tools.find('.comments-showing').fadeOut('slow');
+ return false;
+ });
+ });
+
+ if ($('#editor').length) {
+ var $editor = $('#editor');
+ var $previewer = $('#previewer');
+ var $container = $('#editor-metrics');
+
+ var initial_whitespace_rExp = /^[^A-Za-zА-Яа-я0-9]+/gi;
+ var non_alphanumerics_rExp = rExp = /[^A-Za-zА-Яа-я0-9]+/gi;
+ var editor_interval = null;
+
+ $editor.focus(function() {
+ if (editor_interval == null) {
+ editor_interval = window.setInterval(function() {
+ recalc_metrics();
+ }, 200);
+ }
+ });
+
+ function recalc_metrics() {
+ var text = $previewer.text();
+
+ var char_count = text.length;
+ var fullStr = text + " ";
+ var left_trimmedStr = fullStr.replace(initial_whitespace_rExp, "");
+ var cleanedStr = left_trimmedStr.replace(non_alphanumerics_rExp, " ");
+ var splitString = cleanedStr.split(" ");
+ var word_count = splitString.length - 1;
+
+ var metrics = char_count + " " + (char_count == 1 ? messages.character : messages.characters);
+ metrics += " / " + word_count + " " + (word_count == 1 ? messages.word : messages.words);
+ $container.html(metrics);
+ }
+ }
+});
+
+//var scriptUrl, interestingTags, ignoredTags, tags, $;
+function pickedTags(){
+
+ var sendAjax = function(tagname, reason, action, callback){
+ var url = scriptUrl;
+ if (action == 'add'){
+ url += $.i18n._('mark-tag/');
+ if (reason == 'good'){
+ url += $.i18n._('interesting/');
+ }
+ else {
+ url += $.i18n._('ignored/');
+ }
+ }
+ else {
+ url += $.i18n._('unmark-tag/');
+ }
+ url = url + tagname + '/';
+
+ var call_settings = {
+ type:'POST',
+ url:url,
+ data: ''
+ };
+ if (callback !== false){
+ call_settings.success = callback;
+ }
+ $.ajax(call_settings);
+ };
+
+
+ var unpickTag = function(from_target ,tagname, reason, send_ajax){
+ //send ajax request to delete tag
+ var deleteTagLocally = function(){
+ from_target[tagname].remove();
+ delete from_target[tagname];
+ $(".tags.interesting").trigger('contentchanged');
+ };
+
+ if (send_ajax){
+ sendAjax(tagname,reason,'remove',deleteTagLocally);
+ }
+ else {
+ deleteTagLocally();
+ }
+ };
+
+ var setupTagDeleteEvents = function(obj,tag_store,tagname,reason,send_ajax){
+ obj.unbind('mouseover').bind('mouseover', function(){
+ $(this).attr('src', mediaUrl('media/images/close-small-hover.png'));
+ });
+ obj.unbind('mouseout').bind('mouseout', function(){
+ $(this).attr('src', mediaUrl('media/images/close-small-dark.png'));
+ });
+ obj.click( function(){
+ unpickTag(tag_store,tagname,reason,send_ajax);
+ });
+ };
+
+ var handlePickedTag = function(obj,reason){
+ var tagname = $.trim($(obj).prev().attr('value'));
+ var to_target = interestingTags;
+ var from_target = ignoredTags;
+ var to_tag_container;
+ if (reason == 'bad'){
+ to_target = ignoredTags;
+ from_target = interestingTags;
+ to_tag_container = $('div .tags.ignored');
+ }
+ else if (reason != 'good'){
+ return;
+ }
+ else {
+ to_tag_container = $('div .tags.interesting');
+ }
+
+ if (tagname in from_target){
+ unpickTag(from_target,tagname,reason,false);
+ }
+
+ if (!(tagname in to_target)){
+ //send ajax request to pick this tag
+
+ sendAjax(tagname,reason,'add',function(){
+ var new_tag = $('<span></span>');
+ new_tag.addClass('deletable-tag');
+ var tag_link = $('<a></a>');
+ tag_link.attr('rel','tag');
+ tag_link.attr('href', scriptUrl + $.i18n._('tags/') + tagname + '/');
+ tag_link.html(tagname);
+ var del_link = $('<img />');
+ del_link.addClass('delete-icon');
+ del_link.attr('src', mediaUrl('media/images/close-small-dark.png'));
+
+ setupTagDeleteEvents(del_link, to_target, tagname, reason, true);
+
+ new_tag.append(tag_link);
+ new_tag.append(del_link);
+ to_tag_container.append(new_tag);
+
+ to_target[tagname] = new_tag;
+
+ to_tag_container.trigger('contentchanged');
+ });
+ }
+ };
+
+ var collectPickedTags = function(){
+ var good_prefix = 'interesting-tag-';
+ var bad_prefix = 'ignored-tag-';
+ var good_re = RegExp('^' + good_prefix);
+ var bad_re = RegExp('^' + bad_prefix);
+ interestingTags = {};
+ ignoredTags = {};
+ $('.deletable-tag').each(
+ function(i,item){
+ var item_id = $(item).attr('id');
+ var tag_name, tag_store;
+ if (good_re.test(item_id)){
+ tag_name = item_id.replace(good_prefix,'');
+ tag_store = interestingTags;
+ reason = 'good';
+ }
+ else if (bad_re.test(item_id)){
+ tag_name = item_id.replace(bad_prefix,'');
+ tag_store = ignoredTags;
+ reason = 'bad';
+ }
+ else {
+ return;
+ }
+ tag_store[tag_name] = $(item);
+ setupTagDeleteEvents($(item).find('img'),tag_store,tag_name,reason,true);
+ }
+ );
+ };
+
+ var setupHideIgnoredQuestionsControl = function(){
+ $('#hideIgnoredTagsCb').unbind('click').click(function(){
+ $.ajax({
+ type: 'POST',
+ dataType: 'json',
+ cache: false,
+ url: scriptUrl + $.i18n._('command/'),
+ data: {command:'toggle-ignored-questions'}
+ });
+ });
+ };
+ return {
+ init: function(){
+ collectPickedTags();
+ setupHideIgnoredQuestionsControl();
+ $("#interestingTagInput, #ignoredTagInput").autocomplete(messages.matching_tags_url, {
+ minChars: 1,
+ matchContains: true,
+ max: 20,
+ /*multiple: false, - the favorite tags and ignore tags don't let you do multiple tags
+ multipleSeparator: " "*/
+
+ formatItem: function(row, i, max, value) {
+ return row[1] + " (" + row[2] + ")";
+ },
+
+ formatResult: function(row, i, max, value){
+ return row[1];
+ }
+
+ });
+ $("#interestingTagAdd").click(function(){handlePickedTag(this,'good');});
+ $("#ignoredTagAdd").click(function(){handlePickedTag(this,'bad');});
+ }
+ };
+}
+
+Hilite={elementid:"content",exact:true,max_nodes:1000,onload:true,style_name:"hilite",style_name_suffix:true,debug_referrer:""};Hilite.search_engines=[["local","q"],["cnprog\\.","q"],["google\\.","q"],["search\\.yahoo\\.","p"],["search\\.msn\\.","q"],["search\\.live\\.","query"],["search\\.aol\\.","userQuery"],["ask\\.com","q"],["altavista\\.","q"],["feedster\\.","q"],["search\\.lycos\\.","q"],["alltheweb\\.","q"],["technorati\\.com/search/([^\\?/]+)",1],["dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)",1,true]];Hilite.decodeReferrer=function(d){var g=null;var e=new RegExp("");for(var c=0;c<Hilite.search_engines.length;c++){var f=Hilite.search_engines[c];e.compile("^http://(www\\.)?"+f[0],"i");var b=d.match(e);if(b){var a;if(isNaN(f[1])){a=Hilite.decodeReferrerQS(d,f[1])}else{a=b[f[1]+1]}if(a){a=decodeURIComponent(a);if(f.length>2&&f[2]){a=decodeURIComponent(a)}a=a.replace(/\'|"/g,"");a=a.split(/[\s,\+\.]+/);return a}break}}return null};Hilite.decodeReferrerQS=function(f,d){var b=f.indexOf("?");var c;if(b>=0){var a=new String(f.substring(b+1));b=0;c=0;while((b>=0)&&((c=a.indexOf("=",b))>=0)){var e,g;e=a.substring(b,c);b=a.indexOf("&",c)+1;if(e==d){if(b<=0){return a.substring(c+1)}else{return a.substring(c+1,b-1)}}else{if(b<=0){return null}}}}return null};Hilite.hiliteElement=function(f,e){if(!e||f.childNodes.length==0){return}var c=new Array();for(var b=0;b<e.length;b++){e[b]=e[b].toLowerCase();if(Hilite.exact){c.push("\\b"+e[b]+"\\b")}else{c.push(e[b])}}c=new RegExp(c.join("|"),"i");var a={};for(var b=0;b<e.length;b++){if(Hilite.style_name_suffix){a[e[b]]=Hilite.style_name+(b+1)}else{a[e[b]]=Hilite.style_name}}var d=function(m){var j=c.exec(m.data);if(j){var n=j[0];var i="";var h=m.splitText(j.index);var g=h.splitText(n.length);var l=m.ownerDocument.createElement("SPAN");m.parentNode.replaceChild(l,h);l.className=a[n.toLowerCase()];l.appendChild(h);return l}else{return m}};Hilite.walkElements(f.childNodes[0],1,d)};Hilite.hilite=function(){var a=Hilite.debug_referrer?Hilite.debug_referrer:document.referrer;var b=null;a=Hilite.decodeReferrer(a);if(a&&((Hilite.elementid&&(b=document.getElementById(Hilite.elementid)))||(b=document.body))){Hilite.hiliteElement(b,a)}};Hilite.walkElements=function(d,f,e){var a=/^(script|style|textarea)/i;var c=0;while(d&&f>0){c++;if(c>=Hilite.max_nodes){var b=function(){Hilite.walkElements(d,f,e)};setTimeout(b,50);return}if(d.nodeType==1){if(!a.test(d.tagName)&&d.childNodes.length>0){d=d.childNodes[0];f++;continue}}else{if(d.nodeType==3){d=e(d)}}if(d.nextSibling){d=d.nextSibling}else{while(f>0){d=d.parentNode;f--;if(d.nextSibling){d=d.nextSibling;break}}}}};if(Hilite.onload){if(window.attachEvent){window.attachEvent("onload",Hilite.hilite)}else{if(window.addEventListener){window.addEventListener("load",Hilite.hilite,false)}else{var __onload=window.onload;window.onload=function(){Hilite.hilite();__onload()}}}};
+
+var mediaUrl = function(resource){
+ return scriptUrl + 'm/' + osqaSkin + '/' + resource;
+};
+
+/*
+ * jQuery i18n plugin
+ * @requires jQuery v1.1 or later
+ *
+ * Examples at: http://recurser.com/articles/2008/02/21/jquery-i18n-translation-plugin/
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Based on 'javascript i18n that almost doesn't suck' by markos
+ * http://markos.gaivo.net/blog/?p=100
+ *
+ * Revision: $Id$
+ * Version: 1.0.0 Feb-10-2008
+ */
+ (function($) {
+/**
+ * i18n provides a mechanism for translating strings using a jscript dictionary.
+ *
+ */
+
+
+/*
+ * i18n property list
+ */
+$.i18n = {
+
+/**
+ * setDictionary()
+ * Initialise the dictionary and translate nodes
+ *
+ * @param property_list i18n_dict : The dictionary to use for translation
+ */
+ setDictionary: function(i18n_dict) {
+ i18n_dict = i18n_dict;
+ },
+
+/**
+ * _()
+ * The actual translation function. Looks the given string up in the
+ * dictionary and returns the translation if one exists. If a translation
+ * is not found, returns the original word
+ *
+ * @param string str : The string to translate
+ * @param property_list params : params for using printf() on the string
+ * @return string : Translated word
+ *
+ */
+ _: function (str, params) {
+ var transl = str;
+ if (i18n_dict&& i18n_dict[str]) {
+ transl = i18n_dict[str];
+ }
+ return this.printf(transl, params);
+ },
+
+/**
+ * toEntity()
+ * Change non-ASCII characters to entity representation
+ *
+ * @param string str : The string to transform
+ * @return string result : Original string with non-ASCII content converted to entities
+ *
+ */
+ toEntity: function (str) {
+ var result = '';
+ for (var i=0;i<str.length; i++) {
+ if (str.charCodeAt(i) > 128)
+ result += "&#"+str.charCodeAt(i)+";";
+ else
+ result += str.charAt(i);
+ }
+ return result;
+ },
+
+/**
+ * stripStr()
+ *
+ * @param string str : The string to strip
+ * @return string result : Stripped string
+ *
+ */
+ stripStr: function(str) {
+ return str.replace(/^\s*/, "").replace(/\s*$/, "");
+ },
+
+/**
+ * stripStrML()
+ *
+ * @param string str : The multi-line string to strip
+ * @return string result : Stripped string
+ *
+ */
+ stripStrML: function(str) {
+ // Split because m flag doesn't exist before JS1.5 and we need to
+ // strip newlines anyway
+ var parts = str.split('\n');
+ for (var i=0; i<parts.length; i++)
+ parts[i] = stripStr(parts[i]);
+
+ // Don't join with empty strings, because it "concats" words
+ // And strip again
+ return stripStr(parts.join(" "));
+ },
+
+/*
+ * printf()
+ * C-printf like function, which substitutes %s with parameters
+ * given in list. %%s is used to escape %s.
+ *
+ * Doesn't work in IE5.0 (splice)
+ *
+ * @param string S : string to perform printf on.
+ * @param string L : Array of arguments for printf()
+ */
+ printf: function(S, L) {
+ if (!L) return S;
+
+ var nS = "";
+ var tS = S.split("%s");
+
+ for(var i=0; i<L.length; i++) {
+ if (tS[i].lastIndexOf('%') == tS[i].length-1 && i != L.length-1)
+ tS[i] += "s"+tS.splice(i+1,1)[0];
+ nS += tS[i] + L[i];
+ }
+ return nS + tS[tS.length-1];
+ }
+
+};
+
+
+})(jQuery);
+
+
+//var i18nLang;
+var i18nZh = {
+ 'insufficient privilege':'??????????',
+ 'cannot pick own answer as best':'??????????????',
+ 'anonymous users cannot select favorite questions':'?????????????',
+ 'please login':'??????',
+ 'anonymous users cannot vote':'????????',
+ '>15 points requried to upvote':'??+15?????????',
+ '>100 points required to downvote':'??+100?????????',
+ 'please see': '??',
+ 'cannot vote for own posts':'??????????',
+ 'daily vote cap exhausted':'????????????????',
+ 'cannot revoke old vote':'??????????????',
+ 'please confirm offensive':"??????????????????????",
+ 'anonymous users cannot flag offensive posts':'???????????',
+ 'cannot flag message as offensive twice':'???????',
+ 'flag offensive cap exhausted':'?????????????5?\91??\92???',
+ 'need >15 points to report spam':"??+15??????\91???\92?",
+ 'confirm delete':"?????/????????",
+ 'anonymous users cannot delete/undelete':"???????????????",
+ 'post recovered':"?????????????",
+ 'post deleted':"????????????",
+ 'add comment':'????',
+ 'community karma points':'????',
+ 'to comment, need':'????',
+ 'delete this comment':'?????',
+ 'hide comments':"????",
+ 'add a comment':"????",
+ 'comments':"??",
+ 'confirm delete comment':"?????????",
+ 'characters':'??',
+ 'can write':'???',
+ 'click to close':'???????',
+ 'loading...':'???...',
+ 'tags cannot be empty':'???????',
+ 'tablimits info':"??5????????????20????",
+ 'content cannot be empty':'???????',
+ 'content minchars': '????? {0} ???',
+ 'please enter title':'??????',
+ 'title minchars':"????? {0} ???",
+ 'delete':'??',
+ 'undelete': '??',
+ 'bold':'??',
+ 'italic':'??',
+ 'link':'???',
+ 'quote':'??',
+ 'preformatted text':'??',
+ 'image':'??',
+ 'numbered list':'??????',
+ 'bulleted list':'??????',
+ 'heading':'??',
+ 'horizontal bar':'???',
+ 'undo':'??',
+ 'redo':'??',
+ 'enter image url':'<b>??????</b></p><p>???<br />http://www.example.com/image.jpg \"????\"',
+ 'enter url':'<b>??Web??</b></p><p>???<br />http://www.cnprog.com/ \"????\"</p>"',
+ 'upload image':'?????????'
+};
+
+var i18nEn = {
+ 'need >15 points to report spam':'need >15 points to report spam ',
+ '>15 points requried to upvote':'>15 points required to upvote ',
+ 'tags cannot be empty':'please enter at least one tag',
+ 'anonymous users cannot vote':'sorry, anonymous users cannot vote ',
+ 'anonymous users cannot select favorite questions':'sorry, anonymous users cannot select favorite questions ',
+ 'to comment, need': '(to comment other people\'s posts, karma ',
+ 'please see':'please see ',
+ 'community karma points':' or more is necessary) - ',
+ 'upload image':'Upload image:',
+ 'enter image url':'enter URL of the image, e.g. http://www.example.com/image.jpg \"image title\"',
+ 'enter url':'enter Web address, e.g. http://www.example.com \"page title\"',
+ 'daily vote cap exhausted':'sorry, you\'ve used up todays vote cap',
+ 'cannot pick own answer as best':'sorry, you cannot accept your own answer',
+ 'cannot revoke old vote':'sorry, older votes cannot be revoked',
+ 'please confirm offensive':'are you sure this post is offensive, contains spam, advertising, malicious remarks, etc.?',
+ 'flag offensive cap exhausted':'sorry, you\'ve used up todays cap of flagging offensive messages ',
+ 'confirm delete':'are you sure you want to delete this?',
+ 'anonymous users cannot delete/undelete':'sorry, anonymous users cannot delete or undelete posts',
+ 'post recovered':'your post is now restored!',
+ 'post deleted':'your post has been deleted',
+ 'confirm delete comment':'do you really want to delete this comment?',
+ 'can write':'have ',
+ 'tablimits info':'up to 5 tags, no more than 20 characters each',
+ 'content minchars': 'please enter more than {0} characters',
+ 'title minchars':"please enter at least {0} characters",
+ 'characters':'characters left',
+ 'cannot vote for own posts':'sorry, you cannot vote for your own posts',
+ 'cannot flag message as offensive twice':'cannot flag message as offensive twice ',
+ '>100 points required to downvote':'>100 points required to downvote '
+};
+
+var i18nEs = {
+ 'insufficient privilege':'privilegio insuficiente',
+ 'cannot pick own answer as best':'no puede escoger su propia respuesta como la mejor',
+ 'anonymous users cannot select favorite questions':'usuarios anonimos no pueden seleccionar',
+ 'please login':'por favor inicie sesión',
+ 'anonymous users cannot vote':'usuarios anónimos no pueden votar',
+ '>15 points requried to upvote': '>15 puntos requeridos para votar positivamente',
+ '>100 points required to downvote':'>100 puntos requeridos para votar negativamente',
+ 'please see': 'por favor vea',
+ 'cannot vote for own posts':'no se puede votar por sus propias publicaciones',
+ 'daily vote cap exhausted':'cuota de votos diarios excedida',
+ 'cannot revoke old vote':'no puede revocar un voto viejo',
+ 'please confirm offensive':"por favor confirme ofensiva",
+ 'anonymous users cannot flag offensive posts':'usuarios anónimos no pueden marcar publicaciones como ofensivas',
+ 'cannot flag message as offensive twice':'no puede marcar mensaje como ofensivo dos veces',
+ 'flag offensive cap exhausted':'cuota para marcar ofensivas ha sido excedida',
+ 'need >15 points to report spam':"necesita >15 puntos para reportar spam",
+ 'confirm delete':"¿Está seguro que desea borrar esto?",
+ 'anonymous users cannot delete/undelete':"usuarios anónimos no pueden borrar o recuperar publicaciones",
+ 'post recovered':"publicación recuperada",
+ 'post deleted':"publicación borrada?",
+ 'add comment':'agregar comentario',
+ 'community karma points':'reputación comunitaria',
+ 'to comment, need':'para comentar, necesita reputación',
+ 'delete this comment':'borrar este comentario',
+ 'hide comments':"ocultar comentarios",
+ 'add a comment':"agregar comentarios",
+ 'comments':"comentarios",
+ 'confirm delete comment':"¿Realmente desea borrar este comentario?",
+ 'characters':'caracteres faltantes',
+ 'can write':'tiene ',
+ 'click to close':'haga click para cerrar',
+ 'loading...':'cargando...',
+ 'tags cannot be empty':'las etiquetas no pueden estar vacías',
+ 'tablimits info':"hasta 5 etiquetas de no mas de 20 caracteres cada una",
+ 'content cannot be empty':'el contenido no puede estar vacío',
+ 'content minchars': 'por favor introduzca mas de {0} caracteres',
+ 'please enter title':'por favor ingrese un título',
+ 'title minchars':"por favor introduzca al menos {0} caracteres",
+ 'delete':'borrar',
+ 'undelete': 'recuperar',
+ 'bold': 'negrita',
+ 'italic':'cursiva',
+ 'link':'enlace',
+ 'quote':'citar',
+ 'preformatted text':'texto preformateado',
+ 'image':'imagen',
+ 'numbered list':'lista numerada',
+ 'bulleted list':'lista no numerada',
+ 'heading':'??',
+ 'horizontal bar':'barra horizontal',
+ 'undo':'deshacer',
+ 'redo':'rehacer',
+ 'enter image url':'introduzca la URL de la imagen, por ejemplo?<br />http://www.example.com/image.jpg \"titulo de imagen\"',
+ 'enter url':'introduzca direcciones web, ejemplo?<br />http://www.cnprog.com/ \"titulo del enlace\"</p>"',
+ 'upload image':'cargar imagen?',
+ 'questions/' : 'preguntas/',
+ 'vote/' : 'votar/'
+};
+
+var i18n = {
+ 'en':i18nEn,
+ 'zh_CN':i18nZh,
+ 'es':i18nEs
+};
+
+var i18n_dict = i18n[i18nLang];
+
+/*
+ jQuery TextAreaResizer plugin
+ Created on 17th January 2008 by Ryan O'Dell
+ Version 1.0.4
+*/(function($){var textarea,staticOffset;var iLastMousePos=0;var iMin=32;var grip;$.fn.TextAreaResizer=function(){return this.each(function(){textarea=$(this).addClass('processed'),staticOffset=null;$(this).wrap('<div class="resizable-textarea"><span></span></div>').parent().append($('<div class="grippie"></div>').bind("mousedown",{el:this},startDrag));var grippie=$('div.grippie',$(this).parent())[0];grippie.style.marginRight=(grippie.offsetWidth-$(this)[0].offsetWidth)+'px'})};function startDrag(e){textarea=$(e.data.el);textarea.blur();iLastMousePos=mousePosition(e).y;staticOffset=textarea.height()-iLastMousePos;textarea.css('opacity',0.25);$(document).mousemove(performDrag).mouseup(endDrag);return false}function performDrag(e){var iThisMousePos=mousePosition(e).y;var iMousePos=staticOffset+iThisMousePos;if(iLastMousePos>=(iThisMousePos)){iMousePos-=5}iLastMousePos=iThisMousePos;iMousePos=Math.max(iMin,iMousePos);textarea.height(iMousePos+'px');if(iMousePos<iMin){endDrag(e)}return false}function endDrag(e){$(document).unbind('mousemove',performDrag).unbind('mouseup',endDrag);textarea.css('opacity',1);textarea.focus();textarea=null;staticOffset=null;iLastMousePos=0}function mousePosition(e){return{x:e.clientX+document.documentElement.scrollLeft,y:e.clientY+document.documentElement.scrollTop}}})(jQuery);
+/*
+ * Autocomplete - jQuery plugin 1.0.3
+ *
+ * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){y.preventDefault();w=true;return false}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multipleSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:""))}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);o=a("<ul/>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass(i.ACTIVE);g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li/>").html(e.highlight(w,m)).addClass(v%2==0?"ac_even":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){o.bgiframe()}}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},emptyList:function(){o&&o.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);
+
+var notify = function() {
+ var visible = false;
+ return {
+ show: function(html) {
+ if (html) {
+ $("body").css("margin-top", "2.2em");
+ $(".notify span").html(html);
+ }
+ $(".notify").fadeIn("slow");
+ visible = true;
+ },
+ close: function(doPostback) {
+ $(".notify").fadeOut("fast");
+ $("body").css("margin-top", "0");
+ visible = false;
+ },
+ isVisible: function() { return visible; }
+ };
+} ();
+
+/*
+ * jQuery outside events - v1.1 - 3/16/2010
+ * http://benalman.com/projects/jquery-outside-events-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,c,b){$.map("click dblclick mousemove mousedown mouseup mouseover mouseout change select submit keydown keypress keyup".split(" "),function(d){a(d)});a("focusin","focus"+b);a("focusout","blur"+b);$.addOutsideEvent=a;function a(g,e){e=e||g+b;var d=$(),h=g+"."+e+"-special-event";$.event.special[e]={setup:function(){d=d.add(this);if(d.length===1){$(c).bind(h,f)}},teardown:function(){d=d.not(this);if(d.length===0){$(c).unbind(h)}},add:function(i){var j=i.handler;i.handler=function(l,k){l.target=k;j.apply(this,arguments)}}};function f(i){$(d).each(function(){var j=$(this);if(this!==i.target&&!j.has(i.target).length){j.triggerHandler(e,[i.target])}})}}})(jQuery,document,"outside");
+
+$(document).ready( function(){
+ pickedTags().init();
+
+ $('input#bnewaccount').click(function() {
+ $('#bnewaccount').disabled=true;
+ });
+});
+
+function yourWorkWillBeLost(e) {
+ if(browserTester('chrome')) {
+ return "Are you sure you want to leave? Your work will be lost.";
+ } else if(browserTester('safari')) {
+ return "Are you sure you want to leave? Your work will be lost.";
+ } else {
+ if(!e) e = window.event;
+ e.cancelBubble = true;
+ e.returnValue = 'If you leave, your work will be lost.';
+
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ return e;
+ }
+}
+
+function browserTester(browserString) {
+ return navigator.userAgent.toLowerCase().indexOf(browserString) > -1;
+}
+
+// Add missing IE functionality
+if (!window.addEventListener) {
+ if (window.attachEvent) {
+ window.addEventListener = function (type, listener, useCapture) {
+ window.attachEvent('on' + type, listener);
+ };
+ window.removeEventListener = function (type, listener, useCapture) {
+ window.detachEvent('on' + type, listener);
+ };
+ } else {
+ window.addEventListener = function (type, listener, useCapture) {
+ window['on' + type] = listener;
+ };
+ window.removeEventListener = function (type, listener, useCapture) {
+ window['on' + type] = null;
+ };
+ }
+}
-/* Miniatury */\r
-.thumbdiv {\r
- float:left; \r
- position:relative;\r
-}\r
-.thumbdiv .title {\r
- position:absolute;\r
- padding:2px;\r
- font-size:1.0em;\r
- color:#fff;\r
- background:#000;\r
- border-top:solid 1px #000;\r
- opacity:0.8;\r
- bottom:14px;\r
- left:8px;\r
- right:9px;\r
-}\r
-/* VIEWBOX */\r
-#viewbox {\r
- position:fixed;\r
- height:100%;\r
- width:100%; \r
- top:0;\r
- left:0;\r
- background:#383739;\r
- z-index:2190; \r
- overflow:auto;\r
-} \r
-.vb_wrap {\r
- position:absolute; \r
- padding:10px;\r
- height:20px;\r
- width:20px; \r
- background-image:url(../images/viewbox/ViewBox_bg.png);\r
- background-color:#0f0e0e;\r
- overflow:visible; \r
- z-index:2200;\r
- margin:0 auto;\r
- top:0; \r
- left:0;\r
- border-radius:10px;\r
- box-shadow: 4px 4px 7px #000;\r
-} \r
-.vb_wrap .content {\r
- position:relative;\r
- overflow:visible;\r
-}\r
-.vb_wrap .number {\r
- position:absolute;\r
- top:-32px;\r
- left:1px;\r
- font-size:0.9em;\r
- color:#0c0c0c;\r
-} \r
-.vb_wrap .close {\r
- position:absolute; \r
- top:-40px;\r
- right:-7px;\r
- background:url(../images/viewbox/viewbox_close.png) top left no-repeat;\r
- height:30px;\r
- width:30px;\r
-}\r
-* html .vb_wrap .close {\r
- top:-26px;\r
- right:7px;\r
-}\r
-.vb_wrap .next {\r
- position:absolute; \r
- right:-60px;\r
- background:url(../images/viewbox/ViewBox_next.png) top left no-repeat;\r
- height:50px;\r
- width:50px;\r
- z-index:2190;\r
-}\r
-.vb_wrap .prev {\r
- position:absolute; \r
- left:-59px;\r
- background:url(../images/viewbox/ViewBox_prev.png) top right no-repeat;\r
- height:50px;\r
- width:50px;\r
- z-index:2190;\r
-}\r
-.vb_wrap .close a, .vb_wrap .next a, .vb_wrap .prev a {\r
- display:block;\r
- height:100%;\r
- width:100%;\r
- text-indent:-777em;\r
- outline:none;\r
-}\r
-.vb_wrap h1 {\r
- margin:5px 0px 8px;\r
- padding-bottom:3px;\r
- letter-spacing:1.3px; \r
- font-family:Arial, Helvetica, sans-serif;\r
- font-size:0.9em;\r
- color:#cdcdcd;\r
- border-bottom:solid 1px #7e7e7e;\r
- \r
-}\r
-.vb_wrap p { \r
- font-family:Arial, Helvetica, sans-serif;\r
- font-size:0.8em;\r
- text-align:justify;\r
- color:#e5e5e5;\r
-}\r
-.vb_wrap .text {\r
- position:absolute;\r
- background: url(../images/viewbox/ViewBox_bg.png) top left repeat;\r
- border-top:solid 1px #121212;\r
- bottom:0; left:0;\r
- padding:5px;\r
- width:99%; \r
- z-index:2110;\r
-}\r
-* html .vb_wrap .text {\r
- background-image:none;\r
- background-color:#0f0e0e;\r
-}\r
-.vb_wrap .image {\r
- z-index:2220;\r
-}\r
-.vb_wrap .text h1 {\r
- margin:2px; \r
- padding:1px;\r
- color:#919191;\r
- z-index:2230;\r
-}\r
-.vb_wrap .text .description {\r
- position:relative;\r
- bottom:0px; \r
- left:0px;\r
- padding:2px 2px;\r
- font-family:Arial, Helvetica, sans-serif;\r
- font-size:0.8em;\r
- z-index:2260;\r
- color:#949494; \r
-}\r
+/* Miniatury */
+.thumbdiv {
+ float:left;
+ position:relative;
+}
+.thumbdiv .title {
+ position:absolute;
+ padding:2px;
+ font-size:1.0em;
+ color:#fff;
+ background:#000;
+ border-top:solid 1px #000;
+ opacity:0.8;
+ bottom:14px;
+ left:8px;
+ right:9px;
+}
+/* VIEWBOX */
+#viewbox {
+ position:fixed;
+ height:100%;
+ width:100%;
+ top:0;
+ left:0;
+ background:#383739;
+ z-index:2190;
+ overflow:auto;
+}
+.vb_wrap {
+ position:absolute;
+ padding:10px;
+ height:20px;
+ width:20px;
+ background-image:url(../images/viewbox/ViewBox_bg.png);
+ background-color:#0f0e0e;
+ overflow:visible;
+ z-index:2200;
+ margin:0 auto;
+ top:0;
+ left:0;
+ border-radius:10px;
+ box-shadow: 4px 4px 7px #000;
+}
+.vb_wrap .content {
+ position:relative;
+ overflow:visible;
+}
+.vb_wrap .number {
+ position:absolute;
+ top:-32px;
+ left:1px;
+ font-size:0.9em;
+ color:#0c0c0c;
+}
+.vb_wrap .close {
+ position:absolute;
+ top:-40px;
+ right:-7px;
+ background:url(../images/viewbox/viewbox_close.png) top left no-repeat;
+ height:30px;
+ width:30px;
+}
+* html .vb_wrap .close {
+ top:-26px;
+ right:7px;
+}
+.vb_wrap .next {
+ position:absolute;
+ right:-60px;
+ background:url(../images/viewbox/ViewBox_next.png) top left no-repeat;
+ height:50px;
+ width:50px;
+ z-index:2190;
+}
+.vb_wrap .prev {
+ position:absolute;
+ left:-59px;
+ background:url(../images/viewbox/ViewBox_prev.png) top right no-repeat;
+ height:50px;
+ width:50px;
+ z-index:2190;
+}
+.vb_wrap .close a, .vb_wrap .next a, .vb_wrap .prev a {
+ display:block;
+ height:100%;
+ width:100%;
+ text-indent:-777em;
+ outline:none;
+}
+.vb_wrap h1 {
+ margin:5px 0px 8px;
+ padding-bottom:3px;
+ letter-spacing:1.3px;
+ font-family:Arial, Helvetica, sans-serif;
+ font-size:0.9em;
+ color:#cdcdcd;
+ border-bottom:solid 1px #7e7e7e;
+
+}
+.vb_wrap p {
+ font-family:Arial, Helvetica, sans-serif;
+ font-size:0.8em;
+ text-align:justify;
+ color:#e5e5e5;
+}
+.vb_wrap .text {
+ position:absolute;
+ background: url(../images/viewbox/ViewBox_bg.png) top left repeat;
+ border-top:solid 1px #121212;
+ bottom:0; left:0;
+ padding:5px;
+ width:99%;
+ z-index:2110;
+}
+* html .vb_wrap .text {
+ background-image:none;
+ background-color:#0f0e0e;
+}
+.vb_wrap .image {
+ z-index:2220;
+}
+.vb_wrap .text h1 {
+ margin:2px;
+ padding:1px;
+ color:#919191;
+ z-index:2230;
+}
+.vb_wrap .text .description {
+ position:relative;
+ bottom:0px;
+ left:0px;
+ padding:2px 2px;
+ font-family:Arial, Helvetica, sans-serif;
+ font-size:0.8em;
+ z-index:2260;
+ color:#949494;
+}
{% load i18n %}
{% block title %}{% trans "Not logged in" %}{% endblock %}
{% block meta %}
- <!-- <meta http-equiv="refresh" content="5;url={% url auth_signin %}"> -->
+ <!-- <meta http-equiv="refresh" content="5;url={% url "auth_signin" %}"> -->
{% endblock %}
{% block forestyle%}
<style type="text/css">
}, 800);
window.setTimeout(function() {
- window.location = "{% url auth_signin %}";
+ window.location = "{% url "auth_signin" %}";
}, 5000);
});
</p>
<p>
{% trans "If you're not automatically redirected in 5 seconds, please click" %}
- <a href="{% url auth_signin %}">{% trans "here" %}</a>.
+ <a href="{% url "auth_signin" %}">{% trans "here" %}</a>.
</p>
</div>
</div>
<li>{% trans "you followed a link on an email, but you're currently logged in as another user;" %}</li>
<li>{% trans "there are errors in the url, please confirm it;" %}</li>
<li>{% trans "if you believe you shouldn't bee seeing this error, please" %}
- <a href="{% if settings.CONTACT_URL %}{{ settings.CONTACT_URL }}{% else %}{% url feedback %}{% endif %}" target="_blank">
+ <a href="{% if settings.CONTACT_URL %}{{ settings.CONTACT_URL }}{% else %}{% url "feedback" %}{% endif %}" target="_blank">
{% trans "report this problem" %}
</a>
</li>
</ul>
</div>
<ul>
- <li><a href="{% url index %}">{% trans "to home page" %} »</a></li>
- <li><a href="{% url questions %}">{% trans "see all questions" %} »</a></li>
- <li><a href="{% url tags %}">{% trans "see all tags" %} »</a></li>
+ <li><a href="{% url "index" %}">{% trans "to home page" %} »</a></li>
+ <li><a href="{% url "questions" %}">{% trans "see all questions" %} »</a></li>
+ <li><a href="{% url "tags" %}">{% trans "see all tags" %} »</a></li>
</ul>
</div>
<li>{% trans "this question or answer has been deleted;" %}</li>
<li>{% trans "url has error - please check it;" %}</li>
<li>{% trans "if you believe this error 404 should not have occurred, please" %}
- <a href="{% if settings.CONTACT_URL %}{{ settings.CONTACT_URL }}{% else %}{% url feedback %}{% endif %}">{% trans "report this problem" %}</a></li>
+ <a href="{% if settings.CONTACT_URL %}{{ settings.CONTACT_URL }}{% else %}{% url "feedback" %}{% endif %}">{% trans "report this problem" %}</a></li>
</ul>
</div>
<script type="text/javascript">
<script type="text/javascript" src="http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script>
<ul>
<li><a href="#" id="linkPrevious">{% trans "back to previous page" %} »</a></li>
- <li><a href="{% url questions %}">{% trans "see all questions" %} »</a></li>
- <li><a href="{% url tags %}">{% trans "see all tags" %} »</a></li>
+ <li><a href="{% url "questions" %}">{% trans "see all questions" %} »</a></li>
+ <li><a href="{% url "tags" %}">{% trans "see all tags" %} »</a></li>
</ul>
</div>
{% trans "please report the error to the site administrators if you wish" %}
<ul>
<li><a href="#" id="linkPrevious">{% trans "back to previous page" %}</a></li>
- <li><a href="{% url questions %}">{% trans "see latest questions" %}</a></li>
- <li><a href="{% url tags %}">{% trans "see tags" %}</a></li>
+ <li><a href="{% url "questions" %}">{% trans "see latest questions" %}</a></li>
+ <li><a href="{% url "tags" %}">{% trans "see tags" %}</a></li>
</ul>
</div>
{% endif %}
<dl class="list-item">
- <dt>» <a href="{% url user_changepw %}">{% trans "Change password" %}</a></dt>
+ <dt>» <a href="{% url "user_changepw" %}">{% trans "Change password" %}</a></dt>
<dd>{% trans "Give your account a new password." %}</dd>
{% comment %}
- <dt>» <a href="{% url user_changeemail %}">{% trans "Change email " %}</a></dt>
+ <dt>» <a href="{% url "user_changeemail" %}">{% trans "Change email " %}</a></dt>
<dd>{% trans "Add or update the email address associated with your account." %}</dd>
- <dt>» <a href="{% url user_changeopenid %}">{% trans "Change OpenID" %}</a></dt>
+ <dt>» <a href="{% url "user_changeopenid" %}">{% trans "Change OpenID" %}</a></dt>
<dd>{% trans "Change openid associated to your account" %}</dd>
- <dt>» <a href="{% url user_delete %}">{% trans "Delete account" %}</a></dt>
+ <dt>» <a href="{% url "user_delete" %}">{% trans "Delete account" %}</a></dt>
<dd>{% trans "Erase your username and all your data from website" %}</dd>
{% endcomment %}
</dl>
</div>
<div id="main-body" class="ask-body">
<div id="askform">
- <form id="fmedit" action="{% url edit_answer answer.id %}" method="post">
+ <form id="fmedit" action="{% url "edit_answer" answer.id %}" method="post">
{% csrf_token %}
<label for="id_revision" ><strong>{% trans "revision" %}:</strong></label> <br/>
{% if revision_form.revision.errors %}{{ revision_form.revision.errors.as_ul }}{% endif %}
</li>
</ul>
<p class='info-box-follow-up-links'>
- <a href="{% url faq %}" target="_blank" title="{% trans "see frequently asked questions" %}">faq »</a>
+ <a href="{% url "faq" %}" target="_blank" title="{% trans "see frequently asked questions" %}">faq »</a>
</p>
</div>
</div>
$('#editor').TextAreaResizer();
//toggle preview of editor
- //todo remove copy-paste
+ //todo remove copy-paste
var display = true;
var txt = "[{% trans "hide preview" %}]";
$('#pre-collapse').text(txt);
});
//Tags autocomplete action
- $("#id_tags").autocomplete("{% url matching_tags %}", {
+ $("#id_tags").autocomplete('{% url "matching_tags" %}', {
minChars: 1,
- matchContains: true,
+ matchContains: true,
max: 10,
multiple: true,
multipleSeparator: " ",
scroll: true,
scrollHeight: 300,
-
- /*
- formatItem: function(row, i, max) {
- return row.n + " ("+ row.c +")";
- },
- formatResult: function(row, i, max){
- return row.n;
- }
- */
-
formatItem: function(row, i, max, value) {
return row[1] + " (" + row[2] + ")";
},
}
window.addEventListener('beforeunload', beforeUnload, true);
- var related_questions_url = "{% url related_questions %}";
+ var related_questions_url = '{% url "related_questions" %}';
</script>
<script src="{% media "/media/js/osqa.ask.js" %}" type="text/javascript"></script>
{% endblock %}
{% block content %}
<div id="main-bar" class="headNormal">
- {% trans "Ask a question" %}
+ {% trans "Ask a question" %}
</div>
<div id="main-body" class="ask-body">
<div id="askform">
<form id="fmask" action="" method="post" accept-charset="utf-8">
{% csrf_token %}
- {% if not request.user.is_authenticated %}
+ {% if not request.user.is_authenticated %}
<div class="message">
<span class="strong big">{% trans "You are welcome to start submitting your question anonymously." %}</span>
<p>{% blocktrans %}
{% if not request.user.email_valid_and_can_ask %}
<div class="message">
{% blocktrans %}Remember, your question will not be published until you validate your email.{% endblocktrans %}
- <a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>
+ <a href="{% url "send_validation_email" %}">{% trans "Send me a validation link." %}</a>
</div>
{% endif %}
- {% endif %}
+ {% endif %}
<div class="form-item">
<label for="id_title" ><strong>{{ form.title.label_tag }}:</strong></label> <span class="form-error"></span><br/>
{{ form.title }} {{ form.title.errors }}
<p class="message">{% blocktrans %}These are the external authentication providers currently associated with your account.{% endblocktrans %}</p>
<div>
{% for key in auth_keys %}
- <p>{{ key.name }} (<a href="{% url user_remove_external_provider id=key.id %}">{% trans "remove" %}</a>)</p>
+ <p>{{ key.name }} (<a href="{% url "user_remove_external_provider" id=key.id %}">{% trans "remove" %}</a>)</p>
{% endfor %}
</div>
{% endif %}
<p class="message">{% blocktrans %}You currently have no external authentication provider associated with your account.{% endblocktrans %}</p>
{% endif %}
{% ifequal view_user request.user %}
- <input type="button" class="submit" value="{% trans "Add new provider" %}" onclick="window.location='{% url user_add_external_provider %}'" />
+ <input type="button" class="submit" value="{% trans "Add new provider" %}" onclick="window.location='{% url "user_add_external_provider" %}'" />
{% endifequal %}
{% if allow_local_auth %}
{% if has_password %}
{% comment %}<!-- this form associates openID with an existing password-protected account, not yet functional -->
{% if form2 %}
<div class="login" style="display:none">
- <form name="fverify" action="{% url user_register %}" method="POST">
+ <form name="fverify" action="{% url "user_register" %}" method="POST">
{% csrf_token %}
{{ form2.next }}
<fieldset style="padding:10px">
<!--todo double check translation from chinese 确认 = "Register" -->
<div class="submit-row">
<input type="submit" class="submit" name="bverify" value="{% trans "Register" %}"/>
- <a href="{% url user_sendpw %}">{% trans "Forgot your password?" %}</a>
+ <a href="{% url "user_sendpw" %}">{% trans "Forgot your password?" %}</a>
</div>
</fieldset>
</form>
-{% extends "base.html" %}\r
-\r
-{% load i18n %}\r
-{% load extra_tags %}\r
-\r
-{% block title %}{% spaceless %}{% trans "Login" %}{% endspaceless %}{% endblock %}\r
- \r
-{% block forejs %}\r
- <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/auth.css" %}"/>\r
- {% for provider in all_providers %}\r
- {% for location in provider.extra_css %}\r
- <link rel="stylesheet" type="text/css" media="screen" href="{{ location }}"/>\r
- {% endfor %}\r
- {% endfor %}\r
-{% endblock %}\r
-\r
-{% block content %}\r
- {% for provider in all_providers %}\r
- {% if provider.pre_code %}\r
- {{ provider.pre_code|safe }}\r
- {% endif %}\r
- {% endfor %}\r
- <div class="headNormal">\r
- {% trans "User login" %}\r
- </div>\r
- {% if msg %}\r
- <p class="error">{{ msg }}</p>\r
- {% endif %}\r
- {% for provider in top_stackitem_providers %}\r
- <form class="signin_form" method="POST" action="{% url auth_provider_signin provider=provider.id %}" accept-charset="utf-8">\r
- {% csrf_token %}\r
- {% include provider.stack_item_template %}\r
- <input type="hidden" class="validate_email" name="validate_email" value="yes" />\r
- </form>\r
- {% endfor %}\r
- {% if top_stackitem_providers %}\r
- <h3 class="or_label">{% trans 'Or...' %}</h3>\r
- {% endif %}\r
- <div style="width:600px;float:left;margin-bottom:5px;">\r
- {% blocktrans %}\r
- External login services use <b><a href="http://openid.net/">OpenID</a></b> technology, where your password always stays confidential between\r
- you and your login provider and you don't have to remember another one.\r
- {% endblocktrans %}\r
- </div>\r
- {% if request.user.is_anonymous %}\r
- <div style="width:600px;float:left;margin-bottom:5px;">\r
- <input type="checkbox" checked="checked" id="validate_email" />\r
- {% trans "Validate my email after I login." %}\r
- </div>\r
- {% endif %}\r
- <div id="bigicon_providers">\r
- {% for provider in bigicon_providers %}\r
- <div class="provider_logo big" name="{{ provider.id }}">\r
- <div class="inner">\r
- {% ifequal provider.type "DIRECT" %}\r
- <a class="provider_direct" href="{% url auth_provider_signin provider=provider.id %}">\r
- <img src="{% media provider.icon %}" />\r
- </a>\r
- {% endifequal %}\r
- {% ifequal provider.type "CUSTOM" %}\r
- {% include provider.code_template %}\r
- {% endifequal %}\r
- {% ifequal provider.type "SIMPLE_FORM" %}\r
- <img alt="{{ provider.simple_form_context.your_what }}" class="simple_form_provider" src="{% media provider.icon %}" />\r
- {% endifequal %}\r
- </div>\r
- </div>\r
- {% endfor %}\r
- </div>\r
- <div id="smallicon_providers">\r
- {% for provider in smallicon_providers %}\r
- <div class="provider_logo small" name="{{ provider.id }}">\r
- <div class="inner">\r
- {% ifequal provider.type "DIRECT" %}\r
- <a class="provider_direct" href="{% url auth_provider_signin provider=provider.id %}">\r
- <img src="{% media provider.icon %}" />\r
- </a>\r
- {% endifequal %}\r
- {% ifequal provider.type "CUSTOM" %}\r
- {% include provider.code_template %}\r
- {% endifequal %}\r
- {% ifequal provider.type "SIMPLE_FORM" %}\r
- <img alt="{{ provider.simple_form_context.your_what }}" class="simple_form_provider" src="{% media provider.icon %}" />\r
- {% endifequal %}\r
- </div>\r
- </div>\r
- {% endfor %}\r
- </div>\r
- <form name="signin_form" id="signin_form" class="signin_form" method="POST" action="">\r
- {% csrf_token %}\r
- <div id="signin_form_slot"></div>\r
- <input type="hidden" class="validate_email" name="validate_email" value="yes" />\r
- </form>\r
- {% for provider in stackitem_providers %}\r
- <h3 class="or_label">{% trans 'Or...' %}</h3>\r
- <form class="signin_form" method="POST" action="{% url auth_provider_signin provider=provider.id %}" accept-charset="utf-8">\r
- {% csrf_token %}\r
- {% include provider.stack_item_template %}\r
- <input type="hidden" class="validate_email" name="validate_email" value="yes" />\r
- </form>\r
- {% endfor %}\r
- <h3 class="or_label">{% trans 'Or...' %}</h3>\r
- <form name="signin_form" id="dummy_form_unused" class="signin_form" method="POST" action="">\r
- {% csrf_token %}\r
- <fieldset>\r
- {% trans 'Click' %} <a href="{% url auth_request_tempsignin %}">{% trans 'here' %}</a> {% trans "if you're having trouble signing in." %}\r
- </fieldset>\r
- </form>\r
- <script type="text/html" id="simple_form_template">\r
- <fieldset id="slot_form">\r
- <p id="provider_name_slot">{% trans 'Enter your ' %}%%YOUR_WHAT%%</p>\r
- <div><p><span></span>\r
- <input id="input_field" type="text" name="input_field" /><span></span>\r
- <input id="ssignin" name="ssignin" type="submit" value="Login" />\r
- </p></div>\r
- <input type="hidden" class="validate_email" name="validate_email" value="yes" />\r
- </fieldset>\r
- </script>\r
- <script type="text/javascript">\r
- $(function() {\r
- var signin_url = "{% url auth_provider_signin provider='PROVIDER' %}";\r
-\r
- function set_validate_email() {\r
- var validate = $('#validate_email').attr('checked') ? 'yes' : 'no';\r
- $('.validate_email').attr('value', validate);\r
-\r
- $('.provider_direct').each(function() {\r
- var current_url = $(this).attr('href');\r
- if (!/\?validate_email\=(yes|no)$/.test(current_url)) {\r
- current_url += ('?validate_email=' + validate);\r
- } else {\r
- current_url = current_url.replace(/(yes|no)$/, validate);\r
- }\r
-\r
- $(this).attr('href', current_url);\r
- })\r
- }\r
-\r
- $('#validate_email').change(set_validate_email);\r
-\r
- function set_form_action(el) {\r
- var provider = el.parents('.provider_logo').attr('name');\r
- $('#signin_form').attr('action', signin_url.replace('PROVIDER', provider));\r
- }\r
-\r
- $('.provider_logo').click(function() {\r
- $('.provider_logo').removeClass('selected');\r
- $(this).addClass('selected');\r
- });\r
-\r
- $('.simple_form_provider').click(function() {\r
- $('#signin_form_slot').html('');\r
- var new_html = $('#simple_form_template').html()\r
- .replace('%%YOUR_WHAT%%', $(this).attr('alt'));\r
- $('#signin_form_slot').html(new_html);\r
- set_form_action($(this));\r
- set_validate_email();\r
- })\r
-\r
- set_validate_email();\r
- });\r
- </script>\r
-{% endblock %}\r
-\r
-{% block sidebar %}\r
-<div class="boxC">\r
- <h3 class="subtitle">{% trans "Why use OpenID?" %}</h3>\r
- <ul class="list-item">\r
- <li>\r
- {% trans "with openid it is easier" %}\r
- </li>\r
- <li>\r
- {% trans "reuse openid" %}\r
- </li>\r
- <li>\r
- {% trans "openid is widely adopted" %}\r
- </li>\r
- <li>\r
- {% trans "openid is supported open standard" %}\r
- </li>\r
-\r
- </ul>\r
- <p class="info-box-follow-up-links">\r
- <a href="http://openid.net/what/" target="_blank">{% trans "Find out more" %} </a><br/>\r
- <a href="http://openid.net/get/" target="_blank">{% trans "Get OpenID" %} </a>\r
- </p>\r
-</div>\r
-{% endblock%}\r
+{% extends "base.html" %}
+
+{% load i18n %}
+{% load extra_tags %}
+
+{% block title %}{% spaceless %}{% trans "Login" %}{% endspaceless %}{% endblock %}
+
+{% block forejs %}
+ <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/auth.css" %}"/>
+ {% for provider in all_providers %}
+ {% for location in provider.extra_css %}
+ <link rel="stylesheet" type="text/css" media="screen" href="{{ location }}"/>
+ {% endfor %}
+ {% endfor %}
+{% endblock %}
+
+{% block content %}
+ {% for provider in all_providers %}
+ {% if provider.pre_code %}
+ {{ provider.pre_code|safe }}
+ {% endif %}
+ {% endfor %}
+ <div class="headNormal">
+ {% trans "User login" %}
+ </div>
+ {% if msg %}
+ <p class="error">{{ msg }}</p>
+ {% endif %}
+ {% for provider in top_stackitem_providers %}
+ <form class="signin_form" method="POST" action="{% url "auth_provider_signin" provider=provider.id %}" accept-charset="utf-8">
+ {% csrf_token %}
+ {% include provider.stack_item_template %}
+ <input type="hidden" class="validate_email" name="validate_email" value="yes" />
+ </form>
+ {% endfor %}
+ {% if top_stackitem_providers %}
+ <h3 class="or_label">{% trans 'Or...' %}</h3>
+ {% endif %}
+ <div style="width:600px;float:left;margin-bottom:5px;">
+ {% blocktrans %}
+ External login services use <b><a href="http://openid.net/">OpenID</a></b> technology, where your password always stays confidential between
+ you and your login provider and you don't have to remember another one.
+ {% endblocktrans %}
+ </div>
+ {% if request.user.is_anonymous %}
+ <div style="width:600px;float:left;margin-bottom:5px;">
+ <input type="checkbox" checked="checked" id="validate_email" />
+ {% trans "Validate my email after I login." %}
+ </div>
+ {% endif %}
+ <div id="bigicon_providers">
+ {% for provider in bigicon_providers %}
+ <div class="provider_logo big" name="{{ provider.id }}">
+ <div class="inner">
+ {% ifequal provider.type "DIRECT" %}
+ <a class="provider_direct" href="{% url "auth_provider_signin" provider=provider.id %}">
+ <img src="{% media provider.icon %}" />
+ </a>
+ {% endifequal %}
+ {% ifequal provider.type "CUSTOM" %}
+ {% include provider.code_template %}
+ {% endifequal %}
+ {% ifequal provider.type "SIMPLE_FORM" %}
+ <img alt="{{ provider.simple_form_context.your_what }}" class="simple_form_provider" src="{% media provider.icon %}" />
+ {% endifequal %}
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+ <div id="smallicon_providers">
+ {% for provider in smallicon_providers %}
+ <div class="provider_logo small" name="{{ provider.id }}">
+ <div class="inner">
+ {% ifequal provider.type "DIRECT" %}
+ <a class="provider_direct" href="{% url "auth_provider_signin" provider=provider.id %}">
+ <img src="{% media provider.icon %}" />
+ </a>
+ {% endifequal %}
+ {% ifequal provider.type "CUSTOM" %}
+ {% include provider.code_template %}
+ {% endifequal %}
+ {% ifequal provider.type "SIMPLE_FORM" %}
+ <img alt="{{ provider.simple_form_context.your_what }}" class="simple_form_provider" src="{% media provider.icon %}" />
+ {% endifequal %}
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+ <form name="signin_form" id="signin_form" class="signin_form" method="POST" action="">
+ {% csrf_token %}
+ <div id="signin_form_slot"></div>
+ <input type="hidden" class="validate_email" name="validate_email" value="yes" />
+ </form>
+ {% for provider in stackitem_providers %}
+ <h3 class="or_label">{% trans 'Or...' %}</h3>
+ <form class="signin_form" method="POST" action="{% url "auth_provider_signin" provider=provider.id %}" accept-charset="utf-8">
+ {% csrf_token %}
+ {% include provider.stack_item_template %}
+ <input type="hidden" class="validate_email" name="validate_email" value="yes" />
+ </form>
+ {% endfor %}
+ <h3 class="or_label">{% trans 'Or...' %}</h3>
+ <form name="signin_form" id="dummy_form_unused" class="signin_form" method="POST" action="">
+ {% csrf_token %}
+ <fieldset>
+ {% trans 'Click' %} <a href="{% url "auth_request_tempsignin" %}">{% trans 'here' %}</a> {% trans "if you're having trouble signing in." %}
+ </fieldset>
+ </form>
+ <script type="text/html" id="simple_form_template">
+ <fieldset id="slot_form">
+ <p id="provider_name_slot">{% trans 'Enter your ' %}%%YOUR_WHAT%%</p>
+ <div><p><span></span>
+ <input id="input_field" type="text" name="input_field" /><span></span>
+ <input id="ssignin" name="ssignin" type="submit" value="Login" />
+ </p></div>
+ <input type="hidden" class="validate_email" name="validate_email" value="yes" />
+ </fieldset>
+ </script>
+ <script type="text/javascript">
+ $(function() {
+ var signin_url = "{% url "auth_provider_signin" provider='PROVIDER' %}";
+
+ function set_validate_email() {
+ var validate = $('#validate_email').attr('checked') ? 'yes' : 'no';
+ $('.validate_email').attr('value', validate);
+
+ $('.provider_direct').each(function() {
+ var current_url = $(this).attr('href');
+ if (!/\?validate_email\=(yes|no)$/.test(current_url)) {
+ current_url += ('?validate_email=' + validate);
+ } else {
+ current_url = current_url.replace(/(yes|no)$/, validate);
+ }
+
+ $(this).attr('href', current_url);
+ })
+ }
+
+ $('#validate_email').change(set_validate_email);
+
+ function set_form_action(el) {
+ var provider = el.parents('.provider_logo').attr('name');
+ $('#signin_form').attr('action', signin_url.replace('PROVIDER', provider));
+ }
+
+ $('.provider_logo').click(function() {
+ $('.provider_logo').removeClass('selected');
+ $(this).addClass('selected');
+ });
+
+ $('.simple_form_provider').click(function() {
+ $('#signin_form_slot').html('');
+ var new_html = $('#simple_form_template').html()
+ .replace('%%YOUR_WHAT%%', $(this).attr('alt'));
+ $('#signin_form_slot').html(new_html);
+ set_form_action($(this));
+ set_validate_email();
+ })
+
+ set_validate_email();
+ });
+ </script>
+{% endblock %}
+
+{% block sidebar %}
+<div class="boxC">
+ <h3 class="subtitle">{% trans "Why use OpenID?" %}</h3>
+ <ul class="list-item">
+ <li>
+ {% trans "with openid it is easier" %}
+ </li>
+ <li>
+ {% trans "reuse openid" %}
+ </li>
+ <li>
+ {% trans "openid is widely adopted" %}
+ </li>
+ <li>
+ {% trans "openid is supported open standard" %}
+ </li>
+
+ </ul>
+ <p class="info-box-follow-up-links">
+ <a href="http://openid.net/what/" target="_blank">{% trans "Find out more" %} </a><br/>
+ <a href="http://openid.net/get/" target="_blank">{% trans "Get OpenID" %} </a>
+ </p>
+</div>
+{% endblock%}
-{% extends "base.html" %}\r
-\r
-{% load i18n %}\r
-{% block head %}{% endblock %}\r
-{% block title %}{% spaceless %}{% trans "Request temporary login key" %}{% endspaceless %}{% endblock %}\r
-{% block content %}\r
-<div class="headNormal">{% trans "Account: request temporary login key" %}</div>\r
-<p class="message">{% blocktrans %}\r
- If you're experiencing problems accessing your account, or if you forgot your password,\r
- here you can request a temporary login key. Fill out your account email and we'll send you a temporary access link that\r
- will enable you to access your account. This token is valid only once and for a limited period of time.\r
- {% endblocktrans %}</p>\r
-<div class="aligned">\r
- {% if form.errors %}\r
- <ul class="errorlist">\r
- {% for error in form.errors %}\r
- <li>{{ error }}</li>\r
- {% endfor %}\r
- </ul>\r
- {% endif %}\r
- <form action="" method="post" accept-charset="utf-8">\r
- {% csrf_token %}\r
- <ul id="changepw-form" class="form-horizontal-rows">\r
- {{form.as_ul}}\r
- </ul>\r
- <div class="submit-row"><input type="submit" class="submit" value="{% trans "Send link" %}" /></div>\r
- </form>\r
- </div>\r
+{% extends "base.html" %}
+
+{% load i18n %}
+{% block head %}{% endblock %}
+{% block title %}{% spaceless %}{% trans "Request temporary login key" %}{% endspaceless %}{% endblock %}
+{% block content %}
+<div class="headNormal">{% trans "Account: request temporary login key" %}</div>
+<p class="message">{% blocktrans %}
+ If you're experiencing problems accessing your account, or if you forgot your password,
+ here you can request a temporary login key. Fill out your account email and we'll send you a temporary access link that
+ will enable you to access your account. This token is valid only once and for a limited period of time.
+ {% endblocktrans %}</p>
+<div class="aligned">
+ {% if form.errors %}
+ <ul class="errorlist">
+ {% for error in form.errors %}
+ <li>{{ error }}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+ <form action="" method="post" accept-charset="utf-8">
+ {% csrf_token %}
+ <ul id="changepw-form" class="form-horizontal-rows">
+ {{form.as_ul}}
+ </ul>
+ <div class="submit-row"><input type="submit" class="submit" value="{% trans "Send link" %}" /></div>
+ </form>
+ </div>
{% endblock %}
\ No newline at end of file
<p style="{{ p_style }}">{% trans "The following link will help us verify your email address:" %}</p>
- <p style="{{ p_style }}"><a style="{{ a_style }}" href="{% fullurl auth_validate_email user=recipient.id,code=validation_code %}">{% trans "Validate my email address" %}</a></p>
+ <p style="{{ p_style }}"><a style="{{ a_style }}" href="{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}">{% trans "Validate my email address" %}</a></p>
<p style="{{ p_style }}">{% trans "If the above link is not clickable, copy and paste this url into your web browser's address bar:" %}</p>
- <p style="{{ p_style }}">{% fullurl auth_validate_email user=recipient.id,code=validation_code %}</p>
+ <p style="{{ p_style }}">{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}</p>
{% endhtmlcontent %}
{% textcontent notifications/base_text.html %}
{% trans "Copy and paste this url into your web browser's address bar to help us verify your email address:" %}
-{% fullurl auth_validate_email user=recipient.id,code=validation_code %}
+{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}
{% endtextcontent %}
{% endemail %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- base_content.html -->
-{% load i18n extra_tags extra_filters markup ui_registry %}
+{% load i18n extra_tags extra_filters ui_registry %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>{% block after_head_js %}{% endblock %}
<title>{% block fulltitle %}{% block title %}{% endblock %} - {{ settings.APP_SHORT_NAME }}{% endblock %}</title>
<link rel="shortcut icon" href="{{ settings.APP_FAVICON }}" />
<link href="{% media "/media/style/style.css" %}" rel="stylesheet" type="text/css" />
{% if settings.USE_CUSTOM_CSS|or_preview:request %}
- <link href="{% url custom_css %}" rel="stylesheet" type="text/css" />
+ <link href="{% url "custom_css" %}" rel="stylesheet" type="text/css" />
{% endif %}
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" />
<!--[if IE 6]>
cancel: "{% trans "Cancel" %}",
close: "{% trans "Close" %}",
ok: "{% trans "Ok" %}",
- matching_tags_url: "{% url matching_tags %}",
+ matching_tags_url: "{% url "matching_tags" %}",
word: "{% trans "word" %}",
words: "{% trans "words" %}",
character: "{% trans "character" %}",
{{ settings.CUSTOM_HEAD|or_preview:request|safe }}
{% endif %}
{% block forejs %}{% endblock %}
- <link rel="search" type="application/opensearchdescription+xml" href="{% url opensearch %}" title="{{ settings.APP_SHORT_NAME }} Search" />
+ <link rel="search" type="application/opensearchdescription+xml" href="{% url "opensearch" %}" title="{{ settings.APP_SHORT_NAME }} Search" />
{% loadregistry head_content %}{% endloadregistry %}
</head>
<body>
<strong>{{ question.get_question_title }}</strong></a>
</p>
- <form id="fmclose" action="{% url close question.id %}" method="post" >
+ <form id="fmclose" action="{% url "close" question.id %}" method="post" >
{% csrf_token %}
<p>
<strong>{% trans "Reasons" %}:</strong> {{ form.reason }}
{% trans "Give us your feedback!" %}
</div>
<div class="content">
- <form method="post" action="{% url feedback %}" accept-charset="utf-8">
+ <form method="post" action="{% url "feedback" %}" accept-charset="utf-8">
{% csrf_token %}
{% if user.is_authenticated %}
<p class="message">
{% loadregistry footer_links %}<span class="link-separator"> |</span>{% endloadregistry %}
</div>
<p>
- <a href="http://osqa.net" target="_blank" title="OSQA {{ settings.OSQA_VERSION }} ({{ settings.SVN_REVISION }})">
+ <a href="http://osqa.net" target="_blank" title="OSQA {{ settings.OSQA_VERSION }} ({{ settings.VCS_REVISION }})">
powered by OSQA
</a>
</p>
<!-- template header.html -->
-{% load extra_tags ui_registry i18n extra_filters markup %}
+{% load extra_tags ui_registry i18n extra_filters %}
<div id="roof">
<div id="logo">
- <a href="{% url index %}">
+ <a href="{% url "index" %}">
<img src="{{ settings.APP_LOGO }}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/>
</a>
</div>
{% loopregistry page_top_tabs %}{% spaceless %}
<a id="nav_{{ tab_name }}"{% ifequal tab tab_name %} class="on"{% endifequal %} href="{{ tab_url }}" >{{ tab_title }}</a>
{% endspaceless %}{% endloopregistry %}
- <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a>
+ <a id="nav_ask" href="{% url "ask" %}" class="special">{% trans "ask a question" %}</a>
</div>
</div>
<div class="clear"></div>
<div id="searchBar">
- <form action="{% url search %}" method="get">
+ <form action="{% url "search" %}" method="get">
{% csrf_token %}
<div>
<input type="text" class="searchInput" value="{{ keywords }}" name="q" id="keywords" />
-{% extends "questions.html" %}\r
-<!-- index.html -->\r
-{% load general_sidebar_tags %}\r
-{% load question_list_tags %}\r
-{% load i18n %}\r
-{% block fulltitle %}{{ settings.APP_TITLE }}{% endblock %}\r
-{% block sidebar %}\r
- {% if not request.user.is_authenticated %}\r
- {% if settings.SHOW_WELCOME_BOX %}\r
- <div class="boxA">\r
- <h3>{% trans "welcome to " %}{{ settings.APP_SHORT_NAME }}</h3>\r
- <div class="body">\r
- {{ settings.APP_INTRO|safe }}\r
- <div class="more"><a href="{% url about %}">{% trans "about" %} </a></div>\r
- <div class="more"><a href="{% url faq %}">{% trans "faq" %} </a></div>\r
- </div>\r
- </div>\r
- {% endif %}\r
- {% endif %}\r
- {% include "question_list/count.html" %}\r
- {% sidebar_upper %}\r
- {% if request.user.is_authenticated %}\r
- {% tag_selector %}\r
- {% endif %}\r
- {% sidebar_lower %}\r
- {% recent_tags %}\r
- {% recent_awards %}\r
-{% endblock %}\r
-<!-- index.html -->\r
-\r
+{% extends "questions.html" %}
+<!-- index.html -->
+{% load general_sidebar_tags %}
+{% load question_list_tags %}
+{% load i18n %}
+{% block fulltitle %}{{ settings.APP_TITLE }}{% endblock %}
+{% block sidebar %}
+ {% if not request.user.is_authenticated %}
+ {% if settings.SHOW_WELCOME_BOX %}
+ <div class="boxA">
+ <h3>{% trans "welcome to " %}{{ settings.APP_SHORT_NAME }}</h3>
+ <div class="body">
+ {{ settings.APP_INTRO|safe }}
+ <div class="more"><a href="{% url "about" %}">{% trans "about" %} </a></div>
+ <div class="more"><a href="{% url "faq" %}">{% trans "faq" %} </a></div>
+ </div>
+ </div>
+ {% endif %}
+ {% endif %}
+ {% include "question_list/count.html" %}
+ {% sidebar_upper %}
+ {% if request.user.is_authenticated %}
+ {% tag_selector %}
+ {% endif %}
+ {% sidebar_lower %}
+ {% recent_tags %}
+ {% recent_awards %}
+{% endblock %}
+<!-- index.html -->
+
{% block forejs %}
<script type="text/javascript">
$().ready(function(){
- $('#btLogout').bind('click', function(){ window.location.href='{% url user_signout %}?next={{ next }}'; });
+ $('#btLogout').bind('click', function(){ window.location.href='{% url "user_signout" %}?next={{ next }}'; });
});
</script>
{% endblock %}
-{% load i18n %}\r
-\r
-{% if can_accept %}\r
- <a id="accept-answer-{{ answer.id }}" class="ajax-command accept-answer{% if answer.nis.accepted %} on{% endif %}"\r
- title=" {% if answer.nis.accepted %}\r
- {% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}\r
- {% else %}\r
- {% trans "mark this answer as the accepted answer" %}\r
- {% endif %}"\r
- bn:on="{% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}"\r
- bn:off="{% trans "mark this answer as the accepted answer" %}"\r
- href="{% url accept_answer id=answer.id %}" rel="nofollow"> \r
- </a>\r
-{% else %}\r
- {% if answer.nis.accepted %}\r
- <a class="accept-answer on"\r
- title="{% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}"\r
- href="{% url accept_answer id=answer.id %}" rel="nofollow"> \r
- </a>\r
- {% endif %}\r
-{% endif %}\r
-\r
+{% load i18n %}
+
+{% if can_accept %}
+ <a id="accept-answer-{{ answer.id }}" class="ajax-command accept-answer{% if answer.nis.accepted %} on{% endif %}"
+ title=" {% if answer.nis.accepted %}
+ {% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}
+ {% else %}
+ {% trans "mark this answer as the accepted answer" %}
+ {% endif %}"
+ bn:on="{% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}"
+ bn:off="{% trans "mark this answer as the accepted answer" %}"
+ href="{% url "accept_answer" id=answer.id %}" rel="nofollow">
+ </a>
+{% else %}
+ {% if answer.nis.accepted %}
+ <a class="accept-answer on"
+ title="{% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}"
+ href="{% url "accept_answer" id=answer.id %}" rel="nofollow">
+ </a>
+ {% endif %}
+{% endif %}
+
<div class="clear"></div>
<div id="comment-{{ post.id }}-form-container" class="comment-form-container">
{% if can_comment %}
- <form id="comment-{{ post.id }}-form" method="post" action="{% url comment id=post.id %}" accept-charset="utf-8">
+ <form id="comment-{{ post.id }}-form" method="post" action="{% url "comment" id=post.id %}" accept-charset="utf-8">
{% csrf_token %}
<div class="comment-form-widgets-container">
<textarea name="comment" class="commentBox" id="comment"></textarea>
-{% load extra_tags %}\r
-{% load i18n %}\r
-\r
-{% if show_latest_comments_first %}{% include "node/comment_skeleton.html" %}{% endif %}\r
-\r
-<div class="comments-container" id="comments-container-{{ post.id }}">\r
- {% for comment in comments %}\r
- <a name="{{ comment.id }}"></a>\r
- <div class="comment{% if not comment.top_scorer %} not_top_scorer{% endif %}" id="comment-{{comment.id}}">\r
- <div id="post-{{ comment.id }}-score" class="comment-score">{% if comment.score %}{{ comment.score }}{% endif %}</div>\r
- <div class="comment-text">{{ comment.comment }}</div>\r
- <div class="comment-info" id="comment-{{comment.id}}-info">\r
- {% if comment.can_like %}\r
- <a id="post-{{ comment.id }}-upvote" href="{% url like_comment id=comment.id %}"\r
- title="{% trans "I like this comment (click again to cancel)" %}" class="ajax-command comment-like{% if comment.likes %} on{% endif %}"\r
- rel="nofollow"> </a>\r
- {% endif %}\r
- {% if comment.can_edit %}\r
- <a id="comment-{{ comment.id }}-edit" href="{% url node_markdown id=comment.id %}" title="{% trans "Edit comment" %}"\r
- class="comment-edit" rel="nofollow"> </a>\r
- {% endif %}\r
- {% if comment.can_delete %}\r
- <a id="comment-{{ comment.id }}-delete" href="{% url delete_comment id=comment.id %}" title="{% trans "Delete comment" %}"\r
- class="ajax-command comment-delete confirm" rel="nofollow"> </a>\r
- {% endif %}\r
- {% if comment.can_convert %}\r
- <a rel="nofollow" id="comment-{{ comment.id }}-convert" href="{% url convert_comment id=comment.id %}" title="{% trans "Convert comment to answer" %}"\r
- class="ajax-command comment-convert confirm" rel="nofollow"> </a>\r
- <a rel="nofollow" id="comment-{{ comment.id }}-convert-to-question" href="{% url convert_to_question id=comment.id %}?node_type=comment" title="{% trans "Convert comment to question" %}"\r
- class="comment-convert-to-question" rel="nofollow"> </a>\r
- {% endif %}\r
-\r
- {% if comment.additional_controls %}\r
- {{ comment.additional_controls }}\r
- {% endif %}\r
-\r
- <span class="comment-age">({% diff_date comment.added_at %})</span>\r
- <a class="comment-user userinfo" href="{{comment.user.get_profile_url}}">{{comment.user.decorated_name}}</a>\r
- {% if show_gravatar %}{% gravatar comment.user 18 %}{% endif %}\r
- </div>\r
- </div>\r
- {% endfor %}\r
-</div>\r
-<div id="comment-tools-{{ post.id }}" class="comment-tools">\r
- {% ifnotequal showing total %}\r
- <span class="comments-showing">\r
- {% blocktrans %}showing {{ showing }} of {{ total }}{% endblocktrans %}\r
- </span>\r
- <a href="#" class="show-all-comments-link">{% blocktrans %}show {{ more_comments_count }} more comments{% endblocktrans %}</a>\r
- {% endifnotequal %}\r
- {% if can_comment %}\r
- <a href="#" class="add-comment-link">{% trans "add new comment" %}</a>\r
- {% endif %}\r
-</div>\r
-\r
-{% if not show_latest_comments_first %}{% include "node/comment_skeleton.html" %}{% endif %}\r
+{% load extra_tags %}
+{% load i18n %}
+
+{% if show_latest_comments_first %}{% include "node/comment_skeleton.html" %}{% endif %}
+
+<div class="comments-container" id="comments-container-{{ post.id }}">
+ {% for comment in comments %}
+ <a name="{{ comment.id }}"></a>
+ <div class="comment{% if not comment.top_scorer %} not_top_scorer{% endif %}" id="comment-{{comment.id}}">
+ <div id="post-{{ comment.id }}-score" class="comment-score">{% if comment.score %}{{ comment.score }}{% endif %}</div>
+ <div class="comment-text">{{ comment.comment }}</div>
+ <div class="comment-info" id="comment-{{comment.id}}-info">
+ {% if comment.can_like %}
+ <a id="post-{{ comment.id }}-upvote" href="{% url "like_comment" id=comment.id %}"
+ title="{% trans "I like this comment (click again to cancel)" %}" class="ajax-command comment-like{% if comment.likes %} on{% endif %}"
+ rel="nofollow"> </a>
+ {% endif %}
+ {% if comment.can_edit %}
+ <a id="comment-{{ comment.id }}-edit" href="{% url "node_markdown" id=comment.id %}" title="{% trans "Edit comment" %}"
+ class="comment-edit" rel="nofollow"> </a>
+ {% endif %}
+ {% if comment.can_delete %}
+ <a id="comment-{{ comment.id }}-delete" href="{% url "delete_comment" id=comment.id %}" title="{% trans "Delete comment" %}"
+ class="ajax-command comment-delete confirm" rel="nofollow"> </a>
+ {% endif %}
+ {% if comment.can_convert %}
+ <a rel="nofollow" id="comment-{{ comment.id }}-convert" href="{% url "convert_comment" id=comment.id %}" title="{% trans "Convert comment to answer" %}"
+ class="ajax-command comment-convert confirm" rel="nofollow"> </a>
+ <a rel="nofollow" id="comment-{{ comment.id }}-convert-to-question" href="{% url "convert_to_question" id=comment.id %}?node_type=comment" title="{% trans "Convert comment to question" %}"
+ class="comment-convert-to-question" rel="nofollow"> </a>
+ {% endif %}
+
+ {% if comment.additional_controls %}
+ {{ comment.additional_controls }}
+ {% endif %}
+
+ <span class="comment-age">({% diff_date comment.added_at %})</span>
+ <a class="comment-user userinfo" href="{{comment.user.get_profile_url}}">{{comment.user.decorated_name}}</a>
+ {% if show_gravatar %}{% gravatar comment.user 18 %}{% endif %}
+ </div>
+ </div>
+ {% endfor %}
+</div>
+<div id="comment-tools-{{ post.id }}" class="comment-tools">
+ {% ifnotequal showing total %}
+ <span class="comments-showing">
+ {% blocktrans %}showing {{ showing }} of {{ total }}{% endblocktrans %}
+ </span>
+ <a href="#" class="show-all-comments-link">{% blocktrans %}show {{ more_comments_count }} more comments{% endblocktrans %}</a>
+ {% endifnotequal %}
+ {% if can_comment %}
+ <a href="#" class="add-comment-link">{% trans "add new comment" %}</a>
+ {% endif %}
+</div>
+
+{% if not show_latest_comments_first %}{% include "node/comment_skeleton.html" %}{% endif %}
-{% load i18n %}\r
-\r
-<a id="favorite-mark" title="{% trans "mark/unmark this question as favorite (click again to cancel)" %}"\r
- class="ajax-command favorite-mark {% if favorited %} on{% endif %}"\r
- href="{% url mark_favorite id=question.id %}" rel="nofollow"> </a>\r
-<div id="favorite-count" class="favorite-count">\r
- {% if favorite_count %}{{ favorite_count }}{% endif %}\r
-</div>\r
+{% load i18n %}
+
+<a id="favorite-mark" title="{% trans "mark/unmark this question as favorite (click again to cancel)" %}"
+ class="ajax-command favorite-mark {% if favorited %} on{% endif %}"
+ href="{% url "mark_favorite" id=question.id %}" rel="nofollow"> </a>
+<div id="favorite-count" class="favorite-count">
+ {% if favorite_count %}{{ favorite_count }}{% endif %}
+</div>
-{% load i18n %}\r
-{% spaceless %}\r
-{% for control in controls %}\r
- <span class="action-link">\r
- <a rel="nofollow" title="{{ control.title }}" class="{{ control.classes }}" href="{{ control.url }}">{{ control.text }}</a>\r
- </span>\r
- {% ifnotequal controls|last control %}\r
- <span class="action-link-separator">|</span>\r
- {% endifnotequal %}\r
-{% endfor %}\r
-{% if menu|length %}\r
- <span class="action-link-separator">|</span>\r
- <span id="node-{{ post.id }}-menu" class="context-menu">\r
- <span id="node-{{ post.id }}-menu-trigger" class="action-link context-menu-trigger">{% trans "more" %} ▼</span>\r
- <ul id="node-{{ post.id }}-menu-dropdown" class="context-menu-dropdown">\r
- {% for item in menu %}\r
- <li class="item"><a rel="nofollow" class="{{ item.classes }}" href="{{ item.url }}" title="{{ item.title }}" >{{ item.text }}</a></li>\r
- {% endfor %}\r
- </ul>\r
- </span>\r
-{% endif %}\r
+{% load i18n %}
+{% spaceless %}
+{% for control in controls %}
+ <span class="action-link">
+ <a rel="nofollow" title="{{ control.title }}" class="{{ control.classes }}" href="{{ control.url }}">{{ control.text }}</a>
+ </span>
+ {% ifnotequal controls|last control %}
+ <span class="action-link-separator">|</span>
+ {% endifnotequal %}
+{% endfor %}
+{% if menu|length %}
+ <span class="action-link-separator">|</span>
+ <span id="node-{{ post.id }}-menu" class="context-menu">
+ <span id="node-{{ post.id }}-menu-trigger" class="action-link context-menu-trigger">{% trans "more" %} ▼</span>
+ <ul id="node-{{ post.id }}-menu-dropdown" class="context-menu-dropdown">
+ {% for item in menu %}
+ <li class="item"><a rel="nofollow" class="{{ item.classes }}" href="{{ item.url }}" title="{{ item.title }}" >{{ item.text }}</a></li>
+ {% endfor %}
+ </ul>
+ </span>
+{% endif %}
{% endspaceless %}
\ No newline at end of file
-{% load i18n %}\r
-\r
-{% trans "Please select a reason bellow or use the text box to input your own reason." %}\r
-<select class="prompt-examples">\r
- {% for type in types %}\r
- <option value="{{ type }}">{{ type }}</option>\r
- {% endfor %}\r
-</select>\r
-<textarea name="prompt">{{ types|first }}</textarea>\r
-<script>\r
-$('.prompt-examples').change(function() {\r
- $('textarea[name=prompt]').val($(this).val()) \r
-})\r
+{% load i18n %}
+
+{% trans "Please select a reason bellow or use the text box to input your own reason." %}
+<select class="prompt-examples">
+ {% for type in types %}
+ <option value="{{ type }}">{{ type }}</option>
+ {% endfor %}
+</select>
+<textarea name="prompt">{{ types|first }}</textarea>
+<script>
+$('.prompt-examples').change(function() {
+ $('textarea[name=prompt]').val($(this).val())
+})
</script>
\ No newline at end of file
-{% load extra_tags %}\r
-<div class='post-update-info'>\r
- <p style="line-height:12px;">\r
- <strong>{% diff_date revision.revised_at %}</strong>\r
- </p>\r
- <a href="{{ revision.author.get_profile_url }}">{% gravatar revision.author 32 %}</a>\r
- <p><a href="{{ revision.author.get_profile_url }}">{{ revision.author.username }}</a><br/>\r
- {% get_score_badge revision.author %}</p>\r
+{% load extra_tags %}
+<div class='post-update-info'>
+ <p style="line-height:12px;">
+ <strong>{% diff_date revision.revised_at %}</strong>
+ </p>
+ <a href="{{ revision.author.get_profile_url }}">{% gravatar revision.author 32 %}</a>
+ <p><a href="{{ revision.author.get_profile_url }}">{{ revision.author.username }}</a><br/>
+ {% get_score_badge revision.author %}</p>
</div>
\ No newline at end of file
-{% spaceless %}\r
- {% if title %}<h1>{{ title }}</h1>{% endif %}\r
- <div class="text">{{ html }}</div>\r
- {% if tags %}\r
- <div class="tags">\r
- {% for tag in tags %}\r
- <a class="post-tag tag-link-{{ tag }}">{{ tag }}</a>\r
- {% endfor %}\r
- </div>\r
- {% endif %}\r
+{% spaceless %}
+ {% if title %}<h1>{{ title }}</h1>{% endif %}
+ <div class="text">{{ html }}</div>
+ {% if tags %}
+ <div class="tags">
+ {% for tag in tags %}
+ <a class="post-tag tag-link-{{ tag }}">{{ tag }}</a>
+ {% endfor %}
+ </div>
+ {% endif %}
{% endspaceless %}
\ No newline at end of file
-{% load i18n %}\r
-\r
-<a id="post-{{ post.id }}-upvote" title="{% trans "I like this post (click again to cancel)" %}"\r
- class="ajax-command post-vote up {% ifequal user_vote "up" %} on{% endifequal %}"\r
- href="{% url vote_post id=post.id,vote_type='up' %}" rel="nofollow"> </a>\r
-<div id="post-{{ post.id }}-score" class="post-score"\r
- title="{% trans "current number of votes" %}">\r
- {{ post.score }}\r
-</div>\r
-<a id="post-{{ post.id }}-downvote" title="{% trans "I dont like this post (click again to cancel)" %}"\r
- class="ajax-command post-vote down{% ifequal user_vote "down" %} on{% endifequal %}"\r
- href="{% url vote_post id=post.id,vote_type='down' %}" rel="nofollow"> </a>
\ No newline at end of file
+{% load i18n %}
+
+<a id="post-{{ post.id }}-upvote" title="{% trans "I like this post (click again to cancel)" %}"
+ class="ajax-command post-vote up {% ifequal user_vote "up" %} on{% endifequal %}"
+ href="{% url "vote_post" id=post.id vote_type='up' %}" rel="nofollow"> </a>
+<div id="post-{{ post.id }}-score" class="post-score"
+ title="{% trans "current number of votes" %}">
+ {{ post.score }}
+</div>
+<a id="post-{{ post.id }}-downvote" title="{% trans "I dont like this post (click again to cancel)" %}"
+ class="ajax-command post-vote down{% ifequal user_vote "down" %} on{% endifequal %}"
+ href="{% url "vote_post" id=post.id vote_type='down' %}" rel="nofollow"> </a>
-{% extends "base.html" %}\r
-\r
-{% load i18n extra_tags general_sidebar_tags %}\r
-\r
-{% block title %}{% trans "Site Administration" %}{% endblock %}\r
-\r
-{% block forejs %}\r
- <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/admin.css" %}"/>\r
- <script type="text/javascript" src="{% media "/media/js/osqa.admin.js" %}"></script>\r
- {% block adminjs %}{% endblock %}\r
-{% endblock %}\r
-\r
-{% block content %}\r
- <div class="headNormal">\r
- {% trans "OSQA administration area" %} - {% block subtitle %}{% endblock %}\r
- </div>\r
- <div id="admin_page_description">\r
- {% block description %}{% endblock %}\r
- </div>\r
- <div>\r
- {% block admincontent %}\r
- {% endblock %}\r
- </div>\r
-{% endblock %}\r
-\r
-{% block sidebar %}\r
- {% if hide_navigation %}\r
-\r
- {% else %}\r
- <div class="boxC">\r
- <a href="{% url admin_switch_interface %}?to=djstyle">{% trans "Switch to django style interface" %}</a>\r
- <h3 class="subtitle">{% trans "Administration menu" %}</h3>\r
- <ul>\r
- {% for set in allsets.values %}\r
- <li><a href="{% url admin_set set.name %}">{{ set.title }}</a></li>\r
- {% endfor %}\r
- \r
- {% for set in othersets %}\r
- <li>\r
- <a href="{% url admin_set set.name %}">{{ set.title }}</a>\r
- </li>\r
- {% endfor %}\r
- \r
- <li><a href="{% url admin_maintenance %}">{% trans "Maintenance mode" %}</a></li>\r
- <li><a href="{% url admin_flagged_posts %}">{% trans "Flagged Posts" %}</a></li>\r
- {% for name,tool in tools %}\r
- <li><a href="{% url admin_tools name %}">{{ tool }}</a></li>\r
- {% endfor %}\r
- </ul>\r
- </div>\r
- {% if markdown %}\r
- {% markdown_help %}\r
- {% endif %}\r
-\r
- {% endif %}\r
-{% endblock %}\r
-\r
- \r
+{% extends "base.html" %}
+
+{% load i18n extra_tags general_sidebar_tags %}
+
+{% block title %}{% trans "Site Administration" %}{% endblock %}
+
+{% block forejs %}
+ <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/admin.css" %}"/>
+ <script type="text/javascript" src="{% media "/media/js/osqa.admin.js" %}"></script>
+ {% block adminjs %}{% endblock %}
+{% endblock %}
+
+{% block content %}
+ <div class="headNormal">
+ {% trans "OSQA administration area" %} - {% block subtitle %}{% endblock %}
+ </div>
+ <div id="admin_page_description">
+ {% block description %}{% endblock %}
+ </div>
+ <div>
+ {% block admincontent %}
+ {% endblock %}
+ </div>
+{% endblock %}
+
+{% block sidebar %}
+ {% if hide_navigation %}
+
+ {% else %}
+ <div class="boxC">
+ <a href="{% url "admin_switch_interface" %}?to=djstyle">{% trans "Switch to django style interface" %}</a>
+ <h3 class="subtitle">{% trans "Administration menu" %}</h3>
+ <ul>
+ {% for set in allsets.values %}
+ <li><a href="{% url "admin_set" set.name %}">{{ set.title }}</a></li>
+ {% endfor %}
+
+ {% for set in othersets %}
+ <li>
+ <a href="{% url "admin_set" set.name %}">{{ set.title }}</a>
+ </li>
+ {% endfor %}
+
+ <li><a href="{% url "admin_maintenance" %}">{% trans "Maintenance mode" %}</a></li>
+ <li><a href="{% url "admin_flagged_posts" %}">{% trans "Flagged Posts" %}</a></li>
+ {% for name,tool in tools %}
+ <li><a href="{% url "admin_tools" name %}">{{ tool }}</a></li>
+ {% endfor %}
+ </ul>
+ </div>
+ {% if markdown %}
+ {% markdown_help %}
+ {% endif %}
+
+ {% endif %}
+{% endblock %}
\ No newline at end of file
{% endifequal %}
{% endifequal %}
{% ifnotequal settings_pack "default" %}
- <button onclick="if (window.confirm('{% trans "Are you sure you want to revert to the defaults?" %}')) window.location='{% url admin_go_defaults %}';">{% trans "revert to defaults" %}</button>
+ <button onclick="if (window.confirm('{% trans "Are you sure you want to revert to the defaults?" %}')) window.location='{% url "admin_go_defaults" %}';">{% trans "revert to defaults" %}</button>
{% endifnotequal %}
{% ifnotequal settings_pack "bootstrap" %}
- <button onclick="if (window.confirm('{% trans "Are you sure you want to run bootstrap mode?" %}')) window.location='{% url admin_go_bootstrap %}';">{% trans "go bootstrap" %}</button>
+ <button onclick="if (window.confirm('{% trans "Are you sure you want to run bootstrap mode?" %}')) window.location='{% url "admin_go_bootstrap" %}';">{% trans "go bootstrap" %}</button>
{% endifnotequal %}
</td>
</tr>
-{% load extra_tags extra_filters i18n %}
+{% load extra_tags extra_filters i18n admin_static %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <link rel="stylesheet" href="{{ settings.ADMIN_MEDIA_PREFIX }}css/base.css" type="text/css"/>
- <link rel="stylesheet" href="{{ settings.ADMIN_MEDIA_PREFIX }}css/forms.css" type="text/css"/>
- <link rel="stylesheet" href="{{ settings.ADMIN_MEDIA_PREFIX }}css/changelists.css" type="text/css"/>
- <!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="{{ settings.ADMIN_MEDIA_PREFIX }}css/ie.css" /><![endif]-->
+ <link rel="stylesheet" href="{% static 'admin/css/base.css' %}" type="text/css"/>
+ <link rel="stylesheet" href="{% static 'admin/css/forms.css' %}" type="text/css"/>
+ <link rel="stylesheet" href="{% static 'admin/css/changelists.css' %}" type="text/css"/>
+ <!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="{% static 'admin/css/ie.css' %}" /><![endif]-->
<link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/djstyle_admin.css" %}"/>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
<div id="user-tools">
{% trans "Welcome," %}
<strong>{{ request.user.username }}</strong>.
- <a href="{% url admin_switch_interface %}?to=default">{% trans "To standard interface" %}</a>
- / <a href="{% url index %}">{% trans "Back to home page" %}</a>
- / <a href="{% url logout %}">{% trans "Log out" %}</a>
+ <a href="{% url "admin_switch_interface" %}?to=default">{% trans "To standard interface" %}</a>
+ / <a href="{% url "index" %}">{% trans "Back to home page" %}</a>
+ / <a href="{% url "logout" %}">{% trans "Log out" %}</a>
</div>
</div>
<div class="breadcrumbs">
- <a href="{% url index %}">{% trans "Home" %}</a> >
- <a href="{% url admin_index %}">{% trans "Dashboard" %}</a> >
+ <a href="{% url "index" %}">{% trans "Home" %}</a> >
+ <a href="{% url "admin_index" %}">{% trans "Dashboard" %}</a> >
{% block pagename %}{% endblock %} -
{% block description %}{% endblock %}
</div>
<div id="changes-box" class="module">
<h2>{% trans "Unpublished changes" %}</h2>
<p>
- <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" />
+ <img src="{% static 'admin/img/admin/icon_alert.gif' %}" />
{% trans "Items marked with this icon have unpublished changes." %}
</p>
</div>
<div id="basic-sets-menu" class="module">
<h2>{% trans "Basic settings" %}</h2>
<ul>
- <li><a href="{% url admin_set allsets.basic.name %}">{{ allsets.basic.title }}</a></li>
- <li><a href="{% url admin_set allsets.users.name %}">{{ allsets.users.title }}</a></li>
- <li><a href="{% url admin_set allsets.email.name %}">{{ allsets.email.title }}</a></li>
- <li><a href="{% url admin_set allsets.paths.name %}">{{ allsets.paths.title }}</a></li>
- <li><a href="{% url admin_set allsets.urls.name %}">{{ allsets.urls.title }}</a></li>
- <li><a href="{% url admin_set allsets.extkeys.name %}">{{ allsets.extkeys.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.basic.name %}">{{ allsets.basic.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.users.name %}">{{ allsets.users.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.email.name %}">{{ allsets.email.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.paths.name %}">{{ allsets.paths.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.urls.name %}">{{ allsets.urls.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.extkeys.name %}">{{ allsets.extkeys.title }}</a></li>
</ul>
</div>
<div id="workflow-sets-menu" class="module">
<h2>{% trans "Workflow settings" %}</h2>
<ul>
- <li><a href="{% url admin_set allsets.repgain.name %}">{{ allsets.repgain.title }}</a></li>
- <li><a href="{% url admin_set allsets.minrep.name %}">{{ allsets.minrep.title }}</a></li>
- <li><a href="{% url admin_set allsets.voting.name %}">{{ allsets.voting.title }}</a></li>
- <li><a href="{% url admin_set allsets.accept.name %}">{{ allsets.accept.title }}</a></li>
- <li><a href="{% url admin_set allsets.badges.name %}">{{ allsets.badges.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.repgain.name %}">{{ allsets.repgain.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.minrep.name %}">{{ allsets.minrep.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.voting.name %}">{{ allsets.voting.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.accept.name %}">{{ allsets.accept.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.badges.name %}">{{ allsets.badges.title }}</a></li>
</ul>
</div>
<div id="forum-sets-menu" class="module">
<h2>{% trans "Forum settings" %}</h2>
<ul>
- <li><a href="{% url admin_set allsets.form.name %}">{{ allsets.form.title }}</a></li>
- <li><a href="{% url admin_set allsets.view.name %}">{{ allsets.view.title }}</a></li>
- <li><a href="{% url admin_set allsets.moderation.name %}">{{ allsets.moderation.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.form.name %}">{{ allsets.form.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.view.name %}">{{ allsets.view.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.moderation.name %}">{{ allsets.moderation.title }}</a></li>
</ul>
</div>
<div id="pages-sets-menu" class="module">
<h2>{% trans "Static content" %}</h2>
<ul>
- <li><a href="{% url admin_static_pages %}">{% trans "Custom Pages" %}</a></li>
- <li><a href="{% url admin_set allsets.about.name %}">{{ allsets.about.title }}</a></li>
- <li><a href="{% url admin_set allsets.faq.name %}">{{ allsets.faq.title }}</a></li>
- <li><a href="{% url admin_set allsets.sidebar.name %}">{{ allsets.sidebar.title }}</a></li>
+ <li><a href="{% url "admin_static_pages" %}">{% trans "Custom Pages" %}</a></li>
+ <li><a href="{% url "admin_set" allsets.about.name %}">{{ allsets.about.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.faq.name %}">{{ allsets.faq.title }}</a></li>
+ <li><a href="{% url "admin_set" allsets.sidebar.name %}">{{ allsets.sidebar.title }}</a></li>
<li>
- <a href="{% url admin_set allsets.css.name %}">{{ allsets.css.title }}</a>
- {% if "css"|contained_in:unsaved %}<img width="12" height="12" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" alt="{% trans "Unsaved changes" %}" />{% endif %}
+ <a href="{% url "admin_set" allsets.css.name %}">{{ allsets.css.title }}</a>
+ {% if "css"|contained_in:unsaved %}<img width="12" height="12" src="{% static 'admin/img/admin/icon_alert.gif' %}" alt="{% trans "Unsaved changes" %}" />{% endif %}
</li>
<li>
- <a href="{% url admin_set allsets.headandfoot.name %}">{{ allsets.headandfoot.title }}</a>
- {% if "headandfoot"|contained_in:unsaved %}<img width="12" height="12" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" alt="{% trans "Unsaved changes" %}" />{% endif %}
+ <a href="{% url "admin_set" allsets.headandfoot.name %}">{{ allsets.headandfoot.title }}</a>
+ {% if "headandfoot"|contained_in:unsaved %}<img width="12" height="12" src="{% static 'admin/img/admin/icon_alert.gif' %}" alt="{% trans "Unsaved changes" %}" />{% endif %}
</li>
<li>
- <a href="{% url admin_set allsets.head.name %}">{{ allsets.head.title }}</a>
- {% if "head"|contained_in:unsaved %}<img width="12" height="12" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" alt="{% trans "Unsaved changes" %}" />{% endif %}
+ <a href="{% url "admin_set" allsets.head.name %}">{{ allsets.head.title }}</a>
+ {% if "head"|contained_in:unsaved %}<img width="12" height="12" src="{% static 'admin/img/admin/icon_alert.gif' %}" alt="{% trans "Unsaved changes" %}" />{% endif %}
</li>
</ul>
</div>
<ul>
{% for set in othersets %}
<li>
- <a href="{% url admin_set set.name %}">{{ set.title }}</a>
- {% if set.name|contained_in:unsaved %}<img width="12" height="12" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" alt="{% trans "Unsaved changes" %}" />{% endif %}
+ <a href="{% url "admin_set" set.name %}">{{ set.title }}</a>
+ {% if set.name|contained_in:unsaved %}<img width="12" height="12" src="{% static 'admin/img/admin/icon_alert.gif' %}" alt="{% trans "Unsaved changes" %}" />{% endif %}
</li>
{% endfor %}
</ul>
<div id="tools-menu" class="module">
<h2>{% trans "Tools" %}</h2>
<ul>
- <li><a href="{% url admin_maintenance %}">{% trans "Maintenance mode" %}</a></li>
- <li><a href="{% url admin_flagged_posts %}">{% trans "Flagged Posts" %}</a></li>
+ <li><a href="{% url "admin_maintenance" %}">{% trans "Maintenance mode" %}</a></li>
+ <li><a href="{% url "admin_flagged_posts" %}">{% trans "Flagged Posts" %}</a></li>
{% for name,tool in tools %}
- <li><a href="{% url admin_tools name %}">{{ tool }}</a></li>
+ <li><a href="{% url "admin_tools" name %}">{{ tool }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
<div id="footer" class="breadcumbs">
- <a href="http://www.osqa.net">OSQA</a> <span class="version">{{ settings.OSQA_VERSION }} ({{ settings.SVN_REVISION }})</span>
+ <a href="http://www.osqa.net">OSQA</a> <span class="version">{{ settings.OSQA_VERSION }} ({{ settings.VCS_REVISION }})</span>
</div>
</div>
-</body>
\ No newline at end of file
+</body>
{% block subtitle %}{% trans "Editing page" %}{% endblock %}
{% block pagename %}
- <a href="{% url admin_static_pages %}">{% trans "Static Pages" %}</a> >
+ <a href="{% url "admin_static_pages" %}">{% trans "Static Pages" %}</a> >
{% if page %}{% trans "Editing page" %}{% else %}{% trans "Creating page" %}{% endif %}
{% endblock %}
{% block description %}
-{% extends "osqaadmin/base.html" %}\r
-\r
-{% load i18n %}\r
-{% load user_tags %}\r
-\r
-{% block subtitle %}\r
- {% trans "Dashboard" %}\r
-{% endblock %}\r
-{% block description %}\r
- {% trans "Welcome to the OSQA administration area." %}\r
-{% endblock %}\r
-\r
-{% block admincontent %}\r
- <table width="100%">\r
- <tr>\r
- <td width="50%" valign="top">\r
- <h3>{%trans "Site statistics" %}</h3>\r
- <table>\r
- <tr>\r
- <td>\r
- {{ statistics.total_questions }} {% trans "question" %}{{ statistics.total_questions|pluralize }} ({{ statistics.questions_last_24 }} {% trans "in the last 24 hours" %})\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- {{ statistics.total_answers }} {% trans "answer" %}{{ statistics.total_answers|pluralize }} ({{ statistics.answers_last_24 }} {% trans "in the last 24 hours" %})\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- {{ statistics.total_users }} {% trans "user" %}{{ statistics.total_users|pluralize }} ({{ statistics.users_last_24 }} {% trans "joined in the last 24 hours" %})\r
- </td>\r
- </tr>\r
- </table>\r
- </td>\r
- <td valign="top">\r
- <h3>{%trans "Site status" %}</h3>\r
- <table>\r
- <tr>\r
- <td>\r
- {% ifequal settings_pack "bootstrap" %}\r
- {% trans "Your site is running in bootstrap mode, click the button below to revert to defaults." %}<br />\r
- {% else %}\r
- {% ifequal settings_pack "default" %}\r
- {% trans "Your site is running in standard mode, click the button below to run in bootstrap mode." %}<br />\r
- {% else %}\r
- {% trans "Your site is running with some customized settings, click the buttons below to run with defaults or in bootstrap mode" %}\r
- {% endifequal %}\r
- {% endifequal %}\r
- {% ifnotequal settings_pack "default" %}\r
- <button onclick="if (window.confirm('{% trans "Are you sure you want to revert to the defaults?" %}')) window.location='{% url admin_go_defaults %}';">{% trans "revert to defaults" %}</button>\r
- {% endifnotequal %}\r
- {% ifnotequal settings_pack "bootstrap" %}\r
- <button onclick="if (window.confirm('{% trans "Are you sure you want to run bootstrap mode?" %}')) window.location='{% url admin_go_bootstrap %}';">{% trans "go bootstrap" %}</button>\r
- {% endifnotequal %}\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <em>"Bootstrap mode" relaxes the minimum required reputation to perform actions like voting and commenting.\r
- This is useful to help new communities get started.</em>\r
- </td>\r
- </tr>\r
- </table>\r
- <h3>{%trans "Recalculate scores and reputation" %}</h3>\r
- <button onclick="if (window.confirm('{% trans "This is a heavy operation, are you sure?" %}')) window.location='{% url admin_denormalize %}';">{% trans "Recalculate" %}</button>\r
- </td>\r
- </tr>\r
- <tr>\r
- <td colspan="2">\r
- <h3>{% trans "Recent activity" %}</h3>\r
- <table width="100%">\r
- {% for activity in recent_activity %}\r
- {% activity_item activity request.user %}\r
- {% endfor %}\r
- </table>\r
- </td>\r
- </tr>\r
- </table> \r
+{% extends "osqaadmin/base.html" %}
+
+{% load i18n %}
+{% load user_tags %}
+
+{% block subtitle %}
+ {% trans "Dashboard" %}
+{% endblock %}
+{% block description %}
+ {% trans "Welcome to the OSQA administration area." %}
+{% endblock %}
+
+{% block admincontent %}
+ <table width="100%">
+ <tr>
+ <td width="50%" valign="top">
+ <h3>{%trans "Site statistics" %}</h3>
+ <table>
+ <tr>
+ <td>
+ {{ statistics.total_questions }} {% trans "question" %}{{ statistics.total_questions|pluralize }} ({{ statistics.questions_last_24 }} {% trans "in the last 24 hours" %})
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {{ statistics.total_answers }} {% trans "answer" %}{{ statistics.total_answers|pluralize }} ({{ statistics.answers_last_24 }} {% trans "in the last 24 hours" %})
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {{ statistics.total_users }} {% trans "user" %}{{ statistics.total_users|pluralize }} ({{ statistics.users_last_24 }} {% trans "joined in the last 24 hours" %})
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td valign="top">
+ <h3>{%trans "Site status" %}</h3>
+ <table>
+ <tr>
+ <td>
+ {% ifequal settings_pack "bootstrap" %}
+ {% trans "Your site is running in bootstrap mode, click the button below to revert to defaults." %}<br />
+ {% else %}
+ {% ifequal settings_pack "default" %}
+ {% trans "Your site is running in standard mode, click the button below to run in bootstrap mode." %}<br />
+ {% else %}
+ {% trans "Your site is running with some customized settings, click the buttons below to run with defaults or in bootstrap mode" %}
+ {% endifequal %}
+ {% endifequal %}
+ {% ifnotequal settings_pack "default" %}
+ <button onclick="if (window.confirm('{% trans "Are you sure you want to revert to the defaults?" %}')) window.location='{% url "admin_go_defaults" %}';">{% trans "revert to defaults" %}</button>
+ {% endifnotequal %}
+ {% ifnotequal settings_pack "bootstrap" %}
+ <button onclick="if (window.confirm('{% trans "Are you sure you want to run bootstrap mode?" %}')) window.location='{% url "admin_go_bootstrap" %}';">{% trans "go bootstrap" %}</button>
+ {% endifnotequal %}
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <em>"Bootstrap mode" relaxes the minimum required reputation to perform actions like voting and commenting.
+ This is useful to help new communities get started.</em>
+ </td>
+ </tr>
+ </table>
+ <h3>{%trans "Recalculate scores and reputation" %}</h3>
+ <button onclick="if (window.confirm('{% trans "This is a heavy operation, are you sure?" %}')) window.location='{% url "admin_denormalize" %}';">{% trans "Recalculate" %}</button>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <h3>{% trans "Recent activity" %}</h3>
+ <table width="100%">
+ {% for activity in recent_activity %}
+ {% activity_item activity request.user %}
+ {% endfor %}
+ </table>
+ </td>
+ </tr>
+ </table>
{% endblock %}
\ No newline at end of file
{% extends basetemplate %}
-{% load i18n humanize %}
+{% load i18n humanize admin_static %}
{% block subtitle %}{% trans "Moderation" %}{% endblock %}
{% block pagename %}{% trans "Moderation" %}{% endblock %}
<p><a href="{{ cheater.get_profile_url }}">{{ cheater.username }}</a></p>
<p><b>{% trans "Email" %}</b>
{% if cheater.email_isvalid %}
- <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon-yes.gif" alt="{% trans "Validated" %}" />
+ <img src="{% static 'img/admin/icon-yes.gif' %}" alt="{% trans "Validated" %}" />
{% else %}
- <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon-no.gif" alt="{% trans "Not validated" %}" />
+ <img src="{% static 'img/admin/icon-no.gif' %}" alt="{% trans "Not validated" %}" />
{% endif %}
<a href="mailto: {{ cheater.email }}">{{ cheater.email }}</a></p>
<p><b>{% trans "Reputation:" %}</b> {{ cheater.reputation|intcomma }}</p>
<td><a href="{{ fake.get_profile_url }}">{{ fake.username }}</a></td>
<td>
{% if fake.email_isvalid %}
- <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon-yes.gif" alt="{% trans "Validated" %}" />
+ <img src="{% static 'img/admin/icon-yes.gif' %}" alt="{% trans "Validated" %}" />
{% else %}
- <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon-no.gif" alt="{% trans "Not validated" %}" />
+ <img src="{% static 'img/admin/icon-no.gif' %}" alt="{% trans "Not validated" %}" />
{% endif %}
<a href="mailto: {{ fake.email }}">{{ fake.email }}</a>
</td>
</table>
{% endif %}
</div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
{% extends basetemplate %}
-{% load i18n user_tags extra_tags extra_filters %}
+{% load i18n user_tags extra_tags extra_filters admin_static %}
{% block adminjs %}
<script type="text/javascript">
}
});
- $('#author-selector').autocomplete('{% url matching_users %}', {
+ $('#author-selector').autocomplete('{% url "matching_users" %}', {
minChars: 1,
matchContains: true,
max: 10,
}
});
- $('#tag-selector').autocomplete('{% url matching_tags %}', {
+ $('#tag-selector').autocomplete('{% url "matching_tags" %}', {
minChars: 1,
matchContains: true,
max: 10,
padding: 0 0 0 0;
}
</style>
- <script type="text/javascript">window.__admin_media_prefix__ = "{{ settings.ADMIN_MEDIA_PREFIX }}";</script>
- <link href="{{ settings.ADMIN_MEDIA_PREFIX }}css/base.css" rel="stylesheet" type="text/css" media="screen" />
+ <link href="{% static 'admin/css/base.css' %}" rel="stylesheet" type="text/css" media="screen" />
<script type="text/javascript">
/* gettext identity library */
}
</script>
- <script type="text/javascript" src="{{ settings.ADMIN_MEDIA_PREFIX }}js/core.js"></script>
+ <script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
{% endblock %}
{% block subtitle %}
{% csrf_token %}
<div>
<div>
- <label><img alt="Search" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_searchbox.png"></label>
+ <label><img alt="Search" src="{% static 'admin/img/admin/icon_searchbox.png' %}"></label>
<input type="text" size="40" name="text" id="text-filter-input" value="{{ text }}">
<input type="submit" value="{% trans "Search" %}">
{% if text %}
{% endif %}
<ul id="pre-filter-container">
{% for name, uri in settings.NODE_MAN_FILTERS %}
- <li class="selected"><a href="{% url admin_tools "nodeman" %}?{{ uri }}">{{ name }}</a></li>
+ <li class="selected"><a href="{% url "admin_tools" "nodeman" %}?{{ uri }}">{{ name }}</a></li>
{% endfor %}
</ul>
<form action="" method="POST">
{{ nodes.paginator.page_numbers }}
</form>
</div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
-{% extends basetemplate %}\r
-\r
-{% load i18n extra_tags extra_filters %}\r
-\r
-{% block subtitle %}{{ form.set.title }}{% endblock %}\r
-{% block pagename %}{{ form.set.title }}{% endblock %}\r
-{% block description %}{{ form.set.description }}{% endblock %}\r
-\r
-{% block admincontent %}\r
- <form action="" method="POST" enctype="multipart/form-data" accept-charset="utf-8">\r
- {% csrf_token %}\r
- <table id="admin_form" style="width: 100%">\r
- {{ form.as_table }}\r
- <tr>\r
- <th></th>\r
- <td>\r
- <input id="submit" name="submit" type="submit" value="{% trans "Save" %}" onclick="this.form.target=''; return true;" />\r
- {% if form.set.can_preview %}\r
- <input id="preview" name="preview" type="submit" value="{% trans "Preview" %}" onclick="this.form.target='_blank'; return true;" />\r
- {% if form.set.name|contained_in:unsaved %}\r
- <input id="reset" name="reset" type="submit" value="{% trans "Reset Changes" %}" onclick="this.form.target=''; return true;" />\r
- {% endif %}\r
- {% endif %}\r
- </td>\r
- </tr>\r
- </table>\r
- </form>\r
+{% extends basetemplate %}
+
+{% load i18n extra_tags extra_filters %}
+
+{% block subtitle %}{{ form.set.title }}{% endblock %}
+{% block pagename %}{{ form.set.title }}{% endblock %}
+{% block description %}{{ form.set.description }}{% endblock %}
+
+{% block admincontent %}
+ <form action="" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
+ {% csrf_token %}
+ <table id="admin_form" style="width: 100%">
+ {{ form.as_table }}
+ <tr>
+ <th></th>
+ <td>
+ <input id="submit" name="submit" type="submit" value="{% trans "Save" %}" onclick="this.form.target=''; return true;" />
+ {% if form.set.can_preview %}
+ <input id="preview" name="preview" type="submit" value="{% trans "Preview" %}" onclick="this.form.target='_blank'; return true;" />
+ {% if form.set.name|contained_in:unsaved %}
+ <input id="reset" name="reset" type="submit" value="{% trans "Reset Changes" %}" onclick="this.form.target=''; return true;" />
+ {% endif %}
+ {% endif %}
+ </td>
+ </tr>
+ </table>
+ </form>
{% endblock %}
\ No newline at end of file
{% block admincontent %}
<h1>{% trans "Select page to edit" %}</h1>
<ul class="object-tools">
- <li><a class="addlink" href="{% url admin_new_page %}">{% trans "New page" %}</a></li>
+ <li><a class="addlink" href="{% url "admin_new_page" %}">{% trans "New page" %}</a></li>
</ul>
<div class="module">
<table style="width: 100%">
<tbody>
{% for page in pages %}
<tr>
- <th scope="row"><a href="{% url admin_edit_page id=page.id %}">{{ page.headline }}</a></th>
- <td style="width: 125px;"><a class="changelink" href="{% url admin_edit_page id=page.id %}">{% trans "Edit" %}</a></td>
+ <th scope="row"><a href="{% url "admin_edit_page" id=page.id %}">{{ page.headline }}</a></th>
+ <td style="width: 125px;"><a class="changelink" href="{% url "admin_edit_page" id=page.id %}">{% trans "Edit" %}</a></td>
<td style="width: 125px;">
- <a onclick="return confirm('{% trans "Are you sure you want to delete this page?" %}');" class="deletelink" href="{% url admin_delete_page id=page.id %}">
+ <a onclick="return confirm('{% trans "Are you sure you want to delete this page?" %}');" class="deletelink" href="{% url "admin_delete_page" id=page.id %}">
{% trans "Delete" %}
</a>
</td>
{% extends base %}
-{% load i18n markup node_tags general_sidebar_tags %}
+{% load i18n node_tags general_sidebar_tags %}
{% block title %}{% spaceless %}{{ page.title }}{% endspaceless %}{% endblock %}
{% block content %}
-{% extends "base.html" %}\r
-<!-- question.html -->\r
-{% load node_tags %}\r
-{% load extra_tags %}\r
-{% load extra_filters %}\r
-{% load general_sidebar_tags %}\r
-{% load smart_if %}\r
-{% load humanize %}\r
-{% load i18n %}\r
-{% load cache %}\r
-{% block metadescription %}{{ question.meta_description }}{% endblock %}\r
-{% block metakeywords %}{{question.tagname_meta_generator}}{% endblock %}\r
-{% block meta %}\r
- <link rel="canonical" href="{{settings.APP_BASE_URL}}{{question.get_absolute_url}}" />\r
- <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ question.get_absolute_url }}?type=rss">\r
-{% endblock %}\r
-{% block title %}{% spaceless %}{{ question.headline }}{% endspaceless %}{% endblock %}\r
-{% block forejs %}\r
- {% if not question.nis.closed %}\r
- <script type='text/javascript' src='{% media "/media/js/osqa.question.js" %}'></script>\r
- <script type='text/javascript' src='{% media "/media/js/jquery.caret.js" %}'></script>\r
- <script type='text/javascript' src='{% media "/media/js/wmd/showdown.js" %}'></script>\r
- <script type='text/javascript' src='{% media "/media/js/wmd/wmd.js" %}'></script>\r
- <script type='text/javascript' src='{% media "/media/js/html_sanitizer.js" %}'></script>\r
- <link rel="stylesheet" type="text/css" href="{% media "/media/js/wmd/wmd.css" %}" />\r
-\r
- {% if embed_youtube_videos %}\r
- <script type='text/javascript' src='{% media "/media/js/viewbox_min.js" %}'></script>\r
- <script type='text/javascript' src='{% media "/media/js/youtube.js" %}'></script>\r
- <link rel="stylesheet" type="text/css" href="{% media "/media/js/viewbox.css" %}" />\r
- {% endif %}\r
- {% endif %}\r
-\r
- <script type="text/javascript">\r
- $().ready(function(){\r
- $("#nav_questions").attr('className',"on");\r
- var answer_sort_tab = "{{ tab_id }}";\r
-\r
- if (answer_sort_tab) {\r
- $("#" + answer_sort_tab).attr('className',"on");\r
- }\r
-\r
- $('#editor').TextAreaResizer();\r
-\r
- //toggle preview of editor\r
- var display = true;\r
- var txt = "[{% trans "hide preview" %}]";\r
- $('#pre-collapse').text(txt);\r
- $('#pre-collapse').bind('click', function(){\r
- txt = display ? "[{% trans "show preview" %}]" : "[{% trans "hide preview" %}]";\r
- display = !display;\r
- $('#previewer').toggle();\r
- $('#pre-collapse').text(txt);\r
- });\r
- });\r
-\r
- function submitClicked(e, f) {\r
- if(!(browserTester('chrome') || browserTester('safari'))) {\r
- $("input.submit")[0].disabled=true;\r
- }\r
- window.removeEventListener('beforeunload', beforeUnload, true);\r
- if (f) {\r
- f.submit();\r
- }\r
- }\r
-\r
- function beforeUnload(e) {\r
-\r
- if($("textarea#editor")[0].value != "") {\r
- return yourWorkWillBeLost(e);\r
- }\r
-\r
- var commentBoxes = $("textarea.commentBox");\r
- for(var index = 0; index < commentBoxes.length; index++) {\r
- if(commentBoxes[index].value != "") {\r
- return yourWorkWillBeLost(e);\r
- }\r
- }\r
- }\r
- window.addEventListener('beforeunload', beforeUnload, true);\r
- </script>\r
- <noscript>\r
- <style>\r
- .comment.not_top_scorer {\r
- display: block;\r
- }\r
- .comment-form-container {\r
- display: block;\r
- }\r
- .div.comment-tools {\r
- display: none;\r
- }\r
- </style>\r
- </noscript>\r
-{% endblock %}\r
- \r
-{% block content %}\r
-<div class="headNormal">\r
- <h1><a href="{{ question.get_absolute_url }}">{{ question.headline }}</a></h1>\r
-</div>\r
-<div id="main-body" class="">\r
- <div id="askform">\r
- <table style="width:100%;" id="question-table" {% post_classes question %}>\r
- <tr>\r
- <td style="width:30px;vertical-align:top">\r
- <div class="vote-buttons">\r
- {% vote_buttons question request.user %}\r
- {% favorite_mark question request.user %} \r
- </div>\r
- </td>\r
- <td>\r
- <div id="item-right">\r
- <div class="question-body">\r
- {{ question.html|safe }}\r
- </div>\r
- <div id="question-tags" class="tags-container tags">\r
- {% for tag in question.tagname_list %}\r
- <a href="{% url tag_questions tag|urlencode %}" class="post-tag tag-link-{{ tag }}"\r
- title="{% blocktrans with tag as tagname %}see questions tagged '{{ tagname }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>\r
- {% endfor %}\r
- </div>\r
- <div id="question-controls" class="post-controls"> \r
- {% post_controls question request.user %}\r
- {% wiki_symbol request.user question %}\r
- </div>\r
- <div class="post-update-info-container">\r
- {% contributors_info question %}\r
- </div>\r
- {% comments question request.user %}\r
- </div>\r
- \r
- </td>\r
- </tr>\r
- </table>\r
- {% if question.nis.closed %}\r
- <div class="question-status" style="margin-bottom:15px">\r
- <h3>\r
- {% blocktrans with question.nstate.closed.extra as close_reason %}The question has been closed for the following reason "{{ close_reason }}" by{% endblocktrans %}\r
- <a href="{{ question.nstate.closed.by.get_profile_url }}">{{ question.nstate.closed.by.username }}</a>\r
- {% diff_date question.nstate.closed.at %}\r
- </h3>\r
- </div>\r
- {% endif %}\r
- {% if answers %}\r
- <hr/>\r
- <div class="tabBar">\r
- <a name="sort-top"></a>\r
- <div class="headQuestions">\r
- {% blocktrans count answers.paginator.count as counter %}One Answer:{% plural %}{{counter}} Answers:{% endblocktrans %}\r
- </div>\r
- {{ answers.paginator.sort_tabs }}\r
- </div>\r
- {{ answers.paginator.page_numbers }}\r
- \r
- {% for answer in answers.paginator.page %}\r
- <a name="{{ answer.id }}"></a>\r
- <div id="answer-container-{{ answer.id }}" class="answer {% post_classes answer %}{% ifequal answer.id focused_answer_id %} focusedAnswer{% endifequal %}">\r
- <table style="width:100%;">\r
- <tr>\r
- <td style="width:30px;vertical-align:top">\r
- <div class="vote-buttons">\r
- {% vote_buttons answer request.user %}\r
- {% accept_button answer request.user %}\r
- </div>\r
- </td>\r
- <td>\r
- <div class="item-right">\r
- <div class="answer-body">\r
- {{ answer.html|safe }}\r
- </div>\r
- <div class="answer-controls post-controls">\r
- {% post_controls answer request.user %}\r
- {% wiki_symbol request.user answer %}\r
- </div>\r
- <div class="post-update-info-container">\r
- {% contributors_info answer %}\r
- </div>\r
- {% comments answer request.user %}\r
- </div>\r
- </td>\r
- </tr>\r
- </table>\r
- </div>\r
- {% endfor %}\r
- <div class="paginator-container-left">\r
- {{ answers.paginator.page_numbers }}\r
- </div>\r
- {% endif %}\r
- <form id="fmanswer" action="{% url answer question.id %}" method="post">\r
- {% csrf_token %}\r
- <div style="clear:both">\r
- </div>\r
- \r
- {% if not question.closed %}\r
- <div style="padding:10px 0 0 0;">\r
- {% spaceless %}\r
- <div class="headNormal">\r
- {% if answers %}\r
- {% trans "Your answer" %}\r
- {% else %}\r
- {% trans "Be the first one to answer this question!" %}\r
- {% endif %}\r
- </div>\r
- {% endspaceless %}\r
- </div>\r
- {% comment %}\r
- {% if not request.user.is_authenticated %}\r
- <div class="message">{% trans "You can answer anonymously and then login." %}</div>\r
- {% else %}\r
- <p class="message">\r
- {% ifequal request.user question.author %}\r
- {% trans "Answer your own question only to give an answer." %}\r
- {% else %}\r
- {% trans "Please only give an answer, no discussions." %}\r
- {% endifequal %}\r
- {% if not request.user.email_valid_and_can_answer %}\r
- {% blocktrans %}Remember, your answer will not be published until you validate your email.{% endblocktrans %}\r
- <a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>\r
- {% endif %}\r
- </p>\r
- {% endif %}\r
- {% endcomment %}\r
-\r
- <div id="description" class="" >\r
- <div id="wmd-button-bar" class="wmd-panel"></div>\r
- {{ answer.text }}\r
- <div class="preview-toggle">\r
- <table width="100%">\r
- <tr>\r
- <td>\r
- <span id="pre-collapse" \r
- title="{% trans "Toggle the real time Markdown editor preview" %}">\r
- {% trans "toggle preview" %}\r
- </span>\r
- </td>\r
- <td style="text-align: right;" id="editor-metrics"></td>\r
- {% if settings.WIKI_ON %}\r
- <td style="text-align:right;">\r
- {{ answer.wiki }} \r
- <span style="font-weight:normal;cursor:help" \r
- title="{{answer.wiki.help_text}}">\r
- {{ answer.wiki.label_tag }} \r
- </span>\r
- </td>\r
- {% endif %}\r
- </tr>\r
- \r
- </table> \r
- </div>\r
- {{ answer.text.errors }}\r
- <div id="previewer" class="wmd-preview"></div>\r
- </div>\r
-\r
- {% if answer.recaptcha %}\r
- <div class="question-captcha" style="float: left;">\r
- {{ answer.recaptcha.errors }}\r
- {{ answer.recaptcha }}\r
- </div>\r
- <div class="clear"></div>\r
- {% endif %}\r
- \r
- <p><span class="form-error"></span></p>\r
- <input type="button"\r
- {% if user.is_anonymous %}\r
- value="{% trans "Login/Signup to Post Your Answer" %}" \r
- {% else %}\r
- {% if user == question.author %}\r
- value="{% trans "Answer Your Own Question" %}" \r
- {% else %}\r
- value="{% trans "Answer the question" %}" \r
- {% endif %}\r
- {% endif %}\r
- class="submit" style="float:left" onclick="submitClicked(event, this.form)"/>\r
- {% endif %}\r
- </form>\r
- </div>\r
-</div>\r
-{% endblock %}\r
-\r
-{% block sidebar %}\r
-<div class="boxC" id="subscription_box">\r
- {% include "subscription_status.html" %}\r
-</div>\r
-\r
-{% markdown_help %}\r
-\r
-{% sidebar_upper %}\r
-\r
-{% cache 60 questions_tags settings.APP_URL question.id %}\r
-<div class="boxC">\r
- <p>\r
- {% trans "Question tags" %}:\r
- </p>\r
- <p class="tags" >\r
- {% for tag in question.tags.all %}\r
- <a href="{% url tag_questions tag.name|urlencode %}"\r
- class="tag-link-{{ tag.name }}"\r
- title="{% trans "see questions tagged"%}'{{tag.name}}'{% trans "using tags" %}"\r
- rel="tag">{{ tag.name }}</a> <span class="tag-number">×{{ tag.used_count|intcomma }}</span><br/>\r
- {% endfor %}\r
- </p>\r
- <p>\r
- {% trans "question asked" %}: <strong title="{{ question.added_at }}">{% diff_date question.added_at %}</strong>\r
- </p>\r
- <p> \r
- {% trans "question was seen" %}: <strong>{{ question.view_count|intcomma }} {% trans "times" %}</strong>\r
- </p>\r
- <p> \r
- {% trans "last updated" %}: <strong title="{{ question.last_activity_at }}">{% diff_date question.last_activity_at %}</strong>\r
- </p>\r
-</div>\r
-{% endcache %}\r
-{% sidebar_lower %}\r
-<div class="boxC">\r
- <h3 class="subtitle">{% trans "Related questions" %}</h3>\r
- <div class="questions-related">\r
-\r
- {% for question in similar_questions %}\r
- <p>\r
- <a href="{{ question.get_absolute_url }}">{{ question.headline }}</a>\r
- </p>\r
- {% endfor %}\r
-\r
- </div>\r
-</div>\r
-\r
-{% endblock %}\r
-\r
-{% block endjs %}\r
-{% endblock %}\r
-<!-- end question.html -->\r
+{% extends "base.html" %}
+<!-- question.html -->
+{% load node_tags %}
+{% load extra_tags %}
+{% load extra_filters %}
+{% load general_sidebar_tags %}
+{% load smart_if %}
+{% load humanize %}
+{% load i18n %}
+{% load cache %}
+{% block metadescription %}{{ question.meta_description }}{% endblock %}
+{% block metakeywords %}{{question.tagname_meta_generator}}{% endblock %}
+{% block meta %}
+ <link rel="canonical" href="{{settings.APP_BASE_URL}}{{question.get_absolute_url}}" />
+ <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ question.get_absolute_url }}?type=rss">
+{% endblock %}
+{% block title %}{% spaceless %}{{ question.headline }}{% endspaceless %}{% endblock %}
+{% block forejs %}
+ {% if not question.nis.closed %}
+ <script type='text/javascript' src='{% media "/media/js/osqa.question.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.caret.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/showdown.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/wmd.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/html_sanitizer.js" %}'></script>
+ <link rel="stylesheet" type="text/css" href="{% media "/media/js/wmd/wmd.css" %}" />
+
+ {% if embed_youtube_videos %}
+ <script type='text/javascript' src='{% media "/media/js/viewbox_min.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/youtube.js" %}'></script>
+ <link rel="stylesheet" type="text/css" href="{% media "/media/js/viewbox.css" %}" />
+ {% endif %}
+ {% endif %}
+
+ <script type="text/javascript">
+ $().ready(function(){
+ $("#nav_questions").attr('className',"on");
+ var answer_sort_tab = "{{ tab_id }}";
+
+ if (answer_sort_tab) {
+ $("#" + answer_sort_tab).attr('className',"on");
+ }
+
+ $('#editor').TextAreaResizer();
+
+ //toggle preview of editor
+ var display = true;
+ var txt = "[{% trans "hide preview" %}]";
+ $('#pre-collapse').text(txt);
+ $('#pre-collapse').bind('click', function(){
+ txt = display ? "[{% trans "show preview" %}]" : "[{% trans "hide preview" %}]";
+ display = !display;
+ $('#previewer').toggle();
+ $('#pre-collapse').text(txt);
+ });
+ });
+
+ function submitClicked(e, f) {
+ if(!(browserTester('chrome') || browserTester('safari'))) {
+ $("input.submit")[0].disabled=true;
+ }
+ window.removeEventListener('beforeunload', beforeUnload, true);
+ if (f) {
+ f.submit();
+ }
+ }
+
+ function beforeUnload(e) {
+
+ if($("textarea#editor")[0].value != "") {
+ return yourWorkWillBeLost(e);
+ }
+
+ var commentBoxes = $("textarea.commentBox");
+ for(var index = 0; index < commentBoxes.length; index++) {
+ if(commentBoxes[index].value != "") {
+ return yourWorkWillBeLost(e);
+ }
+ }
+ }
+ window.addEventListener('beforeunload', beforeUnload, true);
+ </script>
+ <noscript>
+ <style>
+ .comment.not_top_scorer {
+ display: block;
+ }
+ .comment-form-container {
+ display: block;
+ }
+ .div.comment-tools {
+ display: none;
+ }
+ </style>
+ </noscript>
+{% endblock %}
+
+{% block content %}
+<div class="headNormal">
+ <h1><a href="{{ question.get_absolute_url }}">{{ question.headline }}</a></h1>
+</div>
+<div id="main-body" class="">
+ <div id="askform">
+ <table style="width:100%;" id="question-table" {% post_classes question %}>
+ <tr>
+ <td style="width:30px;vertical-align:top">
+ <div class="vote-buttons">
+ {% vote_buttons question request.user %}
+ {% favorite_mark question request.user %}
+ </div>
+ </td>
+ <td>
+ <div id="item-right">
+ <div class="question-body">
+ {{ question.html|safe }}
+ </div>
+ <div id="question-tags" class="tags-container tags">
+ {% for tag in question.tagname_list %}
+ <a href="{% url "tag_questions" tag|urlencode %}" class="post-tag tag-link-{{ tag }}"
+ title="{% blocktrans with tag as tagname %}see questions tagged '{{ tagname }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
+ {% endfor %}
+ </div>
+ <div id="question-controls" class="post-controls">
+ {% post_controls question request.user %}
+ {% wiki_symbol request.user question %}
+ </div>
+ <div class="post-update-info-container">
+ {% contributors_info question %}
+ </div>
+ {% comments question request.user %}
+ </div>
+
+ </td>
+ </tr>
+ </table>
+ {% if question.nis.closed %}
+ <div class="question-status" style="margin-bottom:15px">
+ <h3>
+ {% blocktrans with question.nstate.closed.extra as close_reason %}The question has been closed for the following reason "{{ close_reason }}" by{% endblocktrans %}
+ <a href="{{ question.nstate.closed.by.get_profile_url }}">{{ question.nstate.closed.by.username }}</a>
+ {% diff_date question.nstate.closed.at %}
+ </h3>
+ </div>
+ {% endif %}
+ {% if answers %}
+ <hr/>
+ <div class="tabBar">
+ <a name="sort-top"></a>
+ <div class="headQuestions">
+ {% blocktrans count answers.paginator.count as counter %}One Answer:{% plural %}{{counter}} Answers:{% endblocktrans %}
+ </div>
+ {{ answers.paginator.sort_tabs }}
+ </div>
+ {{ answers.paginator.page_numbers }}
+
+ {% for answer in answers.paginator.page %}
+ <a name="{{ answer.id }}"></a>
+ <div id="answer-container-{{ answer.id }}" class="answer {% post_classes answer %}{% ifequal answer.id focused_answer_id %} focusedAnswer{% endifequal %}">
+ <table style="width:100%;">
+ <tr>
+ <td style="width:30px;vertical-align:top">
+ <div class="vote-buttons">
+ {% vote_buttons answer request.user %}
+ {% accept_button answer request.user %}
+ </div>
+ </td>
+ <td>
+ <div class="item-right">
+ <div class="answer-body">
+ {{ answer.html|safe }}
+ </div>
+ <div class="answer-controls post-controls">
+ {% post_controls answer request.user %}
+ {% wiki_symbol request.user answer %}
+ </div>
+ <div class="post-update-info-container">
+ {% contributors_info answer %}
+ </div>
+ {% comments answer request.user %}
+ </div>
+ </td>
+ </tr>
+ </table>
+ </div>
+ {% endfor %}
+ <div class="paginator-container-left">
+ {{ answers.paginator.page_numbers }}
+ </div>
+ {% endif %}
+ <form id="fmanswer" action="{% url "answer" question.id %}" method="post">
+ {% csrf_token %}
+ <div style="clear:both">
+ </div>
+
+ {% if not question.closed %}
+ <div style="padding:10px 0 0 0;">
+ {% spaceless %}
+ <div class="headNormal">
+ {% if answers %}
+ {% trans "Your answer" %}
+ {% else %}
+ {% trans "Be the first one to answer this question!" %}
+ {% endif %}
+ </div>
+ {% endspaceless %}
+ </div>
+ {% comment %}
+ {% if not request.user.is_authenticated %}
+ <div class="message">{% trans "You can answer anonymously and then login." %}</div>
+ {% else %}
+ <p class="message">
+ {% ifequal request.user question.author %}
+ {% trans "Answer your own question only to give an answer." %}
+ {% else %}
+ {% trans "Please only give an answer, no discussions." %}
+ {% endifequal %}
+ {% if not request.user.email_valid_and_can_answer %}
+ {% blocktrans %}Remember, your answer will not be published until you validate your email.{% endblocktrans %}
+ <a href="{% url "send_validation_email" %}">{% trans "Send me a validation link." %}</a>
+ {% endif %}
+ </p>
+ {% endif %}
+ {% endcomment %}
+
+ <div id="description" class="" >
+ <div id="wmd-button-bar" class="wmd-panel"></div>
+ {{ answer.text }}
+ <div class="preview-toggle">
+ <table width="100%">
+ <tr>
+ <td>
+ <span id="pre-collapse"
+ title="{% trans "Toggle the real time Markdown editor preview" %}">
+ {% trans "toggle preview" %}
+ </span>
+ </td>
+ <td style="text-align: right;" id="editor-metrics"></td>
+ {% if settings.WIKI_ON %}
+ <td style="text-align:right;">
+ {{ answer.wiki }}
+ <span style="font-weight:normal;cursor:help"
+ title="{{answer.wiki.help_text}}">
+ {{ answer.wiki.label_tag }}
+ </span>
+ </td>
+ {% endif %}
+ </tr>
+
+ </table>
+ </div>
+ {{ answer.text.errors }}
+ <div id="previewer" class="wmd-preview"></div>
+ </div>
+
+ {% if answer.recaptcha %}
+ <div class="question-captcha" style="float: left;">
+ {{ answer.recaptcha.errors }}
+ {{ answer.recaptcha }}
+ </div>
+ <div class="clear"></div>
+ {% endif %}
+
+ <p><span class="form-error"></span></p>
+ <input type="button"
+ {% if user.is_anonymous %}
+ value="{% trans "Login/Signup to Post Your Answer" %}"
+ {% else %}
+ {% if user == question.author %}
+ value="{% trans "Answer Your Own Question" %}"
+ {% else %}
+ value="{% trans "Answer the question" %}"
+ {% endif %}
+ {% endif %}
+ class="submit" style="float:left" onclick="submitClicked(event, this.form)"/>
+ {% endif %}
+ </form>
+ </div>
+</div>
+{% endblock %}
+
+{% block sidebar %}
+<div class="boxC" id="subscription_box">
+ {% include "subscription_status.html" %}
+</div>
+
+{% markdown_help %}
+
+{% sidebar_upper %}
+
+{% cache 60 questions_tags settings.APP_URL question.id %}
+<div class="boxC">
+ <p>
+ {% trans "Question tags" %}:
+ </p>
+ <p class="tags" >
+ {% for tag in question.tags.all %}
+ <a href="{% url "tag_questions" tag.name|urlencode %}"
+ class="tag-link-{{ tag.name }}"
+ title="{% trans "see questions tagged"%}'{{tag.name}}'{% trans "using tags" %}"
+ rel="tag">{{ tag.name }}</a> <span class="tag-number">×{{ tag.used_count|intcomma }}</span><br/>
+ {% endfor %}
+ </p>
+ <p>
+ {% trans "question asked" %}: <strong title="{{ question.added_at }}">{% diff_date question.added_at %}</strong>
+ </p>
+ <p>
+ {% trans "question was seen" %}: <strong>{{ question.view_count|intcomma }} {% trans "times" %}</strong>
+ </p>
+ <p>
+ {% trans "last updated" %}: <strong title="{{ question.last_activity_at }}">{% diff_date question.last_activity_at %}</strong>
+ </p>
+</div>
+{% endcache %}
+{% sidebar_lower %}
+<div class="boxC">
+ <h3 class="subtitle">{% trans "Related questions" %}</h3>
+ <div class="questions-related">
+
+ {% for question in similar_questions %}
+ <p>
+ <a href="{{ question.get_absolute_url }}">{{ question.headline }}</a>
+ </p>
+ {% endfor %}
+
+ </div>
+</div>
+
+{% endblock %}
+
+{% block endjs %}
+{% endblock %}
+<!-- end question.html -->
});
//Tags autocomplete action
- $("#id_tags").autocomplete("{% url matching_tags %}", {
+ $("#id_tags").autocomplete("{% url "matching_tags" %}", {
matchContains: true,
max: 20,
multiple: true,
<!-- question_edit_tips.html -->
-{% load markup %}
-{% load i18n general_sidebar_tags %}
+{% load i18n general_sidebar_tags extra_filters %}
<div class="boxC" id="title_side_bar">
<p class="subtitle darkred">{% trans "Title Tips" %}</p>
<div class="list-item">
- {{ settings.QUESTION_TITLE_TIPS|markdown:"settingsparser" }}
+ {{ settings.QUESTION_TITLE_TIPS|static_content:"markdown" }}
<p class='info-box-follow-up-links'>
- <a href="{% url faq %}" target="_blank" title="{% trans "see frequently asked questions" %}">{% trans "faq" %} »</a>
+ <a href="{% url "faq" %}" target="_blank" title="{% trans "see frequently asked questions" %}">{% trans "faq" %} »</a>
</p>
</div>
</div>
<div class="boxC" id="tags_side_bar" align="left">
<p class="subtitle darkred">{% trans "What Are Tags" %}</p>
<div class="list-item">
- {{ settings.QUESTION_TAG_TIPS|markdown:"settingsparser" }}
+ {{ settings.QUESTION_TAG_TIPS|static_content:"markdown" }}
</div>
</div>
<!-- end question_edit_tips.html -->
-
\ No newline at end of file
-{% spaceless %}\r
-{% load i18n humanize extra_tags %}\r
-{% declare %}\r
- answer_count = questions.children_count('answer')\r
-{% enddeclare %}\r
-\r
-<div class="boxC">\r
- <div class="questions-count">\r
- {{ questions.paginator.count }}<span style="color:black;font-size:14px;margin-left:5px">{{ list_description }}</span>\r
- </div>\r
-\r
-\r
- {% if answer_count %}\r
- <div class="questions-count">\r
- {{ answer_count }}<span style="color:black;font-size:14px;margin-left:5px">{% trans "answers" %}</span>\r
- </div>\r
-\r
- {% endif %}\r
-\r
- <div>\r
- <p class="nomargin">\r
- {{ questions.paginator.sort_description }}\r
- </p>\r
- </div>\r
-</div>\r
+{% spaceless %}
+{% load i18n humanize extra_tags %}
+{% declare %}
+ answer_count = questions.children_count('answer')
+{% enddeclare %}
+
+<div class="boxC">
+ <div class="questions-count">
+ {{ questions.paginator.count }}<span style="color:black;font-size:14px;margin-left:5px">{{ list_description }}</span>
+ </div>
+
+
+ {% if answer_count %}
+ <div class="questions-count">
+ {{ answer_count }}<span style="color:black;font-size:14px;margin-left:5px">{% trans "answers" %}</span>
+ </div>
+
+ {% endif %}
+
+ <div>
+ <p class="nomargin">
+ {{ questions.paginator.sort_description }}
+ </p>
+ </div>
+</div>
{% endspaceless %}
\ No newline at end of file
-{% load i18n humanize extra_filters extra_tags user_tags %}\r
-<div class="short-summary">\r
- <div class="counts">{% if favorite_count %}\r
- <div class="favorites">\r
- <span class="favorite-mark{% if question.favourite_count %} on{% endif %}"></span>\r
- <div class="item-count">{{question.favourite_count|intcomma}}</div>\r
- </div>\r
- {% endif %}\r
- <div class="votes">\r
- <div class="item-count">{{question.score|intcomma}}</div>\r
- <div>{% ifequal question.score 1 %}{% trans "vote" %}{% else %}{% trans "votes" %}{% endifequal %}</div>\r
- </div >\r
- <div {% if question.accepted_count %}title="{% trans "this question has an accepted answer" %}"{% endif %} class="status {% if question.accepted_count %}answered-accepted{% endif %} {% ifequal question.answer_count 0 %}unanswered{% endifequal %}{% ifnotequal question.answer_count 0 %}answered{% endifnotequal %}">\r
- <div class="item-count">{{question.answer_count|intcomma}}</div>\r
- <div>{% ifequal question.answer_count 1 %}{% trans "answer" %}{% else %}{% trans "answers" %}{% endifequal %}</div>\r
- </div>\r
- <div class="views">\r
- <div class="item-count">{{question.view_count|decorated_int|safe}}</div>\r
- <div>{% ifequal question.view_count 1 %}{% trans "view" %}{% else %}{% trans "views" %}{% endifequal %}</div>\r
- </div>\r
- </div>\r
-\r
- <div class="question-summary-wrapper">\r
- <h2><a {% if not question_summary %}title="{{ question.summary }}"{% endif %} href="{{ question.get_absolute_url }}">{{question.headline}}</a></h2>\r
- {% if question_summary %}\r
- <div class="summary">\r
- {{ question.summary }}\r
- </div>\r
- {% endif %}\r
- <div class="userinfo">\r
- <span class="relativetime" title="{{question.last_activity_at}}">{% diff_date question.last_activity_at %}</span>\r
- {% if question.last_activity_by %}{% user_signature question.last_activity_by signature_type %}{% endif %}\r
- </div>\r
-\r
- <div class="tags">{% for tag in question.tagname_list %}\r
- <a class="tag-link-{{ tag }}" href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}'" rel="tag">{{ tag }}</a>{% endfor %}\r
- </div>\r
- </div>\r
-\r
+{% load i18n humanize extra_filters extra_tags user_tags %}
+<div class="short-summary">
+ <div class="counts">{% if favorite_count %}
+ <div class="favorites">
+ <span class="favorite-mark{% if question.favourite_count %} on{% endif %}"></span>
+ <div class="item-count">{{question.favourite_count|intcomma}}</div>
+ </div>
+ {% endif %}
+ <div class="votes">
+ <div class="item-count">{{question.score|intcomma}}</div>
+ <div>{% ifequal question.score 1 %}{% trans "vote" %}{% else %}{% trans "votes" %}{% endifequal %}</div>
+ </div >
+ <div {% if question.accepted_count %}title="{% trans "this question has an accepted answer" %}"{% endif %} class="status {% if question.accepted_count %}answered-accepted{% endif %} {% ifequal question.answer_count 0 %}unanswered{% endifequal %}{% ifnotequal question.answer_count 0 %}answered{% endifnotequal %}">
+ <div class="item-count">{{question.answer_count|intcomma}}</div>
+ <div>{% ifequal question.answer_count 1 %}{% trans "answer" %}{% else %}{% trans "answers" %}{% endifequal %}</div>
+ </div>
+ <div class="views">
+ <div class="item-count">{{question.view_count|decorated_int|safe}}</div>
+ <div>{% ifequal question.view_count 1 %}{% trans "view" %}{% else %}{% trans "views" %}{% endifequal %}</div>
+ </div>
+ </div>
+
+ <div class="question-summary-wrapper">
+ <h2><a {% if not question_summary %}title="{{ question.summary }}"{% endif %} href="{{ question.get_absolute_url }}">{{question.headline}}</a></h2>
+ {% if question_summary %}
+ <div class="summary">
+ {{ question.summary }}
+ </div>
+ {% endif %}
+ <div class="userinfo">
+ <span class="relativetime" title="{{question.last_activity_at}}">{% diff_date question.last_activity_at %}</span>
+ {% if question.last_activity_by %}{% user_signature question.last_activity_by signature_type %}{% endif %}
+ </div>
+
+ <div class="tags">{% for tag in question.tagname_list %}
+ <a class="tag-link-{{ tag }}" href="{% url "tag_questions" tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}'" rel="tag">{{ tag }}</a>{% endfor %}
+ </div>
+ </div>
+
</div>
\ No newline at end of file
-{% load i18n %}\r
-{% load humanize %}\r
-\r
-{% if tags %}\r
- <div class="boxC">\r
- <h3 class="subtitle">{% trans "Related tags" %}</h3>\r
- <div class="tags" id="recent-tags">\r
- {% for tag in tags %}\r
- <a rel="tag" class="tag-link-{{ tag.name }}" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>\r
- <span class="tag-number">× {{ tag.used_count|intcomma }}</span>\r
- <br />\r
- {% endfor %}\r
- </div>\r
- </div>\r
+{% load i18n %}
+{% load humanize %}
+
+{% if tags %}
+ <div class="boxC">
+ <h3 class="subtitle">{% trans "Related tags" %}</h3>
+ <div class="tags" id="recent-tags">
+ {% for tag in tags %}
+ <a rel="tag" class="tag-link-{{ tag.name }}" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}" href="{% url "tag_questions" tag.name|urlencode %}">{{ tag.name }}</a>
+ <span class="tag-number">× {{ tag.used_count|intcomma }}</span>
+ <br />
+ {% endfor %}
+ </div>
+ </div>
{% endif %}
\ No newline at end of file
-{% load i18n %}\r
-\r
-<div class="tabsA">\r
- <a id="active" href="{{ base_url }}active"{% ifequal current "active" %} class="on"{% endifequal %} title="{% trans "most recently updated questions" %}">{% trans "active" %}</a>\r
- <a id="latest" href="{{ base_url }}latest"{% ifequal current "latest" %} class="on"{% endifequal %} title="{% trans "most recently asked questions" %}">{% trans "newest" %}</a>\r
- <a id="hottest" href="{{ base_url }}hottest"{% ifequal current "hottest" %} class="on"{% endifequal %} title="{% trans "hottest questions" %}">{% trans "hottest" %}</a>\r
- <a id="mostvoted" href="{{ base_url }}mostvoted"{% ifequal current "mostvoted" %} class="on"{% endifequal %} title="{% trans "most voted questions" %}">{% trans "most voted" %}</a>\r
-</div>\r
+{% load i18n %}
+
+<div class="tabsA">
+ <a id="active" href="{{ base_url }}active"{% ifequal current "active" %} class="on"{% endifequal %} title="{% trans "most recently updated questions" %}">{% trans "active" %}</a>
+ <a id="latest" href="{{ base_url }}latest"{% ifequal current "latest" %} class="on"{% endifequal %} title="{% trans "most recently asked questions" %}">{% trans "newest" %}</a>
+ <a id="hottest" href="{{ base_url }}hottest"{% ifequal current "hottest" %} class="on"{% endifequal %} title="{% trans "hottest questions" %}">{% trans "hottest" %}</a>
+ <a id="mostvoted" href="{{ base_url }}mostvoted"{% ifequal current "mostvoted" %} class="on"{% endifequal %} title="{% trans "most voted questions" %}">{% trans "most voted" %}</a>
+</div>
{% load i18n humanize extra_filters extra_tags user_tags %}
<div class="subscription_summary">
- <div style="height:100%"><a class="sidebar_button subscription_unsubscribe_button" href="{% url subscribe id=subscription.question.id user=subscription.user.id %}">
+ <div style="height:100%"><a class="sidebar_button subscription_unsubscribe_button" href="{% url "subscribe" id=subscription.question.id user=subscription.user.id %}">
{% trans "Unsubscribe" %}
</a></div>
<a rel="tag"
class="tag-link-{{ tag_name }}"
title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
- href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
+ href="{% url "tag_questions" tag_name|urlencode %}">{{tag_name}}</a>
<img class="delete-icon"
src="{% media "/media/images/close-small-dark.png" %}"
title="{% blocktrans %}remove '{{tag_name}}' from the list of interesting tags{% endblocktrans %}"/>
<a rel="tag"
class="tag-link-{{ tag_name }}"
title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
- href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
+ href="{% url "tag_questions" tag_name|urlencode %}">{{tag_name}}</a>
<img class="delete-icon"
src="{% media "/media/images/close-small-dark.png" %}"
title="{% blocktrans %}remove '{{tag_name}}' from the list of ignored tags{% endblocktrans %}"/>
-{% load i18n %}\r
-\r
-<div class="headQuestions">\r
- {% if searchtag %}\r
- {% trans "Found by tags" %}\r
- {% else %}\r
- {% if searchtitle %}\r
- {% if settings.USE_SPHINX_SEARCH %}\r
- {% trans "Search results" %}\r
- {% else %}\r
- {% trans "Found by title" %}\r
- {% endif %}\r
- {% else %}\r
- {% if is_unanswered %}\r
- {% trans "Unanswered questions" %}\r
- {% else %}\r
- {% if page_title %}\r
- {% trans page_title %}\r
- {% else %}\r
- {% trans "All Questions" %}\r
- {% endif %}\r
- {% endif %}\r
- {% endif %}\r
- {% endif %}\r
+{% load i18n %}
+
+<div class="headQuestions">
+ {% if searchtag %}
+ {% trans "Found by tags" %}
+ {% else %}
+ {% if searchtitle %}
+ {% if settings.USE_SPHINX_SEARCH %}
+ {% trans "Search results" %}
+ {% else %}
+ {% trans "Found by title" %}
+ {% endif %}
+ {% else %}
+ {% if is_unanswered %}
+ {% trans "Unanswered questions" %}
+ {% else %}
+ {% if page_title %}
+ {% trans page_title %}
+ {% else %}
+ {% trans "All Questions" %}
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ {% endif %}
</div>
\ No newline at end of file
<script type="text/javascript">
$().ready(function(){
- $("#id_tags").autocomplete("{% url matching_tags %}", {
+ $("#id_tags").autocomplete("{% url "matching_tags" %}", {
matchContains: true,
max: 20,
multiple: true,
</div>
<div id="main-body" class="ask-body">
<div id="askform">
- <form id="fmretag" action="{% url edit_question question.id %}" method="post">
+ <form id="fmretag" action="{% url "edit_question" question.id %}" method="post">
{% csrf_token %}
<h3>
{{ question.headline }}
</li>
</ul>
<p class='info-box-follow-up-links'>
- <a href="{% url faq %}">faq »</a>
+ <a href="{% url "faq" %}">faq »</a>
</p>
</div>
<div class="tags">
{% for tag in question.tagname_list %}
- <a class="tag-link-{{ tag }}" href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a class="tag-link-{{ tag }}" href="{% url "tag_questions" tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
-{% extends "base.html" %}\r
-<!-- questions.html -->\r
-{% load question_list_tags %}\r
-{% load i18n %}\r
-{% load extra_tags %}\r
-{% load general_sidebar_tags %}\r
-\r
-{% block title %}{% spaceless %}{{ page_title }}{% endspaceless %}{% endblock %}\r
-\r
-{% block metadescription %}{% spaceless %}\r
- {% if tag %}\r
- {% blocktrans with settings.APP_TITLE as app_title %}Questions and answers about {{ tag }} on {{ app_title }}{% endblocktrans %}\r
- {% endif %}\r
-{% endspaceless %}{% endblock %}\r
-\r
-{% block meta %}\r
- <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ feed_url }}" />\r
-{% endblock %}\r
-\r
-{% block content %}\r
-\r
-<div class="tabBar">\r
- {% include "question_list/title.html" %}\r
- <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');" href="{{ feed_url }}" title="{% trans "subscribe to question RSS feed" %}"></a>\r
- {{ questions.paginator.sort_tabs }}\r
-</div>\r
-<div id="listA">{% for question in questions.paginator.page %}\r
- {% if show_summary %}\r
- {% question_list_item question question_summary=yes %}\r
- {% else %}\r
- {% question_list_item question %}\r
- {% endif %}\r
-{% endfor %}</div>\r
-{% endblock %}\r
-\r
-{% block tail %}\r
- <div class="pager">{{ questions.paginator.page_numbers }}</div>\r
- <div class="pagesize">{{ questions.paginator.page_sizes }}</div>\r
-{% endblock %}\r
-\r
-{% block sidebar %}\r
- {% include "question_list/count.html" %}\r
- {% sidebar_upper %}\r
- {% tag_selector %}\r
- {% sidebar_lower %}\r
- {% question_list_related_tags questions.paginator.page %}\r
-\r
-{% endblock %}\r
-<!-- end questions.html -->\r
+{% extends "base.html" %}
+<!-- questions.html -->
+{% load question_list_tags %}
+{% load i18n %}
+{% load extra_tags %}
+{% load general_sidebar_tags %}
+
+{% block title %}{% spaceless %}{{ page_title }}{% endspaceless %}{% endblock %}
+
+{% block metadescription %}{% spaceless %}
+ {% if tag %}
+ {% blocktrans with settings.APP_TITLE as app_title %}Questions and answers about {{ tag }} on {{ app_title }}{% endblocktrans %}
+ {% endif %}
+{% endspaceless %}{% endblock %}
+
+{% block meta %}
+ <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ feed_url }}" />
+{% endblock %}
+
+{% block content %}
+
+<div class="tabBar">
+ {% include "question_list/title.html" %}
+ <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');" href="{{ feed_url }}" title="{% trans "subscribe to question RSS feed" %}"></a>
+ {{ questions.paginator.sort_tabs }}
+</div>
+<div id="listA">{% for question in questions.paginator.page %}
+ {% if show_summary %}
+ {% question_list_item question question_summary=yes %}
+ {% else %}
+ {% question_list_item question %}
+ {% endif %}
+{% endfor %}</div>
+{% endblock %}
+
+{% block tail %}
+ <div class="pager">{{ questions.paginator.page_numbers }}</div>
+ <div class="pagesize">{{ questions.paginator.page_sizes }}</div>
+{% endblock %}
+
+{% block sidebar %}
+ {% include "question_list/count.html" %}
+ {% sidebar_upper %}
+ {% tag_selector %}
+ {% sidebar_lower %}
+ {% question_list_related_tags questions.paginator.page %}
+
+{% endblock %}
+<!-- end questions.html -->
</strong>
</p>
- <form id="fmclose" action="{% url reopen question.id %}" method="post">
+ <form id="fmclose" action="{% url "reopen" question.id %}" method="post">
{% csrf_token %}
<div id="" style="padding:20px 0 20px 0">
<input type="submit" value="{% trans "Reopen this question" %}" class="submit" />
{% endblocktrans %}
</div>
<div id="main-body" style="text-align: center; height: 400px;">
-<form action="{% url search %}" method="get">
+<form action="{% url "search" %}" method="get">
{% csrf_token %}
<div>
<input type="text" class="searchInput" value="{{ keywords }}" name="q" id="keywords" style="width: 600px" />
</li>
</ul>
<p class='info-box-follow-up-links'>
- <a href="{% url markdown_help %}" target="_blank">{% trans "learn more about Markdown" %} </a>
+ <a href="{% url "markdown_help" %}" target="_blank">{% trans "learn more about Markdown" %} </a>
</p>
</div>
-{% load i18n %}\r
-\r
-<div class="boxC">\r
- <h3>{% trans "Recent awards" %}</h3>\r
- <div class="body">\r
- <ul class="badge-list">\r
- {% for award in awards %}\r
- <li>\r
- <a href="{% url badges %}{{award.badge.id}}/{{award.badge.name|slugify}}" title="{{ award.badge.description }}" class="medal">\r
- <span class="badge{{ award.badge.type }}">●</span> {{ award.badge.name }}</a>\r
- <a href="{{ award.user.get_profile_url }}">{{ award.user.decorated_name }}</a>\r
- </li>\r
- {% endfor %}\r
- </ul>\r
- <div class="more"><a href="{% url badges %}">{% trans "all awards" %} </a> </div>\r
- </div>\r
+{% load i18n %}
+
+<div class="boxC">
+ <h3>{% trans "Recent awards" %}</h3>
+ <div class="body">
+ <ul class="badge-list">
+ {% for award in awards %}
+ <li>
+ <a href="{% url "badges" %}{{award.badge.id}}/{{award.badge.name|slugify}}" title="{{ award.badge.description }}" class="medal">
+ <span class="badge{{ award.badge.type }}">●</span> {{ award.badge.name }}</a>
+ <a href="{{ award.user.get_profile_url }}">{{ award.user.decorated_name }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ <div class="more"><a href="{% url "badges" %}">{% trans "all awards" %} </a> </div>
+ </div>
</div>
\ No newline at end of file
-{% load i18n extra_tags %}\r
-{% declare %}\r
- show_tags_in_a_cloud = settings.SHOW_TAGS_IN_A_CLOUD\r
-{% enddeclare %}\r
-\r
-<div class="boxC">\r
- <h3>{% trans "Recent tags" %}</h3>\r
- <div class="body">\r
- <div class="tags" id="recent-tags">\r
- {% for tag in tags %}\r
- <a rel="tag"{% if show_tags_in_a_cloud %} style="font-size: {% get_tag_font_size tag %}px;"{% endif %} class="tag-link-{{ tag.name }}" title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>\r
- {% endfor %}\r
- </div>\r
- <div class="more"><a href="{% url tags %}">{% trans "popular tags" %} </a> </div>\r
- </div>\r
+{% load i18n extra_tags %}
+{% declare %}
+ show_tags_in_a_cloud = settings.SHOW_TAGS_IN_A_CLOUD
+{% enddeclare %}
+
+<div class="boxC">
+ <h3>{% trans "Recent tags" %}</h3>
+ <div class="body">
+ <div class="tags" id="recent-tags">
+ {% for tag in tags %}
+ <a rel="tag"{% if show_tags_in_a_cloud %} style="font-size: {% get_tag_font_size tag %}px;"{% endif %} class="tag-link-{{ tag.name }}" title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url "tag_questions" tag.name|urlencode %}">{{ tag.name }}</a>
+ {% endfor %}
+ </div>
+ <div class="more"><a href="{% url "tags" %}">{% trans "popular tags" %} </a> </div>
+ </div>
</div>
\ No newline at end of file
-{% load markup %}
-
{% if show %}
{% if wrap %}<div id="{{ blockid }}" class="boxC">
<div class="body">{% endif %}
{% extends "base_content.html" %}
-{% load i18n %}
-{% load markup %}
+{% load i18n extra_filters %}
{% block title %}{% spaceless %}{{ title }}{% endspaceless %}{% endblock %}
{% block content %}
<div class="headNormal">{{ title }}</div>
<div class="content">
-{{ content|markdown:"settingsparser" }}
+{{ content|static_content:"markdown" }}
</div>
{% endblock %}
-{% spaceless %}\r
-{% load i18n extra_tags %}\r
-<h3 class="subtitle">{% trans "Follow this question" %}</h3>\r
-<strong>{% trans "By Email" %}:</strong>\r
-{% if request.user.is_authenticated %}\r
- <div class="subscription-status">\r
- {% if subscription %}\r
- {% if subscription.auto_subscription %}\r
- <p>{% trans "You were automatically subscribed to this question." %}</p>\r
- {% else %}\r
- <p>{% trans "You are subscribed to this question." %}</p>\r
- {% endif %}\r
- {% else %}\r
- <p>{% trans "You are not subscribed to this question." %}</p>\r
- {% endif %}\r
- </div>\r
- <p><a class="ajax-command sidebar_button subscription_switch" href="{% url subscribe_simple id=question.id %}">\r
- {% if subscription %}\r
- {% trans "unsubscribe me" %}\r
- {% else %}\r
- {% trans "subscribe me" %}\r
- {% endif %}\r
- </a></p>\r
- <p>\r
- {% blocktrans with request.user.get_user_subscriptions_url as subscriptions_url %}\r
- (you can adjust your notification settings on your <a href="{{ subscriptions_url }}">profile</a>)\r
- {% endblocktrans %}\r
- </p>\r
-{% else %}\r
- <p>{% trans "Once you sign in you will be able to subscribe for any updates here" %}</p>\r
-{% endif %}\r
-<strong>{% trans "By RSS" %}:</strong>\r
-<p>\r
- <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');"\r
- href="{{ question.get_absolute_url }}?type=rss" title="{% trans "subscribe to answers" %}"></a>\r
- {% trans "Answers" %}\r
-</p>\r
-<p>\r
- <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');"\r
- href="{{ question.get_absolute_url }}?type=rss&comments=yes" title="{% trans "subscribe to comments and answers" %}"></a>\r
- {% trans "Answers and Comments" %}\r
-</p>\r
-{% endspaceless %}\r
+{% spaceless %}
+{% load i18n extra_tags %}
+<h3 class="subtitle">{% trans "Follow this question" %}</h3>
+<strong>{% trans "By Email" %}:</strong>
+{% if request.user.is_authenticated %}
+ <div class="subscription-status">
+ {% if subscription %}
+ {% if subscription.auto_subscription %}
+ <p>{% trans "You were automatically subscribed to this question." %}</p>
+ {% else %}
+ <p>{% trans "You are subscribed to this question." %}</p>
+ {% endif %}
+ {% else %}
+ <p>{% trans "You are not subscribed to this question." %}</p>
+ {% endif %}
+ </div>
+ <p><a class="ajax-command sidebar_button subscription_switch" href="{% url "subscribe_simple" id=question.id %}">
+ {% if subscription %}
+ {% trans "unsubscribe me" %}
+ {% else %}
+ {% trans "subscribe me" %}
+ {% endif %}
+ </a></p>
+ <p>
+ {% blocktrans with request.user.get_user_subscriptions_url as subscriptions_url %}
+ (you can adjust your notification settings on your <a href="{{ subscriptions_url }}">profile</a>)
+ {% endblocktrans %}
+ </p>
+{% else %}
+ <p>{% trans "Once you sign in you will be able to subscribe for any updates here" %}</p>
+{% endif %}
+<strong>{% trans "By RSS" %}:</strong>
+<p>
+ <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');"
+ href="{{ question.get_absolute_url }}?type=rss" title="{% trans "subscribe to answers" %}"></a>
+ {% trans "Answers" %}
+</p>
+<p>
+ <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');"
+ href="{{ question.get_absolute_url }}?type=rss&comments=yes" title="{% trans "subscribe to comments and answers" %}"></a>
+ {% trans "Answers and Comments" %}
+</p>
+{% endspaceless %}
<ul class="tagsList tags">
{% for tag in tags.paginator.page %}
<li>
- <a class="tag-link-{{ tag }}" href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">
+ <a class="tag-link-{{ tag }}" href="{% url "tag_questions" tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">
{{ tag }}
</a>
<span class="tag-number">× {{ tag.used_count|intcomma }}</span>
-{% load extra_tags %}\r
-{% load humanize %}\r
-{% load extra_tags %}\r
-\r
-<div class="action_container">\r
- <div class="action_body">\r
- {{ describe }}\r
- </div>\r
- <div class="action_date" style="text-align: right;">\r
- {% diff_date action.action_date %}\r
- </div>\r
+{% load extra_tags %}
+{% load humanize %}
+{% load extra_tags %}
+
+<div class="action_container">
+ <div class="action_body">
+ {{ describe }}
+ </div>
+ <div class="action_date" style="text-align: right;">
+ {% diff_date action.action_date %}
+ </div>
</div>
\ No newline at end of file
-{% extends "base_content.html" %}\r
-<!-- user_edit.html -->\r
-{% load extra_tags %}\r
-{% load humanize %}\r
-{% load i18n %}\r
-{% block title %}{% spaceless %}{% trans "Edit user profile" %}{% endspaceless %}{% endblock %}\r
-{% block forejs %}\r
- <script type="text/javascript">google.load("jquery", "1.4.2");google.load("jqueryui", "1.8.1");</script>\r
-\r
- <link rel="stylesheet" href="http://jquery-ui.googlecode.com/svn/tags/latest/themes/base/jquery-ui.css" type="text/css" media="all" />\r
- <link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" />\r
-\r
- <script type="text/javascript">\r
- $().ready(function(){\r
- $("#id_birthday").datepicker({\r
- changeMonth: true,\r
- changeYear: true,\r
- dateFormat: 'yy-mm-dd',\r
- minDate: null,\r
- maxDate: '0M 0D',\r
- yearRange: '1920:2010'\r
- });\r
-\r
- $("#nav_profile").attr('className',"on");\r
- $("#cancel").bind('click', function(){history.go(-1);})\r
- }); \r
- </script>\r
- {% block userjs %}\r
- {% endblock %}\r
-{% endblock %}\r
-{% block content %}\r
-<div id="main-bar" class="headNormal">\r
- {{ user.username }} - {% trans "edit profile" %}\r
-</div>\r
-<div id="main-body" style="width:100%;padding-top:10px">\r
- <form name="" action="{% url edit_user user.id user.username|slugify %}" method="post">\r
- {% csrf_token %}\r
- <div id="left" style="float:left;width:180px">\r
- {% if user.email %}\r
- {% gravatar user 128 %}\r
- {% else %}\r
- <img src="{% media "/media/images/nophoto.png" %}">\r
- {% endif %}\r
- <div style="padding:20px 0 0 20px;font-weight:bold;font-size:150%">\r
- <a href="http://www.gravatar.com/" target="_blank" \r
- title="gravatar {% trans "image associated with your email address" %}">{% trans "gravatar" %}</a>\r
- </div>\r
- </div>\r
- \r
- <div id="askform" style="float:right;width:750px;text-align:left;">\r
- <h2>{% trans "Registered user" %}</h2>\r
- <table class="user-details">\r
- <tr>\r
- <th width="100px"></th>\r
- <th></th>\r
- </tr>\r
- <tr style="height:35px">\r
- <td>{% trans "Screen Name" %}:</td>\r
- <td>\r
- {% if form.username %}\r
- {{ form.username }} <span class="form-error"></span> {{ form.username.errors }}\r
- {% else %}\r
- {{ user.username }}\r
- {% endif %}\r
- </td>\r
- </tr>\r
- \r
- <tr style="height:35px">\r
- <td>{{ form.email.label_tag }}:</td>\r
- <td>{{ form.email }} <span class="form-error"></span> {{ form.email.errors }} </td>\r
- </tr>\r
- <tr style="height:35px">\r
- <td></td>\r
- <td class="title-desc">{{ form.email.help_text }}</td>\r
- </tr>\r
- <tr style="height:35px">\r
- <td>{{ form.realname.label_tag }}:</td>\r
- <td>{{ form.realname }} <span class="form-error"></span> {{ form.realname.errors }} </td>\r
- </tr>\r
- <tr style="height:35px">\r
- <td>{{ form.website.label_tag }}:</td>\r
- <td>{{ form.website }} <span class="form-error"></span> {{ form.website.errors }} </td>\r
- </tr>\r
- <tr style="height:35px">\r
- <td>{{ form.city.label_tag }}:</td>\r
- <td>{{ form.city }} <span class="form-error"></span> {{ form.city.errors }} </td>\r
- </tr>\r
- <tr style="height:35px">\r
- <td>{{ form.birthday.label_tag }}:</td>\r
- <td>{{ form.birthday }} <span class="form-error"></span> {{ form.birthday.errors }} </td>\r
- </tr>\r
- <tr>\r
- <td style="vertical-align:top">{{ form.about.label_tag }}:</td>\r
- <td>{{ form.about }} <span class="form-error"></span> {{ form.about.errors }} </td>\r
- </tr>\r
- \r
- </table>\r
- <div style="margin:30px 0 60px 0">\r
- <input type="submit" value="{% trans "Update" %}" class="submit" >\r
- <input id="cancel" type="button" value="{% trans "Cancel" %}" class="submit" >\r
- \r
- </div>\r
- </div>\r
- </form>\r
- \r
-</div>\r
-{% endblock %}\r
-<!-- end user_edit.html -->\r
+{% extends "base_content.html" %}
+<!-- user_edit.html -->
+{% load extra_tags %}
+{% load humanize %}
+{% load i18n %}
+{% block title %}{% spaceless %}{% trans "Edit user profile" %}{% endspaceless %}{% endblock %}
+{% block forejs %}
+ <script type="text/javascript">google.load("jquery", "1.4.2");google.load("jqueryui", "1.8.1");</script>
+
+ <link rel="stylesheet" href="http://jquery-ui.googlecode.com/svn/tags/latest/themes/base/jquery-ui.css" type="text/css" media="all" />
+ <link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" />
+
+ <script type="text/javascript">
+ $().ready(function(){
+ $("#id_birthday").datepicker({
+ changeMonth: true,
+ changeYear: true,
+ dateFormat: 'yy-mm-dd',
+ minDate: null,
+ maxDate: '0M 0D',
+ yearRange: '1920:2010'
+ });
+
+ $("#nav_profile").attr('className',"on");
+ $("#cancel").bind('click', function(){history.go(-1);})
+ });
+ </script>
+ {% block userjs %}
+ {% endblock %}
+{% endblock %}
+{% block content %}
+<div id="main-bar" class="headNormal">
+ {{ user.username }} - {% trans "edit profile" %}
+</div>
+<div id="main-body" style="width:100%;padding-top:10px">
+ <form name="" action="{% url "edit_user" user.id user.username|slugify %}" method="post">
+ {% csrf_token %}
+ <div id="left" style="float:left;width:180px">
+ {% if user.email %}
+ {% gravatar user 128 %}
+ {% else %}
+ <img src="{% media "/media/images/nophoto.png" %}">
+ {% endif %}
+ <div style="padding:20px 0 0 20px;font-weight:bold;font-size:150%">
+ <a href="http://www.gravatar.com/" target="_blank"
+ title="gravatar {% trans "image associated with your email address" %}">{% trans "gravatar" %}</a>
+ </div>
+ </div>
+
+ <div id="askform" style="float:right;width:750px;text-align:left;">
+ <h2>{% trans "Registered user" %}</h2>
+ <table class="user-details">
+ <tr>
+ <th width="100px"></th>
+ <th></th>
+ </tr>
+ <tr style="height:35px">
+ <td>{% trans "Screen Name" %}:</td>
+ <td>
+ {% if form.username %}
+ {{ form.username }} <span class="form-error"></span> {{ form.username.errors }}
+ {% else %}
+ {{ user.username }}
+ {% endif %}
+ </td>
+ </tr>
+
+ <tr style="height:35px">
+ <td>{{ form.email.label_tag }}:</td>
+ <td>{{ form.email }} <span class="form-error"></span> {{ form.email.errors }} </td>
+ </tr>
+ <tr style="height:35px">
+ <td></td>
+ <td class="title-desc">{{ form.email.help_text }}</td>
+ </tr>
+ <tr style="height:35px">
+ <td>{{ form.realname.label_tag }}:</td>
+ <td>{{ form.realname }} <span class="form-error"></span> {{ form.realname.errors }} </td>
+ </tr>
+ <tr style="height:35px">
+ <td>{{ form.website.label_tag }}:</td>
+ <td>{{ form.website }} <span class="form-error"></span> {{ form.website.errors }} </td>
+ </tr>
+ <tr style="height:35px">
+ <td>{{ form.city.label_tag }}:</td>
+ <td>{{ form.city }} <span class="form-error"></span> {{ form.city.errors }} </td>
+ </tr>
+ <tr style="height:35px">
+ <td>{{ form.birthday.label_tag }}:</td>
+ <td>{{ form.birthday }} <span class="form-error"></span> {{ form.birthday.errors }} </td>
+ </tr>
+ <tr>
+ <td style="vertical-align:top">{{ form.about.label_tag }}:</td>
+ <td>{{ form.about }} <span class="form-error"></span> {{ form.about.errors }} </td>
+ </tr>
+
+ </table>
+ <div style="margin:30px 0 60px 0">
+ <input type="submit" value="{% trans "Update" %}" class="submit" >
+ <input id="cancel" type="button" value="{% trans "Cancel" %}" class="submit" >
+
+ </div>
+ </div>
+ </form>
+
+</div>
+{% endblock %}
+<!-- end user_edit.html -->
{% load humanize %}
{% load smart_if %}
{% load i18n %}
-{% load markup %}
{% load user_tags %}
<div id="subheader" class="headUser{% if view_user.is_suspended %} suspended-user{% endif %}">
{% if not view_user.email_isvalid %}
({% trans "not validated" %})
{% ifequal request.user view_user %}
- </td></tr><tr><td></td><td><a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>
+ </td></tr><tr><td></td><td><a href="{% url "send_validation_email" %}">{% trans "Send me a validation link." %}</a>
{% endifequal %}
{% endif %}
</td>
<tr>
<td colspan="2" style="text-align:right">
- <a href="{% url user_report user.pk %}" class="ajax-command withprompt">
+ <a href="{% url "user_report" user.pk %}" class="ajax-command withprompt">
Report user
</a>
</td>
{% if not view_user.is_suspended %}
<div class="user-about">
{% if view_user.about %}
- {{view_user.about|markdown}}
+ {{view_user.about|static_content:"markdown-safe"}}
{% endif %}
</div>
{% endif %}
-{% load i18n smart_if ui_registry %}\r
-\r
-<div id="user-menu-container" class="context-menu">\r
- <span id="user-menu" class="context-menu-trigger">{% trans "User tools" %} ▼</span>\r
- <ul id="user-menu-dropdown" class="context-menu-dropdown">\r
- {% loadregistry user_menu %}{% endloadregistry %}\r
- </ul>\r
-</div>\r
+{% load i18n smart_if ui_registry %}
+
+<div id="user-menu-container" class="context-menu">
+ <span id="user-menu" class="context-menu-trigger">{% trans "User tools" %} ▼</span>
+ <ul id="user-menu-dropdown" class="context-menu-dropdown">
+ {% loadregistry user_menu %}{% endloadregistry %}
+ </ul>
+</div>
-{% load i18n extra_filters %}{% spaceless %}\r
-\r
-{% if not user.is_suspended %}\r
- {% ifequal format "full" %}\r
-\r
- {% else %}\r
- <a href="{{ user.get_absolute_url }}">{{ user.decorated_name }}</a>\r
- <span class="score" title="{{ user.reputation }} {% trans "reputation" %}">{{ user.reputation|decorated_int:"" }}</span>\r
- {% ifequal format "badges" %}\r
- {% if user.gold %}\r
- <span title="{{ user.gold }} {% trans "badges" %}">\r
- <span class="badge1">●</span>\r
- <span class="badgecount">{{ user.gold }}</span>\r
- </span>\r
- {% endif %}\r
- {% if user.silver %}\r
- <span title="{{ user.silver }} {% trans "badges" %}">\r
- <span class="silver">●</span>\r
- <span class="badgecount">{{ user.silver }}</span>\r
- </span>\r
- {% endif %}\r
- {% if user.bronze %}\r
- <span title="{{ user.bronze }} {% trans "badges" %}">\r
- <span class="bronze">●</span>\r
- <span class="badgecount">{{ user.bronze }}</span>\r
- </span>\r
- {% endif %}\r
- {% endifequal %}\r
- {% endifequal %}\r
-{% else %}\r
- <a class="suspended-user" href="{{ user.get_absolute_url }}">{{ user.decorated_name }}</a>{% trans "(suspended)" %}\r
-{% endif %}\r
-{% endspaceless %}\r
+{% load i18n extra_filters %}{% spaceless %}
+
+{% if not user.is_suspended %}
+ {% ifequal format "full" %}
+
+ {% else %}
+ <a href="{{ user.get_absolute_url }}">{{ user.decorated_name }}</a>
+ <span class="score" title="{{ user.reputation }} {% trans "reputation" %}">{{ user.reputation|decorated_int:"" }}</span>
+ {% ifequal format "badges" %}
+ {% if user.gold %}
+ <span title="{{ user.gold }} {% trans "badges" %}">
+ <span class="badge1">●</span>
+ <span class="badgecount">{{ user.gold }}</span>
+ </span>
+ {% endif %}
+ {% if user.silver %}
+ <span title="{{ user.silver }} {% trans "badges" %}">
+ <span class="silver">●</span>
+ <span class="badgecount">{{ user.silver }}</span>
+ </span>
+ {% endif %}
+ {% if user.bronze %}
+ <span title="{{ user.bronze }} {% trans "badges" %}">
+ <span class="bronze">●</span>
+ <span class="badgecount">{{ user.bronze }}</span>
+ </span>
+ {% endif %}
+ {% endifequal %}
+ {% endifequal %}
+{% else %}
+ <a class="suspended-user" href="{{ user.get_absolute_url }}">{{ user.decorated_name }}</a>{% trans "(suspended)" %}
+{% endif %}
+{% endspaceless %}
<a rel="tag"
class="tag-link-{{ tag.name }}"
title="{% blocktrans with tag.name as tag_name %}see other questions with {{view_user}}'s contributions tagged '{{ tag_name }}' {% endblocktrans %}"
- href="{% url tag_questions tag|urlencode %}?user={{view_user.username}}">{{tag.name}}</a>
+ href="{% url "tag_questions" tag|urlencode %}?user={{view_user.username}}">{{tag.name}}</a>
<span class="tag-number">× {{ tag.user_tag_usage_count|intcomma }}</span><br/>
{% if forloop.counter|divisibleby:"10" %}
</td>
<td style="line-height:35px; padding-right: 20px;">
{% for award, count in awards %}
{% spaceless %}
- <a href="{% url badges %}{{award.id}}/{{award.name|slugify}}" title="{{ award.description }}" class="medal">
+ <a href="{% url "badges" %}{{award.id}}/{{award.name|slugify}}" title="{{ award.description }}" class="medal">
<span class="badge{{ award.type }}">●</span> {{ award.name }}
</a>
{% ifnotequal count 1 %}
{% trans "Manage your current subscriptions" %}
<span style="font-size:11px">
{% if auto %}
- <a href='{% url user_subscriptions id=view_user.id slug=view_user.username|slugify %}?auto=False&tab=manage'>{% trans "don't show auto-subscribe" %}</a>
+ <a href='{% url "user_subscriptions" id=view_user.id slug=view_user.username|slugify %}?auto=False&tab=manage'>{% trans "don't show auto-subscribe" %}</a>
{% else %}
- <a href='{% url user_subscriptions id=view_user.id slug=view_user.username|slugify %}?auto=True&tab=manage'>{% trans "show auto-subscribe" %}</a>
+ <a href='{% url "user_subscriptions" id=view_user.id slug=view_user.username|slugify %}?auto=True&tab=manage'>{% trans "show auto-subscribe" %}</a>
{% endif %}
</span>
</h2>
-{% load i18n %}\r
-{% load extra_tags %}\r
-{% load humanize %}\r
-\r
-<h2>{% trans "Notifications and subscription settings" %}</h2>\r
-<p class="message">\r
- {% blocktrans %}\r
- Here you can decide which types of notifications you wish to receive, and their frequency.<br />\r
- {% endblocktrans %}\r
-</p>\r
-<div class='inline-block'>\r
-<form method="POST">\r
- {% csrf_token %}\r
- {{ form.errors }}\r
- <table class="form-as-table">\r
- <tr>\r
- <td colspan="2">\r
- <strong>{% trans "Notify me when:" %}</strong>\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>{% trans "A new member joins" %}</td>\r
- <td>{{ form.member_joins }}</td>\r
- </tr>\r
- <tr>\r
- <td>{% trans "A new question is posted" %}</td>\r
- <td>{{ form.new_question }}</td>\r
- </tr>\r
- <tr>\r
- <td>{% trans "A new question matching my interesting tags is posted" %}</td>\r
- <td>{{ form.new_question_watched_tags }}</td>\r
- </tr>\r
- <tr>\r
- <td>{% trans "There's an update on one of my subscriptions" %}</td>\r
- <td >{{ form.subscribed_questions }}</td>\r
- </tr>\r
- </table>\r
- <p> </p>\r
- <table class="form-as-table check-table">\r
- <tr>\r
- <td colspan="3">\r
- <strong>{% trans "Auto subscribe me to:" %}</strong>\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- {{ form.questions_viewed }}{% trans "Questions I view" %}\r
- </td>\r
- <td>\r
- {{ form.all_questions_watched_tags }}{% trans "All questions matching my interesting tags" %}\r
- </td>\r
- <td>\r
- {{ form.all_questions }}{% trans "All questions" %}\r
- </td>\r
- </tr>\r
- </table>\r
- <p> </p>\r
- <table class="form-as-table check-table">\r
- <tr>\r
- <td colspan="2">\r
- <strong>{% trans "On my subscriptions, notify me when:" %}</strong>\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- {{ form.notify_answers }}{% trans "An answer is posted" %}\r
- </td>\r
- <td>\r
- {{ form.notify_comments_own_post }}{% trans "A comment on one of my posts is posted" %}\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- {{ form.notify_comments }}{% trans "A comment is posted" %}\r
- </td>\r
- <td>\r
- {{ form.notify_accepted }}{% trans "An answer is accepted" %}\r
- </td>\r
- </tr>\r
- </table>\r
- <p> </p>\r
- <table class="form-as-table check-table">\r
- <tr>\r
- <td>\r
- <strong>{% trans "Daily Digest:" %}</strong>\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- {{ form.send_digest }}{% trans "Send me the daily digest with information about the site activity" %}\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <strong>{% trans "Notify When I'm Discussed:" %}</strong>\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- {{ form.notify_reply_to_comments }}{% trans "Notify me when someone replies to one of my comments on any post using the <pre>@username</pre> notation" %}\r
- </td>\r
- </tr>\r
- </table>\r
- <div class="submit-row">\r
- <input type="submit" class="submit" name="save" value="{% trans "Update" %}"/>\r
- </div>\r
-</form>\r
-</div>\r
+{% load i18n %}
+{% load extra_tags %}
+{% load humanize %}
+
+<h2>{% trans "Notifications and subscription settings" %}</h2>
+<p class="message">
+ {% blocktrans %}
+ Here you can decide which types of notifications you wish to receive, and their frequency.<br />
+ {% endblocktrans %}
+</p>
+<div class='inline-block'>
+<form method="POST">
+ {% csrf_token %}
+ {{ form.errors }}
+ <table class="form-as-table">
+ <tr>
+ <td colspan="2">
+ <strong>{% trans "Notify me when:" %}</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>{% trans "A new member joins" %}</td>
+ <td>{{ form.member_joins }}</td>
+ </tr>
+ <tr>
+ <td>{% trans "A new question is posted" %}</td>
+ <td>{{ form.new_question }}</td>
+ </tr>
+ <tr>
+ <td>{% trans "A new question matching my interesting tags is posted" %}</td>
+ <td>{{ form.new_question_watched_tags }}</td>
+ </tr>
+ <tr>
+ <td>{% trans "There's an update on one of my subscriptions" %}</td>
+ <td >{{ form.subscribed_questions }}</td>
+ </tr>
+ </table>
+ <p> </p>
+ <table class="form-as-table check-table">
+ <tr>
+ <td colspan="3">
+ <strong>{% trans "Auto subscribe me to:" %}</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {{ form.questions_viewed }}{% trans "Questions I view" %}
+ </td>
+ <td>
+ {{ form.all_questions_watched_tags }}{% trans "All questions matching my interesting tags" %}
+ </td>
+ <td>
+ {{ form.all_questions }}{% trans "All questions" %}
+ </td>
+ </tr>
+ </table>
+ <p> </p>
+ <table class="form-as-table check-table">
+ <tr>
+ <td colspan="2">
+ <strong>{% trans "On my subscriptions, notify me when:" %}</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {{ form.notify_answers }}{% trans "An answer is posted" %}
+ </td>
+ <td>
+ {{ form.notify_comments_own_post }}{% trans "A comment on one of my posts is posted" %}
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {{ form.notify_comments }}{% trans "A comment is posted" %}
+ </td>
+ <td>
+ {{ form.notify_accepted }}{% trans "An answer is accepted" %}
+ </td>
+ </tr>
+ </table>
+ <p> </p>
+ <table class="form-as-table check-table">
+ <tr>
+ <td>
+ <strong>{% trans "Daily Digest:" %}</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {{ form.send_digest }}{% trans "Send me the daily digest with information about the site activity" %}
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <strong>{% trans "Notify When I'm Discussed:" %}</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {{ form.notify_reply_to_comments }}{% trans "Notify me when someone replies to one of my comments on any post using the <pre>@username</pre> notation" %}
+ </td>
+ </tr>
+ </table>
+ <div class="submit-row">
+ <input type="submit" class="submit" name="save" value="{% trans "Update" %}"/>
+ </div>
+</form>
+</div>
-import re\r
-\r
-splitter = re.compile(r'\s*=\s*')\r
-matcher = re.compile(r'^.+=.+$')\r
-\r
-def argument_parser(arguments):\r
+import re
+
+splitter = re.compile(r'\s*=\s*')
+matcher = re.compile(r'^.+=.+$')
+
+def argument_parser(arguments):
return dict(splitter.split(s) for s in arguments if matcher.match(s))
\ No newline at end of file
def static_content(content, render_mode):
if render_mode == 'markdown':
return mark_safe(markdown.markdown(unicode(content), ["settingsparser"]))
+ elif render_mode == 'markdown-safe':
+ return mark_safe(markdown.markdown(unicode(content), safe_mode=True))
elif render_mode == "html":
return mark_safe(unicode(content))
else:
- return unicode(content)
\ No newline at end of file
+ return unicode(content)
from forum.models import Question, Answer, QuestionRevision, AnswerRevision, NodeRevision
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
-from django.utils import simplejson
from forum import settings
from django.template.defaulttags import url as default_url
from forum import skins
-from django import template\r
-from forum.models import Tag, Award\r
-from forum import settings\r
-\r
-from extra_filters import static_content\r
-\r
-register = template.Library()\r
-\r
-@register.inclusion_tag('sidebar/markdown_help.html')\r
-def markdown_help():\r
- return {}\r
-\r
-@register.inclusion_tag('sidebar/recent_awards.html')\r
-def recent_awards():\r
- return {'awards': Award.objects.order_by('-awarded_at')[:settings.RECENT_AWARD_SIZE]}\r
-\r
-@register.inclusion_tag('sidebar/user_blocks.html')\r
-def sidebar_upper():\r
- return {\r
- 'show': settings.SIDEBAR_UPPER_SHOW,\r
- 'content': static_content(settings.SIDEBAR_UPPER_TEXT, settings.SIDEBAR_UPPER_RENDER_MODE),\r
- 'wrap': not settings.SIDEBAR_UPPER_DONT_WRAP,\r
- 'blockid': 'sidebar-upper'\r
- }\r
-\r
-@register.inclusion_tag('sidebar/user_blocks.html')\r
-def sidebar_lower():\r
- return {\r
- 'show': settings.SIDEBAR_LOWER_SHOW,\r
- 'content': static_content(settings.SIDEBAR_LOWER_TEXT, settings.SIDEBAR_LOWER_RENDER_MODE),\r
- 'wrap': not settings.SIDEBAR_LOWER_DONT_WRAP,\r
- 'blockid': 'sidebar-lower'\r
- }\r
-\r
-@register.inclusion_tag('sidebar/recent_tags.html')\r
-def recent_tags():\r
- return {'tags': Tag.active.order_by('-id')[:settings.RECENT_TAGS_SIZE]}\r
-\r
+from django import template
+from forum.models import Tag, Award
+from forum import settings
+
+from extra_filters import static_content
+
+register = template.Library()
+
+@register.inclusion_tag('sidebar/markdown_help.html')
+def markdown_help():
+ return {}
+
+@register.inclusion_tag('sidebar/recent_awards.html')
+def recent_awards():
+ return {'awards': Award.objects.order_by('-awarded_at')[:settings.RECENT_AWARD_SIZE]}
+
+@register.inclusion_tag('sidebar/user_blocks.html')
+def sidebar_upper():
+ return {
+ 'show': settings.SIDEBAR_UPPER_SHOW,
+ 'content': static_content(settings.SIDEBAR_UPPER_TEXT, settings.SIDEBAR_UPPER_RENDER_MODE),
+ 'wrap': not settings.SIDEBAR_UPPER_DONT_WRAP,
+ 'blockid': 'sidebar-upper'
+ }
+
+@register.inclusion_tag('sidebar/user_blocks.html')
+def sidebar_lower():
+ return {
+ 'show': settings.SIDEBAR_LOWER_SHOW,
+ 'content': static_content(settings.SIDEBAR_LOWER_TEXT, settings.SIDEBAR_LOWER_RENDER_MODE),
+ 'wrap': not settings.SIDEBAR_LOWER_DONT_WRAP,
+ 'blockid': 'sidebar-lower'
+ }
+
+@register.inclusion_tag('sidebar/recent_tags.html')
+def recent_tags():
+ return {'tags': Tag.active.order_by('-id')[:settings.RECENT_TAGS_SIZE]}
+
\ No newline at end of file
-from datetime import datetime, timedelta\r
-import re\r
-\r
-from forum.models import Question, Action\r
-from django.template import Template, Context\r
-from django.utils.translation import ungettext, ugettext as _\r
-from django.utils.html import strip_tags\r
-from django.utils.encoding import smart_unicode\r
-from django.utils.safestring import mark_safe\r
-from django.conf import settings as django_settings\r
-from django.core.urlresolvers import reverse\r
-from django import template\r
-from forum.actions import *\r
-from forum import settings\r
-\r
-register = template.Library()\r
-\r
-@register.inclusion_tag('node/vote_buttons.html')\r
-def vote_buttons(post, user):\r
- context = dict(post=post, user_vote='none')\r
-\r
- if user.is_authenticated():\r
- context['user_vote'] = {1: 'up', -1: 'down', None: 'none'}[VoteAction.get_for(user, post)]\r
-\r
- return context\r
-\r
-@register.inclusion_tag('node/accept_button.html')\r
-def accept_button(answer, user):\r
- if not settings.DISABLE_ACCEPTING_FEATURE:\r
- return {\r
- 'can_accept': user.is_authenticated() and user.can_accept_answer(answer),\r
- 'answer': answer,\r
- 'user': user\r
- }\r
- else:\r
- return ''\r
-\r
-@register.inclusion_tag('node/wiki_symbol.html')\r
-def wiki_symbol(user, post):\r
- context = {\r
- 'is_wiki': post.nis.wiki,\r
- 'post_type': post.friendly_name\r
- }\r
-\r
- if post.nis.wiki:\r
- if user.can_edit_post(post):\r
- context['can_edit'] = True\r
- context['edit_url'] = reverse('edit_' + post.node_type, kwargs={'id': post.id})\r
- context['by'] = post.nstate.wiki.by.username\r
- context['at'] = post.nstate.wiki.at\r
-\r
- return context\r
-\r
-@register.inclusion_tag('node/favorite_mark.html')\r
-def favorite_mark(question, user):\r
- try:\r
- FavoriteAction.objects.get(canceled=False, node=question, user=user)\r
- favorited = True\r
- except:\r
- favorited = False\r
-\r
- return {'favorited': favorited, 'favorite_count': question.favorite_count, 'question': question}\r
-\r
-@register.simple_tag\r
-def post_classes(post):\r
- classes = []\r
-\r
- if post.nis.deleted:\r
- classes.append('deleted')\r
-\r
- if post.node_type == "answer":\r
- if (not settings.DISABLE_ACCEPTING_FEATURE) and post.nis.accepted:\r
- classes.append('accepted-answer')\r
-\r
- if post.author == post.question.author:\r
- classes.append('answered-by-owner')\r
-\r
- return " ".join(classes)\r
-\r
-def post_control(text, url, command=False, withprompt=False, confirm=False, title="", copy=False, extra_classes=[]):\r
- classes = (command and "ajax-command" or " ") + (withprompt and " withprompt" or " ") + (confirm and " confirm" or " ") + \\r
- (copy and " copy" or " ")\r
-\r
- for extra_class in extra_classes:\r
- classes += " %s" % extra_class\r
-\r
- return {'text': text, 'url': url, 'classes': classes, 'title': title}\r
-\r
-\r
-moderation_enabled = False\r
-for m in django_settings.MODULE_LIST:\r
- if m.__name__.endswith('moderation'):\r
- moderation_enabled = True\r
-\r
-@register.inclusion_tag('node/post_controls.html' if not moderation_enabled else "modules/moderation/node/post_controls.html")\r
-def post_controls(post, user):\r
- controls = []\r
- menu = []\r
- post_type = post.node_type\r
-\r
- # We show the link tool if the post is an Answer. It is visible to Guests too.\r
- if post_type == "answer":\r
- # Answer permanent link tool\r
- controls.append(post_control(_('permanent link'), reverse('answer_permanent_link', kwargs={'id' : post.id,}),\r
- title=_("answer permanent link"), command=True, withprompt=True, copy=True))\r
-\r
- # Users should be able to award points for an answer. Users cannot award their own answers\r
- if user != post.author and user.is_authenticated() and user.reputation > 1:\r
- controls.append(post_control(_("award points"), reverse('award_points', kwargs={'user_id' : post.author.id,\r
- 'answer_id' : post.id}), title=_("award points to %s") % smart_unicode(post.author.username),\r
- command=True, withprompt=True))\r
-\r
- # The other controls are visible only to authenticated users.\r
- if user.is_authenticated():\r
- try:\r
- edit_url = reverse('edit_' + post_type, kwargs={'id': post.id})\r
- if user.can_edit_post(post):\r
- controls.append(post_control(_('edit'), edit_url))\r
- elif post_type == 'question' and user.can_retag_questions():\r
- controls.append(post_control(_('retag'), edit_url))\r
- except:\r
- pass\r
-\r
- if post_type == 'question':\r
- if post.nis.closed and user.can_reopen_question(post):\r
- controls.append(post_control(_('reopen'), reverse('reopen', kwargs={'id': post.id}), command=True))\r
- elif not post.nis.closed and user.can_close_question(post):\r
- controls.append(post_control(_('close'), reverse('close', kwargs={'id': post.id}), command=True, withprompt=True))\r
-\r
- if user.can_flag_offensive(post):\r
- label = _('report')\r
- \r
- if user.can_view_offensive_flags(post):\r
- label = "%s (%d)" % (label, post.flag_count)\r
-\r
-\r
- report_control = post_control(label, reverse('flag_post', kwargs={'id': post.id}),\r
- command=True, withprompt=True,\r
- title=_("report as offensive (i.e containing spam, advertising, malicious text, etc.)"))\r
-\r
- # Depending on the setting choose where to attach the control\r
- if settings.REPORT_OFFENSIVE_CONTROL_POSITION.value == "more":\r
- menu.append(report_control)\r
- else:\r
- controls.append(report_control)\r
-\r
- if user.can_delete_post(post):\r
- if post.nis.deleted:\r
- controls.append(post_control(_('undelete'), reverse('delete_post', kwargs={'id': post.id}),\r
- command=True, confirm=True))\r
- else:\r
- controls.append(post_control(_('delete'), reverse('delete_post', kwargs={'id': post.id}),\r
- command=True, confirm=True))\r
-\r
- if user.can_delete_post(post):\r
- menu.append(post_control(_('see revisions'),\r
- reverse('revisions',\r
- kwargs={'id': post.id}),\r
- command=False, confirm=False))\r
-\r
- if settings.WIKI_ON:\r
- if (not post.nis.wiki) and user.can_wikify(post):\r
- menu.append(post_control(_('mark as community wiki'), reverse('wikify', kwargs={'id': post.id}),\r
- command=True, confirm=True))\r
-\r
- elif post.nis.wiki and user.can_cancel_wiki(post):\r
- menu.append(post_control(_('cancel community wiki'), reverse('wikify', kwargs={'id': post.id}),\r
- command=True, confirm=True))\r
-\r
- if post.node_type == "answer" and user.can_convert_to_comment(post):\r
- menu.append(post_control(_('convert to comment'), reverse('convert_to_comment', kwargs={'id': post.id}),\r
- command=True, withprompt=True))\r
- \r
- if post.node_type == "answer" and user.can_convert_to_question(post):\r
- menu.append(post_control(_('convert to question'), reverse('convert_to_question', kwargs={'id': post.id}),\r
- command=False, confirm=True))\r
-\r
- if user.is_superuser or user.is_staff:\r
- plain_text = strip_tags(post.html)\r
-\r
- char_count = len(plain_text)\r
- fullStr = plain_text + " "\r
- left_trimmedStr = re.sub(re.compile(r"^[^\w]+", re.IGNORECASE), "", fullStr)\r
- cleanedStr = re.sub(re.compile(r"[^\w]+", re.IGNORECASE), " ", left_trimmedStr)\r
- splitString = cleanedStr.split(" ")\r
- word_count = len(splitString) - 1\r
-\r
- metrics = mark_safe("<b>%s %s / %s %s</b>" % (char_count, ungettext('character', 'characters', char_count),\r
- word_count, ungettext('word', 'words', word_count)))\r
-\r
- menu.append(post_control(metrics, "#", command=False, withprompt=False))\r
-\r
- return {'controls': controls, 'menu': menu, 'post': post, 'user': user}\r
-\r
-def _comments(post, user):\r
- all_comments = post.comments.filter_state(deleted=False)\\r
- .order_by('-added_at' if settings.SHOW_LATEST_COMMENTS_FIRST else 'added_at')\r
-\r
- if len(all_comments) <= 5:\r
- top_scorers = all_comments\r
- else:\r
- top_scorers = sorted(all_comments, lambda c1, c2: cmp(c2.score, c1.score))[0:5]\r
-\r
- comments = []\r
- showing = 0\r
- for c in all_comments:\r
- context = {\r
- 'can_delete': user.can_delete_comment(c),\r
- 'can_like': user.can_like_comment(c),\r
- 'can_edit': user.can_edit_comment(c),\r
- 'can_convert': user.can_convert_comment_to_answer(c)\r
- }\r
-\r
- if c in top_scorers or c.is_reply_to(user):\r
- context['top_scorer'] = True\r
- showing += 1\r
- \r
- if context['can_like']:\r
- context['likes'] = VoteAction.get_for(user, c) == 1\r
-\r
- context['user'] = c.user\r
- context['comment'] = c.comment\r
- context.update(dict(c.__dict__))\r
- comments.append(context)\r
-\r
- # Generate canned comments\r
- canned_comments = []\r
- for comment in settings.CANNED_COMMENTS:\r
- t = Template(smart_unicode(comment))\r
- c = Context({\r
- 'post' : post,\r
- 'settings' : settings,\r
- })\r
- canned_comments.append(t.render(c))\r
-\r
- total = len(all_comments)\r
- return {\r
- 'comments': comments,\r
- 'canned_comments': canned_comments,\r
- 'post': post,\r
- 'can_comment': user.can_comment(post),\r
- 'max_length': settings.FORM_MAX_COMMENT_BODY,\r
- 'min_length': settings.FORM_MIN_COMMENT_BODY,\r
- 'show_gravatar': settings.FORM_GRAVATAR_IN_COMMENTS,\r
- 'showing': showing,\r
- 'total': total,\r
- 'more_comments_count' : int(total - showing),\r
- 'show_latest_comments_first' : settings.SHOW_LATEST_COMMENTS_FIRST,\r
- 'user': user,\r
- }\r
-\r
-@register.inclusion_tag('node/comments.html')\r
-def comments(post, user):\r
- return _comments(post, user)\r
-\r
-@register.inclusion_tag("node/contributors_info.html", takes_context=True)\r
-def contributors_info(context, node, verb=None):\r
- return {\r
- 'node_verb': verb and verb or ((node.node_type == "question") and _("asked") or (\r
- (node.node_type == "answer") and _("answered") or _("posted"))),\r
- 'node': node,\r
- 'context' : context\r
- }\r
-\r
-@register.inclusion_tag("node/reviser_info.html")\r
-def reviser_info(revision):\r
- return {'revision': revision}\r
+from datetime import datetime, timedelta
+import re
+
+from forum.models import Question, Action
+from django.template import Template, Context
+from django.utils.translation import ungettext, ugettext as _
+from django.utils.html import strip_tags
+from django.utils.encoding import smart_unicode
+from django.utils.safestring import mark_safe
+from django.conf import settings as django_settings
+from django.core.urlresolvers import reverse
+from django import template
+from forum.actions import *
+from forum import settings
+
+register = template.Library()
+
+@register.inclusion_tag('node/vote_buttons.html')
+def vote_buttons(post, user):
+ context = dict(post=post, user_vote='none')
+
+ if user.is_authenticated():
+ context['user_vote'] = {1: 'up', -1: 'down', None: 'none'}[VoteAction.get_for(user, post)]
+
+ return context
+
+@register.inclusion_tag('node/accept_button.html')
+def accept_button(answer, user):
+ if not settings.DISABLE_ACCEPTING_FEATURE:
+ return {
+ 'can_accept': user.is_authenticated() and user.can_accept_answer(answer),
+ 'answer': answer,
+ 'user': user
+ }
+ else:
+ return ''
+
+@register.inclusion_tag('node/wiki_symbol.html')
+def wiki_symbol(user, post):
+ context = {
+ 'is_wiki': post.nis.wiki,
+ 'post_type': post.friendly_name
+ }
+
+ if post.nis.wiki:
+ if user.can_edit_post(post):
+ context['can_edit'] = True
+ context['edit_url'] = reverse('edit_' + post.node_type, kwargs={'id': post.id})
+ context['by'] = post.nstate.wiki.by.username
+ context['at'] = post.nstate.wiki.at
+
+ return context
+
+@register.inclusion_tag('node/favorite_mark.html')
+def favorite_mark(question, user):
+ try:
+ FavoriteAction.objects.get(canceled=False, node=question, user=user)
+ favorited = True
+ except:
+ favorited = False
+
+ return {'favorited': favorited, 'favorite_count': question.favorite_count, 'question': question}
+
+@register.simple_tag
+def post_classes(post):
+ classes = []
+
+ if post.nis.deleted:
+ classes.append('deleted')
+
+ if post.node_type == "answer":
+ if (not settings.DISABLE_ACCEPTING_FEATURE) and post.nis.accepted:
+ classes.append('accepted-answer')
+
+ if post.author == post.question.author:
+ classes.append('answered-by-owner')
+
+ return " ".join(classes)
+
+def post_control(text, url, command=False, withprompt=False, confirm=False, title="", copy=False, extra_classes=[]):
+ classes = (command and "ajax-command" or " ") + (withprompt and " withprompt" or " ") + (confirm and " confirm" or " ") + \
+ (copy and " copy" or " ")
+
+ for extra_class in extra_classes:
+ classes += " %s" % extra_class
+
+ return {'text': text, 'url': url, 'classes': classes, 'title': title}
+
+
+moderation_enabled = False
+for m in django_settings.MODULE_LIST:
+ if m.__name__.endswith('moderation'):
+ moderation_enabled = True
+
+@register.inclusion_tag('node/post_controls.html' if not moderation_enabled else "modules/moderation/node/post_controls.html")
+def post_controls(post, user):
+ controls = []
+ menu = []
+ post_type = post.node_type
+
+ # We show the link tool if the post is an Answer. It is visible to Guests too.
+ if post_type == "answer":
+ # Answer permanent link tool
+ controls.append(post_control(_('permanent link'), reverse('answer_permanent_link', kwargs={'id' : post.id,}),
+ title=_("answer permanent link"), command=True, withprompt=True, copy=True))
+
+ # Users should be able to award points for an answer. Users cannot award their own answers
+ if user != post.author and user.is_authenticated() and user.reputation > 1:
+ controls.append(post_control(_("award points"), reverse('award_points', kwargs={'user_id' : post.author.id,
+ 'answer_id' : post.id}), title=_("award points to %s") % smart_unicode(post.author.username),
+ command=True, withprompt=True))
+
+ # The other controls are visible only to authenticated users.
+ if user.is_authenticated():
+ try:
+ edit_url = reverse('edit_' + post_type, kwargs={'id': post.id})
+ if user.can_edit_post(post):
+ controls.append(post_control(_('edit'), edit_url))
+ elif post_type == 'question' and user.can_retag_questions():
+ controls.append(post_control(_('retag'), edit_url))
+ except:
+ pass
+
+ if post_type == 'question':
+ if post.nis.closed and user.can_reopen_question(post):
+ controls.append(post_control(_('reopen'), reverse('reopen', kwargs={'id': post.id}), command=True))
+ elif not post.nis.closed and user.can_close_question(post):
+ controls.append(post_control(_('close'), reverse('close', kwargs={'id': post.id}), command=True, withprompt=True))
+
+ if user.can_flag_offensive(post):
+ label = _('report')
+
+ if user.can_view_offensive_flags(post):
+ label = "%s (%d)" % (label, post.flag_count)
+
+
+ report_control = post_control(label, reverse('flag_post', kwargs={'id': post.id}),
+ command=True, withprompt=True,
+ title=_("report as offensive (i.e containing spam, advertising, malicious text, etc.)"))
+
+ # Depending on the setting choose where to attach the control
+ if settings.REPORT_OFFENSIVE_CONTROL_POSITION.value == "more":
+ menu.append(report_control)
+ else:
+ controls.append(report_control)
+
+ if user.can_delete_post(post):
+ if post.nis.deleted:
+ controls.append(post_control(_('undelete'), reverse('delete_post', kwargs={'id': post.id}),
+ command=True, confirm=True))
+ else:
+ controls.append(post_control(_('delete'), reverse('delete_post', kwargs={'id': post.id}),
+ command=True, confirm=True))
+
+ if user.can_delete_post(post):
+ menu.append(post_control(_('see revisions'),
+ reverse('revisions',
+ kwargs={'id': post.id}),
+ command=False, confirm=False))
+
+ if settings.WIKI_ON:
+ if (not post.nis.wiki) and user.can_wikify(post):
+ menu.append(post_control(_('mark as community wiki'), reverse('wikify', kwargs={'id': post.id}),
+ command=True, confirm=True))
+
+ elif post.nis.wiki and user.can_cancel_wiki(post):
+ menu.append(post_control(_('cancel community wiki'), reverse('wikify', kwargs={'id': post.id}),
+ command=True, confirm=True))
+
+ if post.node_type == "answer" and user.can_convert_to_comment(post):
+ menu.append(post_control(_('convert to comment'), reverse('convert_to_comment', kwargs={'id': post.id}),
+ command=True, withprompt=True))
+
+ if post.node_type == "answer" and user.can_convert_to_question(post):
+ menu.append(post_control(_('convert to question'), reverse('convert_to_question', kwargs={'id': post.id}),
+ command=False, confirm=True))
+
+ if user.is_superuser or user.is_staff:
+ plain_text = strip_tags(post.html)
+
+ char_count = len(plain_text)
+ fullStr = plain_text + " "
+ left_trimmedStr = re.sub(re.compile(r"^[^\w]+", re.IGNORECASE), "", fullStr)
+ cleanedStr = re.sub(re.compile(r"[^\w]+", re.IGNORECASE), " ", left_trimmedStr)
+ splitString = cleanedStr.split(" ")
+ word_count = len(splitString) - 1
+
+ metrics = mark_safe("<b>%s %s / %s %s</b>" % (char_count, ungettext('character', 'characters', char_count),
+ word_count, ungettext('word', 'words', word_count)))
+
+ menu.append(post_control(metrics, "#", command=False, withprompt=False))
+
+ return {'controls': controls, 'menu': menu, 'post': post, 'user': user}
+
+def _comments(post, user):
+ all_comments = post.comments.filter_state(deleted=False)\
+ .order_by('-added_at' if settings.SHOW_LATEST_COMMENTS_FIRST else 'added_at')
+
+ if len(all_comments) <= 5:
+ top_scorers = all_comments
+ else:
+ top_scorers = sorted(all_comments, lambda c1, c2: cmp(c2.score, c1.score))[0:5]
+
+ comments = []
+ showing = 0
+ for c in all_comments:
+ context = {
+ 'can_delete': user.can_delete_comment(c),
+ 'can_like': user.can_like_comment(c),
+ 'can_edit': user.can_edit_comment(c),
+ 'can_convert': user.can_convert_comment_to_answer(c)
+ }
+
+ if c in top_scorers or c.is_reply_to(user):
+ context['top_scorer'] = True
+ showing += 1
+
+ if context['can_like']:
+ context['likes'] = VoteAction.get_for(user, c) == 1
+
+ context['user'] = c.user
+ context['comment'] = c.comment
+ context.update(dict(c.__dict__))
+ comments.append(context)
+
+ # Generate canned comments
+ canned_comments = []
+ for comment in settings.CANNED_COMMENTS:
+ t = Template(smart_unicode(comment))
+ c = Context({
+ 'post' : post,
+ 'settings' : settings,
+ })
+ canned_comments.append(t.render(c))
+
+ total = len(all_comments)
+ return {
+ 'comments': comments,
+ 'canned_comments': canned_comments,
+ 'post': post,
+ 'can_comment': user.can_comment(post),
+ 'max_length': settings.FORM_MAX_COMMENT_BODY,
+ 'min_length': settings.FORM_MIN_COMMENT_BODY,
+ 'show_gravatar': settings.FORM_GRAVATAR_IN_COMMENTS,
+ 'showing': showing,
+ 'total': total,
+ 'more_comments_count' : int(total - showing),
+ 'show_latest_comments_first' : settings.SHOW_LATEST_COMMENTS_FIRST,
+ 'user': user,
+ }
+
+@register.inclusion_tag('node/comments.html')
+def comments(post, user):
+ return _comments(post, user)
+
+@register.inclusion_tag("node/contributors_info.html", takes_context=True)
+def contributors_info(context, node, verb=None):
+ return {
+ 'node_verb': verb and verb or ((node.node_type == "question") and _("asked") or (
+ (node.node_type == "answer") and _("answered") or _("posted"))),
+ 'node': node,
+ 'context' : context
+ }
+
+@register.inclusion_tag("node/reviser_info.html")
+def reviser_info(revision):
+ return {'revision': revision}
-from django import template\r
-from django.utils.translation import ugettext as _\r
-from django.utils.safestring import mark_safe\r
-from forum.models import Tag, MarkedTag\r
-from forum.templatetags import argument_parser\r
-from forum import settings\r
-\r
-register = template.Library()\r
-\r
-class QuestionItemNode(template.Node):\r
- template = template.loader.get_template('question_list/item.html')\r
-\r
- def __init__(self, question, options):\r
- self.question = template.Variable(question)\r
- self.options = options\r
-\r
- def render(self, context):\r
- return self.template.render(template.Context({\r
- 'question': self.question.resolve(context),\r
- 'question_summary': self.options.get('question_summary', 'no' ) == 'yes',\r
- 'favorite_count': self.options.get('favorite_count', 'no') == 'yes',\r
- 'signature_type': self.options.get('signature_type', 'lite'),\r
- }))\r
-\r
-class SubscriptionItemNode(template.Node):\r
- template = template.loader.get_template('question_list/subscription_item.html')\r
-\r
- def __init__(self, subscription, question, options):\r
- self.question = template.Variable(question)\r
- self.subscription = template.Variable(subscription)\r
- self.options = options\r
-\r
- def render(self, context):\r
- return self.template.render(template.Context({\r
- 'question': self.question.resolve(context),\r
- 'subscription': self.subscription.resolve(context),\r
- 'signature_type': self.options.get('signature_type', 'lite'),\r
- }))\r
-\r
-@register.tag\r
-def question_list_item(parser, token):\r
- tokens = token.split_contents()[1:]\r
- return QuestionItemNode(tokens[0], argument_parser(tokens[1:]))\r
-\r
-@register.tag\r
-def subscription_list_item(parser, token):\r
- tokens = token.split_contents()[1:]\r
- return SubscriptionItemNode(tokens[0], tokens[1], argument_parser(tokens[2:]))\r
-\r
-@register.inclusion_tag('question_list/sort_tabs.html')\r
-def question_sort_tabs(sort_context):\r
- return sort_context\r
-\r
-@register.inclusion_tag('question_list/related_tags.html')\r
-def question_list_related_tags(questions):\r
- if len(questions):\r
- tags = Tag.objects.filter(nodes__id__in=[q.id for q in questions]).distinct()\r
-\r
- if settings.LIMIT_RELATED_TAGS:\r
- tags = tags[:settings.LIMIT_RELATED_TAGS]\r
-\r
- return {'tags': tags}\r
- else:\r
- return {'tags': False}\r
-\r
-@register.inclusion_tag('question_list/tag_selector.html', takes_context=True)\r
-def tag_selector(context):\r
- request = context['request']\r
- show_interesting_tags = settings.SHOW_INTERESTING_TAGS_BOX\r
-\r
- if request.user.is_authenticated():\r
- pt = MarkedTag.objects.filter(user=request.user)\r
- return {\r
- 'request' : request,\r
- "interesting_tag_names": pt.filter(reason='good').values_list('tag__name', flat=True),\r
- 'ignored_tag_names': pt.filter(reason='bad').values_list('tag__name', flat=True),\r
- 'user_authenticated': True,\r
- 'show_interesting_tags' : show_interesting_tags,\r
- }\r
- else:\r
- return { 'request' : request, 'user_authenticated': False, 'show_interesting_tags' : show_interesting_tags }\r
+from django import template
+from django.utils.translation import ugettext as _
+from django.utils.safestring import mark_safe
+from forum.models import Tag, MarkedTag
+from forum.templatetags import argument_parser
+from forum import settings
+
+register = template.Library()
+
+class QuestionItemNode(template.Node):
+ template = template.loader.get_template('question_list/item.html')
+
+ def __init__(self, question, options):
+ self.question = template.Variable(question)
+ self.options = options
+
+ def render(self, context):
+ return self.template.render(template.Context({
+ 'question': self.question.resolve(context),
+ 'question_summary': self.options.get('question_summary', 'no' ) == 'yes',
+ 'favorite_count': self.options.get('favorite_count', 'no') == 'yes',
+ 'signature_type': self.options.get('signature_type', 'lite'),
+ }))
+
+class SubscriptionItemNode(template.Node):
+ template = template.loader.get_template('question_list/subscription_item.html')
+
+ def __init__(self, subscription, question, options):
+ self.question = template.Variable(question)
+ self.subscription = template.Variable(subscription)
+ self.options = options
+
+ def render(self, context):
+ return self.template.render(template.Context({
+ 'question': self.question.resolve(context),
+ 'subscription': self.subscription.resolve(context),
+ 'signature_type': self.options.get('signature_type', 'lite'),
+ }))
+
+@register.tag
+def question_list_item(parser, token):
+ tokens = token.split_contents()[1:]
+ return QuestionItemNode(tokens[0], argument_parser(tokens[1:]))
+
+@register.tag
+def subscription_list_item(parser, token):
+ tokens = token.split_contents()[1:]
+ return SubscriptionItemNode(tokens[0], tokens[1], argument_parser(tokens[2:]))
+
+@register.inclusion_tag('question_list/sort_tabs.html')
+def question_sort_tabs(sort_context):
+ return sort_context
+
+@register.inclusion_tag('question_list/related_tags.html')
+def question_list_related_tags(questions):
+ if len(questions):
+ tags = Tag.objects.filter(nodes__id__in=[q.id for q in questions]).distinct()
+
+ if settings.LIMIT_RELATED_TAGS:
+ tags = tags[:settings.LIMIT_RELATED_TAGS]
+
+ return {'tags': tags}
+ else:
+ return {'tags': False}
+
+@register.inclusion_tag('question_list/tag_selector.html', takes_context=True)
+def tag_selector(context):
+ request = context['request']
+ show_interesting_tags = settings.SHOW_INTERESTING_TAGS_BOX
+
+ if request.user.is_authenticated():
+ pt = MarkedTag.objects.filter(user=request.user)
+ return {
+ 'request' : request,
+ "interesting_tag_names": pt.filter(reason='good').values_list('tag__name', flat=True),
+ 'ignored_tag_names': pt.filter(reason='bad').values_list('tag__name', flat=True),
+ 'user_authenticated': True,
+ 'show_interesting_tags' : show_interesting_tags,
+ }
+ else:
+ return { 'request' : request, 'user_authenticated': False, 'show_interesting_tags' : show_interesting_tags }
-from django import template\r
-from django.utils.translation import ugettext as _\r
-from django.utils.safestring import mark_safe\r
-import logging\r
-\r
-register = template.Library()\r
-\r
-class UserSignatureNode(template.Node):\r
- template = template.loader.get_template('users/signature.html')\r
-\r
- def __init__(self, user, format):\r
- self.user = template.Variable(user)\r
- self.format = template.Variable(format)\r
-\r
- def render(self, context):\r
- return self.template.render(template.Context({\r
- 'user': self.user.resolve(context),\r
- 'format': self.format.resolve(context)\r
- }))\r
-\r
-@register.tag\r
-def user_signature(parser, token):\r
- try:\r
- tag_name, user, format = token.split_contents()\r
- except ValueError:\r
- raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]\r
-\r
- return UserSignatureNode(user, format)\r
-\r
-\r
-class ActivityNode(template.Node):\r
- template = template.loader.get_template('users/activity.html')\r
-\r
- def __init__(self, activity, viewer):\r
- self.activity = template.Variable(activity)\r
- self.viewer = template.Variable(viewer)\r
-\r
- def render(self, context):\r
- try:\r
- action = self.activity.resolve(context).leaf\r
- viewer = self.viewer.resolve(context)\r
- describe = mark_safe(action.describe(viewer))\r
- return self.template.render(template.Context(dict(action=action, describe=describe)))\r
- except Exception, e:\r
- import traceback\r
- msg = "Error in action describe: \n %s" % (\r
- traceback.format_exc()\r
- )\r
- logging.error(msg)\r
-\r
-@register.tag\r
-def activity_item(parser, token):\r
- try:\r
- tag_name, activity, viewer = token.split_contents()\r
- except ValueError:\r
- raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]\r
-\r
- return ActivityNode(activity, viewer)\r
-\r
-\r
-@register.tag\r
-def flagged_item(parser, token):\r
- try:\r
- tag_name, post, viewer = token.split_contents()\r
- except ValueError:\r
- raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]\r
-\r
- return ActivityNode(post, viewer)\r
-\r
-\r
-@register.inclusion_tag('users/menu.html')\r
-def user_menu(viewer, user):\r
- return dict(viewer=viewer, user=user)\r
-\r
+from django import template
+from django.utils.translation import ugettext as _
+from django.utils.safestring import mark_safe
+import logging
+
+register = template.Library()
+
+class UserSignatureNode(template.Node):
+ template = template.loader.get_template('users/signature.html')
+
+ def __init__(self, user, format):
+ self.user = template.Variable(user)
+ self.format = template.Variable(format)
+
+ def render(self, context):
+ return self.template.render(template.Context({
+ 'user': self.user.resolve(context),
+ 'format': self.format.resolve(context)
+ }))
+
+@register.tag
+def user_signature(parser, token):
+ try:
+ tag_name, user, format = token.split_contents()
+ except ValueError:
+ raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
+
+ return UserSignatureNode(user, format)
+
+
+class ActivityNode(template.Node):
+ template = template.loader.get_template('users/activity.html')
+
+ def __init__(self, activity, viewer):
+ self.activity = template.Variable(activity)
+ self.viewer = template.Variable(viewer)
+
+ def render(self, context):
+ try:
+ action = self.activity.resolve(context).leaf
+ viewer = self.viewer.resolve(context)
+ describe = mark_safe(action.describe(viewer))
+ return self.template.render(template.Context(dict(action=action, describe=describe)))
+ except Exception, e:
+ import traceback
+ msg = "Error in action describe: \n %s" % (
+ traceback.format_exc()
+ )
+ logging.error(msg)
+
+@register.tag
+def activity_item(parser, token):
+ try:
+ tag_name, activity, viewer = token.split_contents()
+ except ValueError:
+ raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
+
+ return ActivityNode(activity, viewer)
+
+
+@register.tag
+def flagged_item(parser, token):
+ try:
+ tag_name, post, viewer = token.split_contents()
+ except ValueError:
+ raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
+
+ return ActivityNode(post, viewer)
+
+
+@register.inclusion_tag('users/menu.html')
+def user_menu(viewer, user):
+ return dict(viewer=viewer, user=user)
+
import os.path
from forum import settings
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url, include
from django.conf import settings as djsettings
from django.contrib import admin
from forum import views as app
APP_PATH = os.path.dirname(__file__)
-try:
- admin_url = url(r'^%s(.*)' % _('nimda/'), admin.site.root)
-except AttributeError:
- admin_url = url(r'^%s(.*)' % _('nimda/'), admin.site.urls)
-
# Choose the user urls pattern
if bool(settings.INCLUDE_ID_IN_USER_URLS.value):
core_user_urls_prefix = r'^%s(?P<id>\d+)/(?P<slug>.*)'
core_user_urls_prefix = r'^%s(?P<slug>.*)'
core_urls = (
- url(r'^$', app.readers.index, name='index'), admin_url,
+ url(r'^$', app.readers.index, name='index'),
+ url(r'^%s(.*)' % _('nimda/'), admin.site.urls),
url(r'^sitemap.xml$', 'forum.sitemap.index', {'sitemaps': sitemaps}),
url(r'^sitemap-(?P<section>.+)-(?P<page>\d+)\.xml$', 'forum.sitemap.sitemap', {'sitemaps': sitemaps}, name="sitemap_section_page"),
url(r'^%s(?P<id>\d+)/' % _('convert_to_question/'), app.writers.convert_to_question,name='convert_to_question'),
url(r'^%s(?P<id>\d+)/' % _('wikify/'), app.commands.wikify, name='wikify'),
- url(r'^%s(?P<id>\d+)/(?P<slug>[\w-]*)$' % _('question/'), 'django.views.generic.simple.redirect_to', {'url': '/questions/%(id)s/%(slug)s'}),
+ url(r'^%s(?P<id>\d+)/(?P<slug>[\w-]*)$' % _('question/'), 'django.shortcuts.redirect', {'url': '/questions/%(id)s/%(slug)s'}),
url(r'^%s(?P<id>\d+)/?$' % _('questions/'), app.readers.question, name='question'),
url(r'^%s(?P<id>\d+)/(?P<slug>.*)/(?P<answer>\d+)$' % _('questions/'), app.readers.question),
url(r'^%s(?P<id>\d+)/(?P<slug>.*)$' % _('questions/'), app.readers.question, name='question'),
"""
from django.utils.encoding import StrAndUnicode
-from forum.user_messages import get_and_delete_messages
+from django.contrib.messages.api import get_messages
def user_messages (request):
"""
Returns session messages for the current session.
"""
- messages = request.user.get_and_delete_messages()
- #if request.user.is_authenticated():
- #else:
- # messages = LazyMessages(request)
- #import inspect
- #print inspect.stack()[1]
- #print messages
- return { 'user_messages': messages }
-
-class LazyMessages (StrAndUnicode):
- """
- Lazy message container, so messages aren't actually retrieved from
- session and deleted until the template asks for them.
-
- """
- def __init__(self, request):
- self.request = request
-
- def __iter__(self):
- return iter(self.messages)
-
- def __len__(self):
- return len(self.messages)
-
- def __nonzero__(self):
- return bool(self.messages)
-
- def __unicode__(self):
- return unicode(self.messages)
-
- def __getitem__(self, *args, **kwargs):
- return self.messages.__getitem__(*args, **kwargs)
-
- def _get_messages(self):
- if hasattr(self, '_messages'):
- return self._messages
- self._messages = get_and_delete_messages(self.request)
- return self._messages
- messages = property(_get_messages)
-
+ return { 'user_messages': get_messages(request) }
+import json
from django.http import HttpResponse, HttpResponseForbidden, Http404
-from django.utils import simplejson
def ajax_login_required(view_func):
def wrap(request,*args,**kwargs):
if request.user.is_authenticated():
return view_func(request,*args,**kwargs)
else:
- json = simplejson.dumps({'login_required':True})
- return HttpResponseForbidden(json,mimetype='application/json')
+ json = json.dumps({'login_required':True})
+ return HttpResponseForbidden(json, mimetype='application/json')
return wrap
def ajax_method(view_func):
retval.mimetype = 'application/json'
return retval
else:
- json = simplejson.dumps(retval)
- return HttpResponse(json,mimetype='application/json')
+ json = json.dumps(retval)
+ return HttpResponse(json, mimetype='application/json')
return wrap
"""Utilities for working with HTML."""
-#import html5lib
from html5lib import sanitizer, serializer, tokenizer, treebuilders, treewalkers, HTMLParser
from urllib import quote_plus
from django.utils.html import strip_tags
-# Copyright (c) 2001 Chris Withers\r
-#\r
-# This Software is released under the MIT License:\r
-# http://www.opensource.org/licenses/mit-license.html\r
-# See license.txt for more details.\r
-#\r
-# $Id: html2text.py,v 1.7 2002/12/17 16:56:17 fresh Exp $\r
-\r
-import sgmllib\r
-from string import lower, replace, split, join\r
-\r
-class HTML2Text(sgmllib.SGMLParser):\r
-\r
- from htmlentitydefs import entitydefs # replace entitydefs from sgmllib\r
-\r
- def __init__(self, ignore_tags=(), indent_width=4, page_width=80):\r
- sgmllib.SGMLParser.__init__(self)\r
- self.result = ""\r
- self.indent = 0\r
- self.ol_number = 0\r
- self.page_width=page_width\r
- self.inde_width=indent_width\r
- self.lines=[]\r
- self.line=[]\r
- self.ignore_tags = ignore_tags\r
-\r
- def add_text(self,text):\r
- # convert text into words\r
- words = split(replace(text,'\n',' '))\r
- self.line.extend(words)\r
-\r
- def add_break(self):\r
- self.lines.append((self.indent,self.line))\r
- self.line=[]\r
-\r
- def generate(self):\r
- # join lines with indents\r
- indent_width = self.inde_width\r
- page_width = self.page_width\r
- out_paras=[]\r
- for indent,line in self.lines+[(self.indent,self.line)]:\r
-\r
- i=indent*indent_width\r
- indent_string = i*' '\r
- line_width = page_width-i\r
-\r
- out_para=''\r
- out_line=[]\r
- len_out_line=0\r
- for word in line:\r
- len_word = len(word)\r
- if len_out_line+len_word<line_width:\r
- out_line.append(word)\r
- len_out_line = len_out_line + len_word\r
- else:\r
- out_para = out_para + indent_string + join(out_line, ' ') + '\n'\r
- out_line=[word]\r
- len_out_line=len_word\r
-\r
- out_para = out_para + indent_string + join(out_line, ' ')\r
- out_paras.append(out_para)\r
-\r
- self.result = join(out_paras,'\n\n')\r
-\r
-\r
- def mod_indent(self,i):\r
- self.indent = self.indent + i\r
- if self.indent < 0:\r
- self.indent = 0\r
-\r
- def handle_data(self, data):\r
- if data:\r
- self.add_text(data)\r
-\r
- def unknown_starttag(self, tag, attrs):\r
- """ Convert HTML to something meaningful in plain text """\r
- tag = lower(tag)\r
-\r
- if tag not in self.ignore_tags:\r
- if tag[0]=='h' or tag in ['br','pre','p','hr']:\r
- # insert a blank line\r
- self.add_break()\r
-\r
- elif tag =='img':\r
- # newline, text, newline\r
- src = ''\r
-\r
- for k, v in attrs:\r
- if lower(k) == 'src':\r
- src = v\r
-\r
- self.add_break()\r
- self.add_text('Image: ' + src)\r
-\r
- elif tag =='li':\r
- self.add_break()\r
- if self.ol_number:\r
- # num - text\r
- self.add_text(str(self.ol_number) + ' - ')\r
- self.ol_number = self.ol_number + 1\r
- else:\r
- # - text\r
- self.add_text('- ')\r
-\r
- elif tag in ['dd','dt']:\r
- self.add_break()\r
- # increase indent\r
- self.mod_indent(+1)\r
-\r
- elif tag in ['ul','dl','ol']:\r
- # blank line\r
- # increase indent\r
- self.mod_indent(+1)\r
- if tag=='ol':\r
- self.ol_number = 1\r
-\r
- def unknown_endtag(self, tag):\r
- """ Convert HTML to something meaningful in plain text """\r
- tag = lower(tag)\r
-\r
- if tag not in self.ignore_tags:\r
- if tag[0]=='h' or tag in ['pre']:\r
- # newline, text, newline\r
- self.add_break()\r
-\r
- elif tag =='li':\r
- self.add_break()\r
-\r
- elif tag in ['dd','dt']:\r
- self.add_break()\r
- # descrease indent\r
- self.mod_indent(-1)\r
-\r
- elif tag in ['ul','dl','ol']:\r
- # blank line\r
- self.add_break()\r
- # decrease indent\r
- self.mod_indent(-1)\r
- self.ol_number = 0\r
-\r
+# Copyright (c) 2001 Chris Withers
+#
+# This Software is released under the MIT License:
+# http://www.opensource.org/licenses/mit-license.html
+# See license.txt for more details.
+#
+# $Id: html2text.py,v 1.7 2002/12/17 16:56:17 fresh Exp $
+
+import sgmllib
+from string import lower, replace, split, join
+
+class HTML2Text(sgmllib.SGMLParser):
+
+ from htmlentitydefs import entitydefs # replace entitydefs from sgmllib
+
+ def __init__(self, ignore_tags=(), indent_width=4, page_width=80):
+ sgmllib.SGMLParser.__init__(self)
+ self.result = ""
+ self.indent = 0
+ self.ol_number = 0
+ self.page_width=page_width
+ self.inde_width=indent_width
+ self.lines=[]
+ self.line=[]
+ self.ignore_tags = ignore_tags
+
+ def add_text(self,text):
+ # convert text into words
+ words = split(replace(text,'\n',' '))
+ self.line.extend(words)
+
+ def add_break(self):
+ self.lines.append((self.indent,self.line))
+ self.line=[]
+
+ def generate(self):
+ # join lines with indents
+ indent_width = self.inde_width
+ page_width = self.page_width
+ out_paras=[]
+ for indent,line in self.lines+[(self.indent,self.line)]:
+
+ i=indent*indent_width
+ indent_string = i*' '
+ line_width = page_width-i
+
+ out_para=''
+ out_line=[]
+ len_out_line=0
+ for word in line:
+ len_word = len(word)
+ if len_out_line+len_word<line_width:
+ out_line.append(word)
+ len_out_line = len_out_line + len_word
+ else:
+ out_para = out_para + indent_string + join(out_line, ' ') + '\n'
+ out_line=[word]
+ len_out_line=len_word
+
+ out_para = out_para + indent_string + join(out_line, ' ')
+ out_paras.append(out_para)
+
+ self.result = join(out_paras,'\n\n')
+
+
+ def mod_indent(self,i):
+ self.indent = self.indent + i
+ if self.indent < 0:
+ self.indent = 0
+
+ def handle_data(self, data):
+ if data:
+ self.add_text(data)
+
+ def unknown_starttag(self, tag, attrs):
+ """ Convert HTML to something meaningful in plain text """
+ tag = lower(tag)
+
+ if tag not in self.ignore_tags:
+ if tag[0]=='h' or tag in ['br','pre','p','hr']:
+ # insert a blank line
+ self.add_break()
+
+ elif tag =='img':
+ # newline, text, newline
+ src = ''
+
+ for k, v in attrs:
+ if lower(k) == 'src':
+ src = v
+
+ self.add_break()
+ self.add_text('Image: ' + src)
+
+ elif tag =='li':
+ self.add_break()
+ if self.ol_number:
+ # num - text
+ self.add_text(str(self.ol_number) + ' - ')
+ self.ol_number = self.ol_number + 1
+ else:
+ # - text
+ self.add_text('- ')
+
+ elif tag in ['dd','dt']:
+ self.add_break()
+ # increase indent
+ self.mod_indent(+1)
+
+ elif tag in ['ul','dl','ol']:
+ # blank line
+ # increase indent
+ self.mod_indent(+1)
+ if tag=='ol':
+ self.ol_number = 1
+
+ def unknown_endtag(self, tag):
+ """ Convert HTML to something meaningful in plain text """
+ tag = lower(tag)
+
+ if tag not in self.ignore_tags:
+ if tag[0]=='h' or tag in ['pre']:
+ # newline, text, newline
+ self.add_break()
+
+ elif tag =='li':
+ self.add_break()
+
+ elif tag in ['dd','dt']:
+ self.add_break()
+ # descrease indent
+ self.mod_indent(-1)
+
+ elif tag in ['ul','dl','ol']:
+ # blank line
+ self.add_break()
+ # decrease indent
+ self.mod_indent(-1)
+ self.ol_number = 0
+
from datetime import datetime, timedelta
+import json
import time
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.template import RequestContext
from django.utils.translation import ugettext as _
-from django.utils import simplejson
from django.db import models
+from django.contrib import messages
+
from forum.http_responses import HttpResponseUnauthorized
from forum.settings.base import Setting
from forum.forms import MaintenanceModeForm, PageForm, CreateUserForm
'added_at', flat=True)
last_month_n_questions = Question.objects.filter_state(deleted=False).filter(added_at__lt=last_month).count()
- qgraph_data = simplejson.dumps([
+ qgraph_data = json.dumps([
(time.mktime(d.timetuple()) * 1000, i + last_month_n_questions)
for i, d in enumerate(last_month_questions)
])
last_month_n_users = User.objects.filter(date_joined__lt=last_month).count()
- ugraph_data = simplejson.dumps([
+ ugraph_data = json.dumps([
(time.mktime(d.timetuple()) * 1000, i + last_month_n_users)
for i, d in enumerate(last_month_users)
])
if not 'reset' in request.POST:
form.save()
- request.user.message_set.create(message=_("'%s' settings saved succesfully") % set_name)
+ messages.info(request, _("'%s' settings saved succesfully") % set_name)
if set_name in ('minrep', 'badges', 'repgain'):
settings.SETTINGS_PACK.set_value("custom")
settings.SETTINGS_PACK.set_value("bootstrap")
- request.user.message_set.create(message=_('Bootstrap mode enabled'))
+ messages.info(request, _('Bootstrap mode enabled'))
return HttpResponseRedirect(reverse('admin_index'))
@super_user_required
settings.SETTINGS_PACK.set_value("default")
- request.user.message_set.create(message=_('All values reverted to defaults'))
+ messages.info(request, ('All values reverted to defaults'))
return HttpResponseRedirect(reverse('admin_index'))
u.reputation = u.reputes.aggregate(reputation=models.Sum('value'))['reputation']
u.save()
- request.user.message_set.create(message=_('All values recalculated'))
+ messages.info(request, _('All values recalculated'))
return HttpResponseRedirect(reverse('admin_index'))
@admin_page
else:
message = _('Settings adjusted')
- request.user.message_set.create(message=message)
+ messages.info(request, message)
return HttpResponseRedirect(reverse('admin_maintenance'))
elif 'open' in request.POST:
settings.MAINTAINANCE_MODE.set_value(None)
- request.user.message_set.create(message=_("Your site is now running normally"))
+ messages.info(request, _("Your site is now running normally"))
return HttpResponseRedirect(reverse('admin_maintenance'))
else:
form = MaintenanceModeForm(initial={'ips': request.META['REMOTE_ADDR'],
user_.save()
UserJoinsAction(user=user_).save()
- request.user.message_set.create(message=_("New user created sucessfully. %s.") % html.hyperlink(
+ messages.info(request, _("New user created sucessfully. %s.") % html.hyperlink(
user_.get_profile_url(), _("See %s profile") % user_.username, target="_blank"))
return HttpResponseRedirect(reverse("admin_tools", kwargs={'name': 'createuser'}))
message = _("All selected nodes deleted")
- request.user.message_set.create(message=message)
+ messages.info(request, message)
params = pagination.generate_uri(request.GET, ('page',))
'osqaadmin/test_email_settings.html',
{ 'user': user, },
RequestContext(request)
- )
\ No newline at end of file
+ )
from django.utils.encoding import smart_unicode
from django.contrib.auth import login, logout
+from django.contrib import messages
+
from writers import manage_pending_data
from forum.actions import EmailValidationAction
except:
uassoc = AuthKeyUserAssociation(user=request.user, key=assoc_key, provider=provider)
uassoc.save()
- request.user.message_set.create(
- message=_('The new credentials are now associated with your account'))
+ messages.info(request, _('The new credentials are now associated with your account'))
return HttpResponseRedirect(reverse('user_authsettings', args=[request.user.id]))
return HttpResponseRedirect(reverse('auth_signin'))
send_template_email([u], "auth/temp_login_email.html", {'temp_login_code': hash})
- request.user.message_set.create(message=_("An email has been sent with your temporary login key"))
+ messages.info(request, _("An email has been sent with your temporary login key"))
return HttpResponseRedirect(reverse('index'))
else:
'additional_get_params' : additional_get_params
})
- request.user.message_set.create(message=_("A message with an email validation link was just sent to your address."))
+ messages.info(request, _("A message with an email validation link was just sent to your address."))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
user_.save()
if is_new_pass:
- request.user.message_set.create(message=_("New password set"))
+ messages.info(request, _("New password set"))
if not request.user.is_superuser:
form = ChangePasswordForm(user=user_)
else:
- request.user.message_set.create(message=_("Your password was changed"))
+ messages.info(request, _("Your password was changed"))
return HttpResponseRedirect(reverse('user_authsettings', kwargs={'id': user_.id}))
else:
if not (request.user.is_superuser or request.user == association.user):
return HttpResponseUnauthorized(request)
- request.user.message_set.create(message=_("You removed the association with %s") % association.provider)
+ messages.info(request, _("You removed the association with %s") % association.provider)
association.delete()
return HttpResponseRedirect(reverse('user_authsettings', kwargs={'id': association.user.id}))
if message is None:
message = _("Welcome back %s, you are now logged in") % smart_unicode(user.username)
- request.user.message_set.create(message=message)
+ messages.info(request, message)
if not forward:
forward = request.session.get(ON_SIGNIN_SESSION_ATTR, reverse('index'))
if submission_time < datetime.datetime.now() - datetime.timedelta(minutes=int(settings.HOLD_PENDING_POSTS_MINUTES)):
del request.session[PENDING_SUBMISSION_SESSION_ATTR]
elif submission_time < datetime.datetime.now() - datetime.timedelta(minutes=int(settings.WARN_PENDING_POSTS_MINUTES)):
- user.message_set.create(message=(_("You have a %s pending submission.") % pending_data['data_name']) + " %s, %s, %s" % (
+ messages.info(request, (_("You have a %s pending submission.") % pending_data['data_name']) + " %s, %s, %s" % (
html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('save')}), _("save it")),
html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('review')}), _("review")),
html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('cancel')}), _("cancel"))
if suspension:
message += (":<br />" + suspension.extra.get(msg_type, ''))
- request.user.message_set.create(message)
+ messages.info(request, message)
return HttpResponseRedirect(reverse('index'))
@decorate.withfn(login_required)
# -*- coding: utf-8 -*-
import datetime
+import json
import logging
from urllib import urlencode
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
-from django.utils import simplejson
from django.utils.encoding import smart_unicode
from django.utils.translation import ungettext, ugettext as _
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import get_object_or_404, render_to_response
+from django.contrib import messages
+
from forum.models import *
from forum.utils.decorators import ajax_login_required
from forum.actions import *
""")
# Notify the user with a message that an answer has been accepted
- request.user.message_set.create(message=msg)
+ messages.info(request, msg)
# Redirect URL should include additional get parameters that might have been attached
redirect_url = answer.parent.get_absolute_url() + "?accepted_answer=true&%s" % smart_unicode(urlencode(request.GET))
pass
else:
ts.update(reason=reason)
- return HttpResponse(simplejson.dumps(''), mimetype="application/json")
+ return HttpResponse(json.dumps(''), mimetype="application/json")
def matching_tags(request):
if len(request.GET['q']) == 0:
if can_rank and isinstance(can_rank, basestring):
questions = questions.order_by(can_rank)
- return HttpResponse(simplejson.dumps(
+ return HttpResponse(json.dumps(
[dict(title=q.title, url=q.get_absolute_url(), score=q.score, summary=q.summary)
for q in questions.filter_state(deleted=False)[0:10]]), mimetype="application/json")
else:
AwardPointsAction(user=request.user, node=answer, extra=extra).save(data=dict(value=points, affected=awarded_user))
return { 'message' : _("You have awarded %(awarded_user)s with %(points)d points") % {'awarded_user' : awarded_user, 'points' : points} }
+
-# -*- coding: utf-8 -*-\r
-\r
-import logging\r
-\r
-from datetime import datetime\r
-\r
-from django.http import HttpResponse, HttpResponseRedirect\r
-from django.utils import simplejson\r
-from django.shortcuts import render_to_response\r
-from django.core.urlresolvers import reverse\r
-from django.template import RequestContext\r
-from django.utils.translation import ugettext as _\r
-\r
-from forum.modules import ui, decorate\r
-from forum.settings import ONLINE_USERS\r
-\r
-def login_required(func, request, *args, **kwargs):\r
- if not request.user.is_authenticated():\r
- return HttpResponseRedirect(reverse('auth_signin'))\r
- else:\r
- return func(request, *args, **kwargs)\r
-\r
-def render(template=None, tab=None, tab_title='', weight=500, tabbed=True):\r
- def decorator(func): \r
- def decorated(context, request, *args, **kwargs):\r
- if request.user.is_authenticated():\r
- ONLINE_USERS[request.user] = datetime.now()\r
-\r
- if isinstance(context, HttpResponse):\r
- return context\r
-\r
- if tab is not None:\r
- context['tab'] = tab\r
-\r
- return render_to_response(context.pop('template', template), context,\r
- context_instance=RequestContext(request))\r
-\r
- if tabbed and tab and tab_title:\r
- ui.register(ui.PAGE_TOP_TABS,\r
- ui.PageTab(tab, tab_title, lambda: reverse(func.__name__), weight=weight))\r
- \r
- return decorate.result.withfn(decorated, needs_params=True)(func)\r
-\r
- return decorator\r
-\r
-class CommandException(Exception):\r
- pass\r
-\r
-class RefreshPageCommand(HttpResponse):\r
- def __init__(self):\r
- super(RefreshPageCommand, self).__init__(\r
- content=simplejson.dumps({'commands': {'refresh_page': []}, 'success': True}),\r
- mimetype="application/json")\r
-\r
-def command(func, request, *args, **kwargs):\r
- try:\r
- response = func(request, *args, **kwargs)\r
-\r
- if isinstance(response, HttpResponse):\r
- return response\r
-\r
- response['success'] = True\r
- except Exception, e:\r
- import traceback\r
- #traceback.print_exc()\r
-\r
- if isinstance(e, CommandException):\r
- response = {\r
- 'success': False,\r
- 'error_message': e.message\r
- }\r
- else:\r
- logging.error("%s: %s" % (func.__name__, str(e)))\r
- logging.error(traceback.format_exc())\r
- response = {\r
- 'success': False,\r
- 'error_message': _("We're sorry, but an unknown error ocurred.<br />Please try again in a while.")\r
- }\r
-\r
- if request.is_ajax():\r
- return HttpResponse(simplejson.dumps(response), mimetype="application/json")\r
- else:\r
- return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))\r
-\r
+# -*- coding: utf-8 -*-
+import json
+import logging
+
+from datetime import datetime
+
+from django.http import HttpResponse, HttpResponseRedirect
+from django.shortcuts import render_to_response
+from django.core.urlresolvers import reverse
+from django.template import RequestContext
+from django.utils.translation import ugettext as _
+
+from forum.modules import ui, decorate
+from forum.settings import ONLINE_USERS
+
+def login_required(func, request, *args, **kwargs):
+ if not request.user.is_authenticated():
+ return HttpResponseRedirect(reverse('auth_signin'))
+ else:
+ return func(request, *args, **kwargs)
+
+def render(template=None, tab=None, tab_title='', weight=500, tabbed=True):
+ def decorator(func):
+ def decorated(context, request, *args, **kwargs):
+ if request.user.is_authenticated():
+ ONLINE_USERS[request.user] = datetime.now()
+
+ if isinstance(context, HttpResponse):
+ return context
+
+ if tab is not None:
+ context['tab'] = tab
+
+ return render_to_response(context.pop('template', template), context,
+ context_instance=RequestContext(request))
+
+ if tabbed and tab and tab_title:
+ ui.register(ui.PAGE_TOP_TABS,
+ ui.PageTab(tab, tab_title, lambda: reverse(func.__name__), weight=weight))
+
+ return decorate.result.withfn(decorated, needs_params=True)(func)
+
+ return decorator
+
+class CommandException(Exception):
+ pass
+
+class RefreshPageCommand(HttpResponse):
+ def __init__(self):
+ super(RefreshPageCommand, self).__init__(
+ content=json.dumps({'commands': {'refresh_page': []}, 'success': True}),
+ mimetype="application/json")
+
+def command(func, request, *args, **kwargs):
+ try:
+ response = func(request, *args, **kwargs)
+
+ if isinstance(response, HttpResponse):
+ return response
+
+ response['success'] = True
+ except Exception, e:
+ import traceback
+ #traceback.print_exc()
+
+ if isinstance(e, CommandException):
+ response = {
+ 'success': False,
+ 'error_message': e.message
+ }
+ else:
+ logging.error("%s: %s" % (func.__name__, str(e)))
+ logging.error(traceback.format_exc())
+ response = {
+ 'success': False,
+ 'error_message': _("We're sorry, but an unknown error ocurred.<br />Please try again in a while.")
+ }
+
+ if request.is_ajax():
+ return HttpResponse(json.dumps(response), mimetype="application/json")
+ else:
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
+
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
+from django.contrib import messages
+
from forum import settings
from forum.views.decorators import login_required
from forum.forms import FeedbackForm
from forum.modules import decorate
from forum.forms import get_next_url
from forum.models import Badge, Award, User, Page
-from forum.badges.base import BadgesMeta
from forum.http_responses import HttpResponseNotFound, HttpResponseIntServerError
from forum.utils.mail import send_template_email
from forum.templatetags.extra_filters import or_preview
send_template_email(recipients, "notifications/feedback.html", context)
msg = _('Thanks for the feedback!')
- request.user.message_set.create(message=msg)
+ messages.info(request, msg)
return HttpResponseRedirect(get_next_url(request))
else:
form = FeedbackForm(request.user, initial={'next':get_next_url(request)})
@decorators.render('badges.html', 'badges', _('badges'), weight=300)
def badges(request):
+ from forum.badges.base import BadgesMeta
badges = sorted([Badge.objects.get(id=id) for id in BadgesMeta.by_id.keys()], lambda b1, b2: cmp(b1.name, b2.name))
if request.user.is_authenticated():
-from forum.models import User\r
-from django.db.models import Q, Count\r
-from django.core.paginator import Paginator, EmptyPage, InvalidPage\r
-from django.template.defaultfilters import slugify\r
-from django.contrib.contenttypes.models import ContentType\r
-from django.core.urlresolvers import reverse\r
-from django.shortcuts import render_to_response, get_object_or_404\r
-from django.template import RequestContext\r
-from django.http import HttpResponse, HttpResponseRedirect, Http404\r
-from forum.http_responses import HttpResponseUnauthorized\r
-from django.utils.translation import ugettext as _\r
-from django.utils.http import urlquote_plus\r
-from django.utils.html import strip_tags\r
-from django.utils.encoding import smart_unicode\r
-from django.utils import simplejson\r
-from django.core.urlresolvers import reverse, NoReverseMatch\r
-from forum.forms import *\r
-from forum.utils.html import sanitize_html\r
-from forum.modules import decorate, ReturnImediatelyException\r
-from datetime import datetime, date\r
-from forum.actions import EditProfileAction, FavoriteAction, BonusRepAction, SuspendAction, ReportAction\r
-from forum.modules import ui\r
-from forum.utils import pagination\r
-from forum.views.readers import QuestionListPaginatorContext, AnswerPaginatorContext\r
-from forum.settings import ONLINE_USERS\r
- \r
-import time\r
-import datetime\r
-import decorators\r
-\r
-class UserReputationSort(pagination.SimpleSort):\r
- def apply(self, objects):\r
- return objects.order_by('-is_active', self.order_by)\r
-\r
-class UserListPaginatorContext(pagination.PaginatorContext):\r
- def __init__(self, pagesizes=(20, 35, 60), default_pagesize=35):\r
- super (UserListPaginatorContext, self).__init__('USERS_LIST', sort_methods=(\r
- (_('reputation'), UserReputationSort(_('reputation'), '-reputation', _("sorted by reputation"))),\r
- (_('newest'), pagination.SimpleSort(_('recent'), '-date_joined', _("newest members"))),\r
- (_('last'), pagination.SimpleSort(_('oldest'), 'date_joined', _("oldest members"))),\r
- (_('name'), pagination.SimpleSort(_('by username'), 'username', _("sorted by username"))),\r
- ), pagesizes=pagesizes, default_pagesize=default_pagesize)\r
-\r
-class SubscriptionListPaginatorContext(pagination.PaginatorContext):\r
- def __init__(self):\r
- super (SubscriptionListPaginatorContext, self).__init__('SUBSCRIPTION_LIST', pagesizes=(5, 10, 20), default_pagesize=20)\r
-\r
-class UserAnswersPaginatorContext(pagination.PaginatorContext):\r
- def __init__(self):\r
- super (UserAnswersPaginatorContext, self).__init__('USER_ANSWER_LIST', sort_methods=(\r
- (_('oldest'), pagination.SimpleSort(_('oldest answers'), 'added_at', _("oldest answers will be shown first"))),\r
- (_('newest'), pagination.SimpleSort(_('newest answers'), '-added_at', _("newest answers will be shown first"))),\r
- (_('votes'), pagination.SimpleSort(_('popular answers'), '-score', _("most voted answers will be shown first"))),\r
- ), default_sort=_('votes'), pagesizes=(5, 10, 20), default_pagesize=20, prefix=_('answers'))\r
-\r
-USERS_PAGE_SIZE = 35# refactor - move to some constants file\r
-\r
-@decorators.render('users/users.html', 'users', _('users'), weight=200)\r
-def users(request):\r
- suser = request.REQUEST.get('q', "")\r
- users = User.objects.all()\r
-\r
- if suser != "":\r
- users = users.filter(username__icontains=suser)\r
-\r
- return pagination.paginated(request, ('users', UserListPaginatorContext()), {\r
- "users" : users,\r
- "suser" : suser,\r
- })\r
-\r
-\r
-@decorators.render('users/online_users.html', 'online_users', _('Online Users'), weight=200, tabbed=False)\r
-def online_users(request):\r
- suser = request.REQUEST.get('q', "")\r
-\r
- sort = ""\r
- if request.GET.get("sort", None):\r
- try:\r
- sort = int(request.GET["sort"])\r
- except ValueError:\r
- logging.error('Found invalid sort "%s", loading %s, refered by %s' % (\r
- request.GET.get("sort", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
- ))\r
- raise Http404()\r
-\r
- page = 0\r
- if request.GET.get("page", None):\r
- try:\r
- page = int(request.GET["page"])\r
- except ValueError:\r
- logging.error('Found invalid page "%s", loading %s, refered by %s' % (\r
- request.GET.get("page", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
- ))\r
- raise Http404()\r
-\r
- pagesize = 10\r
- if request.GET.get("pagesize", None):\r
- try:\r
- pagesize = int(request.GET["pagesize"])\r
- except ValueError:\r
- logging.error('Found invalid pagesize "%s", loading %s, refered by %s' % (\r
- request.GET.get("pagesize", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
- ))\r
- raise Http404()\r
-\r
-\r
- users = None\r
- if sort == "reputation":\r
- users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.reputation)\r
- elif sort == "newest" :\r
- users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)\r
- elif sort == "last":\r
- users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.last)\r
- elif sort == "name":\r
- users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.name)\r
- elif sort == "oldest":\r
- users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.oldest)\r
- elif sort == "newest":\r
- users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)\r
- elif sort == "votes":\r
- users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.votes)\r
- else:\r
- users = sorted(ONLINE_USERS.iteritems(), key=lambda x: x[1])\r
-\r
- return render_to_response('users/online_users.html', {\r
- "users" : users,\r
- "suser" : suser,\r
- "sort" : sort,\r
- "page" : page,\r
- "pageSize" : pagesize,\r
- })\r
-\r
-\r
-def edit_user(request, id, slug):\r
- user = get_object_or_404(User, id=id)\r
- if not (request.user.is_superuser or request.user == user):\r
- return HttpResponseUnauthorized(request)\r
- if request.method == "POST":\r
- form = EditUserForm(user, request.POST)\r
- if form.is_valid():\r
- new_email = sanitize_html(form.cleaned_data['email'])\r
-\r
- if new_email != user.email:\r
- user.email = new_email\r
- user.email_isvalid = False\r
-\r
- try:\r
- hash = ValidationHash.objects.get(user=request.user, type='email')\r
- hash.delete()\r
- except:\r
- pass\r
-\r
- if settings.EDITABLE_SCREEN_NAME:\r
- user.username = sanitize_html(form.cleaned_data['username'])\r
- user.real_name = sanitize_html(form.cleaned_data['realname'])\r
- user.website = sanitize_html(form.cleaned_data['website'])\r
- user.location = sanitize_html(form.cleaned_data['city'])\r
- user.date_of_birth = form.cleaned_data['birthday']\r
- if user.date_of_birth == "None":\r
- user.date_of_birth = datetime(1900, 1, 1, 0, 0)\r
- user.about = sanitize_html(form.cleaned_data['about'])\r
-\r
- user.save()\r
- EditProfileAction(user=user, ip=request.META['REMOTE_ADDR']).save()\r
-\r
- request.user.message_set.create(message=_("Profile updated."))\r
- return HttpResponseRedirect(user.get_profile_url())\r
- else:\r
- form = EditUserForm(user)\r
- return render_to_response('users/edit.html', {\r
- 'user': user,\r
- 'form' : form,\r
- 'gravatar_faq_url' : reverse('faq') + '#gravatar',\r
- }, context_instance=RequestContext(request))\r
-\r
-\r
-@decorate.withfn(decorators.command)\r
-def user_powers(request, id, action, status):\r
- if not request.user.is_superuser:\r
- raise decorators.CommandException(_("Only superusers are allowed to alter other users permissions."))\r
-\r
- if (action == 'remove' and 'status' == 'super') and not request.user.is_siteowner():\r
- raise decorators.CommandException(_("Only the site owner can remove the super user status from other user."))\r
-\r
- user = get_object_or_404(User, id=id)\r
- new_state = action == 'grant'\r
-\r
- if status == 'super':\r
- user.is_superuser = new_state\r
- elif status == 'staff':\r
- user.is_staff = new_state\r
- else:\r
- raise Http404()\r
-\r
- user.save()\r
- return decorators.RefreshPageCommand()\r
-\r
-\r
-@decorate.withfn(decorators.command)\r
-def award_points(request, id):\r
- if not request.POST:\r
- return render_to_response('users/karma_bonus.html')\r
-\r
- if not request.user.is_superuser:\r
- raise decorators.CommandException(_("Only superusers are allowed to award reputation points"))\r
-\r
- try:\r
- points = int(request.POST['points'])\r
- except:\r
- raise decorators.CommandException(_("Invalid number of points to award."))\r
-\r
- user = get_object_or_404(User, id=id)\r
-\r
- extra = dict(message=request.POST.get('message', ''), awarding_user=request.user.id, value=points)\r
-\r
- BonusRepAction(user=request.user, extra=extra).save(data=dict(value=points, affected=user))\r
-\r
- return {'commands': {\r
- 'update_profile_karma': [user.reputation]\r
- }}\r
- \r
-\r
-@decorate.withfn(decorators.command)\r
-def suspend(request, id):\r
- user = get_object_or_404(User, id=id)\r
-\r
- if not request.user.is_superuser:\r
- raise decorators.CommandException(_("Only superusers can suspend other users"))\r
-\r
- if not request.POST.get('bantype', None):\r
- if user.is_suspended():\r
- suspension = user.suspension\r
- suspension.cancel(user=request.user, ip=request.META['REMOTE_ADDR'])\r
- return decorators.RefreshPageCommand()\r
- else:\r
- return render_to_response('users/suspend_user.html')\r
-\r
- data = {\r
- 'bantype': request.POST.get('bantype', 'Indefinitely').strip(),\r
- 'publicmsg': request.POST.get('publicmsg', _('Bad behaviour')),\r
- 'privatemsg': request.POST.get('privatemsg', None) or request.POST.get('publicmsg', ''),\r
- 'suspended': user\r
- }\r
-\r
- if data['bantype'] == 'forxdays':\r
- try:\r
- data['forxdays'] = int(request.POST['forxdays'])\r
- except:\r
- raise decorators.CommandException(_('Invalid numeric argument for the number of days.'))\r
-\r
- SuspendAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=data)\r
-\r
- return decorators.RefreshPageCommand()\r
-\r
-@decorate.withfn(decorators.command)\r
-def report_user(request, id):\r
- user = get_object_or_404(User, id=id)\r
-\r
- if not request.POST.get('publicmsg', None):\r
- return render_to_response('users/report_user.html')\r
-\r
- data = {\r
- 'publicmsg': request.POST.get('publicmsg', _('N/A')),\r
- 'reported': user\r
- }\r
-\r
- ReportAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=data)\r
-\r
-\r
- return decorators.RefreshPageCommand()\r
-\r
-\r
-\r
-def user_view(template, tab_name, tab_title, tab_description, private=False, tabbed=True, render_to=None, weight=500):\r
- def decorator(fn):\r
- def params(request, id=None, slug=None):\r
- # Get the user object by id if the id parameter has been passed\r
- if id is not None:\r
- user = get_object_or_404(User, id=id)\r
- # ...or by slug if the slug has been given\r
- elif slug is not None:\r
- try:\r
- user = User.objects.get(username__iexact=slug)\r
- except User.DoesNotExist:\r
- raise Http404\r
-\r
- if private and not (user == request.user or request.user.is_superuser):\r
- raise ReturnImediatelyException(HttpResponseUnauthorized(request))\r
-\r
- if render_to and (not render_to(user)):\r
- raise ReturnImediatelyException(HttpResponseRedirect(user.get_profile_url()))\r
-\r
- return [request, user], { 'slug' : slug, }\r
-\r
- decorated = decorate.params.withfn(params)(fn)\r
-\r
- def result(context_or_response, request, user, **kwargs):\r
- rev_page_title = smart_unicode(user.username) + " - " + tab_description\r
-\r
- # Check whether the return type of the decorated function is a context or Http Response\r
- if isinstance(context_or_response, HttpResponse):\r
- response = context_or_response\r
-\r
- # If it is a response -- show it\r
- return response\r
- else:\r
- # ...if it is a context move forward, update it and render it to response\r
- context = context_or_response\r
-\r
- context.update({\r
- "tab": "users",\r
- "active_tab" : tab_name,\r
- "tab_description" : tab_description,\r
- "page_title" : rev_page_title,\r
- "can_view_private": (user == request.user) or request.user.is_superuser\r
- })\r
- return render_to_response(template, context, context_instance=RequestContext(request))\r
-\r
- decorated = decorate.result.withfn(result, needs_params=True)(decorated)\r
-\r
- if tabbed:\r
- def url_getter(vu):\r
- try:\r
- return reverse(fn.__name__, kwargs={'id': vu.id, 'slug': slugify(smart_unicode(vu.username))})\r
- except NoReverseMatch:\r
- try:\r
- return reverse(fn.__name__, kwargs={'id': vu.id})\r
- except NoReverseMatch:\r
- return reverse(fn.__name__, kwargs={'slug': slugify(smart_unicode(vu.username))})\r
-\r
- ui.register(ui.PROFILE_TABS, ui.ProfileTab(\r
- tab_name, tab_title, tab_description,url_getter, private, render_to, weight\r
- ))\r
-\r
- return decorated\r
- return decorator\r
-\r
-\r
-@user_view('users/stats.html', 'stats', _('overview'), _('user overview'))\r
-def user_profile(request, user, **kwargs):\r
- questions = Question.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')\r
- answers = Answer.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')\r
-\r
- # Check whether the passed slug matches the one for the user object\r
- slug = kwargs['slug']\r
- if slug != slugify(smart_unicode(user.username)):\r
- return HttpResponseRedirect(user.get_absolute_url())\r
-\r
- up_votes = user.vote_up_count\r
- down_votes = user.vote_down_count\r
- votes_today = user.get_vote_count_today()\r
- votes_total = user.can_vote_count_today()\r
-\r
- user_tags = Tag.objects.filter(Q(nodes__author=user) | Q(nodes__children__author=user)) \\r
- .annotate(user_tag_usage_count=Count('name')).order_by('-user_tag_usage_count')\r
-\r
- awards = [(Badge.objects.get(id=b['id']), b['count']) for b in\r
- Badge.objects.filter(awards__user=user).values('id').annotate(count=Count('cls')).order_by('-count')]\r
-\r
- return pagination.paginated(request, (\r
- ('questions', QuestionListPaginatorContext('USER_QUESTION_LIST', _('questions'), default_pagesize=15)),\r
- ('answers', UserAnswersPaginatorContext())), {\r
- "view_user" : user,\r
- "questions" : questions,\r
- "answers" : answers,\r
- "up_votes" : up_votes,\r
- "down_votes" : down_votes,\r
- "total_votes": up_votes + down_votes,\r
- "votes_today_left": votes_total-votes_today,\r
- "votes_total_per_day": votes_total,\r
- "user_tags" : user_tags[:50],\r
- "awards": awards,\r
- "total_awards" : len(awards),\r
- })\r
- \r
-@user_view('users/recent.html', 'recent', _('recent activity'), _('recent user activity'))\r
-def user_recent(request, user, **kwargs):\r
- activities = user.actions.exclude(\r
- action_type__in=("voteup", "votedown", "voteupcomment", "flag", "newpage", "editpage")).order_by(\r
- '-action_date')[:USERS_PAGE_SIZE]\r
-\r
- return {"view_user" : user, "activities" : activities}\r
-\r
-\r
-@user_view('users/reputation.html', 'reputation', _('reputation history'), _('graph of user karma'))\r
-def user_reputation(request, user, **kwargs):\r
- rep = list(user.reputes.order_by('date'))\r
- values = [r.value for r in rep]\r
- redux = lambda x, y: x+y\r
-\r
- graph_data = simplejson.dumps([\r
- (time.mktime(rep[i].date.timetuple()) * 1000, reduce(redux, values[:i+1], 0))\r
- for i in range(len(values))\r
- ])\r
-\r
- rep = user.reputes.filter(action__canceled=False).order_by('-date')[0:20]\r
-\r
- return {"view_user": user, "reputation": rep, "graph_data": graph_data}\r
-\r
-@user_view('users/votes.html', 'votes', _('votes'), _('user vote record'), True)\r
-def user_votes(request, user, **kwargs):\r
- votes = user.votes.exclude(node__state_string__contains="(deleted").filter(\r
- node__node_type__in=("question", "answer")).order_by('-voted_at')[:USERS_PAGE_SIZE]\r
-\r
- return {"view_user" : user, "votes" : votes}\r
-\r
-@user_view('users/questions.html', 'favorites', _('favorites'), _('questions that user selected as his/her favorite'))\r
-def user_favorites(request, user, **kwargs):\r
- favorites = FavoriteAction.objects.filter(canceled=False, user=user)\r
-\r
- return {"favorites" : favorites, "view_user" : user}\r
-\r
-@user_view('users/subscriptions.html', 'subscriptions', _('subscription'), _('subscriptions'), True, tabbed=False)\r
-def user_subscriptions(request, user, **kwargs):\r
- return _user_subscriptions(request, user, **kwargs)\r
-\r
-def _user_subscriptions(request, user, **kwargs):\r
- enabled = True\r
-\r
- tab = request.GET.get('tab', "settings")\r
-\r
- # Manage tab\r
- if tab == 'manage':\r
- manage_open = True\r
-\r
- auto = request.GET.get('auto', 'True')\r
- if auto == 'True':\r
- show_auto = True\r
- subscriptions = QuestionSubscription.objects.filter(user=user).order_by('-last_view')\r
- else:\r
- show_auto = False\r
- subscriptions = QuestionSubscription.objects.filter(user=user, auto_subscription=False).order_by('-last_view')\r
-\r
- return pagination.paginated(request, ('subscriptions', SubscriptionListPaginatorContext()), {\r
- 'subscriptions':subscriptions,\r
- 'view_user':user,\r
- "auto":show_auto,\r
- 'manage_open':manage_open,\r
- })\r
- # Settings Tab and everything else\r
- else:\r
- manage_open = False\r
- if request.method == 'POST':\r
- manage_open = False\r
- form = SubscriptionSettingsForm(data=request.POST, instance=user.subscription_settings)\r
-\r
- if form.is_valid():\r
- form.save()\r
- message = _('New subscription settings are now saved')\r
-\r
- user.subscription_settings.enable_notifications = enabled\r
- user.subscription_settings.save()\r
-\r
- request.user.message_set.create(message=message)\r
- else:\r
- form = SubscriptionSettingsForm(instance=user.subscription_settings)\r
-\r
- return {\r
- 'view_user':user,\r
- 'notificatons_on': enabled,\r
- 'form':form,\r
- 'manage_open':manage_open,\r
- }\r
-\r
-@user_view('users/preferences.html', 'preferences', _('preferences'), _('preferences'), True, tabbed=False)\r
-def user_preferences(request, user, **kwargs):\r
- if request.POST:\r
- form = UserPreferencesForm(request.POST)\r
-\r
- if form.is_valid():\r
- user.prop.preferences = form.cleaned_data\r
- request.user.message_set.create(message=_('New preferences saved'))\r
-\r
- else:\r
- preferences = user.prop.preferences\r
-\r
- if preferences:\r
- form = UserPreferencesForm(initial=preferences)\r
- else:\r
- form = UserPreferencesForm()\r
- \r
- return {'view_user': user, 'form': form}\r
-\r
-\r
+from forum.models import User
+from django.db.models import Q, Count
+from django.core.paginator import Paginator, EmptyPage, InvalidPage
+from django.template.defaultfilters import slugify
+from django.contrib.contenttypes.models import ContentType
+from django.core.urlresolvers import reverse
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import RequestContext
+from django.http import HttpResponse, HttpResponseRedirect, Http404
+from forum.http_responses import HttpResponseUnauthorized
+from django.utils.translation import ugettext as _
+from django.utils.http import urlquote_plus
+from django.utils.html import strip_tags
+from django.utils.encoding import smart_unicode
+from django.core.urlresolvers import reverse, NoReverseMatch
+from forum.forms import *
+from forum.utils.html import sanitize_html
+from forum.modules import decorate, ReturnImediatelyException
+from datetime import datetime, date
+from forum.actions import EditProfileAction, FavoriteAction, BonusRepAction, SuspendAction, ReportAction
+from forum.modules import ui
+from forum.utils import pagination
+from forum.views.readers import QuestionListPaginatorContext, AnswerPaginatorContext
+from forum.settings import ONLINE_USERS
+
+from django.contrib import messages
+
+import json
+import time
+import datetime
+import decorators
+
+class UserReputationSort(pagination.SimpleSort):
+ def apply(self, objects):
+ return objects.order_by('-is_active', self.order_by)
+
+class UserListPaginatorContext(pagination.PaginatorContext):
+ def __init__(self, pagesizes=(20, 35, 60), default_pagesize=35):
+ super (UserListPaginatorContext, self).__init__('USERS_LIST', sort_methods=(
+ (_('reputation'), UserReputationSort(_('reputation'), '-reputation', _("sorted by reputation"))),
+ (_('newest'), pagination.SimpleSort(_('recent'), '-date_joined', _("newest members"))),
+ (_('last'), pagination.SimpleSort(_('oldest'), 'date_joined', _("oldest members"))),
+ (_('name'), pagination.SimpleSort(_('by username'), 'username', _("sorted by username"))),
+ ), pagesizes=pagesizes, default_pagesize=default_pagesize)
+
+class SubscriptionListPaginatorContext(pagination.PaginatorContext):
+ def __init__(self):
+ super (SubscriptionListPaginatorContext, self).__init__('SUBSCRIPTION_LIST', pagesizes=(5, 10, 20), default_pagesize=20)
+
+class UserAnswersPaginatorContext(pagination.PaginatorContext):
+ def __init__(self):
+ super (UserAnswersPaginatorContext, self).__init__('USER_ANSWER_LIST', sort_methods=(
+ (_('oldest'), pagination.SimpleSort(_('oldest answers'), 'added_at', _("oldest answers will be shown first"))),
+ (_('newest'), pagination.SimpleSort(_('newest answers'), '-added_at', _("newest answers will be shown first"))),
+ (_('votes'), pagination.SimpleSort(_('popular answers'), '-score', _("most voted answers will be shown first"))),
+ ), default_sort=_('votes'), pagesizes=(5, 10, 20), default_pagesize=20, prefix=_('answers'))
+
+USERS_PAGE_SIZE = 35# refactor - move to some constants file
+
+@decorators.render('users/users.html', 'users', _('users'), weight=200)
+def users(request):
+ suser = request.REQUEST.get('q', "")
+ users = User.objects.all()
+
+ if suser != "":
+ users = users.filter(username__icontains=suser)
+
+ return pagination.paginated(request, ('users', UserListPaginatorContext()), {
+ "users" : users,
+ "suser" : suser,
+ })
+
+
+@decorators.render('users/online_users.html', 'online_users', _('Online Users'), weight=200, tabbed=False)
+def online_users(request):
+ suser = request.REQUEST.get('q', "")
+
+ sort = ""
+ if request.GET.get("sort", None):
+ try:
+ sort = int(request.GET["sort"])
+ except ValueError:
+ logging.error('Found invalid sort "%s", loading %s, refered by %s' % (
+ request.GET.get("sort", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+ ))
+ raise Http404()
+
+ page = 0
+ if request.GET.get("page", None):
+ try:
+ page = int(request.GET["page"])
+ except ValueError:
+ logging.error('Found invalid page "%s", loading %s, refered by %s' % (
+ request.GET.get("page", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+ ))
+ raise Http404()
+
+ pagesize = 10
+ if request.GET.get("pagesize", None):
+ try:
+ pagesize = int(request.GET["pagesize"])
+ except ValueError:
+ logging.error('Found invalid pagesize "%s", loading %s, refered by %s' % (
+ request.GET.get("pagesize", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+ ))
+ raise Http404()
+
+
+ users = None
+ if sort == "reputation":
+ users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.reputation)
+ elif sort == "newest" :
+ users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)
+ elif sort == "last":
+ users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.last)
+ elif sort == "name":
+ users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.name)
+ elif sort == "oldest":
+ users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.oldest)
+ elif sort == "newest":
+ users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)
+ elif sort == "votes":
+ users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.votes)
+ else:
+ users = sorted(ONLINE_USERS.iteritems(), key=lambda x: x[1])
+
+ return render_to_response('users/online_users.html', {
+ "users" : users,
+ "suser" : suser,
+ "sort" : sort,
+ "page" : page,
+ "pageSize" : pagesize,
+ })
+
+
+def edit_user(request, id, slug):
+ user = get_object_or_404(User, id=id)
+ if not (request.user.is_superuser or request.user == user):
+ return HttpResponseUnauthorized(request)
+ if request.method == "POST":
+ form = EditUserForm(user, request.POST)
+ if form.is_valid():
+ new_email = sanitize_html(form.cleaned_data['email'])
+
+ if new_email != user.email:
+ user.email = new_email
+ user.email_isvalid = False
+
+ try:
+ hash = ValidationHash.objects.get(user=request.user, type='email')
+ hash.delete()
+ except:
+ pass
+
+ if settings.EDITABLE_SCREEN_NAME:
+ user.username = sanitize_html(form.cleaned_data['username'])
+ user.real_name = sanitize_html(form.cleaned_data['realname'])
+ user.website = sanitize_html(form.cleaned_data['website'])
+ user.location = sanitize_html(form.cleaned_data['city'])
+ user.date_of_birth = form.cleaned_data['birthday']
+ if user.date_of_birth == "None":
+ user.date_of_birth = datetime(1900, 1, 1, 0, 0)
+ user.about = sanitize_html(form.cleaned_data['about'])
+
+ user.save()
+ EditProfileAction(user=user, ip=request.META['REMOTE_ADDR']).save()
+
+ messages.info(request, _("Profile updated."))
+ return HttpResponseRedirect(user.get_profile_url())
+ else:
+ form = EditUserForm(user)
+ return render_to_response('users/edit.html', {
+ 'user': user,
+ 'form' : form,
+ 'gravatar_faq_url' : reverse('faq') + '#gravatar',
+ }, context_instance=RequestContext(request))
+
+
+@decorate.withfn(decorators.command)
+def user_powers(request, id, action, status):
+ if not request.user.is_superuser:
+ raise decorators.CommandException(_("Only superusers are allowed to alter other users permissions."))
+
+ if (action == 'remove' and 'status' == 'super') and not request.user.is_siteowner():
+ raise decorators.CommandException(_("Only the site owner can remove the super user status from other user."))
+
+ user = get_object_or_404(User, id=id)
+ new_state = action == 'grant'
+
+ if status == 'super':
+ user.is_superuser = new_state
+ elif status == 'staff':
+ user.is_staff = new_state
+ else:
+ raise Http404()
+
+ user.save()
+ return decorators.RefreshPageCommand()
+
+
+@decorate.withfn(decorators.command)
+def award_points(request, id):
+ if not request.POST:
+ return render_to_response('users/karma_bonus.html')
+
+ if not request.user.is_superuser:
+ raise decorators.CommandException(_("Only superusers are allowed to award reputation points"))
+
+ try:
+ points = int(request.POST['points'])
+ except:
+ raise decorators.CommandException(_("Invalid number of points to award."))
+
+ user = get_object_or_404(User, id=id)
+
+ extra = dict(message=request.POST.get('message', ''), awarding_user=request.user.id, value=points)
+
+ BonusRepAction(user=request.user, extra=extra).save(data=dict(value=points, affected=user))
+
+ return {'commands': {
+ 'update_profile_karma': [user.reputation]
+ }}
+
+
+@decorate.withfn(decorators.command)
+def suspend(request, id):
+ user = get_object_or_404(User, id=id)
+
+ if not request.user.is_superuser:
+ raise decorators.CommandException(_("Only superusers can suspend other users"))
+
+ if not request.POST.get('bantype', None):
+ if user.is_suspended():
+ suspension = user.suspension
+ suspension.cancel(user=request.user, ip=request.META['REMOTE_ADDR'])
+ return decorators.RefreshPageCommand()
+ else:
+ return render_to_response('users/suspend_user.html')
+
+ data = {
+ 'bantype': request.POST.get('bantype', 'Indefinitely').strip(),
+ 'publicmsg': request.POST.get('publicmsg', _('Bad behaviour')),
+ 'privatemsg': request.POST.get('privatemsg', None) or request.POST.get('publicmsg', ''),
+ 'suspended': user
+ }
+
+ if data['bantype'] == 'forxdays':
+ try:
+ data['forxdays'] = int(request.POST['forxdays'])
+ except:
+ raise decorators.CommandException(_('Invalid numeric argument for the number of days.'))
+
+ SuspendAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=data)
+
+ return decorators.RefreshPageCommand()
+
+@decorate.withfn(decorators.command)
+def report_user(request, id):
+ user = get_object_or_404(User, id=id)
+
+ if not request.POST.get('publicmsg', None):
+ return render_to_response('users/report_user.html')
+
+ data = {
+ 'publicmsg': request.POST.get('publicmsg', _('N/A')),
+ 'reported': user
+ }
+
+ ReportAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=data)
+
+
+ return decorators.RefreshPageCommand()
+
+
+
+def user_view(template, tab_name, tab_title, tab_description, private=False, tabbed=True, render_to=None, weight=500):
+ def decorator(fn):
+ def params(request, id=None, slug=None):
+ # Get the user object by id if the id parameter has been passed
+ if id is not None:
+ user = get_object_or_404(User, id=id)
+ # ...or by slug if the slug has been given
+ elif slug is not None:
+ try:
+ user = User.objects.get(username__iexact=slug)
+ except User.DoesNotExist:
+ raise Http404
+
+ if private and not (user == request.user or request.user.is_superuser):
+ raise ReturnImediatelyException(HttpResponseUnauthorized(request))
+
+ if render_to and (not render_to(user)):
+ raise ReturnImediatelyException(HttpResponseRedirect(user.get_profile_url()))
+
+ return [request, user], { 'slug' : slug, }
+
+ decorated = decorate.params.withfn(params)(fn)
+
+ def result(context_or_response, request, user, **kwargs):
+ rev_page_title = smart_unicode(user.username) + " - " + tab_description
+
+ # Check whether the return type of the decorated function is a context or Http Response
+ if isinstance(context_or_response, HttpResponse):
+ response = context_or_response
+
+ # If it is a response -- show it
+ return response
+ else:
+ # ...if it is a context move forward, update it and render it to response
+ context = context_or_response
+
+ context.update({
+ "tab": "users",
+ "active_tab" : tab_name,
+ "tab_description" : tab_description,
+ "page_title" : rev_page_title,
+ "can_view_private": (user == request.user) or request.user.is_superuser
+ })
+ return render_to_response(template, context, context_instance=RequestContext(request))
+
+ decorated = decorate.result.withfn(result, needs_params=True)(decorated)
+
+ if tabbed:
+ def url_getter(vu):
+ try:
+ return reverse(fn.__name__, kwargs={'id': vu.id, 'slug': slugify(smart_unicode(vu.username))})
+ except NoReverseMatch:
+ try:
+ return reverse(fn.__name__, kwargs={'id': vu.id})
+ except NoReverseMatch:
+ return reverse(fn.__name__, kwargs={'slug': slugify(smart_unicode(vu.username))})
+
+ ui.register(ui.PROFILE_TABS, ui.ProfileTab(
+ tab_name, tab_title, tab_description,url_getter, private, render_to, weight
+ ))
+
+ return decorated
+ return decorator
+
+
+@user_view('users/stats.html', 'stats', _('overview'), _('user overview'))
+def user_profile(request, user, **kwargs):
+ questions = Question.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')
+ answers = Answer.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')
+
+ # Check whether the passed slug matches the one for the user object
+ slug = kwargs['slug']
+ if slug != slugify(smart_unicode(user.username)):
+ return HttpResponseRedirect(user.get_absolute_url())
+
+ up_votes = user.vote_up_count
+ down_votes = user.vote_down_count
+ votes_today = user.get_vote_count_today()
+ votes_total = user.can_vote_count_today()
+
+ user_tags = Tag.objects.filter(Q(nodes__author=user) | Q(nodes__children__author=user)) \
+ .annotate(user_tag_usage_count=Count('name')).order_by('-user_tag_usage_count')
+
+ awards = [(Badge.objects.get(id=b['id']), b['count']) for b in
+ Badge.objects.filter(awards__user=user).values('id').annotate(count=Count('cls')).order_by('-count')]
+
+ return pagination.paginated(request, (
+ ('questions', QuestionListPaginatorContext('USER_QUESTION_LIST', _('questions'), default_pagesize=15)),
+ ('answers', UserAnswersPaginatorContext())), {
+ "view_user" : user,
+ "questions" : questions,
+ "answers" : answers,
+ "up_votes" : up_votes,
+ "down_votes" : down_votes,
+ "total_votes": up_votes + down_votes,
+ "votes_today_left": votes_total-votes_today,
+ "votes_total_per_day": votes_total,
+ "user_tags" : user_tags[:50],
+ "awards": awards,
+ "total_awards" : len(awards),
+ })
+
+@user_view('users/recent.html', 'recent', _('recent activity'), _('recent user activity'))
+def user_recent(request, user, **kwargs):
+ activities = user.actions.exclude(
+ action_type__in=("voteup", "votedown", "voteupcomment", "flag", "newpage", "editpage")).order_by(
+ '-action_date')[:USERS_PAGE_SIZE]
+
+ return {"view_user" : user, "activities" : activities}
+
+
+@user_view('users/reputation.html', 'reputation', _('reputation history'), _('graph of user karma'))
+def user_reputation(request, user, **kwargs):
+ rep = list(user.reputes.order_by('date'))
+ values = [r.value for r in rep]
+ redux = lambda x, y: x+y
+
+ graph_data = json.dumps([
+ (time.mktime(rep[i].date.timetuple()) * 1000, reduce(redux, values[:i+1], 0))
+ for i in range(len(values))
+ ])
+
+ rep = user.reputes.filter(action__canceled=False).order_by('-date')[0:20]
+
+ return {"view_user": user, "reputation": rep, "graph_data": graph_data}
+
+@user_view('users/votes.html', 'votes', _('votes'), _('user vote record'), True)
+def user_votes(request, user, **kwargs):
+ votes = user.votes.exclude(node__state_string__contains="(deleted").filter(
+ node__node_type__in=("question", "answer")).order_by('-voted_at')[:USERS_PAGE_SIZE]
+
+ return {"view_user" : user, "votes" : votes}
+
+@user_view('users/questions.html', 'favorites', _('favorites'), _('questions that user selected as his/her favorite'))
+def user_favorites(request, user, **kwargs):
+ favorites = FavoriteAction.objects.filter(canceled=False, user=user)
+
+ return {"favorites" : favorites, "view_user" : user}
+
+@user_view('users/subscriptions.html', 'subscriptions', _('subscription'), _('subscriptions'), True, tabbed=False)
+def user_subscriptions(request, user, **kwargs):
+ return _user_subscriptions(request, user, **kwargs)
+
+def _user_subscriptions(request, user, **kwargs):
+ enabled = True
+
+ tab = request.GET.get('tab', "settings")
+
+ # Manage tab
+ if tab == 'manage':
+ manage_open = True
+
+ auto = request.GET.get('auto', 'True')
+ if auto == 'True':
+ show_auto = True
+ subscriptions = QuestionSubscription.objects.filter(user=user).order_by('-last_view')
+ else:
+ show_auto = False
+ subscriptions = QuestionSubscription.objects.filter(user=user, auto_subscription=False).order_by('-last_view')
+
+ return pagination.paginated(request, ('subscriptions', SubscriptionListPaginatorContext()), {
+ 'subscriptions':subscriptions,
+ 'view_user':user,
+ "auto":show_auto,
+ 'manage_open':manage_open,
+ })
+ # Settings Tab and everything else
+ else:
+ manage_open = False
+ if request.method == 'POST':
+ manage_open = False
+ form = SubscriptionSettingsForm(data=request.POST, instance=user.subscription_settings)
+
+ if form.is_valid():
+ form.save()
+ message = _('New subscription settings are now saved')
+
+ user.subscription_settings.enable_notifications = enabled
+ user.subscription_settings.save()
+
+ messages.info(request, message)
+ else:
+ form = SubscriptionSettingsForm(instance=user.subscription_settings)
+
+ return {
+ 'view_user':user,
+ 'notificatons_on': enabled,
+ 'form':form,
+ 'manage_open':manage_open,
+ }
+
+@user_view('users/preferences.html', 'preferences', _('preferences'), _('preferences'), True, tabbed=False)
+def user_preferences(request, user, **kwargs):
+ if request.POST:
+ form = UserPreferencesForm(request.POST)
+
+ if form.is_valid():
+ user.prop.preferences = form.cleaned_data
+ messages.info(request, _('New preferences saved'))
+
+ else:
+ preferences = user.prop.preferences
+
+ if preferences:
+ form = UserPreferencesForm(initial=preferences)
+ else:
+ form = UserPreferencesForm()
+
+ return {'view_user': user, 'form': form}
+
+
from django.utils.html import *
from django.utils.translation import ugettext as _
+from django.contrib import messages
+
from forum.actions import AskAction, AnswerAction, ReviseAction, RollbackAction, RetagAction, AnswerToQuestionAction, CommentToQuestionAction
from forum.forms import *
from forum.models import *
}
if request.user.is_authenticated():
- request.user.message_set.create(message=_("Your question is pending until you %s.") % html.hyperlink(
+ messages.info(request, _("Your question is pending until you %s.") % html.hyperlink(
reverse('send_validation_email'), _("validate your email")
))
return HttpResponseRedirect(reverse('index'))
}
if request.user.is_authenticated():
- request.user.message_set.create(message=_("Your answer is pending until you %s.") % html.hyperlink(
+ messages.info(request, _("Your answer is pending until you %s.") % html.hyperlink(
reverse('send_validation_email'), _("validate your email")
))
return HttpResponseRedirect(question.get_absolute_url())
+import json
+import loggin
+
from django.utils.translation import ugettext as _
from django.http import HttpResponse, HttpResponseRedirect
from django.template import RequestContext
-from django.utils import simplejson
from django.utils.encoding import smart_str
from django.shortcuts import render_to_response
from forum.modules import decorate
from forum.forms.general import SimpleCaptchaForm
import settings
-import logging
def can_bypass_spam_check(user):
return user.is_authenticated and (user.is_superuser or user.is_staff or cmp(int(user.reputation), REP_FOR_NO_SPAM_CHECK) > 0)
'success': False,
'error_message': _("Sorry, but akismet thinks your %s is spam.") % comment_type
}
- return HttpResponse(simplejson.dumps(response), mimetype="application/json")
+ return HttpResponse(json.dumps(response), mimetype="application/json")
else:
captcha_checked = False
try:
if (data.errors == false) {
if (exporting) {
$('#wait_message').html('{% trans "Your backup is ready to be downloaded."%}');
- $('#download_link_a').attr('href', '{% url exporter_download %}?file=' + data.state.overall.fname)
+ $('#download_link_a').attr('href', '{% url "exporter_download" %}?file=' + data.state.overall.fname)
$('#download_link').slideDown();
} else {
$('#wait_message').html('{% trans "All data sucessfully imported."%}')
}
}, 1000);
- $.getJSON('{% url exporter_state %}', callback);
+ $.getJSON('{% url "exporter_state" %}', callback);
}
check_state();
-from django.conf.urls.defaults import *
-from django.views.generic.simple import direct_to_template
+from django.conf.urls import patterns, url, include
from django.utils.translation import ugettext as _
from views import state, running, download
from __future__ import with_statement
import os, tarfile, ConfigParser, datetime
+import json
from StringIO import StringIO
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.utils.translation import ugettext as _
-from django.utils import simplejson
from django.core.cache import cache
from django.core.urlresolvers import reverse
from forum.views.admin import admin_tools_page, admin_page
})
def state(request):
- return HttpResponse(simplejson.dumps(cache.get(CACHE_KEY)), mimetype="application/json")
+ return HttpResponse(json.dumps(cache.get(CACHE_KEY)), mimetype="application/json")
@admin_page
def download(request):
import settings
-try:
- from json import load as load_json
-except Exception:
- from django.utils.simplejson import JSONDecoder
+from json import load as load_json
- def load_json(json):
- decoder = JSONDecoder()
- return decoder.decode(json.read())
class FacebookAuthConsumer(AuthenticationConsumer):
facebook_api_authentication_url = "https://graph.facebook.com/oauth/authorize?" + urlencode(args)
return facebook_api_authentication_url
-
+
def process_authentication_request(self, request):
try:
args = dict(client_id=settings.FB_API_KEY, redirect_uri="%s%s" % (django_settings.APP_URL, request.path))
-{% load extra_tags %}\r
-\r
-<a style="position: relative; top: -8px;" href="{% url auth_provider_signin provider="facebook" %}"><img src="{% media '/media/images/openid/facebook.gif' %}" /></a>\r
+{% load extra_tags %}
+
+<a style="position: relative; top: -8px;" href="{% url "auth_provider_signin" provider="facebook" %}"><img src="{% media '/media/images/openid/facebook.gif' %}" /></a>
-{% load i18n %}\r
-\r
-<fieldset id='local_login_fs'>\r
- <p><span class='big strong'>{% trans 'Enter your local user name and password' %}</span><br/><span class='grey'>({% trans 'or select your external provider above' %})</span></p>\r
- <table>\r
- <tr>\r
- <td>\r
- <label for="id_username">{% trans 'Login name' %}</label>\r
- </td>\r
- <td>\r
- <input id="id_username" type="text" class="required login" name="username" maxlength="30" />\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <label for="id_password">{% trans 'Password' %}</label>\r
- </td>\r
- <td>\r
- <input id="id_password" type="password" class="required login" name="password" maxlength="128" />\r
- </td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <input id="blogin" name="blogin" type="submit" value="{% trans 'Login' %}" />\r
- </td>\r
- <td>\r
- <a href="{% url auth_local_register %}">{% trans 'Create account' %}</a><span> | </span><a href="{% url auth_request_tempsignin %}">{% trans 'Forgot your password?' %}</a>\r
- </td>\r
- </tr>\r
- </table>\r
-</fieldset>\r
+{% load i18n %}
+
+<fieldset id='local_login_fs'>
+ <p><span class='big strong'>{% trans 'Enter your local user name and password' %}</span><br/><span class='grey'>({% trans 'or select your external provider above' %})</span></p>
+ <table>
+ <tr>
+ <td>
+ <label for="id_username">{% trans 'Login name' %}</label>
+ </td>
+ <td>
+ <input id="id_username" type="text" class="required login" name="username" maxlength="30" />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <label for="id_password">{% trans 'Password' %}</label>
+ </td>
+ <td>
+ <input id="id_password" type="password" class="required login" name="password" maxlength="128" />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input id="blogin" name="blogin" type="submit" value="{% trans 'Login' %}" />
+ </td>
+ <td>
+ <a href="{% url "auth_local_register" %}">{% trans 'Create account' %}</a><span> | </span><a href="{% url "auth_request_tempsignin" %}">{% trans 'Forgot your password?' %}</a>
+ </td>
+ </tr>
+ </table>
+</fieldset>
-from django.conf.urls.defaults import *
-from django.views.generic.simple import direct_to_template
+from django.conf.urls import patterns, url, include
from django.utils.translation import ugettext as _
import views as app
urlpatterns = patterns('',
url(r'^%s%s%s$' % (_('account/'), _('local/'), _('register/')), app.register, name='auth_local_register'),
-)
\ No newline at end of file
+)
+import json
+
from consumer import OAuthAbstractAuthConsumer
from forum.authentication.base import ConsumerTemplateContext
-try:
- import json as simplejson
-except ImportError:
- from django.utils import simplejson
-
from lib import oauth2
import settings
json = self.fetch_data(key, "https://twitter.com/account/verify_credentials.json")
if 'screen_name' in json:
- creds = simplejson.loads(json)
+ creds = json.loads(json)
return {
'username': creds['screen_name']
type = 'DIRECT'
weight = 150
human_name = 'Twitter'
- icon = '/media/images/openid/twitter.png'
\ No newline at end of file
+ icon = '/media/images/openid/twitter.png'
from django.utils.encoding import smart_unicode
from django.utils.html import escape
-from django.http import get_host
from forum.authentication.base import AuthenticationConsumer, InvalidAuthentication
import settings
protocol = 'https'
else:
protocol = 'http'
- host = escape(get_host(request))
+ host = escape(request.get_host())
return '%s://%s' % (protocol, host)
def get_full_url(request):
- return get_url_host(request) + request.get_full_path()
\ No newline at end of file
+ return get_url_host(request) + request.get_full_path()
-{% load i18n %}\r
-{% load extra_tags %}\r
-\r
-<fieldset>\r
- <table>\r
- <tr>\r
- <td><p id="provider_name_slot">{% trans 'Enter your OpenId Url' %}</p></td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <input id="openid_identifier" class="icon_input" name="openid_identifier" type="text"\r
- style="width: 500px; background: url('{% media provider.icon %}') no-repeat left center" />\r
- </td>\r
- <td>\r
- <input type="submit" name="ssignin" value="{% trans 'Login' %}" />\r
- </td>\r
- </tr>\r
- </table>\r
-</fieldset>\r
-\r
+{% load i18n %}
+{% load extra_tags %}
+
+<fieldset>
+ <table>
+ <tr>
+ <td><p id="provider_name_slot">{% trans 'Enter your OpenId Url' %}</p></td>
+ </tr>
+ <tr>
+ <td>
+ <input id="openid_identifier" class="icon_input" name="openid_identifier" type="text"
+ style="width: 500px; background: url('{% media provider.icon %}') no-repeat left center" />
+ </td>
+ <td>
+ <input type="submit" name="ssignin" value="{% trans 'Login' %}" />
+ </td>
+ </tr>
+ </table>
+</fieldset>
+
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url, include
from django.http import HttpResponse
import settings
-{% extends "osqaadmin/base.html" %}\r
-\r
-{% load i18n %}\r
-{% load user_tags %}\r
-\r
-{% block subtitle %}\r
- {% trans "SX Importer" %}\r
-{% endblock %}\r
-{% block description %}\r
- {% trans "Welcome to Stack Exchange dump importer." %}\r
-{% endblock %}\r
-\r
-{% block admincontent %}\r
- <form method="post" action="" enctype="multipart/form-data">\r
- {% csrf_token %}\r
- <input type="file" name="dump" /><br>\r
- {% trans "Your user id in stack exchange" %}\r
- <input type="test" name="owneruid" size="3" value="2" /><br />\r
-\r
- <input type="checkbox" checked="checked" name="mergesimilar" />\r
- {% trans "Merge users with same user name and email" %}<br />\r
-\r
- <input type="submit" value="submit" />\r
- </form>\r
- {% for n in names %}\r
- <p>{{ n }}</p>\r
- {% endfor %}\r
+{% extends "osqaadmin/base.html" %}
+
+{% load i18n %}
+{% load user_tags %}
+
+{% block subtitle %}
+ {% trans "SX Importer" %}
+{% endblock %}
+{% block description %}
+ {% trans "Welcome to Stack Exchange dump importer." %}
+{% endblock %}
+
+{% block admincontent %}
+ <form method="post" action="" enctype="multipart/form-data">
+ {% csrf_token %}
+ <input type="file" name="dump" /><br>
+ {% trans "Your user id in stack exchange" %}
+ <input type="test" name="owneruid" size="3" value="2" /><br />
+
+ <input type="checkbox" checked="checked" name="mergesimilar" />
+ {% trans "Merge users with same user name and email" %}<br />
+
+ <input type="submit" value="submit" />
+ </form>
+ {% for n in names %}
+ <p>{{ n }}</p>
+ {% endfor %}
{% endblock %}
\ No newline at end of file
-from django.conf.urls.defaults import *\r
-from django.views.generic.simple import direct_to_template\r
-from django.utils.translation import ugettext as _\r
-\r
-from views import sximporter\r
-\r
-urlpatterns = patterns('',\r
- url(r'^%s%s$' % (_('admin/'), _('sximporter/')), sximporter, name='sximporter'),\r
-)
\ No newline at end of file
+from django.conf.urls import patterns, url, include
+from django.utils.translation import ugettext as _
+
+from views import sximporter
+
+urlpatterns = patterns('',
+ url(r'^%s%s$' % (_('admin/'), _('sximporter/')), sximporter, name='sximporter'),
+)
-from django.shortcuts import render_to_response\r
-from django.template import RequestContext\r
-from forum.http_responses import HttpResponseUnauthorized\r
-from forum.models import User\r
-import importer\r
-from zipfile import ZipFile\r
-import os\r
-\r
-def sximporter(request):\r
- if (not User.objects.exists()) or (request.user.is_authenticated() and request.user.is_superuser):\r
- list = []\r
- if request.method == "POST" and "dump" in request.FILES:\r
- dump = ZipFile(request.FILES['dump'])\r
- members = [f for f in dump.namelist() if f.endswith('.xml')]\r
- extract_to = os.path.join(os.path.dirname(__file__), 'tmp')\r
-\r
- if not os.path.exists(extract_to):\r
- os.makedirs(extract_to)\r
-\r
- for m in members:\r
- f = open(os.path.join(extract_to, m), 'w')\r
- f.write(dump.read(m))\r
- f.close()\r
-\r
- #dump.extractall(extract_to, members)\r
- dump.close()\r
-\r
- options = dict([(k, v) for k, v in request.POST.items()])\r
- options['authenticated_user'] = (request.user.is_authenticated() and (request.user,) or (None,))[0]\r
-\r
- importer.sximport(extract_to, options)\r
-\r
- return render_to_response('modules/sximporter/page.html', {\r
- 'names': list\r
- }, context_instance=RequestContext(request))\r
- else:\r
- return HttpResponseUnauthorized(request)\r
-\r
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from forum.http_responses import HttpResponseUnauthorized
+from forum.models import User
+import importer
+from zipfile import ZipFile
+import os
+
+def sximporter(request):
+ if (not User.objects.exists()) or (request.user.is_authenticated() and request.user.is_superuser):
+ list = []
+ if request.method == "POST" and "dump" in request.FILES:
+ dump = ZipFile(request.FILES['dump'])
+ members = [f for f in dump.namelist() if f.endswith('.xml')]
+ extract_to = os.path.join(os.path.dirname(__file__), 'tmp')
+
+ if not os.path.exists(extract_to):
+ os.makedirs(extract_to)
+
+ for m in members:
+ f = open(os.path.join(extract_to, m), 'w')
+ f.write(dump.read(m))
+ f.close()
+
+ #dump.extractall(extract_to, members)
+ dump.close()
+
+ options = dict([(k, v) for k, v in request.POST.items()])
+ options['authenticated_user'] = (request.user.is_authenticated() and (request.user,) or (None,))[0]
+
+ importer.sximport(extract_to, options)
+
+ return render_to_response('modules/sximporter/page.html', {
+ 'names': list
+ }, context_instance=RequestContext(request))
+ else:
+ return HttpResponseUnauthorized(request)
+
from xml.dom.minidom import parse, parseString
from forum.base import get_database_engine
from forum.models import Question, Answer, Comment, User
-from forum.settings import APP_URL, SVN_REVISION, APP_TITLE, APP_DESCRIPTION
+from forum.settings import APP_URL, VCS_REVISION, APP_TITLE, APP_DESCRIPTION
from django import VERSION as DJANGO_VERSION
-from django.utils import simplejson
from django.utils.html import escape
from django.utils.encoding import smart_unicode
from django.conf import settings as django_settings
def check_for_updates():
# Get the SVN Revision
try:
- svn_revision = int(SVN_REVISION.replace('SVN-', ''))
+ svn_revision = int(VCS_REVISION.replace('SVN-', ''))
except ValueError:
# Here we'll have to find another way of getting the SVN revision
svn_revision = 0
from xml.dom.minidom import parse, parseString
from xml.parsers.expat import ExpatError
from forum.modules import ui, decorate
-from forum.settings import SVN_REVISION
+from forum.settings import VCS_REVISION
from django.contrib.auth.middleware import AuthenticationMiddleware
from django.core.exceptions import ObjectDoesNotExist
from django.utils.encoding import smart_str
for message in messages:
# Get the SVN Revision
try:
- svn_revision = int(SVN_REVISION.replace('SVN-', ''))
+ svn_revision = int(VCS_REVISION.replace('SVN-', ''))
except ValueError:
# Here we'll have to find another way of getting the SVN revision
svn_revision = 0
except ExpatError:
pass
- return result
\ No newline at end of file
+ return result
{% block admincontent %}
-<a href="{% url updater_check %}" id="check_for_updates" class="button">{% trans "Check for Updates" %}</a>
+<a href="{% url "updater_check" %}" id="check_for_updates" class="button">{% trans "Check for Updates" %}</a>
<div id="update_check_status"></div>
{% endblock %}
-from django.conf.urls.defaults import *
-from django.views.generic.simple import direct_to_template
+from django.conf.urls import patterns, url, include
from django.utils.translation import ugettext as _
from views import updater_index, updater_check
#!/usr/bin/env python
-from django.core.management import execute_manager
-try:
- import settings # Assumed to be in the same directory.
-except ImportError, e:
- import traceback
- traceback.print_exc()
- import sys
- sys.stderr.write("Error: Can't find the file 'forms.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file forms.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
- sys.exit(1)
+import os
+import sys
if __name__ == "__main__":
- execute_manager(settings)
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
+
+ from django.core.management import execute_from_command_line
+
+ execute_from_command_line(sys.argv)
SITE_ID = 1
-ADMIN_MEDIA_PREFIX = '/admin_media/'
-SECRET_KEY = '$oo^&_m&qwbib=(_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
+SECRET_KEY = 'a;::qCl1mfh?avagttOJ;8f5Rr54d,9qy7;o15M2cYO75?OQo51u3LnQ;!8N.:,7'
CACHE_MAX_KEY_LENGTH = 235
MIDDLEWARE_CLASSES = [
'django.middleware.csrf.CsrfViewMiddleware',
- 'django.middleware.csrf.CsrfResponseMiddleware',
'forum.middleware.django_cookies.CookiePreHandlerMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.common.CommonMiddleware',
'forum.middleware.extended_user.ExtendedUser',
'forum.middleware.anon_user.ConnectToSessionMessagesMiddleware',
TEMPLATE_CONTEXT_PROCESSORS = [
'django.core.context_processors.request',
'forum.context.application_settings',
+ 'django.contrib.messages.context_processors.messages',
'forum.user_messages.context_processors.user_messages',
- 'django.core.context_processors.auth',
+ 'django.contrib.auth.context_processors.auth',
]
ROOT_URLCONF = 'urls'
ALLOW_FILE_TYPES = ('.jpg', '.jpeg', '.gif', '.bmp', '.png', '.tiff')
ALLOW_MAX_FILE_SIZE = 1024 * 1024
+SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
+
+MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
+
# User settings
from settings_local import *
-if DEBUG:
- TEMPLATE_LOADERS = [
- 'django.template.loaders.filesystem.load_template_source',
- 'django.template.loaders.app_directories.load_template_source',
- 'forum.modules.template_loader.module_templates_loader',
- 'forum.skins.load_template_source',
- ]
-else:
- TEMPLATE_LOADERS = [
- ('django.template.loaders.cached.Loader',(
- 'django.template.loaders.filesystem.load_template_source',
- 'django.template.loaders.app_directories.load_template_source',
- 'forum.modules.template_loader.module_templates_loader',
- 'forum.skins.load_template_source',
- )),
- ]
+template_loaders = (
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
+ 'forum.modules.template_loader.module_templates_loader',
+ 'forum.skins.load_template_source',
+)
+TEMPLATE_LOADERS = list(template_loaders) if DEBUG else [ ('django.template.loaders.cached.Loader', template_loaders) ]
try:
if len(FORUM_SCRIPT_ALIAS) > 0:
'django.contrib.admin',
'django.contrib.humanize',
'django.contrib.sitemaps',
- 'django.contrib.markup',
+ 'django.contrib.messages',
'forum',
]
SITE_SRC_ROOT = os.path.dirname(__file__)
LOG_FILENAME = 'django.osqa.log'
-
-#for logging
-import logging
-logging.basicConfig(
- filename=os.path.join(SITE_SRC_ROOT, 'log', LOG_FILENAME),
- level=logging.ERROR,
- format='%(pathname)s TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s',
-)
+LOGGING = {
+ 'version': 1,
+ 'formatters': {
+ 'default': {
+ 'format': '%(pathname)s TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s',
+ }
+ },
+ 'handlers': {
+ 'file': {
+ 'level': 'DEBUG',
+ 'class': 'logging.FileHandler',
+ 'formatter': 'default',
+ 'filename': os.path.join(SITE_SRC_ROOT, 'log', LOG_FILENAME),
+ },
+ },
+ 'loggers' : {
+ # ensure that all log entries are propagated to root
+ 'django': { 'propagate': True },
+ 'django.request': { 'propagate': True },
+ 'django.security': { 'propagate': True },
+ 'py.warnings': { 'propagate': True },
+ },
+ 'root': {
+ 'handlers': ['file'],
+ 'level': 'DEBUG',
+ },
+}
#ADMINS and MANAGERS
ADMINS = ()
}
TEMPLATE_DEBUG = DEBUG
INTERNAL_IPS = ('127.0.0.1',)
-
+ALLOWED_HOSTS = ('yourhostname.com',)
DATABASES = {
'default': {
'PASSWORD': '',
'HOST': '',
'PORT': '',
+ 'CONN_MAX_AGE': 600,
}
}
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url, include
from django.utils.translation import ugettext as _
from django.conf import settings