# HG changeset patch # User Brian Neal # Date 1464581363 18000 # Node ID 110bbc78a482f5d4ec2a4964dc157a455e036bf9 # Parent 1ac847818aeae0d85b430242bbbc0551998fab86 GCalendar V3 conversion in progress. diff -r 1ac847818aea -r 110bbc78a482 comments/urls.py --- a/comments/urls.py Wed May 11 22:00:44 2016 -0500 +++ b/comments/urls.py Sun May 29 23:09:23 2016 -0500 @@ -8,7 +8,10 @@ urlpatterns = [ url(r'^flag/$', comments.views.flag_comment, name='comments-flag'), - url(r'^markdown/$', comments.views.markdown_preview, name='comments-markdown_preview'), + url(r'^markdown/$', comments.views.markdown_preview, + name='comments-markdown_preview'), + url(r'^markdown/v3/$', comments.views.markdown_preview_v3, + name='comments-markdown_preview_v3'), url(r'^post/$', comments.views.post_comment, name='comments-post'), url(r'^cr/(\d+)/(\d+)/$', django.contrib.contenttypes.views.shortcut, diff -r 1ac847818aea -r 110bbc78a482 comments/views.py --- a/comments/views.py Wed May 11 22:00:44 2016 -0500 +++ b/comments/views.py Sun May 29 23:09:23 2016 -0500 @@ -140,7 +140,7 @@ function for a javascript editor such as markItUp. """ if not request.user.is_authenticated(): - return HttpResponseForbidden('This service is only available to logged in users.') + return HttpResponseForbidden('This service is only available to logged-in users.') data = request.POST.get('data', None) if data is None: @@ -156,3 +156,20 @@ return render(request, 'comments/markdown_preview.html', { 'data': html, }) + + +@require_POST +def markdown_preview_v3(request): + if not request.user.is_authenticated(): + return HttpResponseForbidden( + 'This service is only available to logged-in users.') + + data = request.POST.get('data', None) + html = site_markup(data) if data else '' + if html: + try: + image_check(html) + except ImageCheckError as ex: + html = PREVIEW_UNAVAILABLE.format(ex) + + return HttpResponse(html) diff -r 1ac847818aea -r 110bbc78a482 gcalendar/forms.py --- a/gcalendar/forms.py Wed May 11 22:00:44 2016 -0500 +++ b/gcalendar/forms.py Sun May 29 23:09:23 2016 -0500 @@ -64,17 +64,22 @@ class EventEntryForm(forms.ModelForm): - what = forms.CharField(widget=forms.TextInput(attrs={'size': 60})) - start_date = forms.DateField(widget=forms.TextInput(attrs={'size': 10})) - start_time = forms.TimeField(required=False, widget=forms.Select(choices=TIME_CHOICES)) - end_date = forms.DateField(widget=forms.TextInput(attrs={'size': 10})) - end_time = forms.TimeField(required=False, widget=forms.Select(choices=TIME_CHOICES)) + what = forms.CharField(label='Event Title') + start_date = forms.DateField(label='Start Date') + start_time = forms.TimeField(label='Start Time', required=False, + widget=forms.Select(choices=TIME_CHOICES)) + end_date = forms.DateField(label='End Date') + end_time = forms.TimeField(label='End Time', required=False, + widget=forms.Select(choices=TIME_CHOICES)) time_zone = forms.CharField(required=False, widget=forms.HiddenInput()) - where = forms.CharField(required=False, widget=forms.TextInput(attrs={'size': 60})) + where = forms.CharField( + label='Event Location', + required=False, + help_text='If applicable, please fill this out for an accurate Google map') description = forms.CharField( + label='Event Details', required=False, widget=forms.Textarea(attrs={ - 'class': 'markItUp smileyTarget', 'id': 'id_body', # needed for image related js })) diff -r 1ac847818aea -r 110bbc78a482 gcalendar/static/js/gcalendar.js --- a/gcalendar/static/js/gcalendar.js Wed May 11 22:00:44 2016 -0500 +++ b/gcalendar/static/js/gcalendar.js Sun May 29 23:09:23 2016 -0500 @@ -1,3 +1,46 @@ +function editorReplaceText(textArea, i, j, newText) { + textArea.value = textArea.value.substring(0, i) + newText + + textArea.value.substring(j); +} + +function editorWrapSelection(textArea, wrapText) { + if (wrapText.length == 0) return; + var i = textArea.selectionStart; + var j = textArea.selectionEnd; + if (i == j) return; + var selection = textArea.value.substring(i, j); + var newText = wrapText + selection + wrapText; + editorReplaceText(textArea, i, j, newText); + textArea.focus(); + textArea.setSelectionRange(i, j + 2 * wrapText.length); +} + +function editorPrependLines(textArea, s) { + if (s.length == 0) return; + var i = textArea.selectionStart; + var j = textArea.selectionEnd; + var newText = s; + var selection = textArea.value.substring(i, j); + newText += selection.replace(/\n/gm, '\n' + s); + editorReplaceText(textArea, i, j, newText); +} + +function editorLink(textArea) { + var i = textArea.selectionStart; + var j = textArea.selectionEnd; + var url = window.prompt("Please enter a URL:", "http://"); + if (!url) return; + var link; + if (i == j) { + link = '[Link](' + url + ')'; + } else { + var selection = textArea.value.substring(i, j); + link = '[' + selection + '](' + url + ')'; + } + editorReplaceText(textArea, i, j, link); + textArea.focus(); +} + $(document).ready(function() { $('#id_start_date').datepicker({constrainInput: true, dateFormat: 'mm/dd/yy', @@ -19,15 +62,73 @@ } } }); - if ($('#id_all_day:checked').length) - { - $('#id_start_time').hide(); - $('#id_end_time').hide(); - $('#id_tz_stuff').hide(); + if ($('#id_all_day:checked').length) { + $('.all-day-hide').hide(); } $('#id_all_day').click(function () { - $('#id_start_time').toggle(); - $('#id_end_time').toggle(); - $('#id_tz_stuff').toggle(); - }); + $('.all-day-hide').toggle(); + }); + + var editorPanel = $('#editor-panel textarea'); + var previewPanel = $('#preview-panel'); + previewPanel.css('height', editorPanel.css('height')); + var observer = new MutationObserver(function(mutations) { + if (previewPanel.is(':visible')) { + alert(editorPanel[0].value); + $.ajax({ + url: '/comments/markdown/v3/', + method: 'POST', + data: {'data': editorPanel[0].value}, + dataType: 'html', + success: function(data, textStatus) { + alert(data); + previewPanel.html(data); + }, + error: function (xhr, textStatus, ex) { + alert('Oops, an error occurred: ' + xhr.statusText + ' - ' + + xhr.responseText); + } + }); + } + }); + var target = document.getElementById('preview-panel'); + observer.observe(target, {attributes: true}); + + // Editor stuff + $('.v3-editor').each(function (index) { + var $this = $(this); + var textArea = $this.find('textarea')[0]; + $this.find('.editor-bold').click(function () { + editorWrapSelection(textArea, '**'); + return false; + }); + $this.find('.editor-italic').click(function () { + editorWrapSelection(textArea, '_'); + return false; + }); + $this.find('.editor-strike').click(function () { + editorWrapSelection(textArea, '---'); + return false; + }); + $this.find('.editor-link').click(function () { + editorLink(textArea); + return false; + }); + $this.find('.editor-quote').click(function () { + editorPrependLines(textArea, '> '); + return false; + }); + $this.find('.editor-code').click(function () { + editorPrependLines(textArea, ' '); + return false; + }); + $this.find('.editor-bullet').click(function () { + editorPrependLines(textArea, '* '); + return false; + }); + $this.find('.editor-number').click(function () { + editorPrependLines(textArea, '1. '); + return false; + }); + }); }); diff -r 1ac847818aea -r 110bbc78a482 gcalendar/static/js/gcalendar_edit.js --- a/gcalendar/static/js/gcalendar_edit.js Wed May 11 22:00:44 2016 -0500 +++ b/gcalendar/static/js/gcalendar_edit.js Sun May 29 23:09:23 2016 -0500 @@ -9,8 +9,8 @@ data: { id : RegExp.$1 }, dataType: 'text', success: function (id) { - var id = '#gcal-' + id; - $(id).parents('li').hide('normal'); + var rowId = '#gcal-row-' + id; + $(rowId).fadeOut(800); }, error: function (xhr, textStatus, ex) { alert('Oops, an error occurred. ' + xhr.statusText + ' - ' + diff -r 1ac847818aea -r 110bbc78a482 gcalendar/views.py --- a/gcalendar/views.py Wed May 11 22:00:44 2016 -0500 +++ b/gcalendar/views.py Sun May 29 23:09:23 2016 -0500 @@ -3,8 +3,9 @@ """ from django.contrib.auth.decorators import login_required +from django.core.exceptions import PermissionDenied +from django.core.paginator import InvalidPage from django.core.urlresolvers import reverse -from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from django.http import HttpResponse from django.http import HttpResponseBadRequest from django.http import HttpResponseForbidden @@ -13,6 +14,8 @@ from django.shortcuts import get_object_or_404 from django.shortcuts import render +from core.functions import get_page +from core.paginator import DiggPaginator from gcalendar.forms import EventEntryForm from gcalendar.models import Event @@ -26,6 +29,7 @@ return render(request, 'gcalendar/index.html', { 'tz': tz, + 'V3_DESIGN': True, }) @@ -45,6 +49,7 @@ return render(request, 'gcalendar/event.html', { 'title': 'Add Calendar Event', 'form': form, + 'V3_DESIGN': True, }) @@ -58,17 +63,16 @@ def edit_events(request): events = Event.objects.filter(user=request.user, status=Event.ON_CAL).\ order_by('-start_date') - paginator = Paginator(events, 25) - num = request.GET.get('page') + paginator = DiggPaginator(events, 25, body=5, tail=2, margin=3, padding=2) + num = get_page(request.GET) try: page = paginator.page(num) - except PageNotAnInteger: - page = paginator.page(1) - except EmptyPage: - page = paginator.page(paginator.num_pages) + except InvalidPage: + raise Http404 return render(request, 'gcalendar/edit.html', { 'page': page, + 'V3_DESIGN': True, }) @@ -76,7 +80,7 @@ def edit_event(request, event_id): event = get_object_or_404(Event, pk=event_id) if event.user != request.user: - raise Http404 + raise PermissionDenied if request.method == 'POST': form = EventEntryForm(request.POST, instance=event) @@ -105,11 +109,11 @@ def delete_event(request): """This view marks an event for deletion. It is called via AJAX.""" if request.user.is_authenticated(): - id = request.POST.get('id', None) - if id is None or not id.isdigit(): + event_id = request.POST.get('id') + if event_id is None or not event_id.isdigit(): return HttpResponseBadRequest() try: - event = Event.objects.get(pk=id) + event = Event.objects.get(pk=event_id) except Event.DoesNotExist: return HttpResponseBadRequest() if request.user != event.user: @@ -117,6 +121,6 @@ event.status = Event.DEL_REQ event.save() - return HttpResponse(id) + return HttpResponse(event_id, content_type="text/plain") return HttpResponseForbidden() diff -r 1ac847818aea -r 110bbc78a482 sg101/templates/gcalendar/edit.html --- a/sg101/templates/gcalendar/edit.html Wed May 11 22:00:44 2016 -0500 +++ b/sg101/templates/gcalendar/edit.html Sun May 29 23:09:23 2016 -0500 @@ -1,30 +1,58 @@ -{% extends 'base.html' %} +{% extends 'v3/base.html' %} {% load static from staticfiles %} {% block title %}Edit Calendar Events{% endblock %} +{% block content %} + + + +

Edit Calendar Events

+{% if page.object_list %} +

+You have the following events on our calendar. Click on the event title to edit +it, or click the to delete it. Your changes will +be submitted to the site staff for approval, and won't be reflected on the +Google calendar until then. The approval process usually takes less than 12 +hours. Thanks for helping to keep our calendar up to date! +

+ + + + + + + + {% for event in page.object_list %} + + + + + + {% endfor %} + +
DateEvent TitleActions
{{ event.start_date|date:"M d, Y"}}{{ event.what }} + +
+
+ Please don't worry about deleting old events. It's nice to have + a historical record of events on the calendar. +
+{% include 'core/v3/pagination.html' %} +{% else %} +
+You either have no events on our calendar, or all your events have pending +changes that require admin review. +
+{% endif %} +{% endblock %} {% block custom_js %} {% endblock %} -{% block content %} - -

Edit Calendar Events

-{% if page.object_list %} -

You have the following events on our calendar. Click on the event title to edit it, or click the -Cross to delete it. -Your changes will be submitted to the site staff for approval, and won't be reflected on the Google -calendar until then. The approval process usually takes less than 12 hours. Thanks for helping to -keep our calendar up to date! -

- -{% include 'core/django_pagination.html' with page_obj=page %} -{% else %} -

You either have no events on our calendar, or all your events have pending changes -that require admin review.

-{% endif %} -{% endblock %} diff -r 1ac847818aea -r 110bbc78a482 sg101/templates/gcalendar/event.html --- a/sg101/templates/gcalendar/event.html Wed May 11 22:00:44 2016 -0500 +++ b/sg101/templates/gcalendar/event.html Sun May 29 23:09:23 2016 -0500 @@ -1,19 +1,21 @@ -{% extends 'base.html' %} +{% extends 'v3/base.html' %} {% load core_tags %} {% load script_tags %} {% load static from staticfiles %} {% block title %}{{ title }}{% endblock %} {% block custom_css %} +{% css_tags 'jquery-ui markitup' %} {% endblock %} -{% block custom_js %} -{% script_tags 'jquery-ui markitup' %} - - - -{% endblock %} + {% block content %} - + +

{{ title }}

Use this form to add or change an event on our calendar. Please note the following:

+ +
{% csrf_token %} + {{ form.non_field_errors }} + {{ form.what.errors }} +
+
+ +
+
+ {{ form.start_date.errors }} + {{ form.start_time.errors }} +
+
+ +
+
+ +
+
+ {{ form.end_date.errors }} + {{ form.end_time.errors }} +
+
+ +
+
+ +
+
+ {{ form.all_day.errors }} +
+
+ {{ form.all_day }} + +
+
+
+ Time Zone + {{ form.time_zone.errors }} +
+
+ +
+
+ +
+
+ {{ form.time_zome }} +
+ {{ form.where.errors }} +
+
+ +

+ {{ form.where.help_text }} +

+
+
+ {{ form.description.errors }} +
+
+ + +
+
+ + + + + {{ form.description }} +
+
+

Suspendisse dictum feugiat nisl ut dapibus. Vivamus hendrerit arcu sed erat molestie vehicula. Ut in nulla enim. Phasellus molestie magna non est bibendum non venenatis nisl tempor. Sed auctor neque eu tellus rhoncus ut eleifend nibh porttitor.

+
+
+
+
+ {% if form.create_forum_thread %} + {{ form.create_forum_thread.errors }} +
+
+ {{ form.create_forum_thread }} + +
+
+ {% endif %} + {{ form.time_zone }} + +
+
+ + + {% endblock %} + +{% block custom_js %} +{% js_tags 'jquery-ui markitup' %} + + + +{% endblock %} diff -r 1ac847818aea -r 110bbc78a482 sg101/templates/gcalendar/index.html --- a/sg101/templates/gcalendar/index.html Wed May 11 22:00:44 2016 -0500 +++ b/sg101/templates/gcalendar/index.html Sun May 29 23:09:23 2016 -0500 @@ -1,18 +1,29 @@ -{% extends 'base.html' %} +{% extends 'v3/base.html' %} {% load static from staticfiles %} {% block title %}Event Calendar{% endblock %} {% block content %}

SurfGuitar101 Event Calendar

-Welcome to the SG101 event calendar! Our users can add events to this -calendar. Please see the links below the calendar to add, modify, or delete events. +Welcome to the SG101 event calendar! +Our users can add events to this calendar. +{% if user.is_authenticated %} + Please click the buttons below to add, modify, or delete events. +{% else %} + Please login + to add, modify, or delete events. +{% endif %}

-
-

- This calendar is now aggregating several Google calendars, both from - SurfGuitar101 and other friends in the surf music world. This allows us to give you - more information without duplicating efforts in the community. -

+
+
+
+ +
+
+ This calendar is now aggregating several Google calendars, both from + SurfGuitar101 and other friends in the surf music world. This allows us to give you + more information without duplicating efforts in the community. +
+

By default we show you all events from all calendars. Too much information? No problem, just use the pull-down menu in the upper right corner of the @@ -26,23 +37,16 @@

{% else %}

Please note: all times shown are in the {{ tz }} time zone. Please -login to view the times based on the time zone set in your profile.

+login to view the times based on the time zone set in your profile.

{% endif %} +
- - +
+ {% endblock %}