manager: add an asset management page to remove images (#6590)
This commit is contained in:
parent
36175f47bd
commit
b5fee77f5e
|
@ -205,3 +205,51 @@ p#redirection {
|
|||
.buttons .delete {
|
||||
float: right;
|
||||
}
|
||||
|
||||
div#assets-thumbs {
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div#asset-show {
|
||||
width: 48%;
|
||||
float: right;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
div#assets-thumbs ul {
|
||||
-moz-column-width: 100px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div#assets-thumbs ul li {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div#assets-thumbs a {
|
||||
border: none;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
div#assets-thumbs a:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
div#assets-thumbs img {
|
||||
padding: 5px;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
div#asset-img {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div#asset-img img {
|
||||
max-width: 90%;
|
||||
padding: 5px;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
div#asset-cmds {
|
||||
text-align: right;
|
||||
}
|
||||
|
|
|
@ -134,4 +134,22 @@ $(function() {
|
|||
$('a.menu-opener').on('click', function() {
|
||||
$('#appbar .menu').toggle();
|
||||
});
|
||||
$('#assets-thumbs a').on('click', function() {
|
||||
$('#asset-img').empty().append($('<img src="' + $(this).attr('href') + '"/>'));
|
||||
$('#asset-cmds').show();
|
||||
return false;
|
||||
});
|
||||
$('#asset-delete').on('click', function() {
|
||||
var img_src = $('#asset-img img').attr('src');
|
||||
var thumb_item = $('#assets-thumbs a[href="' + img_src + '"]').parent();
|
||||
console.log('thumb item:', thumb_item);
|
||||
var img_orig = $(thumb_item).data('orig');
|
||||
$(thumb_item).hide();
|
||||
$('#asset-img').empty();
|
||||
$('#asset-cmds').hide();
|
||||
$.ajax({
|
||||
url: $(this).data('asset-delete-url'),
|
||||
data: {'img_orig': img_orig}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
{% extends "combo/manager_base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block appbar %}
|
||||
<h2>{% trans 'Assets' %}</h2>
|
||||
{% endblock %}
|
||||
|
||||
{% block more-user-links %}
|
||||
{{ block.super }}
|
||||
<a href="{% url 'combo-manager-assets' %}">{% trans 'Assets' %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if not files %}
|
||||
<div class="big-msg-info">
|
||||
{% blocktrans %}
|
||||
This site doesn't have any asset yet. You can add some directly when editing
|
||||
pages, in the "Upload Image" dialog.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
|
||||
<div id="assets-browser">
|
||||
<div id="assets-thumbs" class="navigation">
|
||||
<ul>
|
||||
{% for file in files %}
|
||||
<li data-orig="{{ file.orig }}">
|
||||
<a {% if file.is_image %}class="thumb"{% endif %} href="{{ file.src }}">
|
||||
{% if file.is_image %}
|
||||
<img src="{{ file.thumb }}" style="max-width: 75px;"/>
|
||||
{% else %}
|
||||
{{ file.thumb }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="asset-show">
|
||||
<div id="asset-img">
|
||||
</div>
|
||||
<div id="asset-cmds" style="display: none;">
|
||||
<button data-asset-delete-url="{% url 'combo-manager-asset-delete' %}"
|
||||
id="asset-delete">{% trans 'Delete' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -6,6 +6,7 @@
|
|||
<a class="menu-opener">☰</a>
|
||||
<a rel="popup" href="{% url 'combo-manager-page-add' %}">{% trans 'New' %}</a>
|
||||
<ul class="menu" style="display: none">
|
||||
<li><a href="{% url 'combo-manager-assets' %}">{% trans 'Assets' %}</a></li>
|
||||
<li><a href="{% url 'combo-manager-site-export' %}">{% trans 'Export Site' %}</a></li>
|
||||
<li><a href="{% url 'combo-manager-site-import' %}">{% trans 'Import Site' %}</a></li>
|
||||
{% for extra_action in extra_actions %}
|
||||
|
|
|
@ -53,5 +53,7 @@ urlpatterns = patterns('combo.views',
|
|||
name='combo-manager-cell-order'),
|
||||
url(r'^pages/order$', views.page_order,
|
||||
name='combo-manager-page-order'),
|
||||
url(r'^assets/$', views.assets, name='combo-manager-assets'),
|
||||
url(r'^assets/delete$', views.asset_delete, name='combo-manager-asset-delete'),
|
||||
(r'^ckeditor/', include('ckeditor.urls')),
|
||||
)
|
||||
|
|
|
@ -16,15 +16,18 @@
|
|||
|
||||
import json
|
||||
|
||||
import ckeditor
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.files.storage import default_storage
|
||||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||
from django.core.urlresolvers import reverse, reverse_lazy
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.shortcuts import redirect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.decorators.csrf import requires_csrf_token
|
||||
from django.views.generic import (RedirectView, DetailView,
|
||||
from django.views.generic import (TemplateView, RedirectView, DetailView,
|
||||
CreateView, UpdateView, ListView, DeleteView, FormView)
|
||||
|
||||
from combo.data.models import Page, CellBase, UnlockMarkerCell
|
||||
|
@ -268,3 +271,39 @@ def page_get_additional_label(request, page_pk, cell_reference):
|
|||
response = HttpResponse(content_type='application/json')
|
||||
json.dump({'label': cell.get_additional_label()}, response)
|
||||
return response
|
||||
|
||||
|
||||
class Assets(TemplateView):
|
||||
template_name = 'combo/manager_assets.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(Assets, self).get_context_data(**kwargs)
|
||||
context['files'] = []
|
||||
for filename in ckeditor.views.get_image_files(self.request.user):
|
||||
src = ckeditor.utils.get_media_url(filename)
|
||||
if getattr(settings, 'CKEDITOR_IMAGE_BACKEND', None):
|
||||
thumb = ckeditor.utils.get_media_url(
|
||||
ckeditor.utils.get_thumb_filename(filename))
|
||||
else:
|
||||
thumb = src
|
||||
context['files'].append({
|
||||
'thumb': thumb,
|
||||
'src': src,
|
||||
'is_image': ckeditor.views.is_image(src),
|
||||
'orig': filename,
|
||||
})
|
||||
return context
|
||||
|
||||
assets = Assets.as_view()
|
||||
|
||||
def asset_delete(request):
|
||||
img_orig = request.GET['img_orig']
|
||||
if '..' in img_orig:
|
||||
raise PermissionDenied() # better safe than sorry
|
||||
base_path = settings.CKEDITOR_UPLOAD_PATH
|
||||
if getattr(settings, 'CKEDITOR_RESTRICT_BY_USER', False):
|
||||
base_path = os.path.join(base_path, user.username)
|
||||
if not img_orig.startswith(base_path):
|
||||
raise PermissionDenied()
|
||||
default_storage.delete(img_orig);
|
||||
return HttpResponse(status=204)
|
||||
|
|
|
@ -8,3 +8,6 @@ COMBO_WCS_SITES = {
|
|||
'other': {'title': 'test2', 'url': 'http://127.0.0.2:8999/',
|
||||
'secret': 'combo', 'orig': 'combo'},
|
||||
}
|
||||
|
||||
import tempfile
|
||||
MEDIA_ROOT = tempfile.mkdtemp('combo-test')
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
import base64
|
||||
import os
|
||||
import StringIO
|
||||
|
||||
from django.core.files.storage import default_storage
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
import pytest
|
||||
from webtest import TestApp
|
||||
|
@ -104,3 +110,21 @@ def test_logout(admin_user):
|
|||
app = login(TestApp(application))
|
||||
app.get('/logout/')
|
||||
assert app.get('/manage/', status=302).location == 'http://localhost:80/login/?next=/manage/'
|
||||
|
||||
def test_asset_management(admin_user):
|
||||
app = login(TestApp(application))
|
||||
resp = app.get('/manage/assets/')
|
||||
assert 'have any asset yet.' in resp.body
|
||||
|
||||
filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'test.png')
|
||||
pix = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
|
||||
default_storage.save(filepath, StringIO.StringIO(base64.decodestring(pix)))
|
||||
assert os.path.exists(default_storage.path(filepath))
|
||||
|
||||
resp = app.get('/manage/assets/')
|
||||
assert 'have any asset yet.' not in resp.body
|
||||
|
||||
app.get('/manage/assets/delete?img_orig=%s' % filepath, status=204)
|
||||
assert not os.path.exists(default_storage.path(filepath))
|
||||
|
||||
app.get('/manage/assets/delete?img_orig=/foo.png', status=403)
|
||||
|
|
Loading…
Reference in New Issue