← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands-website/cleanup_threadedcomments into lp:widelands-website

 

kaputtnik has proposed merging lp:~widelands-dev/widelands-website/cleanup_threadedcomments into lp:widelands-website.

Commit message:
Removed model FreeThreadedComments and its dependencies
Remove IP-Adress field from Threadedcomments
Scroll directly to the comments when clicking on 'x comments' in the mainpage


Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1780536 in Widelands Website: "Add a GDPR (german: DSGVO) to the website"
  https://bugs.launchpad.net/widelands-website/+bug/1780536

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands-website/cleanup_threadedcomments/+merge/356200

This is a big cleanup for threadedcomments, with regard to bug 1762164

Since we do not allow commenting for not logged in users, i have removed the related model and all it's dependencies. The model does not contain any data, see https://wl.widelands.org/admin/threadedcomments/freethreadedcomment/

Removed the IPAddressField from the other model.

Removed django_comments, because it is not needed.

Clicking on 'x Comments' in the mainpage will directly scroll to the comments section in the related page.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands-website/cleanup_threadedcomments into lp:widelands-website.
=== modified file 'pip_requirements.txt'
--- pip_requirements.txt	2018-04-14 15:03:31 +0000
+++ pip_requirements.txt	2018-10-05 16:29:25 +0000
@@ -2,7 +2,6 @@
 
 BeautifulSoup==3.2.0
 Django==1.11.12
-django-contrib-comments==1.8.0
 django-haystack==2.8.1
 # django-messages is very old on pypi
 # Do not install newer versions because our notifications app is affected

=== modified file 'templates/news/inlines/post_detail.html'
--- templates/news/inlines/post_detail.html	2017-05-20 20:17:28 +0000
+++ templates/news/inlines/post_detail.html	2018-10-05 16:29:25 +0000
@@ -26,6 +26,6 @@
 	
 	<hr />
 	{% get_comment_count for object as ccount %}
-	<span class="small posLeft"><a href="{{ object.get_absolute_url }}">{{ ccount }} comment{{ ccount|pluralize }}</a></span>
+	<span class="small posLeft"><a href="{{ object.get_absolute_url }}#comment_anchor">{{ ccount }} comment{{ ccount|pluralize }}</a></span>
 	<span class="small posRight">Posted by {{object.author|user_link}} on {{ object.publish|custom_date:user }}</span>
 </div>

=== modified file 'templates/news/post_detail.html'
--- templates/news/post_detail.html	2016-11-20 11:55:39 +0000
+++ templates/news/post_detail.html	2018-10-05 16:29:25 +0000
@@ -30,7 +30,7 @@
 	{% include "news/inlines/post_detail.html" %}
 
 	<div class="blogEntry">
-		<h3>Comments on this Post:</h3>
+		<h3 id="comment_anchor">Comments on this Post:</h3>
 		{% include "threadedcomments/inlines/comments.html" %}
 	</div>
 {% endblock %}

=== modified file 'threadedcomments/admin.py'
--- threadedcomments/admin.py	2016-12-13 18:28:51 +0000
+++ threadedcomments/admin.py	2018-10-05 16:29:25 +0000
@@ -1,6 +1,6 @@
 from django.contrib import admin
 from django.utils.translation import ugettext_lazy as _
-from threadedcomments.models import ThreadedComment, FreeThreadedComment
+from threadedcomments.models import ThreadedComment
 
 
 class ThreadedCommentAdmin(admin.ModelAdmin):
@@ -9,7 +9,7 @@
         (_('Parent'), {'fields': ('parent',)}),
         (_('Content'), {'fields': ('user', 'comment')}),
         (_('Meta'), {'fields': ('is_public', 'date_submitted',
-                                'date_modified', 'date_approved', 'is_approved', 'ip_address')}),
+                                'date_modified', 'date_approved', 'is_approved')}),
     )
     list_display = ('user', 'date_submitted', 'content_type',
                     'get_content_object', 'parent', '__unicode__')
@@ -18,20 +18,4 @@
     search_fields = ('comment', 'user__username')
 
 
-class FreeThreadedCommentAdmin(admin.ModelAdmin):
-    fieldsets = (
-        (None, {'fields': ('content_type', 'object_id')}),
-        (_('Parent'), {'fields': ('parent',)}),
-        (_('Content'), {'fields': ('name', 'website', 'email', 'comment')}),
-        (_('Meta'), {'fields': ('date_submitted', 'date_modified',
-                                'date_approved', 'is_public', 'ip_address', 'is_approved')}),
-    )
-    list_display = ('name', 'date_submitted', 'content_type',
-                    'get_content_object', 'parent', '__unicode__')
-    list_filter = ('date_submitted',)
-    date_hierarchy = 'date_submitted'
-    search_fields = ('comment', 'name', 'email', 'website')
-
-
 admin.site.register(ThreadedComment, ThreadedCommentAdmin)
-admin.site.register(FreeThreadedComment, FreeThreadedCommentAdmin)

=== modified file 'threadedcomments/forms.py'
--- threadedcomments/forms.py	2016-12-13 18:28:51 +0000
+++ threadedcomments/forms.py	2018-10-05 16:29:25 +0000
@@ -1,6 +1,6 @@
 from django import forms
 from threadedcomments.models import DEFAULT_MAX_COMMENT_LENGTH
-from threadedcomments.models import FreeThreadedComment, ThreadedComment
+from threadedcomments.models import ThreadedComment
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -21,23 +21,3 @@
     class Meta:
         model = ThreadedComment
         fields = ('comment', 'markup')
-
-
-class FreeThreadedCommentForm(forms.ModelForm):
-    """
-    Form which can be used to validate data for a new FreeThreadedComment.
-    It consists of just a few fields: ``comment``, ``name``, ``website``,
-    ``email``, and ``markup``.
-
-    The fields ``comment``, and ``name`` are the only ones which are required.
-    """
-
-    comment = forms.CharField(
-        label=_('comment'),
-        max_length=DEFAULT_MAX_COMMENT_LENGTH,
-        widget=forms.Textarea
-    )
-
-    class Meta:
-        model = FreeThreadedComment
-        fields = ('comment', 'name', 'website', 'email', 'markup')

=== removed directory 'threadedcomments/management'
=== removed file 'threadedcomments/management/__init__.py'
=== removed directory 'threadedcomments/management/commands'
=== removed file 'threadedcomments/management/commands/__init__.py'
=== removed file 'threadedcomments/management/commands/migratecomments.py'
--- threadedcomments/management/commands/migratecomments.py	2016-12-13 18:28:51 +0000
+++ threadedcomments/management/commands/migratecomments.py	1970-01-01 00:00:00 +0000
@@ -1,56 +0,0 @@
-from django.core.management.base import BaseCommand
-from django.contrib.comments.models import Comment, FreeComment
-from threadedcomments.models import ThreadedComment, FreeThreadedComment
-
-
-class Command(BaseCommand):
-    help = "Migrates Django's built-in django.contrib.comments data to threadedcomments data"
-
-    output_transaction = True
-
-    def handle(self, *args, **options):
-        """Converts all legacy ``Comment`` and ``FreeComment`` objects into
-        ``ThreadedComment`` and ``FreeThreadedComment`` objects,
-        respectively."""
-        self.handle_free_comments()
-        self.handle_comments()
-
-    def handle_free_comments(self):
-        """Converts all legacy ``FreeComment`` objects into
-        ``FreeThreadedComment`` objects."""
-        comments = FreeComment.objects.all()
-        for c in comments:
-            new = FreeThreadedComment(
-                content_type=c.content_type,
-                object_id=c.object_id,
-                comment=c.comment,
-                name=c.person_name,
-                website='',
-                email='',
-                date_submitted=c.submit_date,
-                date_modified=c.submit_date,
-                date_approved=c.submit_date,
-                is_public=c.is_public,
-                ip_address=c.ip_address,
-                is_approved=c.approved
-            )
-            new.save()
-
-    def handle_comments(self):
-        """Converts all legacy ``Comment`` objects into ``ThreadedComment``
-        objects."""
-        comments = Comment.objects.all()
-        for c in comments:
-            new = ThreadedComment(
-                content_type=c.content_type,
-                object_id=c.object_id,
-                comment=c.comment,
-                user=c.user,
-                date_submitted=c.submit_date,
-                date_modified=c.submit_date,
-                date_approved=c.submit_date,
-                is_public=c.is_public,
-                ip_address=c.ip_address,
-                is_approved=not c.is_removed
-            )
-            new.save()

=== added file 'threadedcomments/migrations/0002_auto_20181003_1238.py'
--- threadedcomments/migrations/0002_auto_20181003_1238.py	1970-01-01 00:00:00 +0000
+++ threadedcomments/migrations/0002_auto_20181003_1238.py	2018-10-05 16:29:25 +0000
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.12 on 2018-10-03 12:38
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('threadedcomments', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='freethreadedcomment',
+            name='content_type',
+        ),
+        migrations.RemoveField(
+            model_name='freethreadedcomment',
+            name='parent',
+        ),
+        migrations.DeleteModel(
+            name='TestModel',
+        ),
+        migrations.RemoveField(
+            model_name='threadedcomment',
+            name='ip_address',
+        ),
+        migrations.DeleteModel(
+            name='FreeThreadedComment',
+        ),
+    ]

=== modified file 'threadedcomments/models.py'
--- threadedcomments/models.py	2016-12-13 18:28:51 +0000
+++ threadedcomments/models.py	2018-10-05 16:29:25 +0000
@@ -1,6 +1,5 @@
 from django.db import models
 from django.contrib.contenttypes.models import ContentType
-#from django.contrib.contenttypes import generic
 from django.contrib.contenttypes.fields import GenericForeignKey
 from django.contrib.auth.models import User
 from datetime import datetime
@@ -16,13 +15,11 @@
 MARKDOWN = 1
 TEXTILE = 2
 REST = 3
-#HTML = 4
 PLAINTEXT = 5
 MARKUP_CHOICES = (
     (MARKDOWN, _('markdown')),
     (TEXTILE, _('textile')),
     (REST, _('restructuredtext')),
-    #    (HTML, _("html")),
     (PLAINTEXT, _('plaintext')),
 )
 
@@ -178,10 +175,6 @@
     is_public = models.BooleanField(_('is public'), default=True)
     is_approved = models.BooleanField(_('is approved'), default=False)
 
-    # Extra Field
-    ip_address = models.GenericIPAddressField(
-        _('IP address'), null=True, blank=True)
-
     objects = ThreadedCommentManager()
     public = PublicThreadedCommentManager()
 
@@ -203,158 +196,8 @@
         and due to ``list_display`` limitations."""
         return self.content_object
 
-    def get_base_data(self, show_dates=True):
-        """Outputs a Python dictionary representing the most useful bits of
-        information about this particular object instance.
-
-        This is mostly useful for testing purposes, as the output from
-        the serializer changes from run to run.  However, this may end
-        up being useful for JSON and/or XML data exchange going forward
-        and as the serializer system is changed.
-
-        """
-        markup = 'plaintext'
-        for markup_choice in MARKUP_CHOICES:
-            if self.markup == markup_choice[0]:
-                markup = markup_choice[1]
-                break
-        to_return = {
-            'content_object': self.content_object,
-            'parent': self.parent,
-            'user': self.user,
-            'comment': self.comment,
-            'is_public': self.is_public,
-            'is_approved': self.is_approved,
-            'ip_address': self.ip_address,
-            'markup': force_unicode(markup),
-        }
-        if show_dates:
-            to_return['date_submitted'] = self.date_submitted
-            to_return['date_modified'] = self.date_modified
-            to_return['date_approved'] = self.date_approved
-        return to_return
-
     class Meta:
         ordering = ('-date_submitted',)
         verbose_name = _('Threaded Comment')
         verbose_name_plural = _('Threaded Comments')
         get_latest_by = 'date_submitted'
-
-
-class FreeThreadedComment(models.Model):
-    """
-    A threaded comment which need not be associated with an instance of 
-    ``django.contrib.auth.models.User``.  Instead, it requires minimally a name,
-    and maximally a name, website, and e-mail address.  It is given its hierarchy
-    by a nullable relationship back on itself named ``parent``.
-
-    This ``FreeThreadedComment`` supports several kinds of markup languages,
-    including Textile, Markdown, and ReST.
-
-    It also includes two Managers: ``objects``, which is the same as the normal
-    ``objects`` Manager with a few added utility functions (see above), and
-    ``public``, which has those same utility functions but limits the QuerySet to
-    only those values which are designated as public (``is_public=True``).
-    """
-    # Generic Foreign Key Fields
-    content_type = models.ForeignKey(ContentType)
-    object_id = models.PositiveIntegerField(_('object ID'))
-    content_object = GenericForeignKey()
-
-    # Hierarchy Field
-    parent = models.ForeignKey(
-        'self', null=True, blank=True, default=None, related_name='children')
-
-    # User-Replacement Fields
-    name = models.CharField(_('name'), max_length=128)
-    website = models.URLField(_('site'), blank=True)
-    email = models.EmailField(_('e-mail address'), blank=True)
-
-    # Date Fields
-    date_submitted = models.DateTimeField(
-        _('date/time submitted'), default=datetime.now)
-    date_modified = models.DateTimeField(
-        _('date/time modified'), default=datetime.now)
-    date_approved = models.DateTimeField(
-        _('date/time approved'), default=None, null=True, blank=True)
-
-    # Meat n' Potatoes
-    comment = models.TextField(_('comment'))
-    markup = models.IntegerField(
-        choices=MARKUP_CHOICES, default=DEFAULT_MARKUP, null=True, blank=True)
-
-    # Status Fields
-    is_public = models.BooleanField(_('is public'), default=True)
-    is_approved = models.BooleanField(_('is approved'), default=False)
-
-    # Extra Field
-    ip_address = models.GenericIPAddressField(
-        _('IP address'), null=True, blank=True)
-
-    objects = ThreadedCommentManager()
-    public = PublicThreadedCommentManager()
-
-    def __unicode__(self):
-        if len(self.comment) > 50:
-            return self.comment[:50] + '...'
-        return self.comment[:50]
-
-    def save(self, **kwargs):
-        if not self.markup:
-            self.markup = DEFAULT_MARKUP
-        self.date_modified = datetime.now()
-        if not self.date_approved and self.is_approved:
-            self.date_approved = datetime.now()
-        super(FreeThreadedComment, self).save()
-
-    def get_content_object(self, **kwargs):
-        """Wrapper around the GenericForeignKey due to compatibility reasons
-        and due to ``list_display`` limitations."""
-        return self.content_object
-
-    def get_base_data(self, show_dates=True):
-        """Outputs a Python dictionary representing the most useful bits of
-        information about this particular object instance.
-
-        This is mostly useful for testing purposes, as the output from
-        the serializer changes from run to run.  However, this may end
-        up being useful for JSON and/or XML data exchange going forward
-        and as the serializer system is changed.
-
-        """
-        markup = 'plaintext'
-        for markup_choice in MARKUP_CHOICES:
-            if self.markup == markup_choice[0]:
-                markup = markup_choice[1]
-                break
-        to_return = {
-            'content_object': self.content_object,
-            'parent': self.parent,
-            'name': self.name,
-            'website': self.website,
-            'email': self.email,
-            'comment': self.comment,
-            'is_public': self.is_public,
-            'is_approved': self.is_approved,
-            'ip_address': self.ip_address,
-            'markup': force_unicode(markup),
-        }
-        if show_dates:
-            to_return['date_submitted'] = self.date_submitted
-            to_return['date_modified'] = self.date_modified
-            to_return['date_approved'] = self.date_approved
-        return to_return
-
-    class Meta:
-        ordering = ('-date_submitted',)
-        verbose_name = _('Free Threaded Comment')
-        verbose_name_plural = _('Free Threaded Comments')
-        get_latest_by = 'date_submitted'
-
-
-class TestModel(models.Model):
-    """This model is simply used by this application's test suite as a model to
-    which to attach comments."""
-    name = models.CharField(max_length=5)
-    is_public = models.BooleanField(default=True)
-    date = models.DateTimeField(default=datetime.now)

=== modified file 'threadedcomments/moderation.py'
--- threadedcomments/moderation.py	2016-12-13 18:28:51 +0000
+++ threadedcomments/moderation.py	2018-10-05 16:29:25 +0000
@@ -1,5 +1,5 @@
 from django.db.models import signals
-from threadedcomments.models import ThreadedComment, FreeThreadedComment, MARKUP_CHOICES
+from threadedcomments.models import ThreadedComment, MARKUP_CHOICES
 from threadedcomments.models import DEFAULT_MAX_COMMENT_LENGTH, DEFAULT_MAX_COMMENT_DEPTH
 from comment_utils import moderation
 
@@ -37,9 +37,8 @@
 class Moderator(moderation.Moderator):
 
     def connect(self):
-        for model in (ThreadedComment, FreeThreadedComment):
-            signals.pre_save.connect(self.pre_save_moderation, sender=model)
-            signals.post_save.connect(self.post_save_moderation, sender=model)
+        signals.pre_save.connect(self.pre_save_moderation, sender=ThreadedComment)
+        signals.post_save.connect(self.post_save_moderation, sender=ThreadedComment)
 
     # THE FOLLOWING ARE HACKS UNTIL django-comment-utils GETS UPDATED SIGNALS
     # ####

=== modified file 'threadedcomments/templatetags/threadedcommentstags.py'
--- threadedcomments/templatetags/threadedcommentstags.py	2018-04-08 14:40:17 +0000
+++ threadedcomments/templatetags/threadedcommentstags.py	2018-10-05 16:29:25 +0000
@@ -4,8 +4,8 @@
 from django.urls import reverse
 from django.utils.encoding import force_unicode
 from django.utils.safestring import mark_safe
-from threadedcomments.models import ThreadedComment, FreeThreadedComment
-from threadedcomments.forms import ThreadedCommentForm, FreeThreadedCommentForm
+from threadedcomments.models import ThreadedComment
+from threadedcomments.forms import ThreadedCommentForm
 from mainpage.templatetags.wl_markdown import do_wl_markdown
 
 # Regular expressions for getting rid of newlines and witespace
@@ -78,64 +78,8 @@
     return ''
 
 
-def get_free_comment_url(content_object, parent=None):
-    """Given an object and an optional parent, this tag gets the URL to POST to
-    for the creation of new ``FreeThreadedComment`` objects."""
-    kwargs = get_contenttype_kwargs(content_object)
-    if parent:
-        if not isinstance(parent, FreeThreadedComment):
-            raise template.TemplateSyntaxError, 'get_free_comment_url requires its parent object to be of type FreeThreadedComment'
-        kwargs.update({'parent_id': getattr(
-            parent, 'pk', getattr(parent, 'id'))})
-        return reverse('tc_free_comment_parent', kwargs=kwargs)
-    else:
-        return reverse('tc_free_comment', kwargs=kwargs)
-
-
-def get_free_comment_url_ajax(content_object, parent=None, ajax_type='json'):
-    """Given an object and an optional parent, this tag gets the URL to POST to
-    for the creation of new ``FreeThreadedComment`` objects.
-
-    It returns the latest created object in the AJAX form of the user's
-    choosing (json or xml).
-
-    """
-    kwargs = get_contenttype_kwargs(content_object)
-    kwargs.update({'ajax': ajax_type})
-    if parent:
-        if not isinstance(parent, FreeThreadedComment):
-            raise template.TemplateSyntaxError, 'get_free_comment_url_ajax requires its parent object to be of type FreeThreadedComment'
-        kwargs.update({'parent_id': getattr(
-            parent, 'pk', getattr(parent, 'id'))})
-        return reverse('tc_free_comment_parent_ajax', kwargs=kwargs)
-    else:
-        return reverse('tc_free_comment_ajax', kwargs=kwargs)
-
-
-def get_free_comment_url_json(content_object, parent=None):
-    """
-    Wraps ``get_free_comment_url_ajax`` with ``ajax_type='json'``
-    """
-    try:
-        return get_free_comment_url_ajax(content_object, parent, ajax_type='json')
-    except template.TemplateSyntaxError:
-        raise template.TemplateSyntaxError, 'get_free_comment_url_json requires its parent object to be of type FreeThreadedComment'
-    return ''
-
-
-def get_free_comment_url_xml(content_object, parent=None):
-    """
-    Wraps ``get_free_comment_url_ajax`` with ``ajax_type='xml'``
-    """
-    try:
-        return get_free_comment_url_ajax(content_object, parent, ajax_type='xml')
-    except template.TemplateSyntaxError:
-        raise template.TemplateSyntaxError, 'get_free_comment_url_xml requires its parent object to be of type FreeThreadedComment'
-    return ''
-
-
 def auto_transform_markup(comment):
-    """Given a comment (``ThreadedComment`` or ``FreeThreadedComment``), this
+    """Given a comment, this
     tag simply returns the comment after wl_markdown runs over it.
 
     """
@@ -190,24 +134,6 @@
         raise template.TemplateSyntaxError(error_string)
 
 
-def do_get_free_threaded_comment_tree(parser, token):
-    """Gets a tree (list of objects ordered by traversing tree in preorder, and
-    with an additional ``depth`` integer attribute annotated onto each
-    ``FreeThreadedComment.``"""
-    error_string = '%r tag must be of format {%% get_free_threaded_comment_tree for OBJECT [TREE_ROOT] as CONTEXT_VARIABLE %%}' % token.contents.split()[
-        0]
-    try:
-        split = token.split_contents()
-    except ValueError:
-        raise template.TemplateSyntaxError(error_string)
-    if len(split) == 5:
-        return FreeCommentTreeNode(split[2], split[4], split[3])
-    elif len(split) == 6:
-        return FreeCommentTreeNode(split[2], split[5], split[3])
-    else:
-        raise template.TemplateSyntaxError(error_string)
-
-
 class CommentTreeNode(template.Node):
 
     def __init__(self, content_object, context_name, tree_root):
@@ -233,31 +159,6 @@
         return ''
 
 
-class FreeCommentTreeNode(template.Node):
-
-    def __init__(self, content_object, context_name, tree_root):
-        self.content_object = template.Variable(content_object)
-        self.tree_root = template.Variable(tree_root)
-        self.tree_root_str = tree_root
-        self.context_name = context_name
-
-    def render(self, context):
-        content_object = self.content_object.resolve(context)
-        try:
-            tree_root = self.tree_root.resolve(context)
-        except template.VariableDoesNotExist:
-            if self.tree_root_str == 'as':
-                tree_root = None
-            else:
-                try:
-                    tree_root = int(self.tree_root_str)
-                except ValueError:
-                    tree_root = self.tree_root_str
-        context[self.context_name] = FreeThreadedComment.public.get_tree(
-            content_object, root=tree_root)
-        return ''
-
-
 def do_get_comment_count(parser, token):
     """Gets a count of how many ThreadedComment objects are attached to the
     given object."""
@@ -285,33 +186,6 @@
         return ''
 
 
-def do_get_free_comment_count(parser, token):
-    """Gets a count of how many FreeThreadedComment objects are attached to the
-    given object."""
-    error_message = '%r tag must be of format {%% %r for OBJECT as CONTEXT_VARIABLE %%}' % (
-        token.contents.split()[0], token.contents.split()[0])
-    try:
-        split = token.split_contents()
-    except ValueError:
-        raise template.TemplateSyntaxError, error_message
-    if split[1] != 'for' or split[3] != 'as':
-        raise template.TemplateSyntaxError, error_message
-    return FreeThreadedCommentCountNode(split[2], split[4])
-
-
-class FreeThreadedCommentCountNode(template.Node):
-
-    def __init__(self, content_object, context_name):
-        self.content_object = template.Variable(content_object)
-        self.context_name = context_name
-
-    def render(self, context):
-        content_object = self.content_object.resolve(context)
-        context[self.context_name] = FreeThreadedComment.public.all_for_object(
-            content_object).count()
-        return ''
-
-
 def oneline(value):
     """Takes some HTML and gets rid of newlines and spaces between tags,
     rendering the result all on one line."""
@@ -322,7 +196,7 @@
 
 
 def do_get_threaded_comment_form(parser, token):
-    """Gets a FreeThreadedCommentForm and inserts it into the context."""
+    """Gets a ThreadedCommentForm and inserts it into the context."""
     error_message = '%r tag must be of format {%% %r as CONTEXT_VARIABLE %%}' % (
         token.contents.split()[0], token.contents.split()[0])
     try:
@@ -333,24 +207,18 @@
         raise template.TemplateSyntaxError, error_message
     if len(split) != 3:
         raise template.TemplateSyntaxError, error_message
-    if 'free' in split[0]:
-        is_free = True
-    else:
-        is_free = False
-    return ThreadedCommentFormNode(split[2], free=is_free)
+    
+    return ThreadedCommentFormNode(split[2])
 
 
 class ThreadedCommentFormNode(template.Node):
 
-    def __init__(self, context_name, free=False):
+    def __init__(self, context_name):
         self.context_name = context_name
-        self.free = free
+
 
     def render(self, context):
-        if self.free:
-            form = FreeThreadedCommentForm()
-        else:
-            form = ThreadedCommentForm()
+        form = ThreadedCommentForm()
         context[self.context_name] = form
         return ''
 
@@ -367,26 +235,18 @@
         raise template.TemplateSyntaxError, error_message
     if split[2] != 'as':
         raise template.TemplateSyntaxError, error_message
-    if 'free' in split[0]:
-        is_free = True
-    else:
-        is_free = False
-    return LatestCommentsNode(split[1], split[3], free=is_free)
+
+    return LatestCommentsNode(split[1], split[3])
 
 
 class LatestCommentsNode(template.Node):
 
-    def __init__(self, num, context_name, free=False):
+    def __init__(self, num, context_name):
         self.num = num
         self.context_name = context_name
-        self.free = free
 
     def render(self, context):
-        if self.free:
-            comments = FreeThreadedComment.objects.order_by(
-                '-date_submitted')[:self.num]
-        else:
-            comments = ThreadedComment.objects.order_by(
+        comments = ThreadedComment.objects.order_by(
                 '-date_submitted')[:self.num]
         context[self.context_name] = comments
         return ''
@@ -402,6 +262,7 @@
         raise template.TemplateSyntaxError, error_message
     if len(split) != 5:
         raise template.TemplateSyntaxError, error_message
+
     return UserCommentsNode(split[2], split[4])
 
 
@@ -427,6 +288,7 @@
         raise template.TemplateSyntaxError, error_message
     if len(split) != 5:
         raise template.TemplateSyntaxError, error_message
+
     return UserCommentCountNode(split[2], split[4])
 
 
@@ -445,21 +307,13 @@
 register.simple_tag(get_comment_url)
 register.simple_tag(get_comment_url_json)
 register.simple_tag(get_comment_url_xml)
-register.simple_tag(get_free_comment_url)
-register.simple_tag(get_free_comment_url_json)
-register.simple_tag(get_free_comment_url_xml)
 
 register.filter('oneline', oneline)
 
 register.tag('auto_transform_markup', do_auto_transform_markup)
+register.tag('get_comment_count', do_get_comment_count)
 register.tag('get_threaded_comment_tree', do_get_threaded_comment_tree)
-register.tag('get_free_threaded_comment_tree',
-             do_get_free_threaded_comment_tree)
-register.tag('get_comment_count', do_get_comment_count)
-register.tag('get_free_comment_count', do_get_free_comment_count)
-register.tag('get_free_threaded_comment_form', do_get_threaded_comment_form)
 register.tag('get_threaded_comment_form', do_get_threaded_comment_form)
 register.tag('get_latest_comments', do_get_latest_comments)
-register.tag('get_latest_free_comments', do_get_latest_comments)
 register.tag('get_user_comments', do_get_user_comments)
 register.tag('get_user_comment_count', do_get_user_comment_count)

=== modified file 'threadedcomments/urls.py'
--- threadedcomments/urls.py	2016-12-13 18:28:51 +0000
+++ threadedcomments/urls.py	2018-10-05 16:29:25 +0000
@@ -1,8 +1,6 @@
 from django.conf.urls import url
-from threadedcomments.models import FreeThreadedComment
 from threadedcomments import views
 
-free = {'model': FreeThreadedComment}
 
 urlpatterns = [
     ### Comments ###
@@ -22,22 +20,4 @@
         views.comment, name='tc_comment_parent_ajax'),
     url(r'^comment/(?P<edit_id>\d+)/edit/(?P<ajax>json|xml)/$',
         views.comment, name='tc_comment_edit_ajax'),
-
-    ### Free Comments ###
-    url(r'^freecomment/(?P<content_type>\d+)/(?P<object_id>\d+)/$',
-        views.free_comment, name='tc_free_comment'),
-    url(r'^freecomment/(?P<content_type>\d+)/(?P<object_id>\d+)/(?P<parent_id>\d+)/$',
-        views.free_comment, name='tc_free_comment_parent'),
-    url(r'^freecomment/(?P<object_id>\d+)/delete/$',
-        views.comment_delete, free, name='tc_free_comment_delete'),
-    url(r'^freecomment/(?P<edit_id>\d+)/edit/$',
-        views.free_comment, name='tc_free_comment_edit'),
-
-    ### Free Comments (AJAX) ###
-    url(r'^freecomment/(?P<content_type>\d+)/(?P<object_id>\d+)/(?P<ajax>json|xml)/$',
-        views.free_comment, name='tc_free_comment_ajax'),
-    url(r'^freecomment/(?P<content_type>\d+)/(?P<object_id>\d+)/(?P<parent_id>\d+)/(?P<ajax>json|xml)/$',
-        views.free_comment, name='tc_free_comment_parent_ajax'),
-    url(r'^freecomment/(?P<edit_id>\d+)/edit/(?P<ajax>json|xml)/$',
-        views.free_comment, name='tc_free_comment_edit_ajax'),
 ]

=== modified file 'threadedcomments/views.py'
--- threadedcomments/views.py	2018-04-05 07:30:42 +0000
+++ threadedcomments/views.py	2018-10-05 16:29:25 +0000
@@ -5,8 +5,8 @@
 from django.template import RequestContext, Context, Template
 from django.utils.http import urlquote
 from django.conf import settings
-from threadedcomments.forms import FreeThreadedCommentForm, ThreadedCommentForm
-from threadedcomments.models import ThreadedComment, FreeThreadedComment, DEFAULT_MAX_COMMENT_LENGTH
+from threadedcomments.forms import ThreadedCommentForm
+from threadedcomments.models import ThreadedComment, DEFAULT_MAX_COMMENT_LENGTH
 from threadedcomments.utils import JSONResponse, XMLResponse
 from wl_utils import get_real_ip
 
@@ -59,10 +59,10 @@
                   )
 
 
-def free_comment(request, content_type=None, object_id=None, edit_id=None, parent_id=None, add_messages=False, ajax=False, model=FreeThreadedComment, form_class=FreeThreadedCommentForm, context_processors=[], extra_context={}):
-    """Receives POST data and either creates a new ``ThreadedComment`` or
-    ``FreeThreadedComment``, or edits an old one based upon the specified
-    parameters.
+@login_required
+def comment(request, content_type=None, object_id=None, edit_id=None, parent_id=None, add_messages=False, ajax=False, context_processors=[], extra_context={}):
+    """Receives POST data and creates a new ``ThreadedComment``, or
+    edits an old one based upon the specified parameters.
 
     If there is a 'preview' key in the POST request, a preview will be forced and the
     comment will not be saved until a 'preview' key is no longer in the POST request.
@@ -74,6 +74,8 @@
     where the comment may be edited until it does not contain errors.
 
     """
+    form_class = ThreadedCommentForm
+    model = ThreadedComment
     if not edit_id and not (content_type and object_id):
         raise Http404  # Must specify either content_type and object_id or edit_id
     if 'preview' in request.POST:
@@ -87,25 +89,19 @@
     if form.is_valid():
         new_comment = form.save(commit=False)
         if not edit_id:
-            new_comment.ip_address = get_real_ip(request)
             new_comment.content_type = get_object_or_404(
                 ContentType, id=int(content_type))
             new_comment.object_id = int(object_id)
-        if model == ThreadedComment:
-            new_comment.user = request.user
+
+        new_comment.user = request.user
+
         if parent_id:
             new_comment.parent = get_object_or_404(model, id=int(parent_id))
         new_comment.save()
-        if model == ThreadedComment:
-            if add_messages:
+        if add_messages:
                 request.user.message_set.create(
                     message='Your message has been posted successfully.')
-        else:
-            request.session['successful_data'] = {
-                'name': form.cleaned_data['name'],
-                'website': form.cleaned_data['website'],
-                'email': form.cleaned_data['email'],
-            }
+
         if ajax == 'json':
             return JSONResponse([new_comment, ])
         elif ajax == 'xml':
@@ -131,16 +127,6 @@
         return _preview(request, context_processors, extra_context, form_class=form_class)
 
 
-def comment(*args, **kwargs):
-    """Thin wrapper around free_comment which adds login_required status and
-    also assigns the ``model`` to be ``ThreadedComment``."""
-    kwargs['model'] = ThreadedComment
-    kwargs['form_class'] = ThreadedCommentForm
-    return free_comment(*args, **kwargs)
-# Require login to be required, as request.user must exist and be valid.
-comment = login_required(comment)
-
-
 def can_delete_comment(comment, user):
     """Default callback function to determine wether the given user has the
     ability to delete the given comment."""
@@ -152,8 +138,7 @@
 
 # Todo: Next one is not used so far and may need adjustments to the render()
 def comment_delete(request, object_id, model=ThreadedComment, extra_context={}, context_processors=[], permission_callback=can_delete_comment):
-    """Deletes the specified comment, which can be either a
-    ``FreeThreadedComment`` or a ``ThreadedComment``.
+    """Deletes the specified comment.
 
     If it is a POST request, then the comment will be deleted outright,
     however, if it is a GET request, a confirmation page will be shown.


Follow ups