self.id = id
self._consumer = consumer
- context.id = id
+ if context:
+ context.id = id
self.context = context
@property
])
AUTH_PROVIDERS = dict([
- (name, ConsumerAndContext(name, consumers[name], contexts[name])) for name in consumers.keys()
- if name in contexts
+ (name, ConsumerAndContext(name, consumers[name], contexts.get(name, None))) for name in consumers.keys()
])
+
super(HttpResponseUnauthorized, self).__init__(
content=render_to_string('401.html', context_instance=RequestContext(request)),
status=401
- )
\ No newline at end of file
+ )
+
+class HttpResponseNotFound(HttpResponse):
+ def __init__(self, request):
+ super(HttpResponseNotFound, self).__init__(
+ content=render_to_string('404.html', context_instance=RequestContext(request)),
+ status=404
+ )
+
+class HttpResponseIntServerError(HttpResponse):
+ def __init__(self, request):
+ super(HttpResponseIntServerError, self).__init__(
+ content=render_to_string('500.html', context_instance=RequestContext(request)),
+ status=500
+ )
\ No newline at end of file
--- /dev/null
+from django.core.management.base import BaseCommand, CommandError
+
+class Command(BaseCommand):
+
+ def handle(self, *args, **options):
+
+ for path in args:
+ m = __import__('forum_modules.%s' % path, globals(), locals(), ['forum_modules'])
+
+ if hasattr(m, 'run'):
+ run = getattr(m, 'run')
+ if callable(run):
+ run()
from tag import Tag
from django.utils.translation import ugettext as _
-question_view = django.dispatch.Signal(providing_args=['instance', 'user'])
-
class QuestionManager(NodeManager):
def search(self, keywords):
return False, self.filter(models.Q(title__icontains=keywords) | models.Q(body__icontains=keywords))
return active_users
-def question_viewed(instance, **kwargs):
- instance.extra_count += 1
- instance.save()
-
-question_view.connect(question_viewed)
-
class QuestionSubscription(models.Model):
user = models.ForeignKey(User)
from django.utils.translation import ugettext as _
import logging
-QUESTIONS_PER_PAGE_CHOICES = (
-(10, u'10'),
-(30, u'30'),
-(50, u'50'),
-)
-
class AnonymousUser(DjangoAnonymousUser):
reputation = 0
sub_settings = SubscriptionSettings(user=self)
sub_settings.save()
- def get_absolute_url(self):
- return self.get_profile_url()
-
def get_messages(self):
messages = []
for m in self.message_set.all():
import os
import types
-import re
import logging
-from django.template import Template, TemplateDoesNotExist
-from django.conf import settings
-
MODULES_PACKAGE = 'forum_modules'
-MODULES_FOLDER = os.path.join(os.path.dirname(__file__), '../../' + MODULES_PACKAGE)
+MODULES_FOLDER = None
+MODULE_LIST = []
+
-DISABLED_MODULES = getattr(settings, 'DISABLED_MODULES', [])
+def init_modules_engine(site_src_root, disabled_modules):
+ MODULES_FOLDER = os.path.join(site_src_root, MODULES_PACKAGE)
-MODULE_LIST = filter(lambda m: getattr(m, 'CAN_USE', True), [
- __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 f in DISABLED_MODULES
-])
+ MODULE_LIST.extend(filter(lambda m: getattr(m, 'CAN_USE', True), [
+ __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 f in disabled_modules
+ ]))
def get_modules_script(script_name):
all = []
for m in MODULE_LIST:
+ if hasattr(m, script_name):
+ all.append(getattr(m, script_name))
+ continue
+
try:
all.append(__import__('%s.%s' % (m.__name__, script_name), globals(), locals(), [m.__name__]))
except ImportError, e:
except:
import traceback
msg = "Error importing %s from module %s: \n %s" % (
- script_name, m.__name__, traceback.format_exc()
+ script_name, m, traceback.format_exc()
)
logging.error(msg)
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
-
from decorators import decorate, ReturnImediatelyException
self.ret = ret\r
\r
def _check_decoratable(origin, install=True):\r
- if not isinstance(origin, DecoratableObject):\r
+ if not hasattr(origin, '_decoratable_obj'):\r
if inspect.ismethod(origin) and not hasattr(origin, '_decoratable_obj'):\r
decoratable = DecoratableObject(origin)\r
\r
elif inspect.isfunction(origin):\r
decoratable = DecoratableObject(origin)\r
\r
+ def decorated(*args, **kwargs):\r
+ return decoratable(*args, **kwargs)\r
+\r
+ decorated._decoratable_obj = decoratable\r
+\r
if install:\r
- setattr(inspect.getmodule(origin), origin.__name__, decoratable)\r
+ setattr(inspect.getmodule(origin), origin.__name__, decorated)\r
+\r
+ decorated.__name__ = origin.__name__\r
+ decorated.__module__ = origin.__module__\r
\r
- return decoratable\r
+ return decorated\r
\r
return origin\r
\r
origin = _check_decoratable(origin)\r
\r
def decorator(fn):\r
- origin._decorate(fn, DecoratableObject.MODE_OVERRIDE, needs_origin=needs_origin)\r
+ origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_OVERRIDE, needs_origin=needs_origin)\r
\r
return decorator\r
\r
origin = _check_decoratable(origin)\r
\r
def decorator(fn):\r
- origin._decorate(fn, DecoratableObject.MODE_PARAMS)\r
+ origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_PARAMS)\r
\r
return decorator\r
\r
origin = _check_decoratable(origin)\r
\r
def decorator(fn):\r
- origin._decorate(fn, DecoratableObject.MODE_RESULT, needs_params=needs_params)\r
+ origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_RESULT, needs_params=needs_params)\r
\r
return decorator\r
\r
def _decorate_with(fn):\r
def decorator(origin):\r
origin = _check_decoratable(origin)\r
- origin._decorate(fn, DecoratableObject.MODE_OVERRIDE, needs_origin=True)\r
+ origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_OVERRIDE, needs_origin=True)\r
return origin\r
return decorator\r
\r
def _decorate_result_with(fn, needs_params=False):\r
def decorator(origin):\r
origin = _check_decoratable(origin)\r
- origin._decorate(fn, DecoratableObject.MODE_RESULT, needs_params=needs_params)\r
+ origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_RESULT, needs_params=needs_params)\r
return origin\r
return decorator\r
\r
def _decorate_params_with(fn):\r
def decorator(origin):\r
origin = _check_decoratable(origin)\r
- origin._decorate(fn, DecoratableObject.MODE_PARAMS)\r
+ origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_PARAMS)\r
return origin\r
return decorator\r
\r
--- /dev/null
+import os, re
+
+from forum.skins import load_template_source as skins_template_loader, Template, BaseTemplateLoader
+from forum import modules
+
+MODULES_TEMPLATE_PREFIX = 'modules/'
+NO_OVERRIDE_TEMPLATE_PREFIX = 'no_override/'
+MODULES_TEMPLATE_FOLDER = 'templates'
+MODULES_TEMPLATE_OVERRIDES_FOLDER = 'template_overrides'
+
+TEMPLATE_OVERRIDE_LOOKUP_PATHS = [f for f in [
+ os.path.join(os.path.dirname(m.__file__), MODULES_TEMPLATE_OVERRIDES_FOLDER) for m in modules.MODULE_LIST
+ ] if os.path.exists(f)
+]
+
+class ModulesTemplateLoader(BaseTemplateLoader):
+
+ modules_re = re.compile('^%s(\w+)\/(.*)$' % MODULES_TEMPLATE_PREFIX)
+
+ def load_template_source(self, name, dirs=None):
+ template = None
+
+ if name.startswith(MODULES_TEMPLATE_PREFIX):
+ match = self.modules_re.search(name)
+ file_name = os.path.join(modules.MODULES_FOLDER, match.group(1), MODULES_TEMPLATE_FOLDER, match.group(2))
+
+ if os.path.exists(file_name):
+ template = Template(file_name)
+
+ elif name.startswith(NO_OVERRIDE_TEMPLATE_PREFIX):
+ return skins_template_loader.load_template_source(name[len(NO_OVERRIDE_TEMPLATE_PREFIX):], dirs)
+
+ else:
+ for override_path in TEMPLATE_OVERRIDE_LOOKUP_PATHS:
+ file_name = os.path.join(override_path, name)
+
+ if os.path.exists(file_name):
+ template = Template(file_name)
+ break
+
+
+ return template
+
+module_templates_loader = ModulesTemplateLoader()
-from forum.modules import ui
+from forum.modules import ui, get_modules_script
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify
+from django.template import get_templatetags_modules
from forum.templatetags.extra_tags import get_score_badge
from forum.utils.html import cleanup_urls
from forum import settings
+modules_template_tags = get_modules_script('templatetags')
+django_template_tags = get_templatetags_modules()
+
+for m in modules_template_tags:
+ django_template_tags.append(m.__name__)
+
ui.register(ui.HEADER_LINKS,
ui.Link(_('faq'), ui.Url('faq'), weight=400),
ui.Link(_('about'), ui.Url('about'), weight=300),
from django.conf import settings
-from django.template import loader
-from django.template.loaders import filesystem
-from django.http import HttpResponse
+from django.template.loaders import filesystem
+from django.template import TemplateDoesNotExist, Template as DJTemplate
+from django.conf import settings as djsettings
import os.path
import logging
-#module for skinning osqa
-#at this point skin can be changed only in settings file
-#via OSQA_DEFAULT_SKIN variable
+UNEXISTENT_TEMPLATE = object()
-#note - Django template loaders use method django.utils._os.safe_join
-#to work on unicode file paths
-#here it is ignored because it is assumed that we won't use unicode paths
+SKINS_FOLDER = os.path.dirname(__file__)
+SKIN_TEMPLATES_FOLDER = 'templates'
+DEFAULT_SKIN_NAME = 'default'
+FORCE_DEFAULT_PREFIX = "%s/" % DEFAULT_SKIN_NAME
+
+
+class Template(object):
+
+ def __init__(self, file_name):
+ self._file_name = file_name
+ self._loaded = False
+
+ def _get_mtime(self):
+ return os.path.getmtime(self._file_name)
+
+ def _check_mtime(self):
+ if self._last_mtime is None:
+ return False
+
+ return self._last_mtime == self._get_mtime()
+
+ def _load(self):
+ try:
+ f = open(self._file_name, 'r')
+ self._source = f.read()
+ f.close()
+ self._loaded = True
+
+ self._last_mtime = self._get_mtime()
+ except:
+ self._loaded = False
+ self._last_mtime = None
+
+ raise
+
+ def return_tuple(self):
+ if not (self._loaded and self._check_mtime()):
+ try:
+ self._load()
+ except:
+ raise TemplateDoesNotExist, self._file_name
+
+ return self._source, self._file_name
+
+class BaseTemplateLoader(object):
+ is_usable = True
+
+ def __init__(self):
+ self.cache = {}
+
+ def __call__(self, name=None, dirs=None):
+ if name is None:
+ return self
+
+ return self.load_template(name, dirs)
+
+ def load_template(self, name, dirs=None):
+ if not djsettings.TEMPLATE_DEBUG:
+ if name in self.cache:
+ if self.cache[name] is UNEXISTENT_TEMPLATE:
+ raise TemplateDoesNotExist, name
+
+ try:
+ return self.cache[name].return_tuple()
+ except:
+ del self.cache[name]
+
+ template = self.load_template_source(name, dirs)
+
+ if template is not None:
+ if not djsettings.DEBUG:
+ self.cache[name] = template
+
+ return template.return_tuple()
+ else:
+ if not djsettings.DEBUG:
+ self.cache[name] = UNEXISTENT_TEMPLATE
+
+ raise TemplateDoesNotExist, name
+
+ def load_template_source(self, name, dirs=None):
+ raise NotImplementedError
+
+
+class SkinsTemplateLoader(BaseTemplateLoader):
+
+ def load_template_source(self, name, dirs=None):
+
+ if name.startswith(FORCE_DEFAULT_PREFIX):
+
+ file_name = os.path.join(SKINS_FOLDER, DEFAULT_SKIN_NAME, SKIN_TEMPLATES_FOLDER, name[len(FORCE_DEFAULT_PREFIX):])
+
+ if os.path.exists(file_name):
+ return Template(file_name)
+ else:
+ return None
+
+ for skin in (settings.OSQA_DEFAULT_SKIN, DEFAULT_SKIN_NAME):
+ file_name = os.path.join(SKINS_FOLDER, skin, SKIN_TEMPLATES_FOLDER, name)
+
+ if os.path.exists(file_name):
+ return Template(file_name)
+
+ return None
+
+load_template_source = SkinsTemplateLoader()
-def load_template_source(name, dirs=None):
- try:
- tname = os.path.join(settings.OSQA_DEFAULT_SKIN,'templates',name)
- return filesystem.load_template_source(tname,dirs)
- except:
- tname = os.path.join('default','templates',name)
- return filesystem.load_template_source(tname,dirs)
-load_template_source.is_usable = True
def find_media_source(url):
"""returns url prefixed with the skin name
return None
return use_skin + '/' + url
-
-
\r
# The other controls are visible only to authenticated users.\r
if user.is_authenticated():\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
+ 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
\r
\r
@register.inclusion_tag("node/contributors_info.html")\r
-def contributors_info(node):\r
+def contributors_info(node, verb=None):\r
return {\r
- 'node_verb': (node.node_type == "question") and _("asked") or (\r
- (node.node_type == "answer") and _("answered") or _("posted")),\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
}\r
\r
from django import template
+from django.conf import settings
from forum.modules import ui
import logging
result += separator
result += ui_object.render(context)
except (KeyError, Exception), e:
- import traceback
- logging.error("Exception %s rendering ui objects %s: \n%s" % (
- e, ui_object, traceback.format_exc()
- ))
+ if settings.DEBUG:
+ import traceback
+ logging.error("Exception %s rendering ui objects %s: \n%s" % (
+ e, ui_object, traceback.format_exc()
+ ))
return result
url(r'^feeds/rss[/]?$', app.readers.feed, name="latest_questions_feed"),
- url(r'^(?P<path>.+)$', app.meta.page, name="static_page"),
+ #url(r'^.+$', app.meta.page, name="static_page"),
)
+
question = node.question
elif node.answer:
question = node.answer.question
+ else:
+ return content
# Now we've got the root question. Let's get the list of active users.
active_users = question.get_active_users()
from forum.actions import UserJoinsAction, EmailValidationAction
from forum.models.action import ActionRepute
+
from forum.settings import REP_GAIN_BY_EMAIL_VALIDATION
+from vars import ON_SIGNIN_SESSION_ATTR, PENDING_SUBMISSION_SESSION_ATTR
def signin_page(request):
referer = request.META.get('HTTP_REFERER', '/')
# If the referer is equal to the sign up page, e. g. if the previous login attempt was not successful we do not
# change the sign in URL. The user should go to the same page.
if not referer.replace(settings.APP_URL, '') == reverse('auth_signin'):
- request.session['on_signin_url'] = referer
+ request.session[ON_SIGNIN_SESSION_ATTR] = referer
- all_providers = [provider.context for provider in AUTH_PROVIDERS.values()]
+ all_providers = [provider.context for provider in AUTH_PROVIDERS.values() if provider.context]
sort = lambda c1, c2: c1.weight - c2.weight
can_show = lambda c: not request.user.is_authenticated() or c.show_to_logged_in_user
assoc = AuthKeyUserAssociation.objects.get(key=assoc_key)
user_ = assoc.user
return login_and_forward(request, user_)
- except:
+ except AuthKeyUserAssociation.DoesNotExist:
request.session['assoc_key'] = assoc_key
request.session['auth_provider'] = provider
return HttpResponseRedirect(reverse('auth_external_register'))
return render_to_response('auth/complete.html', {
'form1': form1,
'email_feeds_form': email_feeds_form,
- 'provider':mark_safe(provider_context.human_name),
+ 'provider':provider_context and mark_safe(provider_context.human_name) or _('unknown'),
'login_type':provider_context.id,
'gravatar_faq_url':reverse('faq') + '#gravatar',
}, context_instance=RequestContext(request))
request.user.message_set.create(message=message)
if not forward:
- forward = request.session.get('on_signin_url', reverse('index'))
+ forward = request.session.get(ON_SIGNIN_SESSION_ATTR, reverse('index'))
- pending_data = request.session.get('pending_submission_data', None)
+ pending_data = request.session.get(PENDING_SUBMISSION_SESSION_ATTR, None)
if pending_data and (user.email_isvalid or pending_data['type'] not in settings.REQUIRE_EMAIL_VALIDATION_TO):
submission_time = pending_data['time']
if submission_time < datetime.datetime.now() - datetime.timedelta(minutes=int(settings.HOLD_PENDING_POSTS_MINUTES)):
- del request.session['pending_submission_data']
+ 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" % (
html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('save')}), _("save it")),
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 import settings
from forum.utils.mail import send_template_email
from django.utils.safestring import mark_safe
from forum.templatetags.extra_filters import or_preview
import decorators
-import re
+import re, sys, logging, traceback
def favicon(request):
return HttpResponseRedirect(str(settings.APP_FAVICON))
'badge' : badge,
}, context_instance=RequestContext(request))
-def page(request, path):
+def page(request):
+ path = request.path[1:]
+
if path in settings.STATIC_PAGE_REGISTRY:
try:
page = Page.objects.get(id=settings.STATIC_PAGE_REGISTRY[path])
if (not page.published) and (not request.user.is_superuser):
- raise Http404
+ return HttpResponseNotFound(request)
except:
- raise Http404
+ return HttpResponseNotFound(request)
else:
- raise Http404
+ return HttpResponseNotFound(request)
template = page.extra.get('template', 'default')
sidebar = page.extra.get('sidebar', '')
}, context_instance=RequestContext(request))
+def error_handler(request):
+
+ stacktrace = "".join(["\t\t%s\n" % l for l in traceback.format_exc().split("\n")])
+
+ try:
+ log_msg = """
+ error executing request:
+ PATH: %(path)s
+ USER: %(user)s
+ METHOD: %(method)s
+ POST PARAMETERS:
+ %(post)s
+ GET PARAMETERS:
+ %(get)s
+ HTTP HEADERS:
+ %(headers)s
+ COOKIES:
+ %(cookies)s
+ EXCEPTION INFO:
+ %(stacktrace)s
+ """ % {
+ 'path': request.path,
+ 'user': request.user.is_authenticated() and ("%s (%s)" % (request.user.username, request.user.id)) or "<anonymous>",
+ 'method': request.method,
+ 'post': request.POST and "".join(["\t\t%s: %s\n" % (k, v) for k, v in request.POST.items()]) or "None",
+ 'get': request.GET and "".join(["\t\t%s: %s\n" % (k, v) for k, v in request.GET.items()]) or "None",
+ 'cookies': request.COOKIES and "".join(["\t\t%s: %s\n" % (k, v) for k, v in request.COOKIES.items()]) or "None",
+ 'headers': request.META and "".join(["\t\t%s: %s\n" % (k, v) for k, v in request.META.items()]) or "None",
+ 'stacktrace': stacktrace
+ }
+ except:
+ log_msg = "error executing request:\n%s" % stacktrace
+
+
+ logging.error(log_msg)
+ return HttpResponseIntServerError(request)
@decorators.render('questions.html')
def tag(request, tag):
- questions = Question.objects.filter(tags__name=unquote(tag))
- if not questions:
+ try:
+ tag = Tag.active.get(name=unquote(tag))
+ except Tag.DoesNotExist:
raise Http404
+
return question_list(request,
- questions,
+ Question.objects.filter(tags=tag),
mark_safe(_('questions tagged <span class="tag">%(tag)s</span>') % {'tag': tag}),
None,
mark_safe(_('Questions Tagged With %(tag)s') % {'tag': tag}),
})
def update_question_view_times(request, question):
- if not 'last_seen_in_question' in request.session:
- request.session['last_seen_in_question'] = {}
+ last_seen_in_question = request.session.get('last_seen_in_question', {})
- last_seen = request.session['last_seen_in_question'].get(question.id, None)
+ last_seen = last_seen_in_question.get(question.id, None)
- if (not last_seen) or last_seen < question.last_activity_at:
+ if (not last_seen) or (last_seen < question.last_activity_at):
QuestionViewAction(question, request.user, ip=request.META['REMOTE_ADDR']).save()
- request.session['last_seen_in_question'][question.id] = datetime.datetime.now()
-
- request.session['last_seen_in_question'][question.id] = datetime.datetime.now()
+ last_seen_in_question[question.id] = datetime.datetime.now()
+ request.session['last_seen_in_question'] = last_seen_in_question
def match_question_slug(id, slug):
slug_words = slug.split('-')
--- /dev/null
+ON_SIGNIN_SESSION_ATTR = 'on_signin_url'
+PENDING_SUBMISSION_SESSION_ATTR = 'pending_submission_data'
from forum.forms import get_next_url
from forum.utils import html
+from vars import PENDING_SUBMISSION_SESSION_ATTR
def upload(request):#ajax upload file to a question or answer
class FileTypeNotAllow(Exception):
return HttpResponseRedirect(question.get_absolute_url())
else:
- request.session['pending_submission_data'] = {
+ request.session[PENDING_SUBMISSION_SESSION_ATTR] = {
'POST': request.POST,
'data_name': _("question"),
'type': 'ask',
return HttpResponseRedirect(answer.get_absolute_url())
else:
- request.session['pending_submission_data'] = {
+ request.session[PENDING_SUBMISSION_SESSION_ATTR] = {
'POST': request.POST,
'data_name': _("answer"),
'type': 'answer',
def manage_pending_data(request, action, forward=None):
- pending_data = request.session.pop('pending_submission_data', None)
+ pending_data = request.session.pop(PENDING_SUBMISSION_SESSION_ATTR, None)
if not pending_data:
raise Http404
#'birthdate': 'http://axschema.org/birthDate',
}
+ sreg_attributes = {
+ "required": {
+ "email": "email",
+ "nickname": "username"
+ }
+ }
+
def get_user_url(self, request):
try:
return request.POST['openid_identifier']
except DiscoveryFailure:
raise InvalidAuthentication(_('Sorry, but your input is not a valid OpenId'))
- #sreg = getattr(settings, 'OPENID_SREG', False)
+ sreg = getattr(self, 'sreg_attributes', False)
+
+ if sreg:
+ s = SRegRequest()
+
+ for k, attr_dic in sreg.items():
+ if k == "policy_url":
+ s.policy_url = attr_dic
+ continue
- #if sreg:
- # s = SRegRequest()
- # for sarg in sreg:
- # if sarg.lower().lstrip() == "policy_url":
- # s.policy_url = sreg[sarg]
- # else:
- # for v in sreg[sarg].split(','):
- # s.requestField(field_name=v.lower().lstrip(), required=(sarg.lower().lstrip() == "required"))
- # auth_request.addExtension(s)
+ for attr_name in attr_dic.keys():
+ s.requestField(field_name=attr_name, required=(k == "required"))
- #auth_request.addExtension(SRegRequest(required=['email']))
+ auth_request.addExtension(s)
- if request.session.get('force_email_request', True):
+ ax_schema = getattr(self, 'dataype2ax_schema', False)
+
+ if ax_schema and request.session.get('force_email_request', True):
axr = AXFetchRequest()
- for data_type, schema in self.dataype2ax_schema.items():
+ for data_type, schema in ax_schema.items():
if isinstance(schema, tuple):
axr.add(AttrInfo(schema[0], 1, True, schema[1]))
else:
openid_response = consumer.complete(query_dict, url)
if openid_response.status == SUCCESS:
- if request.session.get('force_email_request', True):
- try:
- ax = AXFetchResponse.fromSuccessResponse(openid_response)
- axargs = ax.getExtensionArgs()
+ consumer_data = {}
+
+ sreg_attrs = getattr(self, 'sreg_attributes', False)
+
+ if sreg_attrs:
+ sreg_response = SRegResponse.fromSuccessResponse(openid_response)
- ax_schema2data_type = dict([(s, t) for t, s in self.dataype2ax_schema.items()])
+ all_attrs = {}
+ [all_attrs.update(d) for k,d in sreg_attrs.items() if k != "policy_url"]
- available_types = dict([
- (ax_schema2data_type[s], re.sub('^type\.', '', n))
- for n, s in axargs.items() if s in ax_schema2data_type
- ])
+ for attr_name, local_name in all_attrs.items():
+ if attr_name in sreg_response:
+ consumer_data[local_name] = sreg_response[attr_name]
- available_data = dict([
- (t, axargs["value.%s.1" % s]) for t, s in available_types.items()
- ])
+ ax_schema = getattr(self, 'dataype2ax_schema', False)
+
+ if ax_schema:
+ ax = AXFetchResponse.fromSuccessResponse(openid_response)
+
+ axargs = ax.getExtensionArgs()
+
+ ax_schema2data_type = dict([(s, t) for t, s in ax_schema.items()])
+
+ available_types = dict([
+ (ax_schema2data_type[s], re.sub('^type\.', '', n))
+ for n, s in axargs.items() if s in ax_schema2data_type
+ ])
+
+ for t, s in available_types.items():
+ if not t in consumer_data:
+ consumer_data[t] = axargs["value.%s.1" % s]
- request.session['auth_consumer_data'] = {
- 'email': available_data.get('email', None),
- }
-
- except Exception, e:
- pass
- #import sys, traceback
- #traceback.print_exc(file=sys.stdout)
+ request.session['auth_consumer_data'] = consumer_data
+
return request.GET['openid.identity']
elif openid_response.status == CANCEL:
# -*- coding: utf-8 -*-
-from xml.dom import minidom
-from datetime import datetime, timedelta
+from datetime import datetime
import time
import re
import os
import gc
from django.utils.translation import ugettext as _
-from django.template.defaultfilters import slugify
-from forum.models.utils import dbsafe_encode
from orm import orm
from django.utils.encoding import force_unicode
openidre = re.compile('^https?\:\/\/')
def userimport(path, options):
-#users = readTable(dump, "Users")
usernames = []
openids = set()
uidmapper = IdMapper()
- #merged_users = []
+ authenticated_user = options.get('authenticated_user', None)
owneruid = options.get('owneruid', None)
#check for empty values
if not owneruid:
if sxu.get('id') == '-1':
return
#print "\n".join(["%s : %s" % i for i in sxu.items()])
+
if int(sxu.get('id')) == int(owneruid):
- osqau = orm.User.objects.get(id=1)
- for assoc in orm.AuthKeyUserAssociation.objects.filter(user=osqau):
- openids.add(assoc.key)
- uidmapper[owneruid] = 1
- uidmapper[-1] = 1
- create = False
- else:
+ if authenticated_user:
+ osqau = orm.User.objects.get(id=authenticated_user.id)
+
+ for assoc in orm.AuthKeyUserAssociation.objects.filter(user=osqau):
+ openids.add(assoc.key)
+
+ uidmapper[owneruid] = osqau.id
+ uidmapper[-1] = osqau.id
+ create = False
+ else:
+ uidmapper[owneruid] = int(owneruid)
+ uidmapper[-1] = int(owneruid)
+
+
+ sxbadges = sxu.get('badgesummary', None)
+ badges = {'1':'0', '2':'0', '3':'0'}
+
+ if sxbadges:
+ badges.update(dict([b.split('=') for b in sxbadges.split()]))
+
+ if create:
username = unicode(sxu.get('displayname',
sxu.get('displaynamecleaned', sxu.get('realname', final_username_attempt(sxu)))))[:30]
if not totest in usernames:
username = totest
- break
-
- sxbadges = sxu.get('badgesummary', None)
- badges = {'1':'0', '2':'0', '3':'0'}
+ break
- if sxbadges:
- badges.update(dict([b.split('=') for b in sxbadges.split()]))
-
- if create:
osqau = orm.User(
id = sxu.get('id'),
username = username,
return uidmapper
def tagsimport(dump, uidmap):
-#tags = readTable(dump, "Tags")
tagmap = {}
post.state_string = "".join("(%s)" % s for s in re.findall('\w+', post.state_string) if s != name)
def postimport(dump, uidmap, tagmap):
-#history = {}
-#accepted = {}
all = []
- #for h in readTable(dump, "PostHistory"):
- # if not history.get(h.get('postid'), None):
- # history[h.get('postid')] = []
- #
- # history[h.get('postid')].append(h)
-
- #posts = readTable(dump, "Posts")
-
def callback(sxpost):
nodetype = (sxpost.get('posttypeid') == '1') and "nodetype" or "answer"
return all
def comment_import(dump, uidmap, posts):
-#comments = readTable(dump, "PostComments")
currid = IdIncrementer(max(posts))
mapping = {}
post.save()
def post_vote_import(dump, uidmap, posts):
-#votes = readTable(dump, "Posts2Votes")
close_reasons = {}
def close_callback(r):
def comment_vote_import(dump, uidmap, comments):
-#votes = readTable(dump, "Comments2Votes")
user2vote = []
comments2score = {}
def badges_import(dump, uidmap, post_list):
-#node_ctype = orm['contenttypes.contenttype'].objects.get(name='node')
sxbadges = {}
for badge in obadges.values():
badge.save()
+def save_setting(k, v):
+ try:
+ kv = orm.KeyValue.objects.get(key=k)
+ kv.value = v
+ except:
+ kv = orm.KeyValue(key = k, value = v)
+
+ kv.save()
+
+
def pages_import(dump, currid):
currid = IdIncrementer(currid)
registry = {}
- #sx_pages = readTable(dump, "FlatPages")
def callback(sxp):
currid.inc()
readTable(dump, "FlatPages", callback)
- kv = orm.KeyValue(key='STATIC_PAGE_REGISTRY', value=dbsafe_encode(registry))
- kv.save()
+ save_setting('STATIC_PAGE_REGISTRY', dbsafe_encode(registry))
sx2osqa_set_map = {
u'theme.html.name': 'APP_TITLE',
def static_import(dump):
-#sx_sets = readTable(dump, "ThemeTextResources")
sx_unknown = {}
def callback(set):
if unicode(set['name']) in sx2osqa_set_map:
- try:
- kv = orm.KeyValue.objects.get(key=sx2osqa_set_map[set['name']])
- kv.value = dbsafe_encode(html_decode(set['value']))
- except:
- kv = orm.KeyValue(
- key = sx2osqa_set_map[set['name']],
- value = dbsafe_encode(html_decode(set['value']))
- )
-
- kv.save()
+ save_setting(sx2osqa_set_map[set['name']], dbsafe_encode(html_decode(set['value'])))
else:
sx_unknown[set['name']] = html_decode(set['value'])
readTable(dump, "ThemeTextResources", callback)
- unknown = orm.KeyValue(key='SXIMPORT_UNKNOWN_SETS', value=dbsafe_encode(sx_unknown))
- unknown.save()
+ save_setting('SXIMPORT_UNKNOWN_SETS', dbsafe_encode(sx_unknown))
def disable_triggers():
from south.db import db
from django.shortcuts import render_to_response\r
from django.template import RequestContext\r
-from forum.views.admin import super_user_required\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
-@super_user_required\r
def sximporter(request):\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
- importer.sximport(extract_to, request.POST)\r
-\r
- return render_to_response('modules/sximporter/page.html', {\r
- 'names': list\r
- }, context_instance=RequestContext(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
# encoding:utf-8
-# Django settings for lanai project.
import os.path
import sys
ADMIN_MEDIA_PREFIX = '/admin_media/'
SECRET_KEY = '$oo^&_m&qwbib=(_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
-# List of callables that know how to import templates from various sources.
-TEMPLATE_LOADERS = (
+
+TEMPLATE_LOADERS = [
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
- 'forum.modules.module_templates_loader',
+ 'forum.modules.template_loader.module_templates_loader',
'forum.skins.load_template_source',
-# 'django.template.loaders.eggs.load_template_source',
-)
+]
MIDDLEWARE_CLASSES = [
- #'django.middleware.gzip.GZipMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
- #'django.middleware.locale.LocaleMiddleware',
- #'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
- #'django.middleware.cache.FetchFromCacheMiddleware',
'forum.middleware.extended_user.ExtendedUser',
- #'django.middleware.sqlprint.SqlPrintingMiddleware',
'forum.middleware.anon_user.ConnectToSessionMessagesMiddleware',
'forum.middleware.request_utils.RequestUtils',
'forum.middleware.cancel.CancelActionMiddleware',
'forum.middleware.admin_messages.AdminMessagesMiddleware',
- #'recaptcha_django.middleware.ReCaptchaMiddleware',
'django.middleware.transaction.TransactionMiddleware',
]
-TEMPLATE_CONTEXT_PROCESSORS = (
+TEMPLATE_CONTEXT_PROCESSORS = [
'django.core.context_processors.request',
'forum.context.application_settings',
- #'django.core.context_processors.i18n',
- 'forum.user_messages.context_processors.user_messages',#must be before auth
- 'django.core.context_processors.auth', #this is required for admin
-)
+ 'forum.user_messages.context_processors.user_messages',
+ 'django.core.context_processors.auth',
+]
ROOT_URLCONF = 'urls'
+APPEND_SLASH = True
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__),'forum','skins').replace('\\','/'),
)
-#UPLOAD SETTINGS
+
FILE_UPLOAD_TEMP_DIR = os.path.join(os.path.dirname(__file__), 'tmp').replace('\\','/')
FILE_UPLOAD_HANDLERS = ("django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler",)
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
-# for user upload
+
ALLOW_FILE_TYPES = ('.jpg', '.jpeg', '.gif', '.bmp', '.png', '.tiff')
-# unit byte
ALLOW_MAX_FILE_SIZE = 1024 * 1024
# User settings
if FORCE_SCRIPT_NAME.endswith('/'):
FORCE_SCRIPT_NAME = FORCE_SCRIPT_NAME[:-1]
+from forum import modules
+
+modules.init_modules_engine(SITE_SRC_ROOT, DISABLED_MODULES)
+
+[MIDDLEWARE_CLASSES.extend(
+ ["%s.%s" % (m.__name__, mc) for mc in getattr(m, 'MIDDLEWARE_CLASSES', [])]
+ ) for m in modules.MODULE_LIST]
+
+[TEMPLATE_LOADERS.extend(
+ ["%s.%s" % (m.__name__, tl) for tl in getattr(m, 'TEMPLATE_LOADERS', [])]
+ ) for m in modules.MODULE_LIST]
+
+
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
url(r'^rosetta/', include('rosetta.urls')),
)
+handler404 = 'forum.views.meta.page'
+handler500 = 'forum.views.meta.error_handler'
+
+