diff options
-rw-r--r-- | forums/settings.py | 2 | ||||
-rw-r--r-- | spoken_auth/models.py | 14 | ||||
-rw-r--r-- | static/website/css/main.css | 13 | ||||
-rw-r--r-- | static/website/js/thread-user.js | 45 | ||||
-rw-r--r-- | static/website/templates/base.html | 9 | ||||
-rw-r--r-- | static/website/templates/get-question.html | 35 | ||||
-rw-r--r-- | static/website/templates/search.html | 4 | ||||
-rw-r--r-- | website/context_processors.py | 6 | ||||
-rw-r--r-- | website/forms.py | 3 | ||||
-rw-r--r-- | website/models.py | 1 | ||||
-rw-r--r-- | website/templatetags/count_tags.py | 4 | ||||
-rw-r--r-- | website/templatetags/notify.py | 2 | ||||
-rw-r--r-- | website/templatetags/permission_tags.py | 8 | ||||
-rw-r--r-- | website/urls.py | 3 | ||||
-rw-r--r-- | website/views.py | 83 |
15 files changed, 195 insertions, 37 deletions
diff --git a/forums/settings.py b/forums/settings.py index 7b758e0..774617a 100644 --- a/forums/settings.py +++ b/forums/settings.py @@ -196,7 +196,7 @@ AUTHENTICATION_BACKENDS = ( 'spoken_auth.backends.DrupalAuthBackend', ) DATABASE_ROUTERS = ['spoken_auth.routers.DrupalAuthRouter'] TEMPLATE_CONTEXT_PROCESSORS += ( 'django.core.context_processors.request', - 'website.context_processors.admin_processor', + #'website.context_processors.admin_processor', ) COMPRESS_ROOT = PROJECT_DIR + "/static/" diff --git a/spoken_auth/models.py b/spoken_auth/models.py index c2fbb6b..676aab7 100644 --- a/spoken_auth/models.py +++ b/spoken_auth/models.py @@ -5,15 +5,29 @@ from django.contrib.auth.models import ( ) #from drupal_auth.managers import DrupalUserManager +class Group(models.Model): + id = models.IntegerField(primary_key=True) + name = models.CharField(max_length=100L, unique=True) + class Meta: + db_table = 'auth_group' + class Users(AbstractBaseUser): id = models.IntegerField(primary_key=True) username = models.CharField(max_length=100L, unique=True) email = models.CharField(max_length=100L, unique=True) is_active = models.BooleanField() + groups = models.ManyToManyField(Group, related_name="user_groups", through='UserGroups') USERNAME_FIELD = 'username' class Meta: db_table = 'auth_user' +class UserGroups(models.Model): + id = models.IntegerField(primary_key=True) + user = models.ForeignKey(Users) + group = models.ForeignKey(Group) + class Meta: + db_table = 'auth_user_groups' + class FossCategory(models.Model): foss = models.CharField(unique=True, max_length = 255) description = models.TextField() diff --git a/static/website/css/main.css b/static/website/css/main.css index 5587da7..054f4d2 100644 --- a/static/website/css/main.css +++ b/static/website/css/main.css @@ -194,7 +194,7 @@ table .title a { .hideme { display: none; } -.saving, .saved { +.saving, .saved, .deleted, .hide-qmsg { position: fixed; z-index: 2000; left: 45%; @@ -215,6 +215,17 @@ table .title a { .saved { background: lightgreen; } +.deleted, .hide-qmsg{ + background: #5bc0de; + color: white; +} +.question-midify{ + overflow: hidden; +} +.question-midify .delete-question, .question-midify .edit, .question-midify .save, .question-midify .hide-question{ + float: left; + margin: 0 3px; +} #content .answer { position: relative; border-bottom: 1px solid #f5f5f5; diff --git a/static/website/js/thread-user.js b/static/website/js/thread-user.js index 1c43342..32e7fae 100644 --- a/static/website/js/thread-user.js +++ b/static/website/js/thread-user.js @@ -14,6 +14,8 @@ $(document).ready(function() { */ $saving = $(".saving"); $saved= $(".saved"); + $deleted= $(".deleted"); + $hide_qmsg= $(".hide-qmsg"); $question = $(".question"); $question_modify = $(".question .modify"); $question_edit = $(".question .modify .edit"); @@ -305,4 +307,47 @@ $(document).ready(function() { $form.submit(); e.preventDefault; }); + /* delete */ + $('.delete-question').on('click', function(e){ + question_id = parseInt($('.delete-question').data("qid")); + $('#confirm-delete').modal({ backdrop: 'static', keyboard: false }) + .one('click', '#delete', function() { + $.ajax({ + url: "/ajax-delete-question/", + type: "POST", + data: { + question_id: question_id, + }, + success: function(data) { + $deleted.hide(); + $deleted.show(); + $deleted.fadeOut(10000); + window.location = '/'; + } + }); + }); + }); + + /* hide */ + $('.hide-question').on('click', function(e){ + question_id = parseInt($('.hide-question').data("qid")); + status = parseInt($('.hide-question').data("status")); + $('#confirm-hide').modal({ backdrop: 'static', keyboard: false }) + .one('click', '#chide', function() { + $.ajax({ + url: "/ajax-hide-question/", + type: "POST", + data: { + question_id: question_id, + status : status, + }, + success: function(data) { + $hide_qmsg.hide(); + $hide_qmsg.show(); + $hide_qmsg.fadeOut(10000); + window.location.reload(); + } + }); + }); + }); }); diff --git a/static/website/templates/base.html b/static/website/templates/base.html index 86ca41a..506cf24 100644 --- a/static/website/templates/base.html +++ b/static/website/templates/base.html @@ -1,5 +1,6 @@ {% load compress %} {% load static %} +{% load permission_tags %} <html> <head> <title> @@ -37,6 +38,14 @@ <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav navbar-right"> + {% if user|isadministrator %} + <li> + <a href="{% url 'website:hidden_questions' %}"> + <span class="glyphicon glyphicon-eye-close"></span> + Hidden Questions + </a> + </li> + {% endif %} <li> <a href="{% url 'website:search' %}"> <span class="glyphicon glyphicon-search"></span> diff --git a/static/website/templates/get-question.html b/static/website/templates/get-question.html index 2983412..cce6469 100644 --- a/static/website/templates/get-question.html +++ b/static/website/templates/get-question.html @@ -7,10 +7,11 @@ {% block title %} {{ question.category }} - {{ question.title }} - Spoken Tutorial Forums {% endblock %} - {% block content %} <span class="saving hideme">saving . . .</span> <span class="saved hideme">saved</span> +<span class="deleted hideme">{{ question.title }} has been deleted.</span> +<span class="hide-qmsg hideme">{{ question.title }} has been {% if question.status == 1 %} hidden {% else %} Shown {% endif %}.</span> <div class="row"> <div class="question-wrapper col-lg-12 col-md-12 col-sm-12 col-xs-12"> @@ -67,13 +68,42 @@ <span class="glyphicon glyphicon-edit"></span> </a> - <span class="modify"> + <span class="modify question-midify"> {% if user|can_edit:question %} + <a class="hide-question btn btn-xs btn-info" data-qid="{{ question.id }}" data-status="{{ question.status }} href="#">{% if question.status == 1 %} Hide {% else %} Show {% endif %}</a> + <a class="delete-question btn btn-xs btn-info" data-qid="{{ question.id }}" href="#">Delete</a> <a class="edit btn btn-xs btn-info" href="#">Edit</a> <a class="save btn btn-xs btn-success" data-qid="{{ question.id }}" href="#">Save</a> {% endif %} </span> + + <div id="confirm-delete" class="modal fade"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-body"> + Are you sure want to delete this question? + </div> + <div class="modal-footer"> + <button type="button" data-dismiss="modal" class="btn btn-primary btn-sm" id="delete">Delete</button> + <button type="button" data-dismiss="modal" class="btn btn-primary btn-sm">Cancel</button> + </div> + </div><!-- /.modal-content --> + </div><!-- /.modal-dialog --> + </div><!-- /.modal --> + <div id="confirm-hide" class="modal fade"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-body"> + Are you sure want to {% if question.status %} Hide {% else %} Show {% endif %} this question? + </div> + <div class="modal-footer"> + <button type="button" data-dismiss="modal" class="btn btn-primary btn-sm" id="chide">Yes</button> + <button type="button" data-dismiss="modal" class="btn btn-primary btn-sm">Cancel</button> + </div> + </div><!-- /.modal-content --> + </div><!-- /.modal-dialog --> + </div><!-- /.modal --> <span class="meta"> <small> <i> @@ -320,7 +350,6 @@ }); </script> {% endblock %} - {% block javascript %} <script src="{% static 'website/js/thread-user.js' %}"></script> <script src="{% static 'website/js/custom.js' %}"></script> diff --git a/static/website/templates/search.html b/static/website/templates/search.html index 3ffc871..a2dc483 100644 --- a/static/website/templates/search.html +++ b/static/website/templates/search.html @@ -45,13 +45,13 @@ <div class="col-lg-2 col-md-2 col-sm-2"> <select id="search-minute-range" class="form-control" disabled="disabled"> - <option value="None">min</option> + <option value="">min</option> </select> </div> <div class="col-lg-2 col-md-2 col-sm-2"> <select id="search-second-range" class="form-control" disabled="disabled"> - <option value="None">sec</option> + <option value="">sec</option> </select> </div> diff --git a/website/context_processors.py b/website/context_processors.py index 2497e7c..df6a5f4 100644 --- a/website/context_processors.py +++ b/website/context_processors.py @@ -1,7 +1,7 @@ -from website.views import admins +#from website.views import admins -def admin_processor(request): - return {'admins': admins} +#def admin_processor(request): +# return {'admins': admins} def booleans(): return { diff --git a/website/forms.py b/website/forms.py index e2e6783..32a21a8 100644 --- a/website/forms.py +++ b/website/forms.py @@ -17,6 +17,7 @@ class NewQuestionForm(forms.Form): category = forms.ChoiceField(choices = [('', 'Select a Category'),] + list(TutorialResources.objects.filter(Q(status = 1) | Q(status = 2), language__name = 'English').values('tutorial_detail__foss__foss').order_by('tutorial_detail__foss__foss').values_list('tutorial_detail__foss__foss', 'tutorial_detail__foss__foss').distinct()), widget=forms.Select(attrs = {}), required = True, error_messages = {'required':'State field is required.'}) def __init__(self, *args, **kwargs): category = kwargs.pop('category', None) + selecttutorial = kwargs.pop('tutorial', None) super(NewQuestionForm, self).__init__(*args, **kwargs) tutorial_choices = ( ("", "Select a Tutorial"), @@ -29,6 +30,8 @@ class NewQuestionForm(forms.Form): for tutorial in tutorials: tutorial_choices += ((tutorial.tutorial, tutorial.tutorial),) self.fields['tutorial'] = forms.CharField(widget=forms.Select(choices=tutorial_choices)) + if TutorialDetails.objects.using('spoken').filter(tutorial=selecttutorial).exists(): + self.fields['tutorial'].initial = selecttutorial else: self.fields['tutorial'] = forms.CharField(widget=forms.Select(choices=tutorial_choices)) diff --git a/website/models.py b/website/models.py index 727edd1..66bdc60 100644 --- a/website/models.py +++ b/website/models.py @@ -16,6 +16,7 @@ class Question(models.Model): date_created = models.DateTimeField(auto_now_add=True) date_modified = models.DateTimeField(auto_now=True) views = models.IntegerField(default=1) + status = models.IntegerField(default=1) # votes = models.IntegerField(default=0) def user(self): diff --git a/website/templatetags/count_tags.py b/website/templatetags/count_tags.py index 3a14d2b..ade2f01 100644 --- a/website/templatetags/count_tags.py +++ b/website/templatetags/count_tags.py @@ -61,12 +61,12 @@ register.filter('div', div) # retriving total number of questions def total_question_count(): - count = Question.objects.all().count() + count = Question.objects.filter(status=1).count() return count register.simple_tag(total_question_count) # retriving total number of answers def total_answer_count(): - count = Answer.objects.all().count() + count = Answer.objects.filter(question__status=1).count() return count register.simple_tag(total_answer_count) diff --git a/website/templatetags/notify.py b/website/templatetags/notify.py index c39e658..55e5fce 100644 --- a/website/templatetags/notify.py +++ b/website/templatetags/notify.py @@ -25,7 +25,7 @@ register.simple_tag(notification_count) def latest_question(category): question = None try: - question = Question.objects.filter(category=category).order_by('-date_created')[0] + question = Question.objects.filter(category=category, status=1).order_by('-date_created')[0] except: pass context = { diff --git a/website/templatetags/permission_tags.py b/website/templatetags/permission_tags.py index b85d747..36461b4 100644 --- a/website/templatetags/permission_tags.py +++ b/website/templatetags/permission_tags.py @@ -1,12 +1,16 @@ from django import template -from website.views import admins +from website.views import is_administrator register = template.Library() def can_edit(user, obj): - if user.id == obj.uid or user.id in admins: + if user.id == obj.uid or is_administrator(user): return True return False +def isadministrator(user): + return is_administrator(user) + register.filter(can_edit) +register.filter(isadministrator) diff --git a/website/urls.py b/website/urls.py index d05a5f0..ad5a24c 100644 --- a/website/urls.py +++ b/website/urls.py @@ -3,6 +3,7 @@ from django.conf.urls import patterns, include, url urlpatterns = patterns('', url(r'^$', 'website.views.home', name='home'), url(r'^questions/$', 'website.views.questions', name='questions'), + url(r'^hidden-questions/$', 'website.views.hidden_questions', name='hidden_questions'), url(r'^question/(?P<question_id>\d+)/$', 'website.views.get_question', name='get_question'), url(r'^question/(?P<question_id>\d+)/(?P<pretty_url>.+)/$', 'website.views.get_question', name='get_question'), url(r'^question-answer/$', 'website.views.question_answer', name='question_answer'), @@ -30,4 +31,6 @@ urlpatterns = patterns('', url(r'^ajax-notification-remove/$', 'website.views.ajax_notification_remove', name='ajax_notification_remove'), url(r'^ajax-keyword-search/$', 'website.views.ajax_keyword_search', name='ajax_keyword_search'), url(r'^ajax-time-search/$', 'website.views.ajax_time_search', name='ajax_time_search'), + url(r'^ajax-delete-question/$', 'website.views.ajax_delete_question', name='ajax_delete_question'), + url(r'^ajax-hide-question/$', 'website.views.ajax_hide_question', name='ajax_hide_question'), ) diff --git a/website/views.py b/website/views.py index 745a123..0c625c8 100644 --- a/website/views.py +++ b/website/views.py @@ -1,4 +1,4 @@ -import re +import re, json from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render, get_object_or_404 @@ -13,14 +13,14 @@ from django.contrib.auth import get_user_model User = get_user_model() from website.models import Question, Answer, Notification, AnswerComment -from spoken_auth.models import TutorialDetails, TutorialResources +from spoken_auth.models import TutorialDetails, TutorialResources, Group from website.forms import NewQuestionForm, AnswerQuesitionForm from website.helpers import get_video_info, prettify from django.db.models import Count -admins = ( - 9, 4376, 4915, 14595, 12329, 22467, 5518, 30705 -) +def is_administrator(user): + if user and user.groups.filter(name='Administrator').count() == 1: + return True categories = [] trs = TutorialResources.objects.filter(Q(status = 1) | Q(status = 2), language__name = 'English').values('tutorial_detail__foss__foss').order_by('tutorial_detail__foss__foss').values_list('tutorial_detail__foss__foss').distinct() @@ -28,7 +28,7 @@ for tr in trs: categories.append(tr[0]) def home(request): - questions = Question.objects.all().order_by('date_created').reverse()[:10] + questions = Question.objects.filter(status = 1).order_by('date_created').reverse()[:10] context = { 'categories': categories, 'questions': questions @@ -36,7 +36,23 @@ def home(request): return render(request, "website/templates/index.html", context) def questions(request): - questions = Question.objects.all().order_by('date_created').reverse() + questions = Question.objects.filter(status=1).order_by('date_created').reverse() + paginator = Paginator(questions, 20) + page = request.GET.get('page') + + try: + questions = paginator.page(page) + except PageNotAnInteger: + questions = paginator.page(1) + except EmptyPage: + questions = paginator.page(paginator.num_pages) + context = { + 'questions': questions + } + return render(request, 'website/templates/questions.html', context) + +def hidden_questions(request): + questions = Question.objects.filter(status=0).order_by('date_created').reverse() paginator = Paginator(questions, 20) page = request.GET.get('page') @@ -192,13 +208,13 @@ def filter(request, category=None, tutorial=None, minute_range=None, second_ran } if category and tutorial and minute_range and second_range: - questions = Question.objects.filter(category=category).filter(tutorial=tutorial).filter(minute_range=minute_range).filter(second_range=second_range) + questions = Question.objects.filter(category=category).filter(tutorial=tutorial).filter(minute_range=minute_range).filter(second_range=second_range, status=1) elif tutorial is None: - questions = Question.objects.filter(category=category) + questions = Question.objects.filter(category=category, status=1) elif minute_range is None: - questions = Question.objects.filter(category=category).filter(tutorial=tutorial) + questions = Question.objects.filter(category=category).filter(tutorial=tutorial, status=1) else: #second_range is None - questions = Question.objects.filter(category=category).filter(tutorial=tutorial).filter(minute_range=minute_range) + questions = Question.objects.filter(category=category).filter(tutorial=tutorial).filter(minute_range=minute_range, status=1) if 'qid' in request.GET: context['qid'] = int(request.GET['qid']) @@ -250,8 +266,8 @@ def new_question(request): return HttpResponseRedirect('/') else: #fix dirty code - category = request.GET.get('category') - tutorial = request.GET.get('tutorial') + category = request.GET.get('category', None) + tutorial = request.GET.get('tutorial', None) form = NewQuestionForm(category=category, tutorial=tutorial) context['category'] = category @@ -380,7 +396,7 @@ def ajax_question_update(request): body = request.POST['question_body'] question = get_object_or_404(Question, pk=qid) if question: - if question.uid == request.user.id or request.user.id in admins: + if question.uid == request.user.id or is_administrator(request.user): question.title = title question.body = body.encode('unicode_escape') question.save() @@ -396,7 +412,7 @@ def ajax_details_update(request): second_range = request.POST['second_range'] question = get_object_or_404(Question, pk=qid) if question: - if question.uid == request.user.id or request.user.id in admins: + if question.uid == request.user.id or is_administrator(request.user): question.category = category question.tutorial = tutorial question.minute_range = minute_range @@ -411,7 +427,7 @@ def ajax_answer_update(request): body = request.POST['answer_body'] answer= get_object_or_404(Answer, pk=aid) if answer: - if answer.uid == request.user.id or request.user.id in admins: + if answer.uid == request.user.id or is_administrator(request.user): answer.body = body.encode('unicode_escape') answer.save() return HttpResponse("saved") @@ -423,7 +439,7 @@ def ajax_answer_comment_update(request): comment_body = request.POST["comment_body"] comment = get_object_or_404(AnswerComment, pk=comment_id) if comment: - if comment.uid == request.user.id or request.user.id in admins: + if comment.uid == request.user.id or is_administrator(request.user): comment.body = comment_body.encode('unicode_escape') comment.save() return HttpResponse("saved") @@ -456,10 +472,36 @@ def ajax_notification_remove(request): return HttpResponse("failed") @csrf_exempt +def ajax_delete_question(request): + result = False + if request.method == "POST": + key = request.POST['question_id'] + question = Question.objects.filter(pk=key) + if question.exists(): + question.delete() + result = True + return HttpResponse(json.dumps(result), mimetype='application/json') + +@csrf_exempt +def ajax_hide_question(request): + result = False + if request.method == "POST": + key = request.POST['question_id'] + question = Question.objects.filter(pk=key) + if question.exists(): + question = question.first() + question.status = 0 + if request.POST['status'] == '0': + question.status = 1 + question.save() + result = True + return HttpResponse(json.dumps(result), mimetype='application/json') + +@csrf_exempt def ajax_keyword_search(request): if request.method == "POST": key = request.POST['key'] - questions = Question.objects.filter(title__icontains=key) + questions = Question.objects.filter(title__icontains=key, status=1) context = { 'questions': questions } @@ -473,17 +515,14 @@ def ajax_time_search(request): minute_range= request.POST.get('minute_range') second_range = request.POST.get('second_range') questions = None - print request.POST, "***********" if category: - questions = Question.objects.filter(category=category.replace(' ', '-')) - print "sssssssssss", questions + questions = Question.objects.filter(category=category.replace(' ', '-'), status = 1) if tutorial: questions = questions.filter(tutorial=tutorial.replace(' ', '-')) if minute_range: questions = questions.filter(category=category.replace(' ', '-'), tutorial=tutorial.replace(' ', '-'), minute_range=minute_range) if second_range: questions = questions.filter(category=category.replace(' ', '-'), tutorial=tutorial.replace(' ', '-'),second_range=second_range) - print questions, "&&&&&&&&&&&" context = { 'questions': questions } |