Skip to content
This repository has been archived by the owner on Jul 25, 2018. It is now read-only.

663576 Basic Snippet Body Editor #1

Merged
merged 7 commits into from
Jun 16, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 57 additions & 33 deletions apps/homesnippets/admin.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import os
from datetime import datetime

from django.contrib import admin, messages
from django import forms
from django.contrib import admin, messages
from django.db import models
from django.http import HttpResponse
from django.template.loader import render_to_string
from django.utils.encoding import smart_unicode
from django.utils.safestring import mark_safe

from django.db.models import get_app, get_apps, get_model, get_models
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response

from smuggler.settings import SMUGGLER_FORMAT, SMUGGLER_FIXTURE_DIR
from smuggler.utils import (get_excluded_models_set, get_file_list,
save_uploaded_file_on_disk, serialize_to_response,
superuser_required)
from smuggler.settings import SMUGGLER_FORMAT
from smuggler.utils import serialize_to_response

from homesnippets.models import Snippet, ClientMatchRule

Expand All @@ -28,54 +25,59 @@ def dump_selected(modeladmin, request, queryset):

dump_selected.short_description = "Dump selected objects as JSON data"


def dump_selected_snippets(modeladmin, request, queryset):
"""Produce a smuggler dump for a selected set of snippets, along with
associated client match rules."""
snippets = queryset.all()

# Assemble a unique set of client match rules used by selected snippets.
rules = dict( )
rules = dict()
for s in snippets:
for rule in s.client_match_rules.all():
rules[rule.pk] = rule

# Combine set of rules and snippets for output
objects = rules.values() + list( snippets )
objects = rules.values() + list(snippets)

filename = '%s-%s_%s.%s' % ('homesnippets', 'snippets',
datetime.now().isoformat(), SMUGGLER_FORMAT)
response = HttpResponse(mimetype="text/plain")
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return serialize_to_response(objects, response)

dump_selected_snippets.short_description = "Dump selected snippets (and client match rules) as JSON data"
dump_selected_snippets.short_description = "Dump selected snippets (and " \
"client match rules) as JSON data"


def disable_selected_snippets(modeladmin, request, queryset):
cnt = 0
for snippet in queryset.all():
snippet.disabled = True
snippet.save()
cnt += 1
messages.add_message(request, messages.INFO,
messages.add_message(request, messages.INFO,
('%(cnt)d snippet(s) disabled') % dict(cnt=cnt))

disable_selected_snippets.short_description = "Disable selected snippets"


def enable_selected_snippets(modeladmin, request, queryset):
cnt = 0
for snippet in queryset.all():
snippet.disabled = False
snippet.save()
cnt += 1
messages.add_message(request, messages.INFO,
messages.add_message(request, messages.INFO,
('%(cnt)d snippet(s) enabled') % dict(cnt=cnt))

enable_selected_snippets.short_description = "Enable selected snippets"


class ClientMatchRuleAdmin(admin.ModelAdmin):
change_list_template = 'smuggler/change_list.html'

actions = [ dump_selected ]
actions = [dump_selected]
dump_name = 'clientmatchrules'

list_per_page = 250
Expand All @@ -84,9 +86,9 @@ class ClientMatchRuleAdmin(admin.ModelAdmin):
'description',
'related_snippets',
'exclude',
'startpage_version', 'name', 'version',
'startpage_version', 'name', 'version',
'locale',
'appbuildid', 'build_target',
'appbuildid', 'build_target',
'channel', 'os_version', 'distribution', 'distribution_version',
'modified',
)
Expand All @@ -95,23 +97,39 @@ class ClientMatchRuleAdmin(admin.ModelAdmin):
)

list_filter = (
'name', 'version', 'os_version',
'name', 'version', 'os_version',
'appbuildid', 'build_target', 'channel', 'distribution',
'locale',
'locale',
)

admin.site.register(ClientMatchRule, ClientMatchRuleAdmin)


class SnippetBodyWidget(forms.Textarea):
class Media:
css = {
'all': ('snippetBodyWidget.css',)
}
js = ('jquery-1.6.1.min.js', 'jquery.easytabs.min.js',
'snippetBodyWidget.js')

def render(self, name, value, attrs=None):
textarea = super(SnippetBodyWidget, self).render(name, value, attrs)
widget = render_to_string('snippetBodyWidget.html',
{"textarea": textarea})
return mark_safe(smart_unicode(widget))


class SnippetAdmin(admin.ModelAdmin):
change_list_template = 'smuggler/change_list.html'

actions = [
actions = [
dump_selected_snippets,
disable_selected_snippets,
enable_selected_snippets,
]
dump_name = 'snippets'

save_on_top = True
actions_on_bottom = True

Expand All @@ -126,20 +144,20 @@ class SnippetAdmin(admin.ModelAdmin):
'client_match_rules',
)

fields = (
'name', 'body',
fields = (
'name', 'body',
'preview', 'disabled',
'priority', 'pub_start', 'pub_end',
'client_match_rules',
'priority', 'pub_start', 'pub_end',
'client_match_rules',
)

list_per_page = 250
list_display = (
'name',

list_display = (
'name',
'disabled',
'priority', 'pub_start', 'pub_end',
'modified'
'modified'
)

list_links = (
Expand All @@ -151,12 +169,18 @@ class SnippetAdmin(admin.ModelAdmin):
'pub_start', 'pub_end',
)

filter_horizontal = ( 'client_match_rules', )
filter_horizontal = ('client_match_rules',)

formfield_overrides = {
models.ManyToManyField: {
"widget": forms.widgets.SelectMultiple(attrs={"size":50})
"widget": forms.widgets.SelectMultiple(attrs={"size": 50})
}
}

def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'body':
kwargs['widget'] = SnippetBodyWidget
return super(SnippetAdmin, self).formfield_for_dbfield(db_field,
**kwargs)

admin.site.register(Snippet, SnippetAdmin)
23 changes: 23 additions & 0 deletions apps/homesnippets/templates/snippetBodyWidget.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div id="snippet-editor">
<ul id="snippet-tabs">
<li><a href="#snippet-basic">{{ _('Basic') }}</a></li>
<li><a href="#snippet-advanced">{{ _('Advanced') }}</a></li>
</ul>
<div id="snippet-basic" class="panel-container">
<div>{{ _('Snippet Preview') }}</div>
<div id="snippet-preview"></div>
<div id="snippet-basic-inputs">
<label for="snippet-icon-url">{{ _('Icon URL (png only)') }}:</label>
<input type="text" id="snippet-icon-url" />
<div>
<button type="button" id="snippet-embed-button">{{ _('Change Icon') }}</button>
</div>
<label for="snippet-text">{{ _('Text') }}:</label>
<textarea id="snippet-text"></textarea>
</div>
<div>{{ _('Add a link using wiki-syntax') }}: <code>[http://www.mozilla.com|{{ _('Link Text') }}]</code></div>
</div>
<div id="snippet-advanced" class="panel-container">
{{ textarea }}
</div>
</div>
1 change: 1 addition & 0 deletions apps/homesnippets/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
url(r'^preview/(?P<startpage_version>[^/]+)/(?P<name>[^/]+)/(?P<version>[^/]+)/(?P<appbuildid>[^/]+)/(?P<build_target>[^/]+)/(?P<locale>[^/]+)/(?P<channel>[^/]+)/(?P<os_version>[^/]+)/(?P<distribution>[^/]+)/(?P<distribution_version>[^/]+)/$',
'view_snippets', name='preview_snippets', kwargs={'preview':True}),

url(r"^base64encode/(?P<url>.+)$", "base64_encode", name="base64_encode"),
url(r"^$", "index", name="index"),
)
49 changes: 30 additions & 19 deletions apps/homesnippets/views.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
"""
Views for home snippets server
"""
import random
from time import time, mktime, gmtime, strftime
import base64
import json
from time import gmtime, strftime
from urllib2 import urlopen, URLError

from django.conf import settings

from django.core.urlresolvers import reverse

from django.http import HttpResponseRedirect, HttpResponse
from django.http import HttpResponseForbidden, HttpResponseNotModified

from django.template import RequestContext

from django.views.decorators import http
from django.views.decorators.vary import vary_on_headers
from django.views.decorators.cache import cache_control, cache_page

from django.contrib.admin.views.decorators import staff_member_required
from django.http import HttpResponse, Http404
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.cache import cache_control

from homesnippets.models import Snippet

Expand All @@ -32,6 +26,7 @@ def index(request):
return render_to_response('index.html', {},
context_instance=RequestContext(request))


@cache_control(public=True, max_age=HTTP_MAX_AGE)
def handler404(request):
"""For 404's, just return a blank cacheable 200 OK response.
Expand All @@ -40,11 +35,12 @@ def handler404(request):
server as much.
"""
resp = HttpResponse('')
resp['Access-Control-Allow-Origin'] = '*'
resp['Access-Control-Allow-Origin'] = '*'
resp['Access-Control-Max-Age'] = HTTP_MAX_AGE
resp['Access-Control-Allow-Methods'] = 'GET, HEAD, OPTIONS'
return resp


def view_snippets(request, **kwargs):
"""Fetch and render snippets matching URL segment args"""

Expand All @@ -54,10 +50,10 @@ def view_snippets(request, **kwargs):
if len(snippets) == 0:
out_txt = ''
else:
out = [ snippet['body'] for snippet in snippets ]
out = [snippet['body'] for snippet in snippets]

out.append('<!-- content generated at %s -->' %
( strftime('%Y-%m-%dT%H:%M:%SZ', gmtime() ) ) )
(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime())))

out_txt = '<div class="snippet_set">%s</div>' % "\n\n".join(out)

Expand All @@ -69,13 +65,28 @@ def view_snippets(request, **kwargs):
resp['Cache-Control'] = 'public, must-revalidate, max-age=0'
else:
max_age = HTTP_MAX_AGE
resp['Cache-Control'] = 'public, max-age=%s' % ( HTTP_MAX_AGE )
resp['Cache-Control'] = 'public, max-age=%s' % (HTTP_MAX_AGE)

# TODO: bug 606555 - Get ACAO working with about:home?
resp['Access-Control-Allow-Origin'] = '*'
resp['Access-Control-Allow-Origin'] = '*'
resp['Access-Control-Max-Age'] = max_age
resp['Access-Control-Allow-Methods'] = 'GET, HEAD, OPTIONS'

resp['X-FRAME-OPTIONS'] = None

return resp

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two spaces before a function definition

run this code through check.py


@staff_member_required
def base64_encode(request, **kwargs):
"""Encode a remote image to base64, and output as JSON"""

url = kwargs['url']
try:
img_file = urlopen(url)
base64_str = base64.encodestring(img_file.read())
except (URLError, ValueError):
raise Http404

return HttpResponse(json.dumps({'img': base64_str}),
mimetype='applications/json')
18 changes: 18 additions & 0 deletions site_media/jquery-1.6.1.min.js

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions site_media/jquery.easytabs.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading