Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 50 additions & 12 deletions Dstonylion/story/utils.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,64 @@
#생성된 동화를 페이지별로 나누는 공통 로직
import re

def split_into_pages(text: str, sentences_per_page: int = 3):
def split_into_pages_classic(text: str):
if not text:
return []

sentences = re.split(r'(?<=[.!?])\s+', text.strip())
sentences = re.split(r'\n+', text.strip())
sentences = [s.strip() for s in sentences if s.strip()]

pages = []
buffer = []
idx = 0

for s in sentences:
if not s:
continue
while idx < len(sentences):
candidates = sentences[idx:idx+3]

buffer.append(s.strip())
placed = False
for count in [3, 2, 1]:
if len(candidates) >= count:
chunk = " ".join(candidates[:count])
if len(chunk) <= 70:
pages.append(chunk)
idx += count
placed = True
break

if len(buffer) == sentences_per_page:
pages.append(" ".join(buffer))
buffer = []

if buffer:
pages.append(" ".join(buffer))
if not placed:
pages.append(candidates[0])
idx += 1

return pages

def split_into_pages(text: str):
if not text:
return []

sentences = re.split(r'(?<=[.!?"]) +', text.strip())
sentences = [s.strip() for s in sentences if s.strip()]

pages = []
idx = 0
max_len = 70

while idx < len(sentences):
candidates = sentences[idx:idx+3]
placed = False

for count in [3, 2, 1]:
if len(candidates) >= count:
chunk = " ".join(candidates[:count])

if len(chunk) <= max_len:
pages.append(chunk)
idx += count
placed = True
break

if not placed:
single = candidates[0]
pages.append(single)
idx += 1

return pages
54 changes: 51 additions & 3 deletions Dstonylion/story/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from rest_framework import viewsets, status
from django.contrib.auth import get_user_model
from django.shortcuts import get_object_or_404
from story.utils import split_into_pages
from story.utils import *
from dotenv import load_dotenv
from django.utils.text import slugify

Expand Down Expand Up @@ -458,6 +458,11 @@ def post(self, request):
- 아래 초안을 참고하되, 내용은 부드럽게 재창작
- 초안을 그대로 복붙하지 말고 흐름을 자연스럽게 구성
- 마무리를 동화스럽게 교훈 키워드를 잘 활용

[문장 길이 규칙 - 강제]
- **한 문장은 공백 포함 35자 이상 70자 이하로 작성**
- 문장은 마침표/물음표/느낌표로 자연스럽게 끝나는 구조로 작성

[사용자 초안]
{draft}
"""
Expand Down Expand Up @@ -808,6 +813,14 @@ def get(self, request, story_id):
serializer = StorySerializer(story)
return Response(serializer.data, status=200)

def delete(self, request, story_id):
story = Story.objects.filter(id=story_id).first()
if not story:
return Response({"detail": "Story not found"}, status=404)

story.delete()
return Response({"detail": "Story deleted successfully"})

class StoryPageListView(APIView):
def get(self, request, story_id):
story = Story.objects.filter(id=story_id).first()
Expand Down Expand Up @@ -878,6 +891,7 @@ def post(self, request):
return Response({"story_id": story.id, "title": story.title}, status=201)

import chardet
from django.core.files.base import ContentFile
class ClassicStoryUploadView(APIView):

def post(self, request):
Expand Down Expand Up @@ -924,18 +938,52 @@ def post(self, request):
created_at=timezone.now(),
)

pages = split_into_pages(raw_text)
pages = split_into_pages_classic(raw_text)

story_pages = []
for i, page_text in enumerate(pages, start=1):
StoryPage.objects.create(
sp = StoryPage.objects.create(
story=story,
page_number=i,
text=page_text
)
story_pages.append(sp)

story.page_count = len(pages)
story.save()

#삽화 png 연결
base_name = filename.replace(".txt", "")
illustration_dir = f"story_illustrations/{base_name}/"

try:
all_files = default_storage.listdir(illustration_dir)[1] # files only
except FileNotFoundError:
all_files = []

#표지 이미지 처리
cover_name = f"{base_name}_cover.png"
cover_path = illustration_dir + cover_name

if cover_name in all_files and default_storage.exists(cover_path):
with default_storage.open(cover_path, "rb") as f:
story.cover.save(cover_name, ContentFile(f.read()))
story.save()

#삽화 이미지 처리
for sp in story_pages:
page_png = f"{base_name}_p{sp.page_number}.png"
png_path = illustration_dir + page_png

if page_png in all_files and default_storage.exists(png_path):
with default_storage.open(png_path, "rb") as f:
img_bytes = f.read()

Illustrations.objects.create(
story_page=sp,
image=ContentFile(img_bytes, name=page_png)
)

return Response({
"story_id": story.id,
"title": story.title,
Expand Down