Added an easy system to update covers using a simple google image search with the first four results with a one-click update system
This commit is contained in:
parent
4c306eb065
commit
8f91f9d30f
|
@ -1,10 +1,13 @@
|
||||||
from django.conf.urls import patterns, url
|
from django.conf.urls import patterns, url
|
||||||
|
|
||||||
from .views import VolumeChangeSeriesView
|
from .views import VolumeChangeSeriesView, VolumeChangeCoverView
|
||||||
|
|
||||||
urlpatterns = patterns(
|
urlpatterns = patterns(
|
||||||
'',
|
'',
|
||||||
url(r'^manga/volume/change_series/$',
|
url(r'^manga/volume/change_series/$',
|
||||||
VolumeChangeSeriesView.as_view(),
|
VolumeChangeSeriesView.as_view(),
|
||||||
name="_admin.manga.volume.change_series"),
|
name="_admin.manga.volume.change_series"),
|
||||||
|
url(r'^manga/volume/cover/(?P<volume_pk>\d+)/$',
|
||||||
|
VolumeChangeCoverView.as_view(),
|
||||||
|
name="_admin.manga.volume.cover"),
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,6 +3,8 @@ from django.template import RequestContext
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
from filer.models import Image
|
||||||
from shelfzilla.views import View
|
from shelfzilla.views import View
|
||||||
from shelfzilla.apps.manga.models import Volume, Series
|
from shelfzilla.apps.manga.models import Volume, Series
|
||||||
|
|
||||||
|
@ -42,3 +44,46 @@ class VolumeChangeSeriesView(View):
|
||||||
messages.success(request, _('Volume series changed'))
|
messages.success(request, _('Volume series changed'))
|
||||||
|
|
||||||
return HttpResponseRedirect('/admin/manga/volume/')
|
return HttpResponseRedirect('/admin/manga/volume/')
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeChangeCoverView(View):
|
||||||
|
@csrf_exempt
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
if not request.user.is_staff:
|
||||||
|
return HttpResponseForbidden()
|
||||||
|
else:
|
||||||
|
return super(VolumeChangeCoverView, self).dispatch(
|
||||||
|
request, *args, **kwargs)
|
||||||
|
|
||||||
|
def post(self, request, volume_pk):
|
||||||
|
try:
|
||||||
|
volume = Volume.objects.get(pk=volume_pk)
|
||||||
|
if 'cover_url' in request.POST:
|
||||||
|
cover_url = request.POST['cover_url']
|
||||||
|
|
||||||
|
from django.core.files.temp import NamedTemporaryFile
|
||||||
|
from django.core.files import File
|
||||||
|
import urllib2
|
||||||
|
|
||||||
|
|
||||||
|
cover_temp = NamedTemporaryFile(delete=True)
|
||||||
|
cover_temp.write(urllib2.urlopen(cover_url).read())
|
||||||
|
cover_temp.flush()
|
||||||
|
|
||||||
|
new_cover, is_new = Image.objects.get_or_create(file=File(cover_temp))
|
||||||
|
# new_cover._move_file()
|
||||||
|
|
||||||
|
if volume.cover:
|
||||||
|
volume.cover.delete()
|
||||||
|
volume.cover = new_cover
|
||||||
|
volume.save()
|
||||||
|
|
||||||
|
messages.success(request, _('Volume series changed'))
|
||||||
|
else:
|
||||||
|
messages.error(request, _('Cover url to update not found.'))
|
||||||
|
except Volume.DoesNotExist:
|
||||||
|
messages.error(request, _('Volume not found.'))
|
||||||
|
|
||||||
|
return HttpResponseRedirect(
|
||||||
|
'/admin/manga/volume/{}/'.format(volume_pk))
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@ class SeriesAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
|
||||||
suit_form_tabs = (
|
suit_form_tabs = (
|
||||||
('general', _('General')),
|
('general', _('General')),
|
||||||
('volumes', _('Volumes')),
|
('volumes', _('Volumes')),
|
||||||
|
('cover', _('Cover')),
|
||||||
('review', _('Review')),
|
('review', _('Review')),
|
||||||
('advanced', _('Advanced')),
|
('advanced', _('Advanced')),
|
||||||
)
|
)
|
||||||
|
@ -133,6 +134,7 @@ class VolumeAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
|
||||||
|
|
||||||
suit_form_tabs = (
|
suit_form_tabs = (
|
||||||
('general', _('General')),
|
('general', _('General')),
|
||||||
|
('cover', _('Cover')),
|
||||||
('review', _('Review')),
|
('review', _('Review')),
|
||||||
('advanced', _('Advanced')),
|
('advanced', _('Advanced')),
|
||||||
)
|
)
|
||||||
|
@ -154,6 +156,10 @@ class VolumeAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
suit_form_includes = (
|
||||||
|
('_admin/volumes/includes/cover.html', 'top', 'cover'),
|
||||||
|
)
|
||||||
|
|
||||||
def change_series(self, request, queryset):
|
def change_series(self, request, queryset):
|
||||||
selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
|
selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
|
|
|
@ -240,8 +240,11 @@ def series_delete_folder(sender, instance, using, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def volume_delete_cover(sender, instance, **kwargs):
|
def volume_delete_cover(sender, instance, **kwargs):
|
||||||
if instance.cover:
|
try:
|
||||||
instance.cover.delete()
|
if instance.cover:
|
||||||
|
instance.cover.delete()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
post_save.connect(series_check_filer, sender=Series)
|
post_save.connect(series_check_filer, sender=Series)
|
||||||
post_save.connect(volume_check_filer, sender=Volume)
|
post_save.connect(volume_check_filer, sender=Volume)
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
{% load i18n %}
|
||||||
|
<table class="table table-striped table-bordered table-hover table-condensed">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>{% trans "Actual cover:" %}</td>
|
||||||
|
<td>{% trans "Search" %}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td width="50%" align="center"><img src="{{ original.cover.url }}" /></td>
|
||||||
|
<td>
|
||||||
|
<input type="text" id="GIMG-query" value="{{ original.series.name }} {{ original.publisher.name }} tomo {{ original.number }} {{ original.name }}" />
|
||||||
|
<input type="text" id="GIMG-limit" value="5" maxlength="2" size="2" style="width: 30px;" />
|
||||||
|
<button class="btn btn-info" id="GIMG-submit" type="button">{% trans "Search" %}</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="GIMG-results" colspan="2"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
var submitButton = $('#GIMG-submit');
|
||||||
|
var results = $('#GIMG-results');
|
||||||
|
var searchQuery = function() { return $('#GIMG-query').val(); };
|
||||||
|
var searchLimit = function() { return $('#GIMG-limit').val(); };
|
||||||
|
$('#GIMG-query').keypress(function(event) {
|
||||||
|
if (event.keyCode == 13) {
|
||||||
|
event.preventDefault();
|
||||||
|
submitButton.click()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
submitButton.on('click', function() {
|
||||||
|
$.getJSON(
|
||||||
|
'http://google-images-api.eu01.aws.af.cm/',
|
||||||
|
{ q: searchQuery(), limit: searchLimit() },
|
||||||
|
function(data) {
|
||||||
|
results.html('');
|
||||||
|
console.log(data.items);
|
||||||
|
for (var i = 0; i < data.items.length; i++) {
|
||||||
|
var image = data.items[i];
|
||||||
|
|
||||||
|
var containerElement = $('<div />');
|
||||||
|
containerElement.css('text-align', 'center')
|
||||||
|
.css('width', '25%')
|
||||||
|
.css('float', 'left');
|
||||||
|
|
||||||
|
var imageElement = $('<img />');
|
||||||
|
imageElement.attr('src', image);
|
||||||
|
/* imageElement.on('error', function(e) {
|
||||||
|
$(this).remove();
|
||||||
|
})*/
|
||||||
|
|
||||||
|
var formElement = $('<form />');
|
||||||
|
formElement.attr('action', '/_admin/manga/volume/cover/{{ original.pk }}/');
|
||||||
|
formElement.attr('method', 'post');
|
||||||
|
|
||||||
|
var buttonElement = $('<button />');
|
||||||
|
buttonElement.attr('type', 'submit');
|
||||||
|
buttonElement.addClass('btn');
|
||||||
|
buttonElement.text('{% trans "Update with this" %}')
|
||||||
|
|
||||||
|
var urlElement = $('<input />');
|
||||||
|
urlElement.attr('type', 'hidden');
|
||||||
|
urlElement.attr('name', 'cover_url');
|
||||||
|
urlElement.val(image);
|
||||||
|
|
||||||
|
formElement.append(buttonElement);
|
||||||
|
formElement.append(urlElement);
|
||||||
|
|
||||||
|
containerElement.append(formElement);
|
||||||
|
containerElement.append(imageElement);
|
||||||
|
|
||||||
|
results.append(containerElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
Reference in New Issue