diff --git a/comic/admin.py b/comic/admin.py index 18a74d8..704ef6c 100644 --- a/comic/admin.py +++ b/comic/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from comic.models import Setting, ComicBook, ComicPage, ComicStatus +from comic.models import Setting, ComicBook, ComicPage, ComicStatus, Directory @admin.register(Setting) @@ -17,6 +17,12 @@ class ComicPageAdmin(admin.ModelAdmin): list_display = ('Comic', 'index', 'page_file_name', 'content_type') list_filter = ['Comic'] + @admin.register(ComicStatus) class ComicStatusAdmin(admin.ModelAdmin): - list_display = ['user', 'comic', 'last_read_page', 'unread'] \ No newline at end of file + list_display = ['user', 'comic', 'last_read_page', 'unread'] + + +@admin.register(Directory) +class DirectoryAdmin(admin.ModelAdmin): + pass diff --git a/comic/management/__init__.py b/comic/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comic/management/commands/__init__.py b/comic/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comic/management/commands/scan_comics.py b/comic/management/commands/scan_comics.py new file mode 100644 index 0000000..c1152c2 --- /dev/null +++ b/comic/management/commands/scan_comics.py @@ -0,0 +1,52 @@ +from django.core.management.base import BaseCommand + +from comic.models import Setting, Directory, ComicBook + +import os +from os.path import isdir + + +class Command(BaseCommand): + help = 'Scan directories to Update Comic DB' + + def __init__(self): + super().__init__() + self.base_dir = Setting.objects.get(name='BASE_DIR').value + + def handle(self, *args, **options): + self.scan_directory() + + def scan_directory(self, directory=False): + + """ + + :type directory: Directory + """ + if not directory: + comic_dir = self.base_dir + else: + comic_dir = os.path.join(self.base_dir, directory.get_path()) + for file in os.listdir(comic_dir): + if isdir(os.path.join(comic_dir, file)): + if directory: + next_directory, created = Directory.objects.get_or_create(name=file, + parent=directory) + else: + next_directory, created = Directory.objects.get_or_create(name=file, + parent__isnull=True) + if created: + next_directory.save() + self.scan_directory(next_directory) + else: + try: + if directory: + ComicBook.objects.get(file_name=file, + directory=directory) + else: + ComicBook.objects.get(file_name=file, + directory__isnull=True) + except ComicBook.DoesNotExist: + ComicBook.process_comic_book(file, directory) + + + diff --git a/comic/migrations/0008_auto_20160331_1140.py b/comic/migrations/0008_auto_20160331_1140.py new file mode 100644 index 0000000..9c76dfb --- /dev/null +++ b/comic/migrations/0008_auto_20160331_1140.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2016-03-31 10:40 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models +import django.db.models.deletion +from django.utils.timezone import utc +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('comic', '0007_auto_20150626_1820'), + ] + + operations = [ + migrations.CreateModel( + name='Directory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('selector', models.UUIDField(default=uuid.uuid4, null=True)), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comic.Directory')), + ], + ), + migrations.AddField( + model_name='comicbook', + name='date_added', + field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 3, 31, 10, 40, 30, 62170, tzinfo=utc)), + preserve_default=False, + ), + migrations.AddField( + model_name='comicbook', + name='selector', + field=models.UUIDField(default=uuid.uuid4, null=True), + ), + migrations.AddField( + model_name='comicbook', + name='version', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='comicbook', + name='directory', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comic.Directory'), + ), + ] diff --git a/comic/migrations/0009_auto_20160331_1140.py b/comic/migrations/0009_auto_20160331_1140.py new file mode 100644 index 0000000..7734683 --- /dev/null +++ b/comic/migrations/0009_auto_20160331_1140.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2016-03-31 10:40 +from __future__ import unicode_literals + +from django.db import migrations + +import uuid + + +def gen_uuid(apps, schema_editor): + comicbook = apps.get_model('comic', 'comicbook') + for row in comicbook.objects.all(): + row.selector = uuid.uuid4() + row.save() + directory = apps.get_model('comic', 'directory') + for row in directory.objects.all(): + row.selector = uuid.uuid4() + row.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('comic', '0008_auto_20160331_1140'), + ] + + operations = [ + migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop), + ] diff --git a/comic/migrations/0010_auto_20160331_1140.py b/comic/migrations/0010_auto_20160331_1140.py new file mode 100644 index 0000000..f31a3b0 --- /dev/null +++ b/comic/migrations/0010_auto_20160331_1140.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2016-03-31 10:40 +from __future__ import unicode_literals + +from django.db import migrations, models + +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('comic', '0009_auto_20160331_1140'), + ] + + operations = [ + migrations.AlterField( + model_name='comicbook', + name='selector', + field=models.UUIDField(default=uuid.uuid4, unique=True), + ), + migrations.AlterField( + model_name='directory', + name='selector', + field=models.UUIDField(default=uuid.uuid4, unique=True), + ), + ] diff --git a/comic/migrations/0011_auto_20160331_1141.py b/comic/migrations/0011_auto_20160331_1141.py new file mode 100644 index 0000000..28a52df --- /dev/null +++ b/comic/migrations/0011_auto_20160331_1141.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2016-03-31 10:41 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('comic', '0010_auto_20160331_1140'), + ] + + operations = [ + migrations.AlterField( + model_name='comicbook', + name='version', + field=models.IntegerField(default=1), + ), + ] diff --git a/comic/migrations/0012_auto_20160401_0949.py b/comic/migrations/0012_auto_20160401_0949.py new file mode 100644 index 0000000..d3fe969 --- /dev/null +++ b/comic/migrations/0012_auto_20160401_0949.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2016-04-01 08:49 +from __future__ import unicode_literals + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('comic', '0011_auto_20160331_1141'), + ] + + operations = [ + migrations.AlterField( + model_name='comicbook', + name='selector', + field=models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + migrations.AlterField( + model_name='directory', + name='selector', + field=models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ] diff --git a/comic/models.py b/comic/models.py index 7a38462..d16ec99 100644 --- a/comic/models.py +++ b/comic/models.py @@ -1,13 +1,14 @@ from django.db import models -from django.db.transaction import atomic from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode from django.contrib.auth.models import User from django.conf import settings +from django.db.transaction import atomic from comic import rarfile -from comic.util import get_ordered_dir_list + +import uuid import zipfile -from os import path +from os import path, listdir if settings.UNRAR_TOOL: rarfile.UNRAR_TOOL = settings.UNRAR_TOOL @@ -24,13 +25,67 @@ class Setting(models.Model): return self.__str__() +class Directory(models.Model): + name = models.CharField(max_length=100) + parent = models.ForeignKey('Directory', null=True, blank=True) + selector = models.UUIDField(unique=True, default=uuid.uuid4, db_index=True) + + def __str__(self): + return 'Directory: {0}; {1}'.format(self.name, self.parent) + + @property + def path(self): + l = self.get_path_items() + l.reverse() + return path.sep.join(l) + + def get_path(self): + l = self.get_path_items() + l.reverse() + return path.sep.join(l) + + def get_path_items(self, p=False): + if not p: + p = [] + p.append(self.name) + if self.parent: + self.parent.get_path_items(p) + return p + + def get_path_objects(self, p=False): + if not p: + p = [] + p.append(self) + if self.parent: + self.parent.get_path_objects(p) + return p + + @staticmethod + def get_dir_from_path(file_path): + file_path = file_path.split(path.sep) + print(file_path) + for d in Directory.objects.filter(name=file_path[-1]): + print(d) + if d.get_path_items() == file_path: + return d + + class ComicBook(models.Model): file_name = models.CharField(max_length=100, unique=True) + date_added = models.DateTimeField(auto_now_add=True) + directory = models.ForeignKey(Directory, blank=True, null=True) + selector = models.UUIDField(unique=True, default=uuid.uuid4, db_index=True) + version = models.IntegerField(default=1) def __str__(self): return self.file_name - def get_image(self, archive_path, page): + def get_image(self, page): + base_dir = Setting.objects.get(name='BASE_DIR').value + if self.directory: + archive_path = path.join(base_dir, self.directory.path, self.file_name) + else: + archive_path = path.join(base_dir, self.file_name) try: archive = rarfile.RarFile(archive_path) except rarfile.NotRarFile: @@ -62,120 +117,103 @@ class ComicBook(models.Model): self.q_prev_to_directory = False self.q_next_to_directory = False - def nav(self, comic_path, page): + def nav(self, page, user): out = self.Navigation() out.cur_index = page - out.cur_path = comic_path + out.cur_path = urlsafe_base64_encode(self.selector.bytes) if page == 0: - out.prev_path, out.prev_index = self.nav_get_prev_comic(comic_path) + out.prev_path, out.prev_index = self.nav_get_prev_comic(user) if out.prev_index == -1: out.q_prev_to_directory = True else: out.prev_index = page - 1 - out.prev_path = comic_path + out.prev_path = out.cur_path if self.is_last_page(page): - out.next_path, out.next_index = self.nav_get_next_comic(comic_path) + out.next_path, out.next_index = self.nav_get_next_comic(user) if out.next_index == -1: out.q_next_to_directory = True else: out.next_index = page + 1 - out.next_path = comic_path + out.next_path = out.cur_path return out - @staticmethod - def nav_get_prev_comic(comic_path): + def nav_get_prev_comic(self, user): base_dir = Setting.objects.get(name='BASE_DIR').value - comic_path = urlsafe_base64_decode(comic_path).decode() - directory, comic = path.split(comic_path) - dir_list = get_ordered_dir_list(path.join(base_dir, directory)) - comic_index = dir_list.index(comic) + if self.directory: + folder = path.join(base_dir, self.directory.path) + else: + folder = base_dir + dir_list = ComicBook.get_ordered_dir_list(folder) + comic_index = dir_list.index(self.file_name) if comic_index == 0: - comic_path = urlsafe_base64_encode(directory.encode()) + if self.directory: + comic_path = urlsafe_base64_encode(self.directory.selector.bytes) + else: + comic_path = '' index = -1 else: prev_comic = dir_list[comic_index - 1] - comic_path = path.join(directory, prev_comic) - if not path.isdir(path.join(base_dir, directory, prev_comic)): + + if not path.isdir(path.join(folder, prev_comic)): try: - book = ComicBook.objects.get(file_name=prev_comic) + if self.directory: + book = ComicBook.objects.get(file_name=prev_comic, + directory=self.directory) + else: + book = ComicBook.objects.get(file_name=prev_comic, + directory__isnull=True) except ComicBook.DoesNotExist: - book = ComicBook.process_comic_book(base_dir, comic_path, prev_comic) - index = ComicPage.objects.filter(Comic=book).count() - 1 - comic_path = urlsafe_base64_encode(comic_path.encode()) + if self.directory: + book = ComicBook.process_comic_book(prev_comic, self.directory) + else: + book = ComicBook.process_comic_book(prev_comic) + cs, _ = ComicStatus.objects.get_or_create(comic=book, user=user) + index = cs.last_read_page + comic_path = urlsafe_base64_encode(book.selector.bytes) else: - comic_path = urlsafe_base64_encode(directory.encode()) + if self.directory: + comic_path = urlsafe_base64_encode(self.directory.selector.bytes) + else: + comic_path = '' index = -1 return comic_path, index - @staticmethod - def nav_get_next_comic(comic_path): - base_dir = Setting.objects.get(name='BASE_DIR') - comic_path = urlsafe_base64_decode(comic_path).decode() - directory, comic = path.split(comic_path) - dir_list = get_ordered_dir_list(path.join(base_dir.value, directory)) - comic_index = dir_list.index(comic) + def nav_get_next_comic(self, user): + base_dir = Setting.objects.get(name='BASE_DIR').value + if self.directory: + folder = path.join(base_dir, self.directory.path) + else: + folder = base_dir + dir_list = ComicBook.get_ordered_dir_list(folder) + comic_index = dir_list.index(self.file_name) try: next_comic = dir_list[comic_index + 1] - comic_path = path.join(directory, next_comic) - comic_path = urlsafe_base64_encode(comic_path) - index = 0 + try: + if self.directory: + book = ComicBook.objects.get(file_name=next_comic, + directory=self.directory) + else: + book = ComicBook.objects.get(file_name=next_comic, + directory__isnull=True) + except ComicBook.DoesNotExist: + if self.directory: + book = ComicBook.process_comic_book(next_comic, self.directory) + else: + book = ComicBook.process_comic_book(next_comic) + comic_path = urlsafe_base64_encode(book.selector.bytes) + cs, _ = ComicStatus.objects.get_or_create(comic=book, user=user) + index = cs.last_read_page except IndexError: - comic_path = urlsafe_base64_encode(directory) + if self.directory: + comic_path = urlsafe_base64_encode(self.directory.selector.bytes) + else: + comic_path = '' index = -1 return comic_path, index - @staticmethod - def process_comic_book(base_dir, comic_path, comic_file_name): - try: - cbx = rarfile.RarFile(path.join(base_dir, comic_path)) - except rarfile.NotRarFile: - cbx = zipfile.ZipFile(path.join(base_dir, comic_path)) - except zipfile.BadZipfile: - return False - with atomic(): - book = ComicBook(file_name=comic_file_name) - book.save() - i = 0 - for f in sorted([str(x) for x in cbx.namelist()], key=str.lower): - try: - dot_index = f.rindex('.') + 1 - except ValueError: - continue - ext = f.lower()[dot_index:] - if ext in ['jpg', 'jpeg']: - page = ComicPage(Comic=book, - index=i, - page_file_name=f, - content_type='image/jpeg') - page.save() - - i += 1 - elif ext == 'png': - page = ComicPage(Comic=book, - index=i, - page_file_name=f, - content_type='image/png') - page.save() - i += 1 - elif ext == 'bmp': - page = ComicPage(Comic=book, - index=i, - page_file_name=f, - content_type='image/bmp') - page.save() - i += 1 - elif ext == 'gif': - page = ComicPage(Comic=book, - index=i, - page_file_name=f, - content_type='image/gif') - page.save() - i += 1 - return book - class DirFile: def __init__(self): self.name = '' @@ -192,7 +230,7 @@ class ComicBook(models.Model): @staticmethod def generate_directory(user, base_dir, comic_path): files = [] - for fn in get_ordered_dir_list(path.join(base_dir, comic_path)): + for fn in ComicBook.get_ordered_dir_list(path.join(base_dir, comic_path)): df = ComicBook.DirFile() df.name = fn if path.isdir(path.join(base_dir, comic_path, fn)): @@ -232,6 +270,76 @@ class ComicBook(models.Model): def page_name(self, index): return ComicPage.objects.get(Comic=self, index=index).page_file_name + @staticmethod + def process_comic_book(comic_file_name, directory=False): + """ + + :type comic_file_name: str + :type directory: Directory + """ + try: + book = ComicBook.objects.get(file_name=comic_file_name, + version=0) + book.directory = directory + book.version = 1 + book.save() + return book + except ComicBook.DoesNotExist: + pass + base_dir = Setting.objects.get(name='BASE_DIR').value + if directory: + comic_full_path = path.join(base_dir, directory.get_path(), comic_file_name) + else: + comic_full_path = path.join(base_dir, comic_file_name) + try: + cbx = rarfile.RarFile(comic_full_path) + except rarfile.NotRarFile: + cbx = zipfile.ZipFile(comic_full_path) + except zipfile.BadZipfile: + return False + with atomic(): + if directory: + book = ComicBook(file_name=comic_file_name, + directory=directory) + else: + book = ComicBook(file_name=comic_file_name) + book.save() + page_index = 0 + for page_file_name in sorted([str(x) for x in cbx.namelist()], key=str.lower): + try: + dot_index = page_file_name.rindex('.') + 1 + except ValueError: + continue + ext = page_file_name.lower()[dot_index:] + if ext in ['jpg', 'jpeg']: + content_type = 'image/jpeg' + elif ext == 'png': + content_type = 'image/png' + elif ext == 'bmp': + content_type = 'image/bmp' + elif ext == 'gif': + content_type = 'image/gif' + else: + content_type = 'text/plain' + page = ComicPage(Comic=book, + index=page_index, + page_file_name=page_file_name, + content_type=content_type) + page.save() + page_index += 1 + return book + + @staticmethod + def get_ordered_dir_list(folder): + directories = [] + files = [] + for item in listdir(folder): + if path.isdir(path.join(folder, item)): + directories.append(item) + else: + files.append(item) + return sorted(directories) + sorted(files) + class ComicPage(models.Model): Comic = models.ForeignKey(ComicBook) @@ -246,5 +354,4 @@ class ComicStatus(models.Model): last_read_page = models.IntegerField(default=0) unread = models.BooleanField(default=True) - # TODO: add support to reference items last being read diff --git a/comic/urls.py b/comic/urls.py index aa53442..e4c4ef9 100644 --- a/comic/urls.py +++ b/comic/urls.py @@ -9,7 +9,7 @@ urlpatterns = [ url(r'^settings/users/(?P[0-9]+)/$', views.user_config_page, name='users'), url(r'^settings/users/add/$', views.user_add_page, name='users'), url(r'^account/$', views.account_page, name='account'), - url(r'^(?P[\w]+)/$', views.comic_list, name='comic_list'), - url(r'^read/(?P[\w]+)/(?P[0-9]+)/$', views.read_comic, name='read_comic'), - url(r'^read/(?P[\w]+)/(?P[0-9]+)/img$', views.get_image, name='get_image'), + url(r'^read/(?P[\w-]+)/(?P[0-9]+)/$', views.read_comic, name='read_comic'), + url(r'^read/(?P[\w-]+)/(?P[0-9]+)/img$', views.get_image, name='get_image'), + url(r'^(?P[\w-]+)/$', views.comic_list, name='comic_list'), ] diff --git a/comic/util.py b/comic/util.py index 44cdb50..dbb57d5 100644 --- a/comic/util.py +++ b/comic/util.py @@ -1,14 +1,15 @@ +from collections import OrderedDict +from os import path, listdir + from django.utils.http import urlsafe_base64_encode -from os import path -from collections import OrderedDict -import os +from .models import ComicBook, Setting, ComicStatus, Directory -def generate_title_from_path(path): - if path == '': +def generate_title_from_path(file_path): + if file_path == '': return 'CBWebReader' - return 'CBWebReader - ' + ' - '.join(path.split(os.sep)) + return 'CBWebReader - ' + ' - '.join(file_path.split(path.sep)) class Menu: @@ -39,19 +40,22 @@ class Breadcrumb: return self.name -def generate_breadcrumbs_from_path(comic_path): +def generate_breadcrumbs_from_path(directory=False): + """ + + :type directory: Directory + """ output = [Breadcrumb()] - prefix = '/comic/' + prefix = b'/comic/' last = '' - comic_path = path.normpath(comic_path) - folders = comic_path.split(os.sep) - for item in folders: - if item == '.': - continue + if directory: + folders = directory.get_path_objects() + else: + folders = [] + for item in folders[::-1]: bc = Breadcrumb() - bc.name = item - last = path.join(last, item) - bc.url = prefix + urlsafe_base64_encode(last.encode()).decode() + bc.name = item.name + bc.url = prefix + urlsafe_base64_encode(item.selector.bytes) output.append(bc) return output @@ -66,12 +70,93 @@ def generate_breadcrumbs_from_menu(paths): return output +def generate_directory(user, directory=False): + """ + + :type user: User + :type directory: Directory + """ + base_dir = Setting.objects.get(name='BASE_DIR').value + files = [] + if directory: + dir_path = directory.path + ordered_dir_list = get_ordered_dir_list(path.join(base_dir, directory.path)) + else: + dir_path = '' + ordered_dir_list = get_ordered_dir_list(base_dir) + for file_name in ordered_dir_list: + df = ComicBook.DirFile() + df.name = file_name + if path.isdir(path.join(base_dir, dir_path, file_name)): + if directory: + d = Directory.objects.get(name=file_name, + parent=directory) + else: + d = Directory.objects.get(name=file_name, + parent__isnull=True) + df.isdir = True + df.icon = 'glyphicon-folder-open' + df.location = urlsafe_base64_encode(d.selector.bytes) + elif file_name.lower()[-4:] in ['.rar', '.zip', '.cbr', '.cbz']: + df.iscb = True + df.icon = 'glyphicon-book' + try: + if directory: + book = ComicBook.objects.get(file_name=file_name, + directory=directory) + else: + book = ComicBook.objects.get(file_name=file_name, + directory__isnull=True) + except ComicBook.DoesNotExist: + book = ComicBook.process_comic_book(file_name, directory) + df.location = urlsafe_base64_encode(book.selector.bytes) + status, _ = ComicStatus.objects.get_or_create(comic=book, user=user) + last_page = status.last_read_page + if status.unread: + df.label = 'Unread' + elif (last_page + 1) == book.page_count: + df.label = 'Read' + df.cur_page = last_page + else: + label_text = '%s/%s' % \ + (last_page + 1, book.page_count) + df.label = label_text + df.cur_page = last_page + + # df.label = 'Unprocessed' + files.append(df) + return files + + def get_ordered_dir_list(folder): directories = [] files = [] - for item in os.listdir(folder): + for item in listdir(folder): if path.isdir(path.join(folder, item)): directories.append(item) else: files.append(item) return sorted(directories) + sorted(files) + + +def scan_directory(directory=False): + """ + TODO: Increase efficiency of this. reduce amount of queries. + :type directory: Directory + """ + base_dir = Setting.objects.get(name='BASE_DIR').value + # filter(os.path.isdir, os.listdir(os.getcwd())) + if directory: + full_path = path.join(base_dir, directory.path) + else: + full_path = base_dir + dir_list = listdir(full_path) + directorys = [d for d in dir_list if path.isdir(path.join(full_path, d))] + for direct in directorys: + if directory: + d, created = Directory.objects.get_or_create(name=direct, + parent=directory) + else: + d, created = Directory.objects.get_or_create(name=direct) + if created: + d.save() diff --git a/comic/views.py b/comic/views.py index 12efe95..4b2ea03 100644 --- a/comic/views.py +++ b/comic/views.py @@ -1,20 +1,21 @@ -from django.http import HttpResponse -from django.template import RequestContext -from django.utils.http import urlsafe_base64_decode -from django.shortcuts import render, redirect, get_object_or_404 +import uuid +from os import path + +from django.contrib.auth import login, authenticate from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.models import User -from django.contrib.auth import login, authenticate +from django.http import HttpResponse +from django.shortcuts import render, redirect, get_object_or_404 +from django.utils.http import urlsafe_base64_decode -from .models import Setting, ComicBook, ComicStatus -from .util import generate_breadcrumbs_from_path, generate_breadcrumbs_from_menu, generate_title_from_path, Menu from .forms import SettingsForm, AccountForm, EditUserForm, AddUserForm, InitialSetupForm - -from os import path +from .models import Setting, ComicBook, ComicStatus, Directory +from .util import generate_breadcrumbs_from_path, generate_breadcrumbs_from_menu, \ + generate_title_from_path, Menu, generate_directory, scan_directory @login_required -def comic_list(request, comic_path=''): +def comic_list(request, directory_selector=False): try: base_dir = Setting.objects.get(name='BASE_DIR').value except Setting.DoesNotExist: @@ -22,16 +23,28 @@ def comic_list(request, comic_path=''): if not path.isdir(base_dir): return redirect('/comic/settings/') - comic_path = urlsafe_base64_decode(comic_path).decode() - title = generate_title_from_path(comic_path) - files = ComicBook.generate_directory(request.user, base_dir, comic_path) - context = { + if directory_selector: + directory_selector = uuid.UUID(bytes=urlsafe_base64_decode(directory_selector)) + directory = Directory.objects.get(selector=directory_selector) + else: + directory = False + + scan_directory(directory) + + if directory: + title = generate_title_from_path(directory.path) + breadcrumbs = generate_breadcrumbs_from_path(directory) + else: + title = generate_title_from_path('Home') + breadcrumbs = generate_breadcrumbs_from_path() + files = generate_directory(request.user, directory) + + return render(request, 'comic/comic_list.html', { 'file_list': files, - 'breadcrumbs': generate_breadcrumbs_from_path(comic_path), + 'breadcrumbs': breadcrumbs, 'menu': Menu(request.user, 'Browse'), 'title': title, - } - return render(request, 'comic/comic_list.html', context) + }) @login_required @@ -184,16 +197,19 @@ def settings_page(request): @login_required -def read_comic(request, comic_path, page): +def read_comic(request, comic_selector, page): base_dir = Setting.objects.get(name='BASE_DIR').value page = int(page) - decoded_path = urlsafe_base64_decode(comic_path).decode() - breadcrumbs = generate_breadcrumbs_from_path(decoded_path) - _, comic_file_name = path.split(decoded_path) - try: - book = ComicBook.objects.get(file_name=comic_file_name) - except ComicBook.DoesNotExist: - book = ComicBook.process_comic_book(base_dir, decoded_path, comic_file_name) + selector = uuid.UUID(bytes=urlsafe_base64_decode(comic_selector)) + book = get_object_or_404(ComicBook, selector=selector) + + breadcrumbs = generate_breadcrumbs_from_path(book.directory) + #comic_file_path, comic_file_name = path.split(decoded_path) + #d = Directory.get_dir_from_path(comic_file_path) + #try: + # book = ComicBook.objects.get(file_name=comic_file_name) + #except ComicBook.DoesNotExist: + # book = ComicBook.process_comic_book(comic_file_name, d) status, _ = ComicStatus.objects.get_or_create(comic=book, user=request.user) status.unread = False status.last_read_page = page @@ -202,7 +218,7 @@ def read_comic(request, comic_path, page): context = { 'book': book, 'orig_file_name': book.page_name(page), - 'nav': book.nav(comic_path, page), + 'nav': book.nav(page, request.user), 'breadcrumbs': breadcrumbs, 'menu': Menu(request.user), 'title': title, @@ -211,17 +227,10 @@ def read_comic(request, comic_path, page): @login_required -def get_image(_, comic_path, page): - base_dir = Setting.objects.get(name='BASE_DIR').value - page = int(page) - decoded_path = urlsafe_base64_decode(comic_path).decode() - _, comic_file_name = path.split(decoded_path) - try: - book = ComicBook.objects.get(file_name=comic_file_name) - except ComicBook.DoesNotExist: - book = ComicBook.process_comic_book(base_dir, decoded_path, comic_file_name) - full_path = path.join(base_dir, decoded_path) - img, content = book.get_image(full_path, page) +def get_image(_, comic_selector, page): + selector = uuid.UUID(bytes=urlsafe_base64_decode(comic_selector)) + book = ComicBook.objects.get(selector=selector) + img, content = book.get_image(int(page)) return HttpResponse(img.read(), content_type=content)