mirror of
https://github.com/ajurna/cbwebreader.git
synced 2025-12-06 06:17:17 +00:00
fixed breadcrumbs
moved some code to util.py to clean up views.py added migration for start of db.
This commit is contained in:
@@ -5,3 +5,4 @@ from comic.models import Setting
|
|||||||
@admin.register(Setting)
|
@admin.register(Setting)
|
||||||
class SettingAdmin(admin.ModelAdmin):
|
class SettingAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'value')
|
list_display = ('name', 'value')
|
||||||
|
|
||||||
|
|||||||
@@ -9,3 +9,13 @@ class Setting(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
||||||
return '"%s":"%s"' % (self.name, self.value)
|
return '"%s":"%s"' % (self.name, self.value)
|
||||||
|
|
||||||
|
class ComicBook(models.Model):
|
||||||
|
file_name = models.CharField(max_length=100, unique=True)
|
||||||
|
last_read_page = models.IntegerField()
|
||||||
|
|
||||||
|
class ComicPage(models.Model):
|
||||||
|
Comic = models.ForeignKey(ComicBook)
|
||||||
|
index = models.IntegerField()
|
||||||
|
page_file_name = models.CharField(max_length=100, unique=False)
|
||||||
|
content_type = models.CharField(max_length=30)
|
||||||
|
|||||||
@@ -5,3 +5,28 @@ body {
|
|||||||
padding: 40px 15px;
|
padding: 40px 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
/* Sticky footer styles
|
||||||
|
-------------------------------------------------- */
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
/* Margin bottom by footer height */
|
||||||
|
margin-bottom: 60px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
/* Set the fixed height of the footer here */
|
||||||
|
height: 60px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#dropdown-list{
|
||||||
|
max-height: 300px;
|
||||||
|
overflow: auto;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@@ -43,7 +42,7 @@
|
|||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
{% block navbar %}
|
{% block navbar %}
|
||||||
<li class="active"><a href="/comic/">Home</a></li>
|
<li class="active"><a href="/comic/">Home</a></li>
|
||||||
<li><a href="#about">About</a></li>
|
<li><a href="settings/">Settings</a></li>
|
||||||
<li><a href="#contact">Contact</a></li>
|
<li><a href="#contact">Contact</a></li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -61,14 +60,18 @@
|
|||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div><!-- /.container -->
|
<!-- /.container -->
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="container">
|
||||||
|
<p class="text-muted"><a href="https://github.com/ajurna/cbreader">CBReader</a></p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
<!-- Bootstrap core JavaScript
|
<!-- Bootstrap core JavaScript
|
||||||
================================================== -->
|
================================================== -->
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
<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>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}My amazing blog{% endblock %}
|
{% block title %}CBreader{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
{% for crumb in breadcrumbs %}
|
{% for crumb in breadcrumbs %}
|
||||||
<li><a href="{{ crumb.url }}"{% if forloop.last %} class="active"{% endif %}>{{ crumb.name }}</a></li>
|
{% if not forloop.last %}
|
||||||
|
<li><a href="{{ crumb.url }}">{{ crumb.name }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li class="active">{{ crumb.name }}</li>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|||||||
@@ -1,22 +1,35 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% block breadcrumb %}
|
||||||
|
{% for crumb in breadcrumbs %}
|
||||||
|
{% if not forloop.last %}
|
||||||
|
<li><a href="{{ crumb.url }}">{{ crumb.name }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li class="active">{{ crumb.name }}</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<center>
|
<center>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="/comic/read/{{ file_name }}/{{ nav.next }}/">
|
<a href="/comic/read/{{ file_name }}/{{ nav.next }}/">
|
||||||
<img src="/comic/read/{{ file_name }}/{{ nav.cur }}/img" height="900" class="img-rounded"></img>
|
<img src="/comic/read/{{ file_name }}/{{ nav.cur }}/img" height="900" class="img-rounded">
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
|
<div class="btn-group">
|
||||||
<a href="/comic/read/{{ file_name }}/{{ nav.prev }}/">Prev</a>
|
<a href="/comic/read/{{ file_name }}/{{ nav.prev }}/" class="btn btn-default">Prev</a>
|
||||||
{% if pages %}
|
{% if pages %}
|
||||||
<select>
|
<div class="btn-group dropup">
|
||||||
{% for file in pages %}
|
<button type="button" data-toggle="dropdown" class="btn btn-default dropdown-toggle ">{{ orig_file_name}}<span class="caret"></span></button>
|
||||||
<option value="{{ file.index }}" {% if nav.cur == file.index%}selected="True"{% endif %}>{{ file.name }}</option>
|
<ul class="dropdown-menu" id="dropdown-list">
|
||||||
{% endfor %}
|
{% for file in pages %}
|
||||||
</select>
|
<li><a href="/comic/read/{{ file_name }}/{{ file.index }}/">{{ file.name }}</a></li>
|
||||||
{% else %}
|
{% endfor %}
|
||||||
<p>No comics.</p>
|
</ul>
|
||||||
{% endif %}
|
</div>
|
||||||
<a href="/comic/read/{{ file_name }}/{{ nav.next }}/">Next</a>
|
{% else %}
|
||||||
|
<p>No comics.</p>
|
||||||
|
{% endif %}
|
||||||
|
<a href="/comic/read/{{ file_name }}/{{ nav.next }}/" class="btn btn-default">Next</a>
|
||||||
|
</div>
|
||||||
</center>
|
</center>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
55
comic/util.py
Normal file
55
comic/util.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
from django.utils.http import urlsafe_base64_encode
|
||||||
|
from os import path
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class Breadcrumb:
|
||||||
|
def __init__(self):
|
||||||
|
self.name = 'Home'
|
||||||
|
self.url = '/comic/'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class DirFile:
|
||||||
|
def __init__(self):
|
||||||
|
self.name = ''
|
||||||
|
self.isdir = False
|
||||||
|
self.icon = ''
|
||||||
|
self.iscb = False
|
||||||
|
self.location = ''
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def generate_breadcrumbs(comic_path):
|
||||||
|
output = [Breadcrumb()]
|
||||||
|
prefix = '/comic/'
|
||||||
|
last = ''
|
||||||
|
comic_path = path.normpath(comic_path)
|
||||||
|
folders = comic_path.split(os.sep)
|
||||||
|
for item in folders:
|
||||||
|
if item == '.':
|
||||||
|
continue
|
||||||
|
bc = Breadcrumb()
|
||||||
|
bc.name = item
|
||||||
|
bc.url = prefix + urlsafe_base64_encode(item)
|
||||||
|
output.append(bc)
|
||||||
|
last = path.join(last, item)
|
||||||
|
return output
|
||||||
|
|
||||||
|
def generate_directory(base_dir, comic_path):
|
||||||
|
files = []
|
||||||
|
for fn in os.listdir(path.join(base_dir.value, comic_path)):
|
||||||
|
df = DirFile()
|
||||||
|
df.name = fn
|
||||||
|
if path.isdir(path.join(base_dir.value, comic_path, fn)):
|
||||||
|
df.isdir = True
|
||||||
|
df.icon = 'glyphicon-folder-open'
|
||||||
|
df.location = urlsafe_base64_encode(path.join(comic_path, fn))
|
||||||
|
elif fn.lower().endswith('cbz') or fn.lower().endswith('cbr'):
|
||||||
|
df.iscb = True
|
||||||
|
df.icon = 'glyphicon-book'
|
||||||
|
df.location = urlsafe_base64_encode(path.join(comic_path, fn))
|
||||||
|
files.append(df)
|
||||||
|
return files
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.template import RequestContext, loader
|
from django.template import RequestContext, loader
|
||||||
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
|
from django.utils.http import urlsafe_base64_decode
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
from comic.models import Setting
|
from comic.models import Setting
|
||||||
|
from util import generate_breadcrumbs, generate_directory
|
||||||
|
|
||||||
from unrar import rarfile
|
from unrar import rarfile
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
import os
|
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
class Comic:
|
class Comic:
|
||||||
@@ -18,52 +19,24 @@ class Navigation:
|
|||||||
self.next = 0
|
self.next = 0
|
||||||
self.prev = 0
|
self.prev = 0
|
||||||
self.cur = 0
|
self.cur = 0
|
||||||
class DirFile:
|
|
||||||
def __init__(self):
|
|
||||||
self.name = ''
|
|
||||||
self.isdir = False
|
|
||||||
self.icon = ''
|
|
||||||
self.iscb = False
|
|
||||||
self.location = ''
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
|
||||||
def index(request, comic_path=''):
|
def index(request, comic_path=''):
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR')
|
base_dir = Setting.objects.get(name='BASE_DIR')
|
||||||
comic_path = urlsafe_base64_decode(comic_path)
|
comic_path = urlsafe_base64_decode(comic_path)
|
||||||
breadcrumbs = generate_breadcrumbs(comic_path)
|
breadcrumbs = generate_breadcrumbs(comic_path)
|
||||||
|
files = generate_directory(base_dir, comic_path)
|
||||||
|
|
||||||
#list and classify files
|
|
||||||
files = []
|
|
||||||
for fn in os.listdir(path.join(base_dir.value, comic_path)):
|
|
||||||
df = DirFile()
|
|
||||||
df.name = fn
|
|
||||||
if path.isdir(path.join(base_dir.value, comic_path, fn)):
|
|
||||||
df.isdir = True
|
|
||||||
df.icon = 'glyphicon-folder-open'
|
|
||||||
df.location = urlsafe_base64_encode(path.join(comic_path, fn))
|
|
||||||
elif fn.lower().endswith('cbz') or fn.lower().endswith('cbr'):
|
|
||||||
df.iscb = True
|
|
||||||
df.icon = 'glyphicon-book'
|
|
||||||
df.location = urlsafe_base64_encode(path.join(comic_path, fn))
|
|
||||||
files.append(df)
|
|
||||||
template = loader.get_template('comic/index.html')
|
|
||||||
context = RequestContext(request, {
|
context = RequestContext(request, {
|
||||||
'file_list': files,
|
'file_list': files,
|
||||||
'breadcrumbs': breadcrumbs,
|
'breadcrumbs': breadcrumbs,
|
||||||
})
|
})
|
||||||
return HttpResponse(template.render(context))
|
return render(request, 'comic/index.html', context)
|
||||||
|
|
||||||
|
|
||||||
def read_comic(request, comic_path, page):
|
def read_comic(request, comic_path, page):
|
||||||
encoded = comic_path
|
encoded = comic_path
|
||||||
comic_path = urlsafe_base64_decode(comic_path)
|
comic_path = urlsafe_base64_decode(comic_path)
|
||||||
|
breadcrumbs = generate_breadcrumbs(comic_path)
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR')
|
base_dir = Setting.objects.get(name='BASE_DIR')
|
||||||
template = loader.get_template('comic/read_comic.html')
|
|
||||||
if comic_path.lower().endswith('cbr'):
|
if comic_path.lower().endswith('cbr'):
|
||||||
cbx = rarfile.RarFile(path.join(base_dir.value, comic_path))
|
cbx = rarfile.RarFile(path.join(base_dir.value, comic_path))
|
||||||
elif comic_path.lower().endswith('cbz'):
|
elif comic_path.lower().endswith('cbz'):
|
||||||
@@ -79,13 +52,15 @@ def read_comic(request, comic_path, page):
|
|||||||
comic.name = name
|
comic.name = name
|
||||||
comic.index = idx
|
comic.index = idx
|
||||||
pages.append(comic)
|
pages.append(comic)
|
||||||
|
|
||||||
context = RequestContext(request, {
|
context = RequestContext(request, {
|
||||||
'pages': pages,
|
'pages': pages,
|
||||||
'file_name': encoded,
|
'file_name': encoded,
|
||||||
|
'orig_file_name': pages[nav.cur].name,
|
||||||
'nav': nav,
|
'nav': nav,
|
||||||
|
'breadcrumbs': breadcrumbs,
|
||||||
})
|
})
|
||||||
return HttpResponse(template.render(context))
|
return render(request, 'comic/read_comic.html', context)
|
||||||
|
|
||||||
|
|
||||||
def get_image(request, comic_path, page):
|
def get_image(request, comic_path, page):
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR')
|
base_dir = Setting.objects.get(name='BASE_DIR')
|
||||||
@@ -113,25 +88,4 @@ def get_image(request, comic_path, page):
|
|||||||
img = cbx.open(page_file)
|
img = cbx.open(page_file)
|
||||||
return HttpResponse(img.read(), content_type=content)
|
return HttpResponse(img.read(), content_type=content)
|
||||||
|
|
||||||
class Breadcrumb:
|
|
||||||
def __init__(self):
|
|
||||||
self.name = 'Home'
|
|
||||||
self.url = '/comic/'
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
def generate_breadcrumbs(comic_path):
|
|
||||||
output = [Breadcrumb()]
|
|
||||||
prefix = '/comic/'
|
|
||||||
last = ''
|
|
||||||
comic_path = path.normpath(comic_path)
|
|
||||||
folders = comic_path.split(os.sep)
|
|
||||||
for item in folders:
|
|
||||||
if item == '.':
|
|
||||||
continue
|
|
||||||
bc = Breadcrumb()
|
|
||||||
bc.name = item
|
|
||||||
bc.url = prefix + urlsafe_base64_encode(item)
|
|
||||||
output.append(bc)
|
|
||||||
last = path.join(last, item)
|
|
||||||
return output
|
|
||||||
Reference in New Issue
Block a user