diff --git a/comic/models.py b/comic/models.py index a87fc77..5c2f516 100644 --- a/comic/models.py +++ b/comic/models.py @@ -99,7 +99,7 @@ class ComicBook(models.Model): base_dir = settings.COMIC_BOOK_VOLUME return Path(base_dir, self.directory.get_path(), self.file_name) - def get_image(self, page): + def get_image(self, page: int): base_dir = settings.COMIC_BOOK_VOLUME if self.directory: archive_path = Path(base_dir, self.directory.path, self.file_name) @@ -112,7 +112,12 @@ class ComicBook(models.Model): except zipfile.BadZipfile: return False page_obj = ComicPage.objects.get(Comic=self, index=page) - out = (archive.open(page_obj.page_file_name), page_obj.content_type) + try: + out = (archive.open(page_obj.page_file_name), page_obj.content_type) + except rarfile.NoRarEntry: + ComicPage.objects.filter(Comic=self).delete() + self.process_comic_pages(archive, self) + out = self.get_image(page) return out def is_last_page(self, page): @@ -271,36 +276,17 @@ class ComicBook(models.Model): if not pdf_file and not cbx: return comic_file_name - 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 - if cbx: - 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 - elif pdf_file: + + if directory: + book = ComicBook(file_name=comic_file_name, directory=directory) + else: + book = ComicBook(file_name=comic_file_name) + book.save() + page_index = 0 + if cbx: + ComicBook.process_comic_pages(cbx, book) + elif pdf_file: + with atomic(): for page_index in range(pdf_file.getNumPages()): page = ComicPage( Comic=book, index=page_index, page_file_name=page_index+1, content_type='application/pdf' @@ -308,6 +294,32 @@ class ComicBook(models.Model): page.save() return book + @staticmethod + def process_comic_pages(cbx, book): + with atomic(): + 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 + @staticmethod def get_ordered_dir_list(folder): directories = [] diff --git a/comic/tests/test_models.py b/comic/tests/test_models.py index 1fa4907..b2465cd 100644 --- a/comic/tests/test_models.py +++ b/comic/tests/test_models.py @@ -280,3 +280,15 @@ class ComicBookTests(TestCase): response = c.get("/comic/account/") self.assertEqual(response.status_code, 200) + + def test_file_not_in_archive(self): + c = Client() + user = User.objects.get(username="test") + book = ComicBook.objects.get(file_name='test1.rar') + page = ComicPage.objects.get(Comic=book, index=0) + page.page_file_name = 'doesnt_exist' + page.save() + generate_directory(user) + c.login(username="test", password="test") + response = c.get(f"/comic/read/{urlsafe_base64_encode(book.selector.bytes)}/0/img") + self.assertEqual(response.status_code, 200) diff --git a/comic/views.py b/comic/views.py index 27b148d..062e4c2 100644 --- a/comic/views.py +++ b/comic/views.py @@ -301,6 +301,7 @@ def read_comic(request, comic_selector): except Directory.DoesNotExist: return HttpResponse(status=404) book = get_object_or_404(ComicBook, selector=selector) + pages = ComicPage.objects.filter(Comic=book) status, _ = ComicStatus.objects.get_or_create(comic=book, user=request.user)