diff options
58 files changed, 265 insertions, 1442 deletions
@@ -2,6 +2,7 @@ *.swp *.log cache/?? +run *.wsgi nbproject settings_local.py diff --git a/askbot.iml b/askbot.iml deleted file mode 100755 index 4e760f0a..00000000 --- a/askbot.iml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<module type="PYTHON_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$" />
- <orderEntry type="jdk" jdkName="Python 2.6.4" jdkType="Python SDK" />
- <orderEntry type="sourceFolder" forTests="false" />
- </component>
-</module>
-
diff --git a/cache/README.TXT b/cache/README.TXT deleted file mode 100755 index 54247a82..00000000 --- a/cache/README.TXT +++ /dev/null @@ -1 +0,0 @@ -this file is just a placeholder so the empty directory is not ignored by version control
\ No newline at end of file diff --git a/django_authopenid/README b/django_authopenid/README new file mode 100644 index 00000000..67c33d60 --- /dev/null +++ b/django_authopenid/README @@ -0,0 +1,5 @@ +this is a forked version of django-authopenid module +specifically for askbot forum project. + +most likely it is not useful for anything else and +in fact will be phased out in askbot as well diff --git a/fbconnect/fb.py b/fbconnect/fb.py deleted file mode 100644 index 8d41c3a2..00000000 --- a/fbconnect/fb.py +++ /dev/null @@ -1,96 +0,0 @@ -from forum.conf import settings as forum_settings -from time import time -from datetime import datetime -from urllib import urlopen, urlencode - -try: - from json import load as load_json -except: - from pjson import fread as load_json - -from models import FBAssociation -import hashlib -import logging - -REST_SERVER = 'http://api.facebook.com/restserver.php' - -def generate_sig(values): - keys = [] - - for key in sorted(values.keys()): - keys.append(key) - - signature = ''.join(['%s=%s' % (key, values[key]) for key in keys]) + forum_settings.FB_SECRET - return hashlib.md5(signature).hexdigest() - -def check_cookies_signature(cookies): - API_KEY = forum_settings.FB_API_KEY - - values = {} - - for key in cookies.keys(): - if (key.startswith(API_KEY + '_')): - values[key.replace(API_KEY + '_', '')] = cookies[key] - - return generate_sig(values) == cookies[API_KEY] - -def get_user_data(cookies): - request_data = { - 'method': 'Users.getInfo', - 'api_key': forum_settings.FB_API_KEY, - 'call_id': time(), - 'v': '1.0', - 'uids': cookies[forum_settings.FB_API_KEY + '_user'], - 'fields': 'name,first_name,last_name', - 'format': 'json', - } - - request_data['sig'] = generate_sig(request_data) - fb_response = urlopen(REST_SERVER, urlencode(request_data)) - #print(fb_response) - return load_json(fb_response)[0] - - -def delete_cookies(response): - API_KEY = forum_settings.FB_API_KEY - - response.delete_cookie(API_KEY + '_user') - response.delete_cookie(API_KEY + '_session_key') - response.delete_cookie(API_KEY + '_expires') - response.delete_cookie(API_KEY + '_ss') - response.delete_cookie(API_KEY) - response.delete_cookie('fbsetting_' + API_KEY) - -def check_session_expiry(cookies): - return datetime.fromtimestamp(float(cookies[forum_settings.FB_API_KEY+'_expires'])) > datetime.now() - -STATES = { - 'FIRSTTIMER': 1, - 'SESSIONEXPIRED': 2, - 'RETURNINGUSER': 3, - 'INVALIDSTATE': 4, -} - -def get_user_state(request): - API_KEY = forum_settings.FB_API_KEY - logging.debug('') - - if API_KEY in request.COOKIES: - logging.debug('FB API key is in request cookies') - if check_cookies_signature(request.COOKIES): - logging.debug('FB cookie signature is fine') - if check_session_expiry(request.COOKIES): - logging.debug('FB session is not expired') - try: - uassoc = FBAssociation.objects.get(fbuid=request.COOKIES[API_KEY + '_user']) - logging.debug('found existing FB user association') - return (STATES['RETURNINGUSER'], uassoc.user) - except: - logging.debug('dont have FB association for this user') - return (STATES['FIRSTTIMER'], get_user_data(request.COOKIES)) - else: - logging.debug('FB session expired') - return (STATES['SESSIONEXPIRED'], None) - logging.debug('FB state is INVALID') - - return (STATES['INVALIDSTATE'], None) diff --git a/fbconnect/forms.py b/fbconnect/forms.py deleted file mode 100644 index 94f86816..00000000 --- a/fbconnect/forms.py +++ /dev/null @@ -1,8 +0,0 @@ -from django_authopenid.forms import NextUrlField, UserNameField, UserEmailField - -from django import forms - -class FBConnectRegisterForm(forms.Form): - next = NextUrlField() - username = UserNameField() - email = UserEmailField() diff --git a/fbconnect/models.py b/fbconnect/models.py deleted file mode 100644 index 2172217d..00000000 --- a/fbconnect/models.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.db import models -from django.contrib.auth.models import User - -class FBAssociation(models.Model): - user = models.ForeignKey(User) - fbuid = models.CharField(max_length=12, unique=True) diff --git a/fbconnect/pjson.py b/fbconnect/pjson.py deleted file mode 100644 index 273b684e..00000000 --- a/fbconnect/pjson.py +++ /dev/null @@ -1,313 +0,0 @@ -import string -import types - -## json.py implements a JSON (http://json.org) reader and writer. -## Copyright (C) 2005 Patrick D. Logan -## Contact mailto:patrickdlogan@stardecisions.com -## -## This library is free software; you can redistribute it and/or -## modify it under the terms of the GNU Lesser General Public -## License as published by the Free Software Foundation; either -## version 2.1 of the License, or (at your option) any later version. -## -## This library is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public -## License along with this library; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -class _StringGenerator(object): - def __init__(self, string): - self.string = string - self.index = -1 - def peek(self): - i = self.index + 1 - if i < len(self.string): - return self.string[i] - else: - return None - def next(self): - self.index += 1 - if self.index < len(self.string): - return self.string[self.index] - else: - raise StopIteration - def all(self): - return self.string - -class WriteException(Exception): - pass - -class ReadException(Exception): - pass - -class JsonReader(object): - hex_digits = {'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F':15} - escapes = {'t':'\t','n':'\n','f':'\f','r':'\r','b':'\b'} - - def read(self, s): - self._generator = _StringGenerator(s) - result = self._read() - return result - - def _read(self): - self._eatWhitespace() - peek = self._peek() - if peek is None: - raise ReadException, "Nothing to read: '%s'" % self._generator.all() - if peek == '{': - return self._readObject() - elif peek == '[': - return self._readArray() - elif peek == '"': - return self._readString() - elif peek == '-' or peek.isdigit(): - return self._readNumber() - elif peek == 't': - return self._readTrue() - elif peek == 'f': - return self._readFalse() - elif peek == 'n': - return self._readNull() - elif peek == '/': - self._readComment() - return self._read() - else: - raise ReadException, "Input is not valid JSON: '%s'" % self._generator.all() - - def _readTrue(self): - self._assertNext('t', "true") - self._assertNext('r', "true") - self._assertNext('u', "true") - self._assertNext('e', "true") - return True - - def _readFalse(self): - self._assertNext('f', "false") - self._assertNext('a', "false") - self._assertNext('l', "false") - self._assertNext('s', "false") - self._assertNext('e', "false") - return False - - def _readNull(self): - self._assertNext('n', "null") - self._assertNext('u', "null") - self._assertNext('l', "null") - self._assertNext('l', "null") - return None - - def _assertNext(self, ch, target): - if self._next() != ch: - raise ReadException, "Trying to read %s: '%s'" % (target, self._generator.all()) - - def _readNumber(self): - isfloat = False - result = self._next() - peek = self._peek() - while peek is not None and (peek.isdigit() or peek == "."): - isfloat = isfloat or peek == "." - result = result + self._next() - peek = self._peek() - try: - if isfloat: - return float(result) - else: - return int(result) - except ValueError: - raise ReadException, "Not a valid JSON number: '%s'" % result - - def _readString(self): - result = "" - assert self._next() == '"' - try: - while self._peek() != '"': - ch = self._next() - if ch == "\\": - ch = self._next() - if ch in 'brnft': - ch = self.escapes[ch] - elif ch == "u": - ch4096 = self._next() - ch256 = self._next() - ch16 = self._next() - ch1 = self._next() - n = 4096 * self._hexDigitToInt(ch4096) - n += 256 * self._hexDigitToInt(ch256) - n += 16 * self._hexDigitToInt(ch16) - n += self._hexDigitToInt(ch1) - ch = unichr(n) - elif ch not in '"/\\': - raise ReadException, "Not a valid escaped JSON character: '%s' in %s" % (ch, self._generator.all()) - result = result + ch - except StopIteration: - raise ReadException, "Not a valid JSON string: '%s'" % self._generator.all() - assert self._next() == '"' - return result - - def _hexDigitToInt(self, ch): - try: - result = self.hex_digits[ch.upper()] - except KeyError: - try: - result = int(ch) - except ValueError: - raise ReadException, "The character %s is not a hex digit." % ch - return result - - def _readComment(self): - assert self._next() == "/" - second = self._next() - if second == "/": - self._readDoubleSolidusComment() - elif second == '*': - self._readCStyleComment() - else: - raise ReadException, "Not a valid JSON comment: %s" % self._generator.all() - - def _readCStyleComment(self): - try: - done = False - while not done: - ch = self._next() - done = (ch == "*" and self._peek() == "/") - if not done and ch == "/" and self._peek() == "*": - raise ReadException, "Not a valid JSON comment: %s, '/*' cannot be embedded in the comment." % self._generator.all() - self._next() - except StopIteration: - raise ReadException, "Not a valid JSON comment: %s, expected */" % self._generator.all() - - def _readDoubleSolidusComment(self): - try: - ch = self._next() - while ch != "\r" and ch != "\n": - ch = self._next() - except StopIteration: - pass - - def _readArray(self): - result = [] - assert self._next() == '[' - done = self._peek() == ']' - while not done: - item = self._read() - result.append(item) - self._eatWhitespace() - done = self._peek() == ']' - if not done: - ch = self._next() - if ch != ",": - raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch) - assert ']' == self._next() - return result - - def _readObject(self): - result = {} - assert self._next() == '{' - done = self._peek() == '}' - while not done: - key = self._read() - if type(key) is not types.StringType: - raise ReadException, "Not a valid JSON object key (should be a string): %s" % key - self._eatWhitespace() - ch = self._next() - if ch != ":": - raise ReadException, "Not a valid JSON object: '%s' due to: '%s'" % (self._generator.all(), ch) - self._eatWhitespace() - val = self._read() - result[key] = val - self._eatWhitespace() - done = self._peek() == '}' - if not done: - ch = self._next() - if ch != ",": - raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch) - assert self._next() == "}" - return result - - def _eatWhitespace(self): - p = self._peek() - while p is not None and p in string.whitespace or p == '/': - if p == '/': - self._readComment() - else: - self._next() - p = self._peek() - - def _peek(self): - return self._generator.peek() - - def _next(self): - return self._generator.next() - -class JsonWriter(object): - - def _append(self, s): - self._results.append(s) - - def write(self, obj, escaped_forward_slash=False): - self._escaped_forward_slash = escaped_forward_slash - self._results = [] - self._write(obj) - return "".join(self._results) - - def _write(self, obj): - ty = type(obj) - if ty is types.DictType: - n = len(obj) - self._append("{") - for k, v in obj.items(): - self._write(k) - self._append(":") - self._write(v) - n = n - 1 - if n > 0: - self._append(",") - self._append("}") - elif ty is types.ListType or ty is types.TupleType: - n = len(obj) - self._append("[") - for item in obj: - self._write(item) - n = n - 1 - if n > 0: - self._append(",") - self._append("]") - elif ty is types.StringType or ty is types.UnicodeType: - self._append('"') - obj = obj.replace('\\', r'\\') - if self._escaped_forward_slash: - obj = obj.replace('/', r'\/') - obj = obj.replace('"', r'\"') - obj = obj.replace('\b', r'\b') - obj = obj.replace('\f', r'\f') - obj = obj.replace('\n', r'\n') - obj = obj.replace('\r', r'\r') - obj = obj.replace('\t', r'\t') - self._append(obj) - self._append('"') - elif ty is types.IntType or ty is types.LongType: - self._append(str(obj)) - elif ty is types.FloatType: - self._append("%f" % obj) - elif obj is True: - self._append("true") - elif obj is False: - self._append("false") - elif obj is None: - self._append("null") - else: - raise WriteException, "Cannot write in JSON: %s" % repr(obj) - -def write(obj, escaped_forward_slash=False): - return JsonWriter().write(obj, escaped_forward_slash) - -def read(s): - return JsonReader().read(s) - -def fread(f): - return read(f.read()) diff --git a/fbconnect/tests.py b/fbconnect/tests.py deleted file mode 100644 index 2247054b..00000000 --- a/fbconnect/tests.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -This file demonstrates two different styles of tests (one doctest and one -unittest). These will both pass when you run "manage.py test". - -Replace these with more appropriate tests for your application. -""" - -from django.test import TestCase - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.failUnlessEqual(1 + 1, 2) - -__test__ = {"doctest": """ -Another way to test that 1 + 1 is equal to 2. - ->>> 1 + 1 == 2 -True -"""} - diff --git a/fbconnect/urls.py b/fbconnect/urls.py deleted file mode 100644 index 81b0cb0f..00000000 --- a/fbconnect/urls.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.conf.urls.defaults import * -from django.utils.translation import ugettext as _ -from django.views.generic.simple import direct_to_template -from views import signin, register - -urlpatterns = patterns('', - url( - r'^xd_receiver$', - direct_to_template, - {'template': 'fbconnect/xd_receiver.html',}, - name='xd_receiver' - ), - - url(r'^%s$' % _('signin/'), signin, name="fb_signin"), - url(r'^%s%s$' % (_('signin/'), _('newquestion/')), signin, {'newquestion': True}, name="fb_signin_new_question"), - url(r'^%s%s$' % (_('signin/'), _('newanswer/')), signin, {'newanswer': True}, name="fb_signin_new_answer"), - - url(r'^%s$' % _('register/'), register, name="fb_user_register"), - url(r'^%s%s$' % (_('register/'), _('newquestion/')), register, {'newquestion': True}, name="fb_user_register_new_question"), - url(r'^%s%s$' % (_('register/'), _('newanswer/')), register, {'newanswer': True}, name="fb_user_register_new_answer"), -) diff --git a/fbconnect/views.py b/fbconnect/views.py deleted file mode 100644 index 91ea757a..00000000 --- a/fbconnect/views.py +++ /dev/null @@ -1,112 +0,0 @@ -from django.shortcuts import render_to_response as render -from django.template import RequestContext -from django.http import HttpResponseRedirect -from django.utils.safestring import mark_safe -from django.core.urlresolvers import reverse -from django.contrib.auth.models import User -from django.contrib.auth import login, logout -from models import FBAssociation -from forum.forms import SimpleEmailSubscribeForm -from django.conf import settings - -import fb -import forms - -import logging - -def signin(request, newquestion = False, newanswer = False): - logging.debug('') - state, context = fb.get_user_state(request) - - if state == fb.STATES['FIRSTTIMER']: - logging.debug('FB state = FIRSTTIMER') - if newquestion: - register_url = 'fb_user_register_new_question' - elif newanswer: - register_url = 'fb_user_register_new_answer' - else: - register_url = 'fb_user_register' - return HttpResponseRedirect(reverse(register_url)) - elif state == fb.STATES['RETURNINGUSER']: - logging.debug('FB state = RETURNINGUSER') - return login_and_forward(request, context, newquestion, newanswer) - elif state == fb.STATES['SESSIONEXPIRED']: - logging.debug('FB state = SESSIONEXPIRED') - response = logout(request, next_page=reverse('index')) - fb.delete_cookies(response) - return response - - return HttpResponseRedirect(reverse('index')) - -def register(request, newquestion = False, newanswer = False): - logging.debug('') - state, context = fb.get_user_state(request) - - if state == fb.STATES['FIRSTTIMER']: - logging.debug('FB FIRSTTIMER - try to register locally') - logging.debug('request method is %s' % request.method) - if request.method == 'POST' and 'bnewaccount' in request.POST: - form1 = forms.FBConnectRegisterForm(request.POST) - email_feeds_form = SimpleEmailSubscribeForm(request.POST) - - if (form1.is_valid() and email_feeds_form.is_valid()): - tmp_pwd = User.objects.make_random_password() - user_ = User.objects.create_user(form1.cleaned_data['username'], - form1.cleaned_data['email'], tmp_pwd) - - user_.set_unusable_password() - logging.debug('created new internal user %s' % form1.cleaned_data['username']) - - uassoc = FBAssociation(user=user_, fbuid=context['uid']) - uassoc.save() - logging.debug('created new user association') - - email_feeds_form.save(user_) - - return login_and_forward(request, user_, newquestion, newanswer) - else: - logging.debug('form user input is invalid') - else: - form1 = forms.FBConnectRegisterForm(initial={ - 'next': '/', - 'username': context['name'], - 'email': '', - }) - email_feeds_form = SimpleEmailSubscribeForm() - - return render('authopenid/complete.html', { - 'form1': form1, - 'email_feeds_form': email_feeds_form, - 'provider':mark_safe('facebook'), - 'login_type':'facebook', - 'gravatar_faq_url':reverse('faq') + '#gravatar', - }, context_instance=RequestContext(request)) - else: - logging.debug('not a FIRSTTIMER --> redirect to index view') - return HttpResponseRedirect(reverse('index')) - -def login_and_forward(request, user, newquestion = False, newanswer = False): - old_session = request.session.session_key - user.backend = "django.contrib.auth.backends.ModelBackend" - logging.debug('attached auth.backends.ModelBackend to this FB user') - login(request, user) - logging.debug('user logged in!') - - from forum.models import signals#todo: move to authentication app - signals.user_logged_in.send(user=user,session_key=old_session,sender=None) - logging.debug('user_logged_in signal sent') - - if (newquestion): - from forum.models import Question - question = Question.objects.filter(author=user).order_by('-added_at')[0] - logging.debug('redirecting to newly posted question') - return HttpResponseRedirect(question.get_absolute_url()) - - if (newanswer): - from forum.models import Answer - answer = Answer.objects.filter(author=user).order_by('-added_at')[0] - logging.debug('redirecting to newly posted answer') - return HttpResponseRedirect(answer.get_absolute_url()) - - logging.debug('redirecting to front page') - return HttpResponseRedirect('/') diff --git a/forum/badges/__init__.py b/forum/badges/__init__.py deleted file mode 100644 index 8d7cd097..00000000 --- a/forum/badges/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -import re - -from forum.badges.base import BadgeImplementation -from forum.modules import get_modules_script_classes - -ALL_BADGES = dict([ - (re.sub('BadgeImpl', '', name).lower(), cls) for name, cls - in get_modules_script_classes('badges', BadgeImplementation).items() - if not re.search('AbstractBadgeImpl$', name) - ])
\ No newline at end of file diff --git a/forum/badges/base.py b/forum/badges/base.py deleted file mode 100644 index 03ef3565..00000000 --- a/forum/badges/base.py +++ /dev/null @@ -1,11 +0,0 @@ - - -class BadgeImplementation(object): - name = "" - description = "" - - def install(self): - pass - - def process_job(self): - raise NotImplementedError
\ No newline at end of file diff --git a/dos2unix.sh b/forum/bin/dos2unix.sh index 2864426a..2864426a 100644 --- a/dos2unix.sh +++ b/forum/bin/dos2unix.sh diff --git a/forum/conf/skin_counter_settings.py b/forum/conf/skin_counter_settings.py index 51c7e332..5a9d177f 100644 --- a/forum/conf/skin_counter_settings.py +++ b/forum/conf/skin_counter_settings.py @@ -4,7 +4,7 @@ Skin settings to color view, vote and answer counters from forum.conf.settings_wrapper import settings from livesettings import ConfigurationGroup, IntegerValue, StringValue from django.utils.translation import ugettext as _ -from forum_modules.grapefruit import Color +from forum.deps.grapefruit import Color SKIN_COUNTER_SETTINGS = ConfigurationGroup( 'SKIN_COUNTER_SETTINGS', diff --git a/forum/const/__init__.py b/forum/const/__init__.py index b1c9de7a..d77ba6b7 100644 --- a/forum/const/__init__.py +++ b/forum/const/__init__.py @@ -104,8 +104,8 @@ TYPE_ACTIVITY_MENTION = 19 #todo: rename this to TYPE_ACTIVITY_CHOICES TYPE_ACTIVITY = ( - (TYPE_ACTIVITY_ASK_QUESTION, _('question')), - (TYPE_ACTIVITY_ANSWER, _('answer')), + (TYPE_ACTIVITY_ASK_QUESTION, _('asked a question')), + (TYPE_ACTIVITY_ANSWER, _('answered a question')), (TYPE_ACTIVITY_COMMENT_QUESTION, _('commented question')), (TYPE_ACTIVITY_COMMENT_ANSWER, _('commented answer')), (TYPE_ACTIVITY_UPDATE_QUESTION, _('edited question')), diff --git a/forum/deps/README b/forum/deps/README new file mode 100644 index 00000000..2dfee4dd --- /dev/null +++ b/forum/deps/README @@ -0,0 +1,2 @@ +any python modules that are not accessible +through easy_install, but are necessary for the askbot forum diff --git a/fbconnect/__init__.py b/forum/deps/__init__.py index e69de29b..e69de29b 100644 --- a/fbconnect/__init__.py +++ b/forum/deps/__init__.py diff --git a/forum_modules/grapefruit.py b/forum/deps/grapefruit.py index ca684745..ca684745 100644 --- a/forum_modules/grapefruit.py +++ b/forum/deps/grapefruit.py diff --git a/forum/management/__init__.py b/forum/management/__init__.py index 60f8f570..e69de29b 100644 --- a/forum/management/__init__.py +++ b/forum/management/__init__.py @@ -1,3 +0,0 @@ -#todo: modules -#from forum.modules import get_modules_script -#get_modules_script('management') diff --git a/forum/models/__init__.py b/forum/models/__init__.py index 5d25da09..1fb18ff9 100644 --- a/forum/models/__init__.py +++ b/forum/models/__init__.py @@ -693,11 +693,4 @@ __all__ = [ #'AuthKeyUserAssociation', 'User', - ] - - -#from forum.modules import get_modules_script_classes -#for k, v in get_modules_script_classes('models', models.Model).items(): -# if not k in __all__: -# __all__.append(k) -# exec "%s = v" % k +] diff --git a/forum/modules.py b/forum/modules.py deleted file mode 100644 index 6c9a9dba..00000000 --- a/forum/modules.py +++ /dev/null @@ -1,78 +0,0 @@ -import os -import types -import re - -from django.template import Template, TemplateDoesNotExist - -MODULES_PACKAGE = 'forum_modules' - -MODULES_FOLDER = os.path.join(os.path.dirname(__file__), '../' + MODULES_PACKAGE) - -MODULE_LIST = [ - __import__('forum_modules.%s' % f, globals(), locals(), ['forum_modules']) - for f in os.listdir(MODULES_FOLDER) - if os.path.isdir(os.path.join(MODULES_FOLDER, f)) and - os.path.exists(os.path.join(MODULES_FOLDER, "%s/__init__.py" % f)) and - not os.path.exists(os.path.join(MODULES_FOLDER, "%s/DISABLED" % f)) -] - -def get_modules_script(script_name): - all = [] - - for m in MODULE_LIST: - try: - all.append(__import__('%s.%s' % (m.__name__, script_name), globals(), locals(), [m.__name__])) - except Exception, e: - #print script_name + ":" + str(e) - pass - - return all - -def get_modules_script_classes(script_name, base_class): - scripts = get_modules_script(script_name) - all_classes = {} - - for script in scripts: - all_classes.update(dict([ - (n, c) for (n, c) in [(n, getattr(script, n)) for n in dir(script)] - if isinstance(c, (type, types.ClassType)) and issubclass(c, base_class) - ])) - - return all_classes - -def get_all_handlers(name): - handler_files = get_modules_script('handlers') - - return [ - h for h in [ - getattr(f, name) for f in handler_files - if hasattr(f, name) - ] - - if callable(h) - ] - -def get_handler(name, default): - all = get_all_handlers(name) - return len(all) and all[0] or default - -module_template_re = re.compile('^modules\/(\w+)\/(.*)$') - -def module_templates_loader(name, dirs=None): - result = module_template_re.search(name) - - if result is not None: - file_name = os.path.join(MODULES_FOLDER, result.group(1), 'templates', result.group(2)) - - if os.path.exists(file_name): - try: - f = open(file_name, 'r') - source = f.read() - f.close() - return (source, file_name) - except: - pass - - raise TemplateDoesNotExist, name - -module_templates_loader.is_usable = True diff --git a/forum/skins/default/media/js/com.cnprog.i18n.js b/forum/skins/default/media/js/com.cnprog.i18n.js index 03690dc5..54c3806f 100644 --- a/forum/skins/default/media/js/com.cnprog.i18n.js +++ b/forum/skins/default/media/js/com.cnprog.i18n.js @@ -1,225 +1,225 @@ -//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次‘水帖’操作。',
- 'need >15 points to report spam':"需要+15积分才能归类‘垃圾帖’。",
- '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 i18nTr = {
- 'insufficient privilege':'buna yetkiniz yoktur',
- 'cannot pick own answer as best':'en cevap olarak kendi cevabınızı seçemezsiniz',
- 'anonymous users cannot select favorite questions':'üye girişi yapmadan favori seçemezsiniz',
- 'please login':'lütfen üye girişi yapınız',
- 'anonymous users cannot vote':'üye girişi yapmadan oy kullanamazsınız',
- '>15 points requried to upvote': 'beğeninizi göstermek için en az 15 puan toplamalısınız',
- '>100 points required to downvote':'beğenmediğinizi göstermek için en az 100 puan toplamalısınız',
- 'please see': 'lütfen bakın',
- 'cannot vote for own posts':'kendi yazılarınıza oy veremezsiniz',
- 'daily vote cap exhausted':'bugünlük oy verme kotanız doldu',
- 'cannot revoke old vote':'verilen bir oyu iptal edemezsiniz',
- 'please confirm offensive':"şikayetinizi onaylayın",
- 'anonymous users cannot flag offensive posts':'üye girişi yapmadan şikayet gönderemezsiniz',
- 'cannot flag message as offensive twice':'şikayet mesajı olarak iki kez işaretlemelisiniz',
- 'flag offensive cap exhausted':'şikayet kotası aşıldı',
- 'need >15 points to report spam':"spam olarak bildirmek için an az 15 puanınız olmalı",
- 'confirm delete':"Bunu silmek istediğinizden emin misiniz?",
- 'anonymous users cannot delete/undelete':"üye girişi yapmadan yazı silemez yada geri alamazsınız",
- 'post recovered':"yazı geri alındı",
- 'post deleted':"yazı silindi",
- 'add comment':'yorum ekle',
- 'community karma points':'site itibar puanları',
- 'to comment, need':'Yorum için itibar puanınız olmalı',
- 'delete this comment':'bu yorumu sil',
- 'hide comments':"yorumları gizle",
- 'add a comment':"yorum ekle",
- 'comments':"yorumlar",
- 'confirm delete comment':"yorumu silmek istediğinizden emin misiniz?",
- 'characters':'karakter eksik',
- 'can write':'yazılabilir ',
- 'click to close':'kapatmak için tıklayın',
- 'loading...':'yükleniyor...',
- 'tags cannot be empty':'etiketler boş olamaz',
- 'tablimits info':"En fazla 5 etiket ve her biri en fazla 20 karakter",
- 'content cannot be empty':'içerik boş olamaz',
- 'content minchars': 'Lütfen en az (0) karakter girin',
- 'please enter title':'lütfen bir başlık yazın',
- 'title minchars':"Lütfen en az (0) karakter girin",
- 'delete':'sil',
- 'undelete': 'geri al',
- 'bold': 'kalın',
- 'italic':'italik',
- 'link':'link',
- 'quote':'alıntı',
- 'preformatted text':'hazır metin',
- 'image':'resimler',
- 'numbered list':'numaralı liste',
- 'bulleted list':'işaretli liste',
- 'heading':'Başlık',
- 'horizontal bar':'yatay bar',
- 'undo':'geri',
- 'redo':'yeniden',
- 'enter image url':'örnek resmin URLsini girin: <br />http://www.example.com/image.jpg \"resim başlığı\"',
- 'enter url':'web adresini girin: <br />http://www.cnprog.com/ \"başlık bağlantısı\"</p>"',
- 'upload image':'resim yükle:',
- 'questions/' : 'sorular/',
- 'answers/' : 'cevaplar/',
- 'comments/' : 'yorumlar/',
- 'vote/' : 'oy/',
- 'delete/' : 'sil/'
-};
-
-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/',
- 'answers/' : 'respuestas/',
- 'comments/' : 'comentarios/',
- 'vote/' : 'votar/',
- 'delete/' : 'eliminar/'
-};
-
-var i18n = {
- 'en':i18nEn,
- 'zh-cn':i18nZh,
- 'es':i18nEs,
- 'tr':i18nTr
-};
-
-var i18n_dict = i18n[i18nLang];
+//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次‘水帖’操作。', + 'need >15 points to report spam':"需要+15积分才能归类‘垃圾帖’。", + '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 i18nTr = { + 'insufficient privilege':'buna yetkiniz yoktur', + 'cannot pick own answer as best':'en cevap olarak kendi cevabınızı seçemezsiniz', + 'anonymous users cannot select favorite questions':'üye girişi yapmadan favori seçemezsiniz', + 'please login':'lütfen üye girişi yapınız', + 'anonymous users cannot vote':'üye girişi yapmadan oy kullanamazsınız', + '>15 points requried to upvote': 'beğeninizi göstermek için en az 15 puan toplamalısınız', + '>100 points required to downvote':'beğenmediğinizi göstermek için en az 100 puan toplamalısınız', + 'please see': 'lütfen bakın', + 'cannot vote for own posts':'kendi yazılarınıza oy veremezsiniz', + 'daily vote cap exhausted':'bugünlük oy verme kotanız doldu', + 'cannot revoke old vote':'verilen bir oyu iptal edemezsiniz', + 'please confirm offensive':"şikayetinizi onaylayın", + 'anonymous users cannot flag offensive posts':'üye girişi yapmadan şikayet gönderemezsiniz', + 'cannot flag message as offensive twice':'şikayet mesajı olarak iki kez işaretlemelisiniz', + 'flag offensive cap exhausted':'şikayet kotası aşıldı', + 'need >15 points to report spam':"spam olarak bildirmek için an az 15 puanınız olmalı", + 'confirm delete':"Bunu silmek istediğinizden emin misiniz?", + 'anonymous users cannot delete/undelete':"üye girişi yapmadan yazı silemez yada geri alamazsınız", + 'post recovered':"yazı geri alındı", + 'post deleted':"yazı silindi", + 'add comment':'yorum ekle', + 'community karma points':'site itibar puanları', + 'to comment, need':'Yorum için itibar puanınız olmalı', + 'delete this comment':'bu yorumu sil', + 'hide comments':"yorumları gizle", + 'add a comment':"yorum ekle", + 'comments':"yorumlar", + 'confirm delete comment':"yorumu silmek istediğinizden emin misiniz?", + 'characters':'karakter eksik', + 'can write':'yazılabilir ', + 'click to close':'kapatmak için tıklayın', + 'loading...':'yükleniyor...', + 'tags cannot be empty':'etiketler boş olamaz', + 'tablimits info':"En fazla 5 etiket ve her biri en fazla 20 karakter", + 'content cannot be empty':'içerik boş olamaz', + 'content minchars': 'Lütfen en az (0) karakter girin', + 'please enter title':'lütfen bir başlık yazın', + 'title minchars':"Lütfen en az (0) karakter girin", + 'delete':'sil', + 'undelete': 'geri al', + 'bold': 'kalın', + 'italic':'italik', + 'link':'link', + 'quote':'alıntı', + 'preformatted text':'hazır metin', + 'image':'resimler', + 'numbered list':'numaralı liste', + 'bulleted list':'işaretli liste', + 'heading':'Başlık', + 'horizontal bar':'yatay bar', + 'undo':'geri', + 'redo':'yeniden', + 'enter image url':'örnek resmin URLsini girin: <br />http://www.example.com/image.jpg \"resim başlığı\"', + 'enter url':'web adresini girin: <br />http://www.cnprog.com/ \"başlık bağlantısı\"</p>"', + 'upload image':'resim yükle:', + 'questions/' : 'sorular/', + 'answers/' : 'cevaplar/', + 'comments/' : 'yorumlar/', + 'vote/' : 'oy/', + 'delete/' : 'sil/' +}; + +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/', + 'answers/' : 'respuestas/', + 'comments/' : 'comentarios/', + 'vote/' : 'votar/', + 'delete/' : 'eliminar/' +}; + +var i18n = { + 'en':i18nEn, + 'zh-cn':i18nZh, + 'es':i18nEs, + 'tr':i18nTr +}; + +var i18n_dict = i18n[i18nLang]; diff --git a/forum/skins/default/media/style/style.css b/forum/skins/default/media/style/style.css index 1ae117c4..9d34a26e 100755 --- a/forum/skins/default/media/style/style.css +++ b/forum/skins/default/media/style/style.css @@ -229,7 +229,7 @@ blockquote { } #CARight { - width: 240px; + width: 235px; float: right; } @@ -272,7 +272,7 @@ blockquote { } #top a.ab-responses-envelope { - margin-left: 0; + margin-left: 3px; } #top a img { vertical-align:middle; @@ -288,7 +288,7 @@ blockquote { #logoContainer { } #navTabContainer { - width: 600px; + width: 610px; padding-left: 10px; text-align: left; } @@ -371,7 +371,7 @@ blockquote { line-height: 24px; height: 36px; width: 605px; - margin: 0px; + margin: 0px 3px 0px 0px; padding: 5px 0 0 5px; } @@ -381,7 +381,7 @@ blockquote { height: 36px; width: 561px; padding: 5px 0 0 5px; - margin: 0px; + margin: 0px 3px 0px 0px; } #searchBar .searchBtn { @@ -392,8 +392,8 @@ blockquote { width: 80px; width: 80px; line-height: 22px; + margin: 0px; text-align: center; - margin-top:1px; padding-bottom: 4px; } @@ -403,8 +403,8 @@ blockquote { height: 40px; width: 40px; line-height: 22px; + margin: 0px 3px 0px 0px; padding-bottom: 4px; - margin-top:1px; text-align: center; } @@ -694,7 +694,6 @@ blockquote { background: white /*#cacdc6; /*f9f7ed;*/ padding: 10px; margin-bottom: 8px; - margin-left: 10px; /* border-top: 1px solid #eeeeec; border-left: 1px solid #eeeeec; @@ -833,7 +832,7 @@ conflicts with WMD! .tags a { white-space: nowrap; - font-size: 13px; + font-size: 10px; font-weight: normal; color: #333; text-decoration: none; @@ -843,6 +842,7 @@ conflicts with WMD! border-bottom: 1px solid #CCC; border-right: 1px solid #CCC; padding: 1px 8px 1px 8px; + margin-right:3px; } .tags a:hover { diff --git a/forum/skins/default/templates/question_list.html b/forum/skins/default/templates/question_list.html index 38ac254a..c9fc1f96 100644 --- a/forum/skins/default/templates/question_list.html +++ b/forum/skins/default/templates/question_list.html @@ -11,7 +11,7 @@ <div class="userinfo">
<span class="relativetime" title="{{question.last_activity_at}}">{% diff_date question.last_activity_at %}</span>
{% if question.last_activity_by %}
- <a href="{% url user_profile question.last_activity_by.id question.last_activity_by.username|slugify %}">{{ question.last_activity_by }}</a> {% get_score_badge question.last_activity_by %}
+ <a href="{% url user_profile question.last_activity_by.id question.last_activity_by.username|slugify %}">{{ question.last_activity_by }}</a> {% get_score_badge question.last_activity_by %}
{% endif %}
</div>
<div class="tags">
diff --git a/forum/skins/default/templates/user_responses.html b/forum/skins/default/templates/user_responses.html index 21f08046..2d96112b 100644 --- a/forum/skins/default/templates/user_responses.html +++ b/forum/skins/default/templates/user_responses.html @@ -28,8 +28,8 @@ response_snippet - abbreviated content of the response </div> <a style="font-size:12px" href="{{ response.user.get_absolute_url }}">{{ response.user.username }}</a> <a style="text-decoration:none;" href="{{ response.response_url }}"> - {{ response.response_type }}, - {% diff_date response.timestamp 3 %}:<br/> + {{ response.response_type }} + ({% diff_date response.timestamp 3 "True" %}):<br/> <strong>"{{ response.response_title }}"</strong> {{ response.response_snippet|safe }} </a> diff --git a/forum/sql_scripts/update_2010_01_23.sql b/forum/sql_scripts/update_2010_01_23.sql deleted file mode 100755 index 621207be..00000000 --- a/forum/sql_scripts/update_2010_01_23.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE `fbconnect_fbassociation` ( - `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, - `user_id` integer NOT NULL, - `fbuid` varchar(12) NOT NULL UNIQUE -) -; -ALTER TABLE `fbconnect_fbassociation` ADD CONSTRAINT `user_id_refs_id_3534873d` -FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`); -CREATE INDEX `fbconnect_fbassociation_user_id` ON `fbconnect_fbassociation` (`user_id`); diff --git a/forum/templatetags/extra_filters.py b/forum/templatetags/extra_filters.py index 2da313db..8c023810 100644 --- a/forum/templatetags/extra_filters.py +++ b/forum/templatetags/extra_filters.py @@ -1,6 +1,6 @@ from django import template from forum import auth -from forum_modules.grapefruit import Color +from forum.deps.grapefruit import Color from django.utils.translation import ugettext as _ import logging diff --git a/forum/templatetags/extra_tags.py b/forum/templatetags/extra_tags.py index 15f97ac8..960870a0 100644 --- a/forum/templatetags/extra_tags.py +++ b/forum/templatetags/extra_tags.py @@ -301,7 +301,7 @@ def convert2tagname_list(question): return '' @register.simple_tag -def diff_date(date, limen=2): +def diff_date(date, limen=2, use_on_prefix = False): now = datetime.datetime.now()#datetime(*time.localtime()[0:6])#??? diff = now - date days = diff.days @@ -310,9 +310,13 @@ def diff_date(date, limen=2): if days > 2: if date.year == now.year: - return date.strftime("%b %d")# at %H:%M") + date_token = date.strftime("%b %d") else: - return date.strftime("%b %d '%y")# at %H:%M") + date_token = date.strftime("%b %d '%y") + if use_on_prefix: + return _('on %(date)s') % { 'date': date_token } + else: + return date_token elif days == 2: return _('2 days ago') elif days == 1: diff --git a/forum/tests.py b/forum/tests.py index 28544b73..4f0482f5 100644 --- a/forum/tests.py +++ b/forum/tests.py @@ -614,7 +614,7 @@ class UpdateNotificationTests(TestCase): class AnonymousVisitorTests(TestCase): - fixtures = ['forum/fixtures/full_dump.json', ] + fixtures = ['tmp/fixture1.json', ] def test_index(self): #todo: merge this with all reader url tests diff --git a/forum/utils/colors.py b/forum/utils/colors.py index 694cc3b0..f7bee01e 100644 --- a/forum/utils/colors.py +++ b/forum/utils/colors.py @@ -1,4 +1,4 @@ -from forum_modules.grapefruit import Color +from forum.deps.grapefruit import Color import math def get_counter_colors(count, counter_max=10, empty_bg='white', empty_fg='black', diff --git a/forum/views/users.py b/forum/views/users.py index 42d406c2..0995812e 100644 --- a/forum/views/users.py +++ b/forum/views/users.py @@ -637,8 +637,8 @@ def user_responses(request, user_id, user_view): page """ user = get_object_or_404(models.User, id=user_id) - #if request.user != user: - # raise Http404 + if request.user != user: + raise Http404 user = get_object_or_404(models.User, id=user_id) response_list = [] diff --git a/forum_modules/__init__.py b/forum_modules/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/forum_modules/__init__.py +++ /dev/null diff --git a/forum_modules/authentication/README b/forum_modules/authentication/README deleted file mode 100644 index a602dc2c..00000000 --- a/forum_modules/authentication/README +++ /dev/null @@ -1,3 +0,0 @@ -THIS DIRECTORY IS NOT USED - -authentication module will be redone as separate application diff --git a/forum_modules/authentication/auth.py b/forum_modules/authentication/auth.py deleted file mode 100644 index b46e3df3..00000000 --- a/forum_modules/authentication/auth.py +++ /dev/null @@ -1,144 +0,0 @@ -from django.shortcuts import render_to_response, get_object_or_404 -from django.template import RequestContext -from django.core.urlresolvers import reverse -from django.contrib.auth.models import User -from django.http import HttpResponseRedirect, Http404 -from django.utils.safestring import mark_safe -from django.utils.translation import ugettext as _ -from django.utils.http import urlquote_plus -from django.contrib.auth.decorators import login_required -from django.contrib.auth import login, logout -from django.http import get_host -import types -import datetime - -from forum.models import AuthKeyUserAssociation, ValidationHash -from forum.authentication.forms import SimpleRegistrationForm, SimpleEmailSubscribeForm, \ - TemporaryLoginRequestForm, ChangePasswordForm, SetPasswordForm -from forum.utils.email import send_email - -from forum.authentication.base import InvalidAuthentication -from forum.authentication import AUTH_PROVIDERS - -from forum.models import Question, Answer - -def send_validation_email(user): - hash = ValidationHash.objects.create_new(user, 'email', [user.email]) - send_email(_("Email Validation"), [user.email], "auth/email_validation.html", { - 'validation_code': hash, - 'user': user - }) - -def validate_email(request, user, code): - user = get_object_or_404(User, id=user) - - if (ValidationHash.objects.validate(code, user, 'email', [user.email])): - user.email_isvalid = True - user.save() - return login_and_forward(request, user, None, _("Thank you, your email is now validated.")) - else: - raise Http404() - -@login_required -def auth_settings(request): - """ - change password view. - - url : /changepw/ - template: authopenid/changepw.html - """ - user_ = request.user - auth_keys = user_.auth_keys.all() - - if user_.has_usable_password(): - FormClass = ChangePasswordForm - else: - FormClass = SetPasswordForm - - if request.POST: - form = FormClass(request.POST, user=user_) - if form.is_valid(): - if user_.has_usable_password(): - request.user.message_set.create(message=_("Your password was changed")) - else: - request.user.message_set.create(message=_("New password set")) - FormClass = ChangePasswordForm - - user_.set_password(form.cleaned_data['password1']) - user_.save() - return HttpResponseRedirect(reverse('user_authsettings')) - - form = FormClass(user=user_) - - auth_keys_list = [] - - for k in auth_keys: - provider = AUTH_PROVIDERS.get(k.provider, None) - - if provider is not None: - name = "%s: %s" % (provider.context.human_name, provider.context.readable_key(k)) - else: - from forum.authentication.base import ConsumerTemplateContext - "unknown: %s" % ConsumerTemplateContext.readable_key(k) - - auth_keys_list.append({ - 'name': name, - 'id': k.id - }) - - return render_to_response('auth/auth_settings.html', { - 'form': form, - 'has_password': user_.has_usable_password(), - 'auth_keys': auth_keys_list, - }, context_instance=RequestContext(request)) - -def newquestion_signin_action(user): - question = Question.objects.filter(author=user).order_by('-added_at')[0] - return question.get_absolute_url() - -def newanswer_signin_action(user): - answer = Answer.objects.filter(author=user).order_by('-added_at')[0] - return answer.get_absolute_url() - -POST_SIGNIN_ACTIONS = { - 'newquestion': newquestion_signin_action, - 'newanswer': newanswer_signin_action, -} - -def login_and_forward(request, user, forward=None, message=None): - old_session = request.session.session_key - user.backend = "django.contrib.auth.backends.ModelBackend" - login(request, user) - - from forum.models import signals#todo: move to auth app - signals.user_logged_in.send(user=user,session_key=old_session,sender=None) - - if not forward: - signin_action = request.session.get('on_signin_action', None) - if not signin_action: - forward = request.session.get('on_signin_url', None) - - if not forward: - forward = reverse('index') - else: - try: - forward = POST_SIGNIN_ACTIONS[signin_action](user) - except: - forward = reverse('index') - - if message is None: - message = _("Welcome back %s, you are now logged in") % user.username - - request.user.message_set.create(message=message) - return HttpResponseRedirect(forward) - -@login_required -def signout(request): - """ - signout from the website. Remove openid from session and kill it. - - url : /signout/" - """ - - logout(request) - return HttpResponseRedirect(reverse('index')) diff --git a/forum_modules/books/__init__.py b/forum_modules/books/__init__.py deleted file mode 100644 index c51a2bfb..00000000 --- a/forum_modules/books/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -NAME = 'Books' -DESCRIPTION = "Allows discussion around books." -CAN_ENABLE = True diff --git a/forum_modules/books/models.py b/forum_modules/books/models.py deleted file mode 100644 index a78c0e76..00000000 --- a/forum_modules/books/models.py +++ /dev/null @@ -1,63 +0,0 @@ -from django.db import models -from django.contrib.auth.models import User -from forum.models import Question -from django.core.urlresolvers import reverse -from django.utils.http import urlquote as django_urlquote -from django.template.defaultfilters import slugify - -class Book(models.Model): - """ - Model for book info - """ - user = models.ForeignKey(User) - title = models.CharField(max_length=255) - short_name = models.CharField(max_length=255) - author = models.CharField(max_length=255) - price = models.DecimalField(max_digits=6, decimal_places=2) - pages = models.SmallIntegerField() - published_at = models.DateTimeField() - publication = models.CharField(max_length=255) - cover_img = models.CharField(max_length=255) - tagnames = models.CharField(max_length=125) - added_at = models.DateTimeField() - last_edited_at = models.DateTimeField() - questions = models.ManyToManyField(Question, related_name='book', db_table='book_question') - - def get_absolute_url(self): - return reverse('book', args=[django_urlquote(slugify(self.short_name))]) - - def __unicode__(self): - return self.title - - class Meta: - app_label = 'forum' - db_table = u'book' - -class BookAuthorInfo(models.Model): - """ - Model for book author info - """ - user = models.ForeignKey(User) - book = models.ForeignKey(Book) - blog_url = models.CharField(max_length=255) - added_at = models.DateTimeField() - last_edited_at = models.DateTimeField() - - class Meta: - app_label = 'forum' - db_table = u'book_author_info' - -class BookAuthorRss(models.Model): - """ - Model for book author blog rss - """ - user = models.ForeignKey(User) - book = models.ForeignKey(Book) - title = models.CharField(max_length=255) - url = models.CharField(max_length=255) - rss_created_at = models.DateTimeField() - added_at = models.DateTimeField() - - class Meta: - app_label = 'forum' - db_table = u'book_author_rss'
\ No newline at end of file diff --git a/forum_modules/books/urls.py b/forum_modules/books/urls.py deleted file mode 100644 index bc0811e7..00000000 --- a/forum_modules/books/urls.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.conf.urls.defaults import * -from django.utils.translation import ugettext as _ - -import views as app - -urlpatterns = patterns('', - url(r'^%s$' % _('books/'), app.books, name='books'), - url(r'^%s%s(?P<short_name>[^/]+)/$' % (_('books/'), _('ask/')), app.ask_book, name='ask_book'), - url(r'^%s(?P<short_name>[^/]+)/$' % _('books/'), app.book, name='book'), -)
\ No newline at end of file diff --git a/forum_modules/books/views.py b/forum_modules/books/views.py deleted file mode 100644 index d4907e5f..00000000 --- a/forum_modules/books/views.py +++ /dev/null @@ -1,142 +0,0 @@ -from django.shortcuts import render_to_response, get_object_or_404 -from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, Http404 -from django.template import RequestContext -from django.contrib.auth.decorators import login_required -from django.core.urlresolvers import reverse -from django.utils.html import * - -from models import * - -from forum.forms import AskForm -from forum.views.readers import _get_tags_cache_json -from forum.models import * -from forum.utils.html import sanitize_html - -def books(request): - return HttpResponseRedirect(reverse('books') + '/mysql-zhaoyang') - -def book(request, short_name, unanswered=False): - """ - 1. questions list - 2. book info - 3. author info and blog rss items - """ - """ - List of Questions, Tagged questions, and Unanswered questions. - """ - books = Book.objects.extra(where=['short_name = %s'], params=[short_name]) - match_count = len(books) - if match_count == 0: - raise Http404 - else: - # the book info - book = books[0] - # get author info - author_info = BookAuthorInfo.objects.get(book=book) - # get author rss info - author_rss = BookAuthorRss.objects.filter(book=book) - - # get pagesize from session, if failed then get default value - user_page_size = request.session.get("page_size", QUESTIONS_PAGE_SIZE) - # set pagesize equal to logon user specified value in database - if request.user.is_authenticated() and request.user.questions_per_page > 0: - user_page_size = request.user.questions_per_page - - try: - page = int(request.GET.get('page', '1')) - except ValueError: - page = 1 - - view_id = request.GET.get('sort', None) - view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" } - try: - orderby = view_dic[view_id] - except KeyError: - view_id = "latest" - orderby = "-added_at" - - # check if request is from tagged questions - if unanswered: - # check if request is from unanswered questions - # Article.objects.filter(publications__id__exact=1) - objects = Question.objects.filter(book__id__exact=book.id, deleted=False, answer_count=0).order_by(orderby) - else: - objects = Question.objects.filter(book__id__exact=book.id, deleted=False).order_by(orderby) - - # RISK - inner join queries - objects = objects.select_related(); - objects_list = Paginator(objects, user_page_size) - questions = objects_list.page(page) - - return render_to_response('book.html', { - "book" : book, - "author_info" : author_info, - "author_rss" : author_rss, - "questions" : questions, - "context" : { - 'is_paginated' : True, - 'pages': objects_list.num_pages, - 'page': page, - 'has_previous': questions.has_previous(), - 'has_next': questions.has_next(), - 'previous': questions.previous_page_number(), - 'next': questions.next_page_number(), - 'base_url' : request.path + '?sort=%s&' % view_id, - 'page_size' : user_page_size - } - }, context_instance=RequestContext(request)) - -@login_required -def ask_book(request, short_name): - if request.method == "POST": - form = AskForm(request.POST) - if form.is_valid(): - added_at = datetime.datetime.now() - html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) - question = Question( - title = strip_tags(form.cleaned_data['title']), - author = request.user, - added_at = added_at, - last_activity_at = added_at, - last_activity_by = request.user, - wiki = form.cleaned_data['wiki'], - tagnames = form.cleaned_data['tags'].strip(), - html = html, - summary = strip_tags(html)[:120] - ) - if question.wiki: - question.last_edited_by = question.author - question.last_edited_at = added_at - question.wikified_at = added_at - - question.save() - - # create the first revision - QuestionRevision.objects.create( - question = question, - revision = 1, - title = question.title, - author = request.user, - revised_at = added_at, - tagnames = question.tagnames, - summary = CONST['default_version'], - text = form.cleaned_data['text'] - ) - - books = Book.objects.extra(where=['short_name = %s'], params=[short_name]) - match_count = len(books) - if match_count == 1: - # the book info - book = books[0] - book.questions.add(question) - - return HttpResponseRedirect(question.get_absolute_url()) - else: - form = AskForm() - - tags = _get_tags_cache_json() - return render_to_response('ask.html', { - 'form' : form, - 'tags' : tags, - 'email_validation_faq_url': reverse('faq') + '#validate', - }, context_instance=RequestContext(request)) diff --git a/forum_modules/pgfulltext/DISABLED b/forum_modules/pgfulltext/DISABLED deleted file mode 100644 index e69de29b..00000000 --- a/forum_modules/pgfulltext/DISABLED +++ /dev/null diff --git a/forum_modules/pgfulltext/__init__.py b/forum_modules/pgfulltext/__init__.py deleted file mode 100644 index 8215e1a9..00000000 --- a/forum_modules/pgfulltext/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -NAME = 'Postgresql Full Text Search' -DESCRIPTION = "Enables PostgreSql full text search functionality." - -try: - import psycopg2 - CAN_ENABLE = True -except: - CAN_ENABLE = False -
\ No newline at end of file diff --git a/forum_modules/pgfulltext/handlers.py b/forum_modules/pgfulltext/handlers.py deleted file mode 100644 index f4a7a3b2..00000000 --- a/forum_modules/pgfulltext/handlers.py +++ /dev/null @@ -1,11 +0,0 @@ -from forum.models import Question - -def question_search(keywords, orderby): - return Question.objects.filter(deleted=False).extra( - select={ - 'ranking': "ts_rank_cd(tsv, plainto_tsquery(%s), 32)", - }, - where=["tsv @@ plainto_tsquery(%s)"], - params=[keywords], - select_params=[keywords] - ).order_by(orderby, '-ranking')
\ No newline at end of file diff --git a/forum_modules/pgfulltext/management.py b/forum_modules/pgfulltext/management.py deleted file mode 100644 index 15ba3bd7..00000000 --- a/forum_modules/pgfulltext/management.py +++ /dev/null @@ -1,30 +0,0 @@ -import os - -from django.db import connection, transaction -from django.conf import settings - -import forum.models - -if settings.DATABASE_ENGINE in ('postgresql_psycopg2', 'postgresql', ): - from django.db.models.signals import post_syncdb - - def setup_pgfulltext(sender, **kwargs): - if sender == forum.models: - install_pg_fts() - - post_syncdb.connect(setup_pgfulltext) - -def install_pg_fts(): - f = open(os.path.join(os.path.dirname(__file__), 'pg_fts_install.sql'), 'r') - - try: - try: - cursor = connection.cursor() - cursor.execute(f.read()) - transaction.commit_unless_managed() - except: - pass - finally: - cursor.close() - - f.close() diff --git a/forum_modules/pgfulltext/pg_fts_install.sql b/forum_modules/pgfulltext/pg_fts_install.sql deleted file mode 100644 index 72eca516..00000000 --- a/forum_modules/pgfulltext/pg_fts_install.sql +++ /dev/null @@ -1,38 +0,0 @@ -ALTER TABLE question ADD COLUMN tsv tsvector;
-
-CREATE OR REPLACE FUNCTION public.create_plpgsql_language ()
- RETURNS TEXT
- AS $$
- CREATE LANGUAGE plpgsql;
- SELECT 'language plpgsql created'::TEXT;
- $$
-LANGUAGE 'sql';
-
-SELECT CASE WHEN
- (SELECT true::BOOLEAN
- FROM pg_language
- WHERE lanname='plpgsql')
- THEN
- (SELECT 'language already installed'::TEXT)
- ELSE
- (SELECT public.create_plpgsql_language())
- END;
-
-DROP FUNCTION public.create_plpgsql_language ();
-
-CREATE OR REPLACE FUNCTION set_question_tsv() RETURNS TRIGGER AS $$
-begin
- new.tsv :=
- setweight(to_tsvector('english', coalesce(new.tagnames,'')), 'A') ||
- setweight(to_tsvector('english', coalesce(new.title,'')), 'B') ||
- setweight(to_tsvector('english', coalesce(new.summary,'')), 'C');
- RETURN new;
-end
-$$ LANGUAGE plpgsql;
-
-CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
-ON question FOR EACH ROW EXECUTE PROCEDURE set_question_tsv();
-
- CREATE INDEX question_tsv ON question USING gin(tsv);
-
-UPDATE question SET title = title;
diff --git a/forum_modules/robotstxt/DISABLED b/forum_modules/robotstxt/DISABLED deleted file mode 100755 index e69de29b..00000000 --- a/forum_modules/robotstxt/DISABLED +++ /dev/null diff --git a/forum_modules/robotstxt/__init__.py b/forum_modules/robotstxt/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/forum_modules/robotstxt/__init__.py +++ /dev/null diff --git a/forum_modules/robotstxt/templates/robots.txt b/forum_modules/robotstxt/templates/robots.txt deleted file mode 100755 index 574fc315..00000000 --- a/forum_modules/robotstxt/templates/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: /
\ No newline at end of file diff --git a/forum_modules/robotstxt/urls.py b/forum_modules/robotstxt/urls.py deleted file mode 100644 index 79a6d84c..00000000 --- a/forum_modules/robotstxt/urls.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.conf.urls.defaults import * -from django.views.generic.simple import direct_to_template - -urlpatterns = patterns('', - (r'^robots.txt$', direct_to_template, {'template': 'modules/robotsdennyall/robots.txt'}), -) diff --git a/forum_modules/sphinxfulltext/DISABLED b/forum_modules/sphinxfulltext/DISABLED deleted file mode 100644 index e69de29b..00000000 --- a/forum_modules/sphinxfulltext/DISABLED +++ /dev/null diff --git a/forum_modules/sphinxfulltext/__init__.py b/forum_modules/sphinxfulltext/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/forum_modules/sphinxfulltext/__init__.py +++ /dev/null diff --git a/forum_modules/sphinxfulltext/dependencies.py b/forum_modules/sphinxfulltext/dependencies.py deleted file mode 100644 index 046ebfc5..00000000 --- a/forum_modules/sphinxfulltext/dependencies.py +++ /dev/null @@ -1,2 +0,0 @@ -DJANGO_APPS = ('djangosphinx', ) - diff --git a/forum_modules/sphinxfulltext/handlers.py b/forum_modules/sphinxfulltext/handlers.py deleted file mode 100644 index 226acf72..00000000 --- a/forum_modules/sphinxfulltext/handlers.py +++ /dev/null @@ -1,4 +0,0 @@ -from forum.models import Question - -def question_search(keywords, orderby): - return Question.search.query(keywords)
\ No newline at end of file diff --git a/forum_modules/sphinxfulltext/models.py b/forum_modules/sphinxfulltext/models.py deleted file mode 100644 index a188728d..00000000 --- a/forum_modules/sphinxfulltext/models.py +++ /dev/null @@ -1,11 +0,0 @@ -from forum.models import Question -from django.conf import settings -from djangosphinx.manager import SphinxSearch - -from djangosphinx.models import SphinxSearch - -Question.add_to_class('search', SphinxSearch( - index=' '.join(settings.SPHINX_SEARCH_INDICES), - mode='SPH_MATCH_ALL', - ) - ) diff --git a/forum_modules/sphinxfulltext/settings.py b/forum_modules/sphinxfulltext/settings.py deleted file mode 100644 index 564404c6..00000000 --- a/forum_modules/sphinxfulltext/settings.py +++ /dev/null @@ -1,5 +0,0 @@ -SPHINX_API_VERSION = 0x113 #refer to djangosphinx documentation -SPHINX_SEARCH_INDICES=('askbot',) #a tuple of index names remember about a comma after the -#last item, especially if you have just one :) -SPHINX_SERVER='localhost' -SPHINX_PORT=3312 diff --git a/livesettings/README b/livesettings/README new file mode 100644 index 00000000..6fe70cc5 --- /dev/null +++ b/livesettings/README @@ -0,0 +1,4 @@ +this is very slightly forked version of django-livesettings +for use in the askbot forum project + +will attempt to re-merge into the original django-livesettings @@ -1 +0,0 @@ -python manage.py runserver `hostname -i`:8000 diff --git a/run-tests b/run-tests deleted file mode 100755 index 642b8a0a..00000000 --- a/run-tests +++ /dev/null @@ -1 +0,0 @@ -python manage.py test forum |