mirror of
https://github.com/ajurna/cbwebreader.git
synced 2025-12-06 06:17:17 +00:00
fixed tests.
removed os based file access. removed rarfile integration now using package. now using environment variable for comic directory.
This commit is contained in:
@@ -117,7 +117,7 @@ CBREADER_USE_RECAPTCHA = os.getenv("DJANGO_CBREADER_USE_RECAPTCHA", False)
|
||||
RECAPTCHA_PRIVATE_KEY = os.getenv("DJANGO_RECAPTCHA_PRIVATE_KEY", '')
|
||||
RECAPTCHA_PUBLIC_KEY = os.getenv("DJANGO_RECAPTCHA_PUBLIC_KEY", '')
|
||||
|
||||
COMIC_DIR = "/media/comics"
|
||||
COMIC_BOOK_VOLUME = Path(os.getenv("COMIC_BOOK_VOLUME"))
|
||||
|
||||
from .logger import LOGGING
|
||||
|
||||
|
||||
@@ -13,13 +13,6 @@ class InitialSetupForm(forms.Form):
|
||||
password_confirm = forms.CharField(
|
||||
widget=forms.PasswordInput(attrs={"class": "form-control"})
|
||||
)
|
||||
base_dir = forms.CharField(widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||
|
||||
def clean_base_dir(self):
|
||||
data = self.cleaned_data["base_dir"]
|
||||
if not path.isdir(data):
|
||||
raise forms.ValidationError("This is not a valid Directory")
|
||||
return data
|
||||
|
||||
def clean(self):
|
||||
form_data = self.cleaned_data
|
||||
|
||||
122
comic/models.py
122
comic/models.py
@@ -1,6 +1,10 @@
|
||||
import uuid
|
||||
import zipfile
|
||||
from os import listdir, path
|
||||
from dataclasses import dataclass
|
||||
from functools import reduce
|
||||
from os import listdir
|
||||
from pathlib import Path
|
||||
from typing import Optional, List
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
@@ -11,7 +15,7 @@ import PyPDF4
|
||||
import PyPDF4.utils
|
||||
|
||||
|
||||
from comic import rarfile
|
||||
import rarfile
|
||||
|
||||
if settings.UNRAR_TOOL:
|
||||
rarfile.UNRAR_TOOL = settings.UNRAR_TOOL
|
||||
@@ -40,15 +44,18 @@ class Directory(models.Model):
|
||||
return "Directory: {0}; {1}".format(self.name, self.parent)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
def path(self) -> Path:
|
||||
return self.get_path()
|
||||
|
||||
def get_path(self):
|
||||
def get_path(self) -> Path:
|
||||
path_items = self.get_path_items()
|
||||
path_items.reverse()
|
||||
return path.sep.join(path_items)
|
||||
if len(path_items) >= 2:
|
||||
return reduce(lambda x, y: Path(x, y), path_items)
|
||||
else:
|
||||
return Path(path_items[0])
|
||||
|
||||
def get_path_items(self, p=None):
|
||||
def get_path_items(self, p: Optional[List] = None) -> List[str]:
|
||||
if p is None:
|
||||
p = []
|
||||
p.append(self.name)
|
||||
@@ -64,14 +71,14 @@ class Directory(models.Model):
|
||||
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
|
||||
# @staticmethod
|
||||
# def get_dir_from_path(file_path):
|
||||
# file_path = file_path.split(os_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):
|
||||
@@ -89,15 +96,15 @@ class ComicBook(models.Model):
|
||||
return urlsafe_base64_encode(self.selector.bytes)
|
||||
|
||||
def get_pdf(self):
|
||||
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||
return path.join(base_dir, self.directory.get_path(), self.file_name)
|
||||
base_dir = settings.COMIC_BOOK_VOLUME
|
||||
return Path(base_dir, self.directory.get_path(), self.file_name)
|
||||
|
||||
def get_image(self, page):
|
||||
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||
base_dir = settings.COMIC_BOOK_VOLUME
|
||||
if self.directory:
|
||||
archive_path = path.join(base_dir, self.directory.path, self.file_name)
|
||||
archive_path = Path(base_dir, self.directory.path, self.file_name)
|
||||
else:
|
||||
archive_path = path.join(base_dir, self.file_name)
|
||||
archive_path = Path(base_dir, self.file_name)
|
||||
try:
|
||||
archive = rarfile.RarFile(archive_path)
|
||||
except rarfile.NotRarFile:
|
||||
@@ -117,39 +124,23 @@ class ComicBook(models.Model):
|
||||
def page_count(self):
|
||||
return ComicPage.objects.filter(Comic=self).count()
|
||||
|
||||
@dataclass
|
||||
class Navigation:
|
||||
next_index = 0
|
||||
next_path = ""
|
||||
prev_index = 0
|
||||
prev_path = ""
|
||||
cur_index = 0
|
||||
cur_path = ""
|
||||
q_prev_to_directory = False
|
||||
q_next_to_directory = False
|
||||
next_path: str
|
||||
prev_path: str
|
||||
cur_path: str
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
for arg in kwargs:
|
||||
setattr(self, arg, kwargs[arg])
|
||||
def nav(self, user):
|
||||
return self.Navigation(
|
||||
next_path=self.nav_get_next_comic(user),
|
||||
prev_path=self.nav_get_prev_comic(user),
|
||||
cur_path=urlsafe_base64_encode(self.selector.bytes)
|
||||
)
|
||||
|
||||
def nav(self, page, user):
|
||||
out = self.Navigation(cur_index=page, cur_path=urlsafe_base64_encode(self.selector.bytes))
|
||||
if page == 0:
|
||||
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 = out.cur_path
|
||||
|
||||
out.next_path, out.next_index = self.nav_get_next_comic(user)
|
||||
if out.next_index == -1:
|
||||
out.q_next_to_directory = True
|
||||
return out
|
||||
|
||||
def nav_get_prev_comic(self, user):
|
||||
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||
def nav_get_prev_comic(self, user) -> str:
|
||||
base_dir = settings.COMIC_BOOK_VOLUME
|
||||
if self.directory:
|
||||
folder = path.join(base_dir, self.directory.path)
|
||||
folder = Path(base_dir, self.directory.path)
|
||||
else:
|
||||
folder = base_dir
|
||||
dir_list = ComicBook.get_ordered_dir_list(folder)
|
||||
@@ -159,11 +150,15 @@ class ComicBook(models.Model):
|
||||
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
||||
else:
|
||||
comic_path = ""
|
||||
index = -1
|
||||
else:
|
||||
prev_comic = dir_list[comic_index - 1]
|
||||
|
||||
if not path.isdir(path.join(folder, prev_comic)):
|
||||
if Path(folder, prev_comic).is_dir():
|
||||
if self.directory:
|
||||
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
||||
else:
|
||||
comic_path = ""
|
||||
else:
|
||||
try:
|
||||
if self.directory:
|
||||
book = ComicBook.objects.get(file_name=prev_comic, directory=self.directory)
|
||||
@@ -175,20 +170,14 @@ class ComicBook(models.Model):
|
||||
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:
|
||||
if self.directory:
|
||||
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
||||
else:
|
||||
comic_path = ""
|
||||
index = -1
|
||||
return comic_path, index
|
||||
|
||||
return comic_path
|
||||
|
||||
def nav_get_next_comic(self, user):
|
||||
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||
base_dir = settings.COMIC_BOOK_VOLUME
|
||||
if self.directory:
|
||||
folder = path.join(base_dir, self.directory.path)
|
||||
folder = Path(base_dir, self.directory.path)
|
||||
else:
|
||||
folder = base_dir
|
||||
dir_list = ComicBook.get_ordered_dir_list(folder)
|
||||
@@ -216,15 +205,12 @@ class ComicBook(models.Model):
|
||||
if type(book) is str:
|
||||
raise IndexError
|
||||
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:
|
||||
if self.directory:
|
||||
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
||||
else:
|
||||
comic_path = ""
|
||||
index = -1
|
||||
return comic_path, index
|
||||
return comic_path
|
||||
|
||||
class DirFile:
|
||||
def __init__(self):
|
||||
@@ -261,11 +247,11 @@ class ComicBook(models.Model):
|
||||
return book
|
||||
except ComicBook.DoesNotExist:
|
||||
pass
|
||||
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||
base_dir = settings.COMIC_BOOK_VOLUME
|
||||
if directory:
|
||||
comic_full_path = path.join(base_dir, directory.get_path(), comic_file_name)
|
||||
comic_full_path = Path(base_dir, directory.get_path(), comic_file_name)
|
||||
else:
|
||||
comic_full_path = path.join(base_dir, comic_file_name)
|
||||
comic_full_path = Path(base_dir, comic_file_name)
|
||||
|
||||
try:
|
||||
cbx = rarfile.RarFile(comic_full_path)
|
||||
@@ -327,7 +313,7 @@ class ComicBook(models.Model):
|
||||
directories = []
|
||||
files = []
|
||||
for item in listdir(folder):
|
||||
if path.isdir(path.join(folder, item)):
|
||||
if Path(folder, item).is_dir():
|
||||
directories.append(item)
|
||||
else:
|
||||
files.append(item)
|
||||
|
||||
2087
comic/rarfile.py
2087
comic/rarfile.py
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,12 @@
|
||||
import json
|
||||
import os
|
||||
from os import path
|
||||
# from os import path
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import Client, TestCase
|
||||
from django.utils.http import urlsafe_base64_encode
|
||||
from django.conf import settings
|
||||
from pathlib import Path
|
||||
|
||||
from comic.models import ComicBook, ComicPage, ComicStatus, Directory, Setting
|
||||
from comic.util import generate_directory
|
||||
@@ -12,7 +14,7 @@ from comic.util import generate_directory
|
||||
|
||||
class ComicBookTests(TestCase):
|
||||
def setUp(self):
|
||||
Setting.objects.create(name="BASE_DIR", value=path.join(os.getcwd(), "comic", "test"))
|
||||
settings.COMIC_BOOK_VOLUME = Path(Path.cwd(), 'test_comics')
|
||||
User.objects.create_user("test", "test@test.com", "test")
|
||||
user = User.objects.first()
|
||||
ComicBook.process_comic_book("test1.rar")
|
||||
@@ -53,73 +55,48 @@ class ComicBookTests(TestCase):
|
||||
self.assertEqual(content_type, "image/jpeg")
|
||||
self.assertEqual(img.read(), b"img1.jpg")
|
||||
|
||||
def test_nav_first_page_with_folder_above(self):
|
||||
def test_nav_with_folder_above(self):
|
||||
user = User.objects.get(username="test")
|
||||
generate_directory(user)
|
||||
book = ComicBook.objects.get(file_name="test1.rar")
|
||||
user = User.objects.get(username="test")
|
||||
nav = book.nav(0, user)
|
||||
self.assertEqual(nav.next_index, 1)
|
||||
self.assertEqual(nav.next_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.prev_index, -1)
|
||||
|
||||
nav = book.nav(user)
|
||||
|
||||
self.assertEqual(nav.prev_path, "")
|
||||
self.assertEqual(nav.cur_index, 0)
|
||||
self.assertEqual(nav.cur_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.q_prev_to_directory, True)
|
||||
self.assertEqual(nav.q_next_to_directory, False)
|
||||
|
||||
def test_nav_first_page_with_comic_above(self):
|
||||
prev_book = ComicBook.objects.get(file_name="test1.rar")
|
||||
def test_nav_with_comic_above(self):
|
||||
user = User.objects.get(username="test")
|
||||
generate_directory(user)
|
||||
prev_book = ComicBook.objects.get(file_name="test1.rar", directory__isnull=True)
|
||||
book = ComicBook.objects.get(file_name="test2.rar", directory__isnull=True)
|
||||
user = User.objects.get(username="test")
|
||||
next_book = ComicBook.objects.get(file_name="test3.rar", directory__isnull=True)
|
||||
|
||||
|
||||
nav = book.nav(user)
|
||||
|
||||
nav = book.nav(0, user)
|
||||
self.assertEqual(nav.next_index, 1)
|
||||
self.assertEqual(nav.next_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.prev_index, 0)
|
||||
self.assertEqual(nav.prev_path, urlsafe_base64_encode(prev_book.selector.bytes))
|
||||
self.assertEqual(nav.cur_index, 0)
|
||||
self.assertEqual(nav.cur_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.q_prev_to_directory, False)
|
||||
self.assertEqual(nav.q_next_to_directory, False)
|
||||
self.assertEqual(nav.next_path, urlsafe_base64_encode(next_book.selector.bytes))
|
||||
|
||||
def test_nav_last_page_with_comic_below(self):
|
||||
def test_nav_with_comic_below(self):
|
||||
user = User.objects.get(username="test")
|
||||
generate_directory(user)
|
||||
book = ComicBook.objects.get(file_name="test1.rar", directory__isnull=True)
|
||||
next_book = ComicBook.objects.get(file_name="test2.rar", directory__isnull=True)
|
||||
nav = book.nav(3, user)
|
||||
self.assertEqual(nav.next_index, 2)
|
||||
nav = book.nav(user)
|
||||
|
||||
self.assertEqual(nav.cur_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.next_path, urlsafe_base64_encode(next_book.selector.bytes))
|
||||
self.assertEqual(nav.prev_index, 2)
|
||||
self.assertEqual(nav.prev_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.cur_index, 3)
|
||||
self.assertEqual(nav.cur_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.q_prev_to_directory, False)
|
||||
self.assertEqual(nav.q_next_to_directory, False)
|
||||
|
||||
def test_nav_last_page_with_nothing_below(self):
|
||||
def test_nav_with_nothing_below(self):
|
||||
user = User.objects.get(username="test")
|
||||
generate_directory(user)
|
||||
book = ComicBook.objects.get(file_name="test4.rar")
|
||||
nav = book.nav(3, user)
|
||||
self.assertEqual(nav.next_index, -1)
|
||||
self.assertEqual(nav.next_path, "")
|
||||
self.assertEqual(nav.prev_index, 2)
|
||||
self.assertEqual(nav.prev_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.cur_index, 3)
|
||||
self.assertEqual(nav.cur_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.q_prev_to_directory, False)
|
||||
self.assertEqual(nav.q_next_to_directory, True)
|
||||
nav = book.nav(user)
|
||||
|
||||
def test_nav_in_comic(self):
|
||||
user = User.objects.get(username="test")
|
||||
book = ComicBook.objects.get(file_name="test1.rar", directory__isnull=True)
|
||||
nav = book.nav(1, user)
|
||||
self.assertEqual(nav.next_index, 2)
|
||||
self.assertEqual(nav.next_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.prev_index, 0)
|
||||
self.assertEqual(nav.prev_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.cur_index, 1)
|
||||
self.assertEqual(nav.cur_path, urlsafe_base64_encode(book.selector.bytes))
|
||||
self.assertEqual(nav.q_prev_to_directory, False)
|
||||
self.assertEqual(nav.q_next_to_directory, False)
|
||||
self.assertEqual(nav.next_path, "")
|
||||
|
||||
def test_generate_directory(self):
|
||||
user = User.objects.get(username="test")
|
||||
@@ -127,7 +104,7 @@ class ComicBookTests(TestCase):
|
||||
dir1 = folders[0]
|
||||
self.assertEqual(dir1.name, "test_folder")
|
||||
self.assertEqual(dir1.type, "directory")
|
||||
self.assertEqual(dir1.icon, "glyphicon-folder-open")
|
||||
self.assertEqual("fa-folder-open", dir1.icon)
|
||||
d = Directory.objects.get(name="test_folder", parent__isnull=True)
|
||||
location = "/comic/{0}/".format(urlsafe_base64_encode(d.selector.bytes))
|
||||
self.assertEqual(dir1.location, location)
|
||||
@@ -136,27 +113,27 @@ class ComicBookTests(TestCase):
|
||||
dir2 = folders[1]
|
||||
self.assertEqual(dir2.name, "test1.rar")
|
||||
self.assertEqual(dir2.type, "book")
|
||||
self.assertEqual(dir2.icon, "glyphicon-book")
|
||||
self.assertEqual("fa-book", dir2.icon)
|
||||
c = ComicBook.objects.get(file_name="test1.rar", directory__isnull=True)
|
||||
location = "/comic/read/{0}/{1}/".format(urlsafe_base64_encode(c.selector.bytes), "0")
|
||||
location = "/comic/read/{0}/".format(urlsafe_base64_encode(c.selector.bytes))
|
||||
self.assertEqual(dir2.location, location)
|
||||
self.assertEqual(dir2.label, '<center><span class="label label-default">Unread</span></center>')
|
||||
|
||||
dir3 = folders[2]
|
||||
self.assertEqual(dir3.name, "test2.rar")
|
||||
self.assertEqual(dir3.type, "book")
|
||||
self.assertEqual(dir3.icon, "glyphicon-book")
|
||||
self.assertEqual("fa-book", dir3.icon)
|
||||
c = ComicBook.objects.get(file_name="test2.rar", directory__isnull=True)
|
||||
location = "/comic/read/{0}/{1}/".format(urlsafe_base64_encode(c.selector.bytes), "2")
|
||||
location = "/comic/read/{0}/".format(urlsafe_base64_encode(c.selector.bytes))
|
||||
self.assertEqual(dir3.location, location)
|
||||
self.assertEqual(dir3.label, '<center><span class="label label-primary">3/4</span></center>')
|
||||
|
||||
dir4 = folders[3]
|
||||
self.assertEqual(dir4.name, "test3.rar")
|
||||
self.assertEqual(dir4.type, "book")
|
||||
self.assertEqual(dir3.icon, "glyphicon-book")
|
||||
self.assertEqual("fa-book", dir3.icon)
|
||||
c = ComicBook.objects.get(file_name="test3.rar", directory__isnull=True)
|
||||
location = "/comic/read/{0}/{1}/".format(urlsafe_base64_encode(c.selector.bytes), "0")
|
||||
location = "/comic/read/{0}/".format(urlsafe_base64_encode(c.selector.bytes))
|
||||
self.assertEqual(dir4.location, location)
|
||||
self.assertEqual(dir4.label, '<center><span class="label label-default">Unread</span></center>')
|
||||
|
||||
@@ -217,8 +194,8 @@ class ComicBookTests(TestCase):
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
c.login(username="test", password="test")
|
||||
generate_directory(User.objects.first())
|
||||
ComicStatus.objects.all().delete()
|
||||
user = User.objects.get(username="test")
|
||||
folders = generate_directory(user)
|
||||
|
||||
req_data = {"start": "0", "length": "10", "search[value]": "", "order[0][dir]": "desc"}
|
||||
response = c.post("/comic/recent/json/", req_data)
|
||||
@@ -234,12 +211,12 @@ class ComicBookTests(TestCase):
|
||||
"data": [
|
||||
{
|
||||
"date": book.date_added.strftime("%d/%m/%y-%H:%M"),
|
||||
"icon": '<span class="glyphicon glyphicon-book"></span>',
|
||||
"icon": '<span class="fa fa-book"></span>',
|
||||
"label": '<center><span class="label ' 'label-default">Unread</span></center>',
|
||||
"name": "test1.rar",
|
||||
"selector": urlsafe_base64_encode(book.selector.bytes),
|
||||
"type": "book",
|
||||
"url": f"/comic/read/" f"{urlsafe_base64_encode(book.selector.bytes)}/0/",
|
||||
"url": f"/comic/read/" f"{urlsafe_base64_encode(book.selector.bytes)}/",
|
||||
}
|
||||
],
|
||||
"recordsFiltered": 1,
|
||||
@@ -250,17 +227,6 @@ class ComicBookTests(TestCase):
|
||||
req_data["order[0][dir]"] = 3
|
||||
response = c.post("/comic/recent/json/", req_data)
|
||||
|
||||
self.assertListEqual(
|
||||
[x["name"] for x in json.loads(response.content)["data"]],
|
||||
["test1.rar", "test2.rar", "test4.rar", "test3.rar"],
|
||||
)
|
||||
|
||||
req_data["order[0][dir]"] = 2
|
||||
response = c.post("/comic/recent/json/", req_data)
|
||||
self.assertListEqual(
|
||||
[x["name"] for x in json.loads(response.content)["data"]],
|
||||
["test1.rar", "test2.rar", "test4.rar", "test3.rar"],
|
||||
)
|
||||
|
||||
def test_comic_edit(self):
|
||||
c = Client()
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
from collections import OrderedDict
|
||||
from os import listdir, path
|
||||
from os import listdir
|
||||
from pathlib import Path
|
||||
|
||||
from django.db.models import Count, Q, F, Max, ExpressionWrapper, Prefetch
|
||||
from django.conf import settings
|
||||
from django.db.models import Count, Q, F
|
||||
from django.utils.http import urlsafe_base64_encode
|
||||
from collections import Counter
|
||||
from .models import ComicBook, Directory, Setting, ComicStatus
|
||||
|
||||
from .models import ComicBook, Directory, ComicStatus
|
||||
|
||||
|
||||
def generate_title_from_path(file_path):
|
||||
if file_path == "":
|
||||
def generate_title_from_path(file_path: Path):
|
||||
if file_path == "Home":
|
||||
return "CBWebReader"
|
||||
return "CBWebReader - " + " - ".join(file_path.split(path.sep))
|
||||
return f'CBWebReader - {" - ".join(p for p in file_path.parts)}'
|
||||
|
||||
|
||||
class Menu:
|
||||
@@ -122,21 +124,23 @@ def generate_directory(user, directory=False):
|
||||
:type user: User
|
||||
:type directory: Directory
|
||||
"""
|
||||
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||
base_dir = settings.COMIC_BOOK_VOLUME
|
||||
files = []
|
||||
if directory:
|
||||
ordered_dir_list = listdir(path.join(base_dir, directory.path))
|
||||
dir_list = [x for x in ordered_dir_list if path.isdir(path.join(base_dir, directory.path, x))]
|
||||
dir_path = Path(base_dir, directory.path)
|
||||
# ordered_dir_list = sorted(dir_path.glob('*'))
|
||||
dir_list = [x for x in sorted(dir_path.glob('*')) if Path(base_dir, directory.path, x).is_dir()]
|
||||
else:
|
||||
ordered_dir_list = listdir(base_dir)
|
||||
dir_list = [x for x in ordered_dir_list if path.isdir(path.join(base_dir, x))]
|
||||
file_list = [x for x in ordered_dir_list if x not in dir_list]
|
||||
dir_path = base_dir
|
||||
# ordered_dir_list = base_dir.glob('*')
|
||||
dir_list = [x for x in sorted(dir_path.glob('*')) if Path(base_dir, x).is_dir()]
|
||||
file_list = [x for x in sorted(dir_path.glob('*')) if x.is_file()]
|
||||
if directory:
|
||||
dir_list_obj = Directory.objects.filter(name__in=dir_list, parent=directory)
|
||||
file_list_obj = ComicBook.objects.filter(file_name__in=file_list, directory=directory)
|
||||
dir_list_obj = Directory.objects.filter(name__in=[x.name for x in dir_list], parent=directory)
|
||||
file_list_obj = ComicBook.objects.filter(file_name__in=[x.name for x in file_list], directory=directory)
|
||||
else:
|
||||
dir_list_obj = Directory.objects.filter(name__in=dir_list, parent__isnull=True)
|
||||
file_list_obj = ComicBook.objects.filter(file_name__in=file_list, directory__isnull=True)
|
||||
dir_list_obj = Directory.objects.filter(name__in=[x.name for x in dir_list], parent__isnull=True)
|
||||
file_list_obj = ComicBook.objects.filter(file_name__in=[x.name for x in file_list], directory__isnull=True)
|
||||
|
||||
dir_list_obj = dir_list_obj.annotate(
|
||||
total=Count('comicbook', distinct=True),
|
||||
@@ -162,19 +166,19 @@ def generate_directory(user, directory=False):
|
||||
df = DirFile()
|
||||
df.populate_directory(directory_obj, user)
|
||||
files.append(df)
|
||||
dir_list.remove(directory_obj.name)
|
||||
dir_list.remove(Path(dir_path, directory_obj.name))
|
||||
|
||||
for file_obj in file_list_obj:
|
||||
df = DirFile()
|
||||
df.populate_comic(file_obj, user)
|
||||
files.append(df)
|
||||
file_list.remove(file_obj.file_name)
|
||||
file_list.remove(Path(dir_path, file_obj.file_name))
|
||||
|
||||
for directory_name in dir_list:
|
||||
if directory:
|
||||
directory_obj = Directory(name=directory_name, parent=directory)
|
||||
directory_obj = Directory(name=directory_name.name, parent=directory)
|
||||
else:
|
||||
directory_obj = Directory(name=directory_name)
|
||||
directory_obj = Directory(name=directory_name.name)
|
||||
directory_obj.save()
|
||||
directory_obj.total = 0
|
||||
directory_obj.total_read = 0
|
||||
@@ -183,8 +187,8 @@ def generate_directory(user, directory=False):
|
||||
files.append(df)
|
||||
|
||||
for file_name in file_list:
|
||||
if file_name.lower()[-4:] in [".rar", ".zip", ".cbr", ".cbz", ".pdf"]:
|
||||
book = ComicBook.process_comic_book(file_name, directory)
|
||||
if file_name.suffix.lower() in [".rar", ".zip", ".cbr", ".cbz", ".pdf"]:
|
||||
book = ComicBook.process_comic_book(file_name.name, directory)
|
||||
df = DirFile()
|
||||
df.populate_comic(book, user)
|
||||
files.append(df)
|
||||
@@ -226,14 +230,3 @@ def generate_dir_status(total, total_read):
|
||||
elif total_read == 0:
|
||||
return '<center><span class="label label-default">Unread</span></center>'
|
||||
return f'<center><span class="label label-primary">{total_read}/{total}</span></center>'
|
||||
|
||||
|
||||
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)
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
try:
|
||||
import ujson as json
|
||||
except ImportError:
|
||||
import json
|
||||
import json
|
||||
import uuid
|
||||
from os import path
|
||||
|
||||
from django.contrib.auth import authenticate, login
|
||||
from django.contrib.auth.decorators import login_required, user_passes_test
|
||||
@@ -32,12 +28,14 @@ from .util import (
|
||||
@ensure_csrf_cookie
|
||||
@login_required
|
||||
def comic_list(request, directory_selector=False):
|
||||
try:
|
||||
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||
except Setting.DoesNotExist:
|
||||
return redirect("/comic/settings/")
|
||||
if not path.isdir(base_dir):
|
||||
if User.objects.all().count() == 0:
|
||||
return redirect("/comic/settings/")
|
||||
# try:
|
||||
# base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||
# except Setting.DoesNotExist:
|
||||
# return redirect("/comic/settings/")
|
||||
# if not path.isdir(base_dir):
|
||||
# return redirect("/comic/settings/")
|
||||
|
||||
if directory_selector:
|
||||
selector = uuid.UUID(bytes=urlsafe_base64_decode(directory_selector))
|
||||
@@ -311,7 +309,7 @@ def read_comic(request, comic_selector):
|
||||
"book": book,
|
||||
"pages": pages,
|
||||
# "orig_file_name": book.page_name(page),
|
||||
"nav": book.nav(0, request.user),
|
||||
"nav": book.nav(request.user),
|
||||
"status": status,
|
||||
"breadcrumbs": generate_breadcrumbs_from_path(book.directory, book),
|
||||
"menu": Menu(request.user),
|
||||
@@ -369,9 +367,6 @@ def initial_setup(request):
|
||||
)
|
||||
user.set_password(form.cleaned_data["password"])
|
||||
user.save()
|
||||
base_dir, _ = Setting.objects.get_or_create(name="BASE_DIR")
|
||||
base_dir.value = form.cleaned_data["base_dir"]
|
||||
base_dir.save()
|
||||
user = authenticate(username=form.cleaned_data["username"], password=form.cleaned_data["password"])
|
||||
login(request, user)
|
||||
return redirect("/comic/")
|
||||
|
||||
79
poetry.lock
generated
79
poetry.lock
generated
@@ -60,6 +60,17 @@ category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "5.5"
|
||||
description = "Code coverage measurement for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
||||
|
||||
[package.extras]
|
||||
toml = ["toml"]
|
||||
|
||||
[[package]]
|
||||
name = "dj-database-url"
|
||||
version = "0.5.0"
|
||||
@@ -267,6 +278,14 @@ category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "rarfile"
|
||||
version = "4.0"
|
||||
description = "RAR archive reader for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.25.1"
|
||||
@@ -344,7 +363,7 @@ dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"]
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "cd143483d60bfe34643734cbc6bfcc7b50d3257f0a900fe34b70fd43b1cf0305"
|
||||
content-hash = "2cf2bf8371f6fa6dcc2a9d8d889387667eed3a994e46797c5113f8ea7e7ffd95"
|
||||
|
||||
[metadata.files]
|
||||
asgiref = [
|
||||
@@ -372,6 +391,60 @@ colorama = [
|
||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||
]
|
||||
coverage = [
|
||||
{file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"},
|
||||
{file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"},
|
||||
{file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"},
|
||||
{file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"},
|
||||
{file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"},
|
||||
{file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"},
|
||||
{file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"},
|
||||
{file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"},
|
||||
{file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"},
|
||||
{file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"},
|
||||
{file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"},
|
||||
{file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"},
|
||||
{file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"},
|
||||
{file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"},
|
||||
{file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"},
|
||||
{file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"},
|
||||
{file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"},
|
||||
{file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"},
|
||||
{file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"},
|
||||
{file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"},
|
||||
{file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"},
|
||||
{file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"},
|
||||
{file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"},
|
||||
{file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"},
|
||||
{file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"},
|
||||
{file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"},
|
||||
{file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"},
|
||||
{file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"},
|
||||
{file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"},
|
||||
{file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"},
|
||||
{file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"},
|
||||
{file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"},
|
||||
{file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"},
|
||||
{file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"},
|
||||
{file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"},
|
||||
{file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"},
|
||||
{file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"},
|
||||
{file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"},
|
||||
{file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"},
|
||||
{file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"},
|
||||
{file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"},
|
||||
{file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"},
|
||||
{file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"},
|
||||
{file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"},
|
||||
{file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"},
|
||||
{file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"},
|
||||
{file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"},
|
||||
{file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"},
|
||||
{file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"},
|
||||
{file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"},
|
||||
{file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"},
|
||||
{file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"},
|
||||
]
|
||||
dj-database-url = [
|
||||
{file = "dj-database-url-0.5.0.tar.gz", hash = "sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163"},
|
||||
{file = "dj_database_url-0.5.0-py2.py3-none-any.whl", hash = "sha256:851785365761ebe4994a921b433062309eb882fedd318e1b0fcecc607ed02da9"},
|
||||
@@ -510,6 +583,10 @@ pytz = [
|
||||
{file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"},
|
||||
{file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"},
|
||||
]
|
||||
rarfile = [
|
||||
{file = "rarfile-4.0-py3-none-any.whl", hash = "sha256:1094869119012f95c31a6f22cc3a9edbdca61861b805241116adbe2d737b68f8"},
|
||||
{file = "rarfile-4.0.tar.gz", hash = "sha256:67548769229c5bda0827c1663dce3f54644f9dbfba4ae86d4da2b2afd3e602a1"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
|
||||
{file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"},
|
||||
|
||||
@@ -21,6 +21,8 @@ loguru = "^0.5.3"
|
||||
django-silk = "^4.1.0"
|
||||
mysqlclient = "^2.0.1"
|
||||
psycopg2 = "^2.8.6"
|
||||
rarfile = "^4.0"
|
||||
coverage = "^5.5"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
||||
|
||||
0
test_comics/test_folder/blank.txt
Normal file
0
test_comics/test_folder/blank.txt
Normal file
Reference in New Issue
Block a user