changeset 211:2a234e11185c

Merge in Wendy's changes
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Wed, 21 Aug 2013 14:43:48 -0400
parents 95edf106bdef (current diff) a22259c9862e (diff)
children b3c3d940cc87
files apps/bundle/views.py templates/bundle/bundle.djhtml
diffstat 22 files changed, 365 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/apps/bundle/views.py	Tue Feb 19 01:53:59 2013 -0500
+++ b/apps/bundle/views.py	Wed Aug 21 14:43:48 2013 -0400
@@ -32,6 +32,7 @@
         'file': file,
         'previous_versions': xrange(1, bundle.latest_version + 1),
         'this_version': version,
+        'show': True,
     }
 
     return render(request, 'bundle/bundle.djhtml', context)
--- a/apps/snippet/forms.py	Tue Feb 19 01:53:59 2013 -0500
+++ b/apps/snippet/forms.py	Wed Aug 21 14:43:48 2013 -0400
@@ -34,6 +34,8 @@
         label=_(u'Expires'),
     )
 
+
+
     def __init__(self, *args, **kwargs):
         request = kwargs.pop('request')
         super(SnippetForm, self).__init__(*args, **kwargs)
--- a/apps/snippet/models.py	Tue Feb 19 01:53:59 2013 -0500
+++ b/apps/snippet/models.py	Wed Aug 21 14:43:48 2013 -0400
@@ -8,11 +8,14 @@
 from mptt.models import MPTTModel, TreeForeignKey
 
 from apps.snippet.highlight import LEXER_DEFAULT, LEXER_LIST, pygmentize
-
+from djangoratings.fields import RatingField
 
 t = 'abcdefghijkmnopqrstuvwwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ1234567890'
 def generate_secret_id(length=4):
-    return ''.join([random.choice(t) for i in range(length)])
+    unique_id = ''.join([random.choice(t) for i in range(length)])
+    while Snippet.objects.filter(secret_id = unique_id ).count()!= 0:
+        unique_id = ''.join([random.choice(t) for i in range(length)])    
+    return unique_id
 
 class SnippetManager(models.Manager):
     def public(self):
@@ -40,7 +43,7 @@
     parent = TreeForeignKey('self', null=True, blank=True,
                                related_name='children')
     num_views = models.IntegerField(default=0)
-
+    rating = RatingField(range=5,can_change_vote=True,allow_anonymous=True,allow_delete=True)
     class Meta:
         ordering = ('-published',)
 
--- a/apps/snippet/urls.py	Tue Feb 19 01:53:59 2013 -0500
+++ b/apps/snippet/urls.py	Wed Aug 21 14:43:48 2013 -0400
@@ -32,4 +32,5 @@
           {'template_name': 'snippet/snippet_details_raw.djhtml',
            'is_raw': True},
         name='snippet_details_raw'),
+    url(r'^(?P<snippet_id>[a-zA-Z0-9]{4})/rating/process/'  , 'processrating' ),
 )
--- a/apps/snippet/views.py	Tue Feb 19 01:53:59 2013 -0500
+++ b/apps/snippet/views.py	Wed Aug 21 14:43:48 2013 -0400
@@ -35,6 +35,7 @@
         if request.user.is_authenticated():
             snippet.author = request.user
 
+
         snippet_form = SnippetForm(request.POST,
                                    request.FILES,
                                    request=request,
@@ -51,17 +52,29 @@
     context = {
         'snippet_form': snippet_form,
         'recent_snippets' : recent,
+        'show': True, # always true b/c guest posting is allowed
     }
 
     return render(request, 'snippet/snippet_new.djhtml', context)
 
 
-def snippet_details(request, snippet_id,
-    template_name='snippet/snippet_details.djhtml', is_raw=False):
+def snippet_details(request, snippet_id,template_name='snippet/snippet_details.djhtml', is_raw=False):
+    
     snippet = get_object_or_404(Snippet, secret_id=snippet_id)
     snippet.num_views += 1
     snippet.save()
 
+
+    if request.user.is_authenticated() and hasattr(snippet,'author'):
+        show = True
+    elif ( request.user.is_anonymous() ) and (hasattr(snippet,'author') ):
+        if snippet.author == None:
+            show = True
+        else:
+            show = False
+    else:
+        show = False
+
     tree = snippet.get_root()
     tree = tree.get_descendants(include_self=True)
 
@@ -74,6 +87,7 @@
         'content': snippet.content,
         'lexer': snippet.lexer,
         'title': reply_title,
+        
     }
 
     if request.method == "POST":
@@ -93,6 +107,13 @@
     else:
         default_pygments_style = PygmentsStyle.objects.get(pk=1)
 
+
+    r = snippet.rating.votes
+    if snippet.rating.votes == 0:
+        r = 1
+
+    score = snippet.rating.score/(r)
+
     context = {
         'snippet_form': snippet_form,
         'snippet': snippet,
@@ -102,6 +123,8 @@
         'pygments_styles': PygmentsStyle.objects.all(),
         'default_style': default_pygments_style,
         'no_descendants': len(tree) == 1,
+        'show': show,
+        'score' : score,
     }
 
     response = render(request, template_name, context)
@@ -213,3 +236,24 @@
     code_string = request.GET.get('codestring', False)
     response = simplejson.dumps({'lexer': guess_code_lexer(code_string)})
     return HttpResponse(response)
+
+
+
+#Rating Processing
+def processrating(request,snippet_id):
+    from djangoratings.views import AddRatingView
+    import django.db.models
+    from django.contrib.contenttypes.models import ContentType
+
+
+    content_type = ContentType.objects.get(model='snippet').id
+    if request.method == 'POST':
+        params = {
+            'content_type_id': content_type,
+            'object_id': get_object_or_404(Snippet,secret_id=snippet_id).id,
+            'field_name': 'rating', # Must be the same as the name declared in the model of snippet
+            'score': int( request.POST['Rate']) , # the score value sent
+            }
+        response = AddRatingView()(request, **params)
+        if response.status_code == 200:
+            return redirect( request.POST['next'] )
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/treecomments/__init__.py	Wed Aug 21 14:43:48 2013 -0400
@@ -0,0 +1,9 @@
+from apps.treecomments.models import TreeComments
+from apps.treecomments.forms import TreeCommentsForm
+
+def get_model():
+	return TreeComments
+
+def get_form():
+	return TreeCommentsForm
+	
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/treecomments/forms.py	Wed Aug 21 14:43:48 2013 -0400
@@ -0,0 +1,13 @@
+from django import forms
+from django.contrib.admin import widgets
+from django.contrib.comments.forms import CommentForm
+from apps.treecomments.models import TreeComments
+
+class TreeCommentsForm(CommentForm):
+	parent = forms.ModelChoiceField(queryset=TreeComments.objects.all(), required=False, widget=forms.HiddenInput)
+	def get_comment_model(self):
+		return TreeComments
+	def get_comment_create_data(self):
+		data = super(TreeCommentsForm,self).get_comment_create_data()
+		data['parent'] = self.cleaned_data['parent']
+		return data
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/treecomments/models.py	Wed Aug 21 14:43:48 2013 -0400
@@ -0,0 +1,15 @@
+from django.contrib.comments.models import Comment
+from mptt.models import MPTTModel, TreeForeignKey
+
+
+
+class TreeComments(MPTTModel,Comment):
+	parent = TreeForeignKey('self', null =True, blank=True,related_name='children')
+
+	class MPTTMeta:
+		order_insertion_by = ['submit_date']
+
+	class Meta:
+		ordering = ['tree_id','lft']
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/treecomments/tests.py	Wed Aug 21 14:43:48 2013 -0400
@@ -0,0 +1,16 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this 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.assertEqual(1 + 1, 2)
--- a/pip-requirements	Tue Feb 19 01:53:59 2013 -0500
+++ b/pip-requirements	Wed Aug 21 14:43:48 2013 -0400
@@ -9,3 +9,5 @@
 django-sizefield==0.1
 python-archive==0.2
 python-magic==0.4.3
+django-ratings==0.3.7
+South==0.8.1
\ No newline at end of file
--- a/settings.py	Tue Feb 19 01:53:59 2013 -0500
+++ b/settings.py	Wed Aug 21 14:43:48 2013 -0400
@@ -141,7 +141,7 @@
     'django.contrib.messages',
     'django.contrib.admindocs',
     'django.contrib.admin',
-#   'django.contrib.comments',
+   'django.contrib.comments',
 
     # Third-party apps
     'registration',
@@ -149,6 +149,8 @@
     'kombu.transport.django',
     'mptt',
     'sizefield',
+    'djangoratings',
+    'south',
 #   'threadedcomments',
 
     # Agora apps
@@ -157,9 +159,10 @@
     'apps.bundle',
     'apps.free_license',
     'apps.pygments_style',
+    'apps.treecomments',
 )
 
-COMMENTS_APP = 'threadedcomments'
+COMMENTS_APP = 'apps.treecomments'
 
 # Doesn't accept view names until Django 1.5
 LOGIN_REDIRECT_URL='/'
--- a/static/css/agora.less	Tue Feb 19 01:53:59 2013 -0500
+++ b/static/css/agora.less	Wed Aug 21 14:43:48 2013 -0400
@@ -425,3 +425,91 @@
     white-space: pre-wrap;
     .hint;
 }
+
+/**/
+#comment
+{
+    /*#gradient(@offWhite, @lighterGrey);*/
+    max-width:700px;
+    border-left: 1px solid #e8e8e8;
+    margin: 5px;
+}
+#comment-box
+{
+    width: 500px;
+    height: 100px;
+    margin-left: 20px;
+}
+.names
+{
+    font-weight: bold;
+    margin-left: 5px;
+}
+
+.comment-node-child
+{
+    margin-left:13px;
+    max-width:700px;
+    margin-bottom: 3px;
+    border-left: 2px solid  #e7e7e7;
+}
+
+.comment-node
+{
+    margin-top: 5px;
+    border: 2px solid #e1e1e1;
+    max-width: 700px;
+    border-radius: 3px;
+}
+.comment-bar
+{
+    margin: 2px 0 2px 2px;
+    color: blue;
+    font-size: 16px;
+    background: #e0e0e0;
+    width: 97%;
+    padding: 2px 0 2px 10px;
+
+}
+[ name=comment ]
+{
+    width:97%;
+    height: 100px;
+}
+.reply-button
+{
+    margin: 3px;
+    border: 3px solid #e9e9e9;
+    width: 70px;
+    height: 30px;
+    background: white;
+    padding: 2px;
+}
+.comment-body
+{
+    padding-left: 15px;
+}
+#radio_votes
+{
+    margin:5px;
+}
+#radio_votes ul
+{
+    list-style: none;
+    display:block;
+}
+#radio_votes ul li
+{
+    float:left;
+    font-weight: bold;
+    margin: 2px;
+}
+#rate_label
+{
+    float:left;
+    margin-right:3px;
+}
+.rate_radio
+{
+    margin:2px;
+}
\ No newline at end of file
--- a/static/js/agora.js	Tue Feb 19 01:53:59 2013 -0500
+++ b/static/js/agora.js	Wed Aug 21 14:43:48 2013 -0400
@@ -37,6 +37,11 @@
         }
     };
 
+    $.fn.ShowCommentForm = function(id){
+            $(this).hide();
+            $('#' + id).show();
+        };
+
     $(document).ready(function () {
         handleLoginLink();
 
@@ -75,4 +80,9 @@
             currentStyle = newStyle;
         });
     });
-})(jQuery);
+    $("input[name=Rate]").change(function()
+    {
+        $("#rate_form").submit();
+    });
+}
+)(jQuery);
\ No newline at end of file
--- a/templates/bundle/bundle.djhtml	Tue Feb 19 01:53:59 2013 -0500
+++ b/templates/bundle/bundle.djhtml	Wed Aug 21 14:43:48 2013 -0400
@@ -13,6 +13,8 @@
 &raquo;
 {{ file }}
 {% endif %}
+
+
 {% endblock %}
 
 {% block title %}
@@ -104,6 +106,10 @@
     </ul>
     {% endif %}
     {% endif %}
+    <h2 class = "names"> Comments for this bundle: </h2>
+    {% with bundle as object %}
+    {% include "comments/rawcomment.html" %}{% endwith %}.
+
 </div>
 {% else %}
 <p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/comments/form.html	Wed Aug 21 14:43:48 2013 -0400
@@ -0,0 +1,31 @@
+{% load comments i18n %}
+
+
+<form action="{% comment_form_target %}" method="post">
+  {% csrf_token %}
+    {{ form.object_pk }}
+    {{ form.content_type }}
+    {{ form.timestamp }}
+    {{ form.security_hash }}
+    {# if it is has a parent #}
+    <input type="hidden" name="next" value="{{ request.get_full_path }}" />
+    {% if node.id %}
+        <input type="hidden" name="parent" id="parent_id" value="{{ node.id }}" />
+        <input type = 'button' value = "Reply" onClick= "$(this).ShowCommentForm({{ node.id }})" id = "{{ node.id }}-button"
+        class = "reply-button"/>
+
+    {% endif %}
+        <!-- I have used node id over here so that I can show/hide comment field -->
+        <div class = "comment-box" style="{% if node.id %}display:none {% else %} display:block {%endif%}" id = "{{ node.id }}"   >
+        <h4>
+        {%if node.id%}
+        Reply:
+        {%else%} Comment:
+        {%endif%}
+        </h4>
+        {{form.comment}}
+
+        <br/>
+        <input type="submit" value = "Submit" class = 'reply-button' >
+        </div>
+    </form>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/comments/list.html	Wed Aug 21 14:43:48 2013 -0400
@@ -0,0 +1,14 @@
+Override
+<dl id="comments">
+  {% for comment in comment_list %}
+    <dt id="c{{ comment.id }}">
+        {{ comment.submit_date }} - {{ comment.name }}
+    </dt>
+    <dt> {{ comment.user_name }} </dt>
+    <dt> {{ comment.ip_address }} </dt>
+    <dt> {{ comment.user_email }} </dt>
+    <dd>
+        <p>{{ comment.user_url }}</p>
+    </dd>
+  {% endfor %}
+</dl>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/comments/rawcomment.html	Wed Aug 21 14:43:48 2013 -0400
@@ -0,0 +1,39 @@
+{% load comments %}
+{% load mptt_tags %}
+<div id = "comment">
+
+
+
+{% if user.is_authenticated %}
+
+
+{% render_comment_form for object %}
+
+{% get_comment_list for object as comments %}
+
+{% if comments %}
+{% recursetree comments %}
+  <a name = "c{{ node.id }}"> </a>
+ <!-- {{ node.id }} -->
+  <div class = "comment-node">
+
+ <p class = "comment-bar"><a href = "{{ object.get_absolute_url }}#c{{ node.id }}"><strong>{{ node.user }} </strong>  ยท    {{ node.submit_date|timesince }}  ago  </a> </p>
+  <p class = "comment"><p class = "comment-body"> {{ node.comment }} </p>
+  {% render_comment_form for object %}
+</div>
+  {# recursion tree logic #}
+  {% if not node.is_leaf_node %}
+  <div class = "comment-node-child">
+  {{ children }}
+</div>
+  {% endif %}
+
+{% endrecursetree %}
+{% endif%}
+
+{% else %}
+    <h4>You need to be logged in to see comments</h4>
+
+{% endif%}
+
+</div>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/snippet/rate_form.djhtml	Wed Aug 21 14:43:48 2013 -0400
@@ -0,0 +1,12 @@
+<div id = "radio_votes">
+<form action = "rating/process/"  method = "POST" id="rate_form">
+{% csrf_token%}
+<h3 id ="rate_label">Rate this Snippet:</h3>
+<ul>
+{% for x in "12345" %}
+<li><label for="id_Rate_{{ forloop.counter }}"><input name="Rate" type="radio" class="rate_radio" value="{{ forloop.counter }}" id="id_Rate_0"> {{ forloop.counter }}</label></li>
+{% endfor %}
+</ul>
+<input type="hidden" name="next" value="{{ request.get_full_path }}" />
+</form>
+</div>
\ No newline at end of file
--- a/templates/snippet/snippet_box.djhtml	Tue Feb 19 01:53:59 2013 -0500
+++ b/templates/snippet/snippet_box.djhtml	Wed Aug 21 14:43:48 2013 -0400
@@ -1,5 +1,8 @@
 {% autoescape off %}
+
 <div class="snippet {{ default_style }}">
+{%  if  show   %}
+
     <div class="code-lines">
         {% for line in lines %}
         <p class="line" id="l{{ forloop.counter }}">{% if line %}{{ line }}{% else %}&nbsp;{% endif %}</p>
@@ -7,4 +10,12 @@
     </div>
     <div class="line-counters"></div>
 </div>
+{%  else %}
+    <div class="code-lines">
+        
+
+<p class="hint">  You need to register first if you want to see the content. Register for a new account or log in. </p>
+</div>
+</div>
+{% endif %}
 {% endautoescape %}
--- a/templates/snippet/snippet_details.djhtml	Tue Feb 19 01:53:59 2013 -0500
+++ b/templates/snippet/snippet_details.djhtml	Wed Aug 21 14:43:48 2013 -0400
@@ -74,6 +74,11 @@
             Language: {{ language }}
             &mdash;
             Number of views: {{ snippet.num_views }}
+            <strong>
+            {%  load ratings %}
+            Total Votes: {{ snippet.rating.votes }}
+            Rating: {{ score }}
+            </strong>
         </div>
     </div><!-- closes .snippet-options -->
     <br />
@@ -81,12 +86,16 @@
     {% include "snippet/snippet_box.djhtml" with lines=snippet.content_splitted %}
 
     <br />
+    {% include "snippet/rate_form.djhtml" %}
+    <br/>
+    <h2> Comments for this snippet: </h2>{% with snippet as object %}{% include "comments/rawcomment.html" %}{% endwith %}.
 
     <h2 id="revise">{% trans "Revise this snippet" %}</h2>
 
     {% include "snippet/snippet_form.djhtml" %}
 </div><div id="sidebar">
     <h2>{% trans "History" %}</h2>
+{% if user.is_authenticated %}
     {% if no_descendants %}
         <p>{% trans "This snippet has no children!" %}</p>
         <p>
@@ -132,23 +141,43 @@
         </ul>
         {% endfor %}
         {% endfor %}
-      </div><!-- closes the .tree div -->
+
+           <div class="submit">
+        <input type="submit" value="{% trans "Compare" %}"/>
+
+
+          </div><!-- closes the .tree div -->
       <br />
-      <div class="submit">
-        <input type="submit" value="{% trans "Compare" %}"/>
+
       </div><!-- closes the .submit div -->
     </form>
+
+
+
     {% endif %}
     <br />
     <h2>{% trans "Options" %}</h2>
     <a href="{% url snippet_details_raw snippet.secret_id %}">
        {% trans "View raw" %}
      </a>
+{% else %}
+     <h4>{% trans "Login to see revision history" %}</h4>
+{% endif %}
+
+
+
+
+
 </div><!-- closes the .sidebar div -->
 {% endblock %}
 
+
+
+
+
+
 {% block script_footer %}
 <script type="text/javascript">
 {%include "snippet/snippet_details.js" %}
 </script>
-{% endblock script_footer %}
+{% endblock script_footer %}
\ No newline at end of file
--- a/templates/snippet/snippet_form.djhtml	Tue Feb 19 01:53:59 2013 -0500
+++ b/templates/snippet/snippet_form.djhtml	Wed Aug 21 14:43:48 2013 -0400
@@ -1,4 +1,6 @@
 {% load i18n %}
+
+{% if show %}
 <form method="post" action="" class="snippetform"
     enctype="multipart/form-data">
     {% if snippet_form.non_field_errors %}
@@ -40,3 +42,4 @@
         <button type="submit" class="button large">{% trans "Paste it" %}</button>
     </div>
 </form>
+{% endif %}
--- a/urls.py	Tue Feb 19 01:53:59 2013 -0500
+++ b/urls.py	Wed Aug 21 14:43:48 2013 -0400
@@ -38,6 +38,7 @@
     url(r'^users/', include('agora.apps.profile.urls')),
     url(r'^snippet/', include('agora.apps.snippet.urls')),
     url(r'^bundles/', include('agora.apps.bundle.urls')),
+    url(r'^comments/', include('django.contrib.comments.urls')),
 )
 
 #Let Django itself serve static data during debugging