mirror of
https://github.com/ajurna/cbwebreader.git
synced 2025-12-06 14:17:19 +00:00
made major changes to interface.
can now mark comics as read! also added a recently added section.
This commit is contained in:
@@ -88,7 +88,7 @@ DATABASES = {
|
|||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'en-ie'
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
||||||
<script src="/static/js/bootstrap.min.js"></script>
|
<script src="/static/js/bootstrap.min.js"></script>
|
||||||
<script src="/static/js/jasny-bootstrap.min.js"></script>
|
<script src="/static/js/jasny-bootstrap.min.js"></script>
|
||||||
<script src="/static/js/jQuery-2.2.2.min.js"></script>
|
<script src="/static/js/jquery-2.2.2.min.js"></script>
|
||||||
<script src="/static/js/js.cookie.js"></script>
|
<script src="/static/js/js.cookie.js"></script>
|
||||||
<script type="text/javascript" src="https://cdn.datatables.net/t/bs/dt-1.10.11,b-colvis-1.1.2,r-2.0.2/datatables.min.js"></script>
|
<script type="text/javascript" src="https://cdn.datatables.net/t/bs/dt-1.10.11,b-colvis-1.1.2,r-2.0.2/datatables.min.js"></script>
|
||||||
{% block script %}
|
{% block script %}
|
||||||
|
|||||||
@@ -3,10 +3,19 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<form id="comic_form" method="post" action="/comic/edit/">
|
||||||
|
{% csrf_token %}
|
||||||
<table class="table table-bordered table-striped table-hover" id="comic_list">
|
<table class="table table-bordered table-striped table-hover" id="comic_list">
|
||||||
<caption><h2>Comics</h2></caption>
|
<caption><h2>Comics</h2> mark selected issues as:
|
||||||
|
<select name="func" id="func_selector">
|
||||||
|
<option value="choose">Choose...</option>
|
||||||
|
<option value="read">Read</option>
|
||||||
|
<option value="unread">Un-Read</option>
|
||||||
|
</select>
|
||||||
|
</caption>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th id="select-all"><input type="checkbox" id="select-all-cb"></th>
|
||||||
<th><center><span class="glyphicon glyphicon-file"></span></center></th>
|
<th><center><span class="glyphicon glyphicon-file"></span></center></th>
|
||||||
<th width="100%">File/Folder</th>
|
<th width="100%">File/Folder</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
@@ -20,30 +29,17 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<!--/.nav-collapse
|
</form>
|
||||||
<h2 class="center">Comics</h2>
|
|
||||||
<div class="list-group">
|
|
||||||
{% if file_list %}
|
|
||||||
{% for file in file_list %}
|
|
||||||
{% if file.isdir %}
|
|
||||||
<a href="/comic/{{ file.location }}/" class="glyphicon {{ file.icon }} list-group-item"> {{ file }}{{ file.label | safe }}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% if file.iscb %}
|
|
||||||
<a href="/comic/read/{{ file.location }}/{{ file.cur_page }}/" class="glyphicon {{ file.icon }} list-group-item"> {{ file }}{{ file.label | safe }}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
<p class="list-group-item">No comics.</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>-->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#comic_list').DataTable({
|
var table = $('#comic_list').DataTable({
|
||||||
"processing": true,
|
"processing": true,
|
||||||
|
"stateSave": true,
|
||||||
"ajax": {
|
"ajax": {
|
||||||
"type": "POST",
|
"type": "POST",
|
||||||
"url": "{{ json_url }}",
|
"url": "{{ json_url }}",
|
||||||
@@ -52,25 +48,68 @@ $(document).ready(function() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rowCallback": function( row, data, index ) {
|
"rowCallback": function( row, data, index ) {
|
||||||
var r = $(row)
|
var r = $(row);
|
||||||
r.attr('data-href', data['url']);
|
var cols = $('td:nth-child(n+2)', row);
|
||||||
r.attr('style', 'cursor: pointer;')
|
cols.attr('data-href', data['url']);
|
||||||
r.click(function() {
|
cols.attr('style', 'cursor: pointer;')
|
||||||
|
cols.click(function() {
|
||||||
window.document.location = $(this).data("href");
|
window.document.location = $(this).data("href");
|
||||||
});
|
});
|
||||||
|
var tds = $('td:eq(0)', row);
|
||||||
|
if (data['type'] == 'directory'){
|
||||||
|
tds.html('');
|
||||||
|
} else {
|
||||||
|
tds.html('<input type="checkbox" name="selected" value="'+data['selector']+'" data-type="'+data['type']+'"/>');
|
||||||
|
var cb = $('input', tds);
|
||||||
|
cb.change(function() {
|
||||||
|
$(this).closest('tr').toggleClass('info')
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
"drawCallback": function( settings ) {
|
||||||
|
var tds = $('table tr td:first-child');
|
||||||
|
tds.click(function(event){
|
||||||
|
if (!$(event.target).is('input')) {
|
||||||
|
var $cb = $('input', this)
|
||||||
|
$cb.click();
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
"columns": [
|
"columns": [
|
||||||
|
{ "data" : "blank", "orderable": false },
|
||||||
{ "data" : "icon", "orderable": false },
|
{ "data" : "icon", "orderable": false },
|
||||||
{ "data" : "name" },
|
{ "data" : "name" },
|
||||||
{ "data" : "label" },
|
{ "data" : "label" },
|
||||||
],
|
],
|
||||||
|
|
||||||
"order": [[ 1, 'asc' ]],
|
"order": [[ 2, 'asc' ]],
|
||||||
});
|
});
|
||||||
$(".clickable-row").click(function() {
|
$(".clickable-row").click(function() {
|
||||||
window.document.location = $(this).data("href");
|
window.document.location = $(this).data("href");
|
||||||
});
|
});
|
||||||
|
$('#func_selector').on('change', function() {
|
||||||
|
$.post('/comic/edit/', $('#comic_form').serialize())
|
||||||
|
.done(function(){
|
||||||
|
$('#func_selector').val('choose');
|
||||||
|
$('#select-all input').prop('checked', false);
|
||||||
|
table.ajax.reload();
|
||||||
|
}).fail(function(){
|
||||||
|
alert('Error Submitting Change');
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
$('#select-all').click(function(event){
|
||||||
|
var cb = $('input', this)
|
||||||
|
if (!$(event.target).is('input')) {
|
||||||
|
cb.click();
|
||||||
|
};
|
||||||
|
$('table tr td:first-child input').each(function(chkbx) {
|
||||||
|
row = $(this)
|
||||||
|
if (row.prop('checked') != cb.prop('checked')){
|
||||||
|
row.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
} );
|
} );
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
123
comic/templates/comic/recent_comics.html
Normal file
123
comic/templates/comic/recent_comics.html
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}{{ title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<form id="comic_form" method="post" action="/comic/edit/">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table class="table table-bordered table-striped table-hover" id="comic_list">
|
||||||
|
<caption><h2>Recent Comics</h2>
|
||||||
|
mark selected issues as:
|
||||||
|
<select name="func" id="func_selector">
|
||||||
|
<option value="choose">Choose...</option>
|
||||||
|
<option value="read">Read</option>
|
||||||
|
<option value="unread">Un-Read</option>
|
||||||
|
</select>
|
||||||
|
</caption>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th id="select-all"><input type="checkbox" id="select-all-cb"></th>
|
||||||
|
<th>
|
||||||
|
<center><span class="glyphicon glyphicon-file"></span></center>
|
||||||
|
</th>
|
||||||
|
<th width="100%">File/Folder</th>
|
||||||
|
<th>Date Added</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="clickable-row" data-href="/comic/">
|
||||||
|
<td>
|
||||||
|
<center><span class="glyphicon glyphicon-file"></span></center>
|
||||||
|
</td>
|
||||||
|
<td>loading data</td>
|
||||||
|
<td><span class="label label-primary pull-right">1/23</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
var table = $('#comic_list').DataTable({
|
||||||
|
"processing": true,
|
||||||
|
"stateSave": true,
|
||||||
|
"serverSide": true,
|
||||||
|
"ajax": {
|
||||||
|
"type": "POST",
|
||||||
|
"url": "/comic/recent/json/",
|
||||||
|
"data": function ( d ) {
|
||||||
|
d.csrfmiddlewaretoken = Cookies.get('csrftoken');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"rowCallback": function( row, data, index ) {
|
||||||
|
var r = $(row);
|
||||||
|
var cols = $('td:nth-child(n+2)', row);
|
||||||
|
cols.attr('data-href', data['url']);
|
||||||
|
cols.attr('style', 'cursor: pointer;')
|
||||||
|
cols.click(function() {
|
||||||
|
window.document.location = $(this).data("href");
|
||||||
|
});
|
||||||
|
var tds = $('td:eq(0)', row);
|
||||||
|
tds.html('<input type="checkbox" name="selected" value="'+data['selector']+'" data-type="'+data['type']+'"/>');
|
||||||
|
var cb = $('input', tds);
|
||||||
|
cb.change(function() {
|
||||||
|
$(this).closest('tr').toggleClass('info')
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
"drawCallback": function( settings ) {
|
||||||
|
var tds = $('table tr td:first-child');
|
||||||
|
tds.click(function(event){
|
||||||
|
if (!$(event.target).is('input')) {
|
||||||
|
var $cb = $('input', this)
|
||||||
|
$cb.click();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"columns": [
|
||||||
|
{ "data" : "selector", "orderable": false },
|
||||||
|
{ "data" : "icon", "orderable": false },
|
||||||
|
{ "data" : "name" },
|
||||||
|
{ "data" : "date" },
|
||||||
|
{ "data" : "label", "orderable": false },
|
||||||
|
],
|
||||||
|
|
||||||
|
"order": [[ 3, 'asc' ]],
|
||||||
|
});
|
||||||
|
$(".clickable-row").click(function() {
|
||||||
|
window.document.location = $(this).data("href");
|
||||||
|
});
|
||||||
|
$('#func_selector').on('change', function() {
|
||||||
|
$.post('/comic/edit/', $('#comic_form').serialize())
|
||||||
|
.done(function(){
|
||||||
|
$('#func_selector').val('choose');
|
||||||
|
$('#select-all input').prop('checked', false);
|
||||||
|
table.ajax.reload();
|
||||||
|
}).fail(function(){
|
||||||
|
alert('Error Submitting Change');
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
$('#select-all').click(function(event){
|
||||||
|
var cb = $('input', this)
|
||||||
|
if (!$(event.target).is('input')) {
|
||||||
|
cb.click();
|
||||||
|
};
|
||||||
|
$('table tr td:first-child input').each(function(chkbx) {
|
||||||
|
row = $(this)
|
||||||
|
if (row.prop('checked') != cb.prop('checked')){
|
||||||
|
row.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
@@ -13,5 +13,8 @@ urlpatterns = [
|
|||||||
url(r'^read/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/img$', views.get_image, name='get_image'),
|
url(r'^read/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/img$', views.get_image, name='get_image'),
|
||||||
url(r'^list_json/$', views.comic_list_json, name='comic_list_json1'),
|
url(r'^list_json/$', views.comic_list_json, name='comic_list_json1'),
|
||||||
url(r'^list_json/(?P<directory_selector>[\w-]+)/$', views.comic_list_json, name='comic_list_json2'),
|
url(r'^list_json/(?P<directory_selector>[\w-]+)/$', views.comic_list_json, name='comic_list_json2'),
|
||||||
|
url(r'^recent/$', views.recent_comics, name='recent_comics'),
|
||||||
|
url(r'^recent/json/$', views.recent_comics_json, name='recent_comics_json'),
|
||||||
|
url(r'^edit/$', views.comic_edit, name='comic_edit'),
|
||||||
url(r'^(?P<directory_selector>[\w-]+)/$', views.comic_list, name='comic_list'),
|
url(r'^(?P<directory_selector>[\w-]+)/$', views.comic_list, name='comic_list'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class Menu:
|
|||||||
"""
|
"""
|
||||||
self.menu_items = OrderedDict()
|
self.menu_items = OrderedDict()
|
||||||
self.menu_items['Browse'] = '/comic/'
|
self.menu_items['Browse'] = '/comic/'
|
||||||
|
self.menu_items['Recent'] = '/comic/recent/'
|
||||||
self.menu_items['Account'] = '/comic/account/'
|
self.menu_items['Account'] = '/comic/account/'
|
||||||
if user.is_superuser:
|
if user.is_superuser:
|
||||||
self.menu_items['Settings'] = '/comic/settings/'
|
self.menu_items['Settings'] = '/comic/settings/'
|
||||||
@@ -84,6 +85,8 @@ class DirFile:
|
|||||||
self.location = ''
|
self.location = ''
|
||||||
self.label = ''
|
self.label = ''
|
||||||
self.cur_page = 0
|
self.cur_page = 0
|
||||||
|
self.type = ''
|
||||||
|
self.selector = ''
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@@ -91,7 +94,6 @@ class DirFile:
|
|||||||
|
|
||||||
def generate_directory(user, directory=False):
|
def generate_directory(user, directory=False):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:type user: User
|
:type user: User
|
||||||
:type directory: Directory
|
:type directory: Directory
|
||||||
"""
|
"""
|
||||||
@@ -123,8 +125,10 @@ def generate_directory(user, directory=False):
|
|||||||
d.save()
|
d.save()
|
||||||
df.isdir = True
|
df.isdir = True
|
||||||
df.icon = 'glyphicon-folder-open'
|
df.icon = 'glyphicon-folder-open'
|
||||||
df.location = '/comic/{0}/'.format(urlsafe_base64_encode(d.selector.bytes).decode())
|
df.selector = urlsafe_base64_encode(d.selector.bytes).decode()
|
||||||
|
df.location = '/comic/{0}/'.format(df.selector)
|
||||||
df.label = generate_dir_status(user, d)
|
df.label = generate_dir_status(user, d)
|
||||||
|
df.type = 'directory'
|
||||||
elif file_name.lower()[-4:] in ['.rar', '.zip', '.cbr', '.cbz']:
|
elif file_name.lower()[-4:] in ['.rar', '.zip', '.cbr', '.cbz']:
|
||||||
df.iscb = True
|
df.iscb = True
|
||||||
df.icon = 'glyphicon-book'
|
df.icon = 'glyphicon-book'
|
||||||
@@ -138,26 +142,32 @@ def generate_directory(user, directory=False):
|
|||||||
except ComicBook.DoesNotExist:
|
except ComicBook.DoesNotExist:
|
||||||
book = ComicBook.process_comic_book(file_name, directory)
|
book = ComicBook.process_comic_book(file_name, directory)
|
||||||
|
|
||||||
status, _ = ComicStatus.objects.get_or_create(comic=book, user=user)
|
status, created = ComicStatus.objects.get_or_create(comic=book, user=user)
|
||||||
|
if created:
|
||||||
|
status.save()
|
||||||
last_page = status.last_read_page
|
last_page = status.last_read_page
|
||||||
df.location = '/comic/read/{0}/{1}/'.format(urlsafe_base64_encode(book.selector.bytes).decode(),
|
df.selector = urlsafe_base64_encode(book.selector.bytes).decode()
|
||||||
|
df.location = '/comic/read/{0}/{1}/'.format(df.selector,
|
||||||
last_page)
|
last_page)
|
||||||
if status.unread:
|
|
||||||
df.label = '<center><span class="label label-default">Unread</span></center>'
|
|
||||||
elif (last_page + 1) == book.page_count:
|
|
||||||
df.label = '<center><span class="label label-success">Read</span></center>'
|
|
||||||
df.cur_page = last_page
|
|
||||||
else:
|
|
||||||
label_text = '<center><span class="label label-primary">%s/%s</span></center>' % \
|
|
||||||
(last_page + 1, book.page_count)
|
|
||||||
df.label = label_text
|
|
||||||
df.cur_page = last_page
|
df.cur_page = last_page
|
||||||
|
df.label = generate_label(book, status)
|
||||||
|
df.type = 'book'
|
||||||
|
|
||||||
# df.label = '<span class="label label-danger pull-right">Unprocessed</span>'
|
|
||||||
files.append(df)
|
files.append(df)
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
|
||||||
|
def generate_label(book, status):
|
||||||
|
if status.unread:
|
||||||
|
label_text = '<center><span class="label label-default">Unread</span></center>'
|
||||||
|
elif (status.last_read_page + 1) == book.page_count:
|
||||||
|
label_text = '<center><span class="label label-success">Read</span></center>'
|
||||||
|
else:
|
||||||
|
label_text = '<center><span class="label label-primary">%s/%s</span></center>' % \
|
||||||
|
(status.last_read_page + 1, book.page_count)
|
||||||
|
return label_text
|
||||||
|
|
||||||
|
|
||||||
def generate_dir_status(user, directory):
|
def generate_dir_status(user, directory):
|
||||||
cb_list = ComicBook.objects.filter(directory=directory)
|
cb_list = ComicBook.objects.filter(directory=directory)
|
||||||
total = cb_list.count()
|
total = cb_list.count()
|
||||||
|
|||||||
@@ -6,18 +6,20 @@ from django.contrib.auth import login, authenticate
|
|||||||
from django.contrib.auth.decorators import login_required, user_passes_test
|
from django.contrib.auth.decorators import login_required, user_passes_test
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
|
from django.db.transaction import atomic
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import render, redirect, get_object_or_404
|
from django.shortcuts import render, redirect, get_object_or_404
|
||||||
from django.utils.http import urlsafe_base64_decode
|
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
|
||||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||||
from django.views.decorators.http import require_POST
|
from django.views.decorators.http import require_POST
|
||||||
|
|
||||||
from .forms import SettingsForm, AccountForm, EditUserForm, AddUserForm, InitialSetupForm
|
from .forms import SettingsForm, AccountForm, EditUserForm, AddUserForm, InitialSetupForm
|
||||||
from .models import Setting, ComicBook, ComicStatus, Directory, ComicPage
|
from .models import Setting, ComicBook, ComicStatus, Directory, ComicPage
|
||||||
from .util import generate_breadcrumbs_from_path, generate_breadcrumbs_from_menu, \
|
from .util import generate_breadcrumbs_from_path, generate_breadcrumbs_from_menu, \
|
||||||
generate_title_from_path, Menu, generate_directory
|
generate_title_from_path, Menu, generate_directory, generate_label
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyTypeChecker
|
||||||
@ensure_csrf_cookie
|
@ensure_csrf_cookie
|
||||||
@login_required
|
@login_required
|
||||||
def comic_list(request, directory_selector=False):
|
def comic_list(request, directory_selector=False):
|
||||||
@@ -42,10 +44,8 @@ def comic_list(request, directory_selector=False):
|
|||||||
title = generate_title_from_path('Home')
|
title = generate_title_from_path('Home')
|
||||||
breadcrumbs = generate_breadcrumbs_from_path()
|
breadcrumbs = generate_breadcrumbs_from_path()
|
||||||
json_url = '/comic/list_json/'
|
json_url = '/comic/list_json/'
|
||||||
files = generate_directory(request.user)
|
|
||||||
|
|
||||||
return render(request, 'comic/comic_list.html', {
|
return render(request, 'comic/comic_list.html', {
|
||||||
'file_list': files,
|
|
||||||
'breadcrumbs': breadcrumbs,
|
'breadcrumbs': breadcrumbs,
|
||||||
'menu': Menu(request.user, 'Browse'),
|
'menu': Menu(request.user, 'Browse'),
|
||||||
'title': title,
|
'title': title,
|
||||||
@@ -67,6 +67,9 @@ def comic_list_json(request, directory_selector=False):
|
|||||||
response_data['data'] = []
|
response_data['data'] = []
|
||||||
for file in files:
|
for file in files:
|
||||||
response_data['data'].append({
|
response_data['data'].append({
|
||||||
|
'blank': '',
|
||||||
|
'selector': file.selector,
|
||||||
|
'type': file.type,
|
||||||
'icon': icon_str.format(file.icon),
|
'icon': icon_str.format(file.icon),
|
||||||
'name': file.name,
|
'name': file.name,
|
||||||
'label': file.label,
|
'label': file.label,
|
||||||
@@ -78,6 +81,87 @@ def comic_list_json(request, directory_selector=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def recent_comics(request):
|
||||||
|
return render(request,
|
||||||
|
'comic/recent_comics.html',
|
||||||
|
{
|
||||||
|
'breadcrumbs': generate_breadcrumbs_from_menu([('Recent', '/comic/recent/')]),
|
||||||
|
'menu': Menu(request.user, 'Recent'),
|
||||||
|
'title': 'Recent Comics'
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@require_POST
|
||||||
|
def recent_comics_json(request):
|
||||||
|
start = int(request.POST['start'])
|
||||||
|
end = start + int(request.POST['length'])
|
||||||
|
icon = '<span class="glyphicon glyphicon-book"></span>'
|
||||||
|
comics = ComicBook.objects.all()
|
||||||
|
response_data = dict()
|
||||||
|
response_data['recordsTotal'] = comics.count()
|
||||||
|
if request.POST['search[value]']:
|
||||||
|
comics = comics.filter(file_name__contains=request.POST['search[value]'])
|
||||||
|
order_string = ''
|
||||||
|
# Ordering
|
||||||
|
if request.POST['order[0][dir]'] == 'desc':
|
||||||
|
order_string += '-'
|
||||||
|
if request.POST['order[0][dir]'] == '3':
|
||||||
|
order_string += 'date_added'
|
||||||
|
elif request.POST['order[0][dir]'] == '2':
|
||||||
|
order_string += 'date_added'
|
||||||
|
else:
|
||||||
|
order_string += 'date_added'
|
||||||
|
comics = comics.order_by(order_string)
|
||||||
|
response_data['recordsFiltered'] = comics.count()
|
||||||
|
response_data['data'] = list()
|
||||||
|
for book in comics[start:end]:
|
||||||
|
status, created = ComicStatus.objects.get_or_create(comic=book,
|
||||||
|
user=request.user)
|
||||||
|
if created:
|
||||||
|
status.save()
|
||||||
|
response_data['data'].append({
|
||||||
|
'selector': urlsafe_base64_encode(book.selector.bytes).decode(),
|
||||||
|
'icon': icon,
|
||||||
|
'type': 'book',
|
||||||
|
'name': book.file_name,
|
||||||
|
'date': book.date_added.strftime('%d/%m/%y-%H:%M'),
|
||||||
|
'label': generate_label(book, status),
|
||||||
|
'url': '/comic/read/{0}/{1}/'.format(urlsafe_base64_encode(book.selector.bytes).decode(),
|
||||||
|
status.last_read_page)
|
||||||
|
})
|
||||||
|
return HttpResponse(
|
||||||
|
json.dumps(response_data),
|
||||||
|
content_type="application/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@require_POST
|
||||||
|
def comic_edit(request):
|
||||||
|
if 'selected' not in request.POST:
|
||||||
|
return HttpResponse(status=200)
|
||||||
|
if request.POST['func'] == 'choose':
|
||||||
|
return HttpResponse(status=200)
|
||||||
|
selected = [uuid.UUID(bytes=urlsafe_base64_decode(item)) for item in request.POST.getlist('selected')]
|
||||||
|
comics = ComicBook.objects.filter(selector__in=selected)
|
||||||
|
with atomic():
|
||||||
|
for comic in comics:
|
||||||
|
status, _ = ComicStatus.objects.get_or_create(comic=comic,
|
||||||
|
user=request.user)
|
||||||
|
if request.POST['func'] == 'read':
|
||||||
|
status.unread = False
|
||||||
|
status.finished = True
|
||||||
|
status.last_read_page = comic.page_count - 1
|
||||||
|
elif request.POST['func'] == 'unread':
|
||||||
|
status.unread = True
|
||||||
|
status.finished = False
|
||||||
|
status.last_read_page = 0
|
||||||
|
status.save()
|
||||||
|
return HttpResponse(status=200)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def account_page(request):
|
def account_page(request):
|
||||||
success_message = []
|
success_message = []
|
||||||
|
|||||||
Reference in New Issue
Block a user