티스토리 게시물을 복구할 모델도 작성했으니, 이번에는 백업파일을 통해 db에 데이터를 채워볼 차례입니다.
백업파일을 읽고, 그 내용을 db에 작성하기 위해 utils.py를 다음과 같이 작성했습니다.
# seolpyo_/utils.py
from os import mkdir, listdir
from os.path import exists, isdir
from shutil import rmtree
from zipfile import ZipFile
from bs4 import BeautifulSoup
from django.conf import settings
from django.utils import timezone
from .models import Post, Category, Tag
base_path = getattr(settings, 'BASE_DIR')
path_zipfile = base_path / 'tistory.zip'
path_backup = base_path / 'backup_tistory'
def _unzip():
if not exists(path_zipfile): raise Exception('tistory.zip 파일을 찾을 수 없습니다.')
if exists(path_backup): raise Exception('압축 해제한 티스토리 백업 폴더가 존재합니다. "backup_tistory" 폴더를 삭제해주세요.')
else:
mkdir(path_backup)
# print('티스토리 백업 파일 디렉토리 생성')
with ZipFile(path_zipfile) as zipfile:
zipfile.extractall(path_backup)
# print('압축 해제 성공')
return
def _get_path():
# print(f'{listdir(path_backup)=}')
backup_name = listdir(path_backup)[0]
list_path = []
for pk in listdir(path_backup / backup_name):
path_pk = path_backup / backup_name / pk
if isdir(path_pk): list_path.append((pk, path_pk))
return list_path
def _convert_datetime(soup: BeautifulSoup):
djagnotime = timezone.now()
date_post = timezone.datetime.strptime(soup.select_one('p.date').text, '%Y-%m-%d %H:%M:%S')
# print(f'{date_post=}')
djagnotime = djagnotime.replace(
year=date_post.year, month=date_post.month, day=date_post.day,
hour=date_post.hour, minute=date_post.minute, second=date_post.second,
microsecond=0
) + timezone.timedelta(hours=-9)
# print(f'{djagnotime=}')
return djagnotime
def _get_category(soup: BeautifulSoup):
category = soup.select_one('p.category').text.strip()
if not category: category = None
else:
if '/' not in category:
category, _ = Category.objects.get_or_create(name=category)
else:
category_parent, category = category.split('/', 1)
category_parent, _ = Category.objects.get_or_create(name=category_parent)
category, _ = Category.objects.get_or_create(name=category)
category.parent = category_parent
category.save()
return category
def _get_tags(soup: BeautifulSoup):
tags = []
for i in soup.select_one('div.tags').text.split('#'):
name = i.strip()
if not name: continue
tag, _ = Tag.objects.get_or_create(name=name)
tags.append(tag)
return tags
def restore(author_id=1):
for i in ['공지사항', '페이지', '서식',]: Category.objects.get_or_create(name=i)
_unzip()
list_path = _get_path()
# print(f'{djagnotime=}')
for pk, path_pk in sorted(list_path, key=lambda x: int(x[0])):
# print()
# print(f'{pk=}')
# print(f'{path_pk=}')
for filename in listdir(path_pk):
filename: str
if filename.endswith('.html'):
with open(path_pk / filename, 'r', encoding='utf-8') as txt:
soup = BeautifulSoup(txt.read(), 'html.parser')
# print(soup.prettify())
date_post = _convert_datetime(soup)
category = _get_category(soup)
tags = _get_tags(soup)
post = Post(
pk=pk,
author_id=author_id,
title=soup.select_one('title').text.strip(),
content=str(soup.select_one('div.contents_style')),
date_post=date_post,
)
# for i in post.__dict__.items(): print(f' {i}')
if category: post.category = category
post.save()
post.tags.clear()
if tags: post.tags.add(*tags)
rmtree(path_backup)
# print('백업 파일 삭제 성공')
if __name__ == '__main__':
restore()
사용방법
utils.py의 restore() 함수를 통해 티스토리 백업파일의 압축을 해제하고, db를 작성(복구)합니다.
장고 프로젝트의 설정 옵션을 사용하기 때문에 django shell에서 실행해야 합니다.
티스토리 백업 파일을 "tistory.zip"이라는 이름으로 변경한 다음, 장고 프로젝트의 BASE_DIR에 옮긴 뒤
명령 프롬프트에 다음과 같이 명령어를 입력해주면 됩니다.
(django) C:\django\mysite>python manage.py shell
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from seolpyo_tistory import utils
>>> utils.restore()
>>> ^Z
now exiting InteractiveConsole...
(django) C:\django\mysite>
데이터베이스를 확인해보면 다음과 같이 티스토리 게시물을 옮겨온 것을 확인할 수 있습니다.
이 글의 댓글 기능은 일부러 막아놓았습니다. 궁금한 내용이 있다면 게시판을 이용해주세요!