class ThreadedCommentForm(CommentForm):
    title = forms.CharField(
        label=_("Title"), required=False, max_length=getattr(settings, "COMMENTS_TITLE_MAX_LENGTH", 255)
    )
    parent = forms.IntegerField(required=False, widget=forms.HiddenInput)

    def __init__(self, target_object, parent=None, data=None, initial=None):
        if django.VERSION >= (1, 7):
            # Using collections.OrderedDict from Python 2.7+
            # This class does not have an insert method, have to replace it.
            from collections import OrderedDict

            keys = list(self.base_fields.keys())
            keys.remove("title")
            keys.insert(keys.index("comment"), "title")

            self.base_fields = OrderedDict((k, self.base_fields[k]) for k in keys)
        else:
            self.base_fields.insert(self.base_fields.keyOrder.index("comment"), "title", self.base_fields.pop("title"))

        # Remove fields
        self.base_fields["email"].required = False
        self.base_fields["email"].widget = forms.HiddenInput()
        self.base_fields["title"].widget = forms.HiddenInput()
        self.base_fields["name"].widget = forms.HiddenInput()
        self.base_fields["url"].widget = forms.HiddenInput()

        self.parent = parent
        if initial is None:
            initial = {}
        initial.update({"parent": self.parent})
        super(ThreadedCommentForm, self).__init__(target_object, data=data, initial=initial)

    def check_for_duplicate_comment(self, new):
        """
        Check that a submitted comment isn't a duplicate. This might be caused
        by someone posting a comment twice. If it is a dup, silently return the *previous* comment.
        """
        possible_duplicates = (
            self.get_comment_model()
            ._default_manager.using(self.target_object._state.db)
            .filter(content_type=new.content_type, object_pk=new.object_pk)
        )
        for old in possible_duplicates:
            if old.submit_date.date() == new.submit_date.date() and old.comment == new.comment:
                return old

        return new

    def get_comment_model(self):
        return ThreadedComment

    def get_comment_create_data(self):
        d = super(ThreadedCommentForm, self).get_comment_create_data()
        d["parent_id"] = self.cleaned_data["parent"]
        d.pop("user_name")
        d.pop("user_email")
        d.pop("user_url")
        d["is_public"] = False
        return d
Example #2
1
class ThreadedCommentForm(CommentForm):
    title = forms.CharField(
        label=_("Title"), required=False, max_length=getattr(settings, "COMMENTS_TITLE_MAX_LENGTH", 255)
    )
    parent = forms.IntegerField(required=False, widget=forms.HiddenInput)

    def __init__(self, target_object, parent=None, data=None, initial=None):
        if django.VERSION >= (1, 7):
            # Using collections.OrderedDict from Python 2.7+
            # This class does not have an insert method, have to replace it.
            from collections import OrderedDict

            keys = list(self.base_fields.keys())
            keys.remove("title")
            keys.insert(keys.index("comment"), "title")

            self.base_fields = OrderedDict((k, self.base_fields[k]) for k in keys)
        else:
            self.base_fields.insert(self.base_fields.keyOrder.index("comment"), "title", self.base_fields.pop("title"))
        self.parent = parent
        if initial is None:
            initial = {}
        initial.update({"parent": self.parent})
        super(ThreadedCommentForm, self).__init__(target_object, data=data, initial=initial)

    def get_comment_model(self):
        return ThreadedComment

    def get_comment_create_data(self):
        d = super(ThreadedCommentForm, self).get_comment_create_data()
        d["parent_id"] = self.cleaned_data["parent"]
        d["title"] = self.cleaned_data["title"]
        return d
Example #3
1
class NexusSite(object):
    def __init__(self, name=None, app_name="nexus"):
        self._registry = {}
        self._categories = OrderedDict()
        if name is None:
            self.name = "nexus"
        else:
            self.name = name
        self.app_name = app_name

    def register_category(self, category, label, index=None):
        if index:
            self._categories.insert(index, category, label)
        else:
            self._categories[category] = label

    def register(self, module, namespace=None, category=None):
        module = module(self, category)
        if not namespace:
            namespace = module.get_namespace()
        if namespace:
            module.app_name = module.name = namespace
        self._registry[namespace] = (module, category)
        return module

    def unregister(self, namespace):
        if namespace in self._registry:
            del self._registry[namespace]

    def get_urls(self):
        base_urls = (
            [
                url(r"^media/(?P<module>[^/]+)/(?P<path>.+)$", self.media, name="media"),
                url(r"^$", self.as_view(self.dashboard), name="index"),
            ],
            self.app_name,
            self.name,
        )

        urlpatterns = [url(r"^", subinclude(base_urls))]
        for namespace, module in self.get_modules():
            urlpatterns += [url(r"^%s/" % namespace, subinclude(module.urls))]

        return urlpatterns

    @property
    def urls(self):
        return self.get_urls()

    def has_permission(self, request, extra_permission=None):
        """
        Returns True if the given HttpRequest has permission to view
        *at least one* page in the admin site.
        """
        permission = request.user.is_active and request.user.is_staff
        if extra_permission:
            permission = permission and request.user.has_perm(extra_permission)
        return permission

    def as_view(self, view, cacheable=False, extra_permission=None):
        """
        Wraps a view in authentication/caching logic

        extra_permission can be used to require an extra permission for this view, such as a module permission
        """

        @wraps(view)
        def inner(request, *args, **kwargs):
            if not self.has_permission(request, extra_permission):
                # Redirect to login
                return self.login(request)
            return view(request, *args, **kwargs)

        # Mark it as never_cache
        if not cacheable:
            inner = never_cache(inner)

        # We add csrf_protect here so this function can be used as a utility
        # function for any view, without having to repeat 'csrf_protect'.
        if not getattr(view, "csrf_exempt", False):
            inner = csrf_protect(inner)

        inner = ensure_csrf_cookie(inner)

        return update_wrapper(inner, view)

    def get_context(self, request):
        context = context_processors.csrf(request)
        context.update(
            {"request": request, "nexus_site": self, "nexus_media_prefix": nexus_settings.MEDIA_PREFIX.rstrip("/")}
        )
        return context

    def get_modules(self):
        for k, v in six.iteritems(self._registry):
            yield k, v[0]

    def get_module(self, module):
        return self._registry[module][0]

    def get_categories(self):
        for k, v in six.iteritems(self._categories):
            yield k, v

    def get_category_label(self, category):
        return self._categories.get(category, category.title().replace("_", " "))

    def render_to_string(self, template, context, request, current_app=None):
        if not current_app:
            current_app = self.name
        else:
            current_app = "%s:%s" % (self.name, current_app)

        if request:
            request.current_app = current_app

        context.update(self.get_context(request))

        return render_to_string(template, context=context, request=request)

    def render_to_response(self, template, context, request, current_app=None):
        "Shortcut for rendering to response and default context instances"
        if not current_app:
            current_app = self.name
        else:
            current_app = "%s:%s" % (self.name, current_app)

        if request:
            request.current_app = current_app

        context.update(self.get_context(request))

        return render(request, template, context=context)

    # Our views

    def media(self, request, module, path):
        """
        Serve static files below a given point in the directory structure.
        """
        if module == "nexus":
            document_root = os.path.join(NEXUS_ROOT, "media")
        else:
            document_root = self.get_module(module).media_root

        path = posixpath.normpath(urllib.parse.unquote(path))
        path = path.lstrip("/")
        newpath = ""
        for part in path.split("/"):
            if not part:
                # Strip empty path components.
                continue
            drive, part = os.path.splitdrive(part)
            head, part = os.path.split(part)
            if part in (os.curdir, os.pardir):
                # Strip '.' and '..' in path.
                continue
            newpath = os.path.join(newpath, part).replace("\\", "/")
        if newpath and path != newpath:
            return HttpResponseRedirect(newpath)
        fullpath = os.path.join(document_root, newpath)
        if os.path.isdir(fullpath):
            raise Http404("Directory indexes are not allowed here.")
        if not os.path.exists(fullpath):
            raise Http404('"%s" does not exist' % fullpath)
        # Respect the If-Modified-Since header.
        statobj = os.stat(fullpath)
        mimetype = mimetypes.guess_type(fullpath)[0] or "application/octet-stream"
        if not was_modified_since(
            request.META.get("HTTP_IF_MODIFIED_SINCE"), statobj[stat.ST_MTIME], statobj[stat.ST_SIZE]
        ):
            return HttpResponseNotModified(content_type=mimetype)
        contents = open(fullpath, "rb").read()
        response = HttpResponse(contents, content_type=mimetype)
        response["Last-Modified"] = http_date(statobj[stat.ST_MTIME])
        response["Content-Length"] = len(contents)
        return response

    @never_cache
    def login(self, request, form_class=None):
        "Login form"
        if request.user.is_authenticated():
            return HttpResponseRedirect(reverse("nexus:index", current_app=self.name))

        return HttpResponseRedirect(
            "{login}?{get}".format(
                login=reverse("admin:login"), get=urllib.parse.urlencode({REDIRECT_FIELD_NAME: request.path})
            )
        )

    def dashboard(self, request):
        "Basic dashboard panel"
        module_set = []
        for namespace, module in self.get_modules():
            home_url = module.get_home_url(request)

            if hasattr(module, "render_on_dashboard"):
                # Show by default, unless a permission is required
                if not module.permission or request.user.has_perm(module.permission):
                    module_set.append((module.get_dashboard_title(), module.render_on_dashboard(request), home_url))

        return self.render_to_response("nexus/dashboard.html", {"module_set": module_set}, request)