옵시디언 파일 중 옵션에 따른 업로드 파일 설정
연결 문서
옵시디언 파일 중 옵션에 따른 업로드 파일 설정
- 원본 폴더 : 옵시디언 루트 디렉토리
- 복사 폴더 : 블로그 폴더로 절대 경로로 _post 를 가르키면 됨
import os
import yaml
import re
import shutil
from datetime import datetime
def get_md_files_with_blog_true(folder_path):
md_files_with_metadata = []
for root, dirs, files in os.walk(folder_path):
for file in files:
if file.endswith('.md'):
full_path = os.path.join(root, file)
with open(full_path, 'r', encoding='utf-8') as f:
content = f.read()
# YAML 프론트 매터 추출 (정규표현식 사용)
yaml_match = re.match(r'^---\s*\n(.*?)\n---\s*\n?', content, re.DOTALL)
if yaml_match:
yaml_content = yaml_match.group(1)
try:
metadata = yaml.safe_load(yaml_content)
# metadata가 딕셔너리인지 확인
if isinstance(metadata, dict) and 'blog' in metadata and metadata['blog'] == True:
md_files_with_metadata.append((full_path, metadata, content))
except yaml.YAMLError as e:
print(f"YAML 파싱 오류 ({full_path}): {e}")
return md_files_with_metadata
def generate_destination_path(md_file, metadata, folder_path, destination_base):
# 원본 폴더로부터의 상대 경로 계산
relative_path = os.path.relpath(md_file, folder_path)
# 파일 이름과 디렉토리 분리
relative_dir, original_filename = os.path.split(relative_path)
# 파일명과 확장자 분리
filename_without_ext, ext = os.path.splitext(original_filename)
# 파일 이름의 띄어쓰기를 '-'로 대체
modified_filename = filename_without_ext.replace(' ', '-')
# create_date 추출 및 날짜 부분만 사용
if 'create_date' in metadata:
# 날짜 부분만 추출 (YYYY-MM-DD)
create_date_str = str(metadata['create_date'])
try:
# create_date가 datetime 형식이 아닌 문자열일 수 있으므로 파싱 시도
create_date = datetime.strptime(create_date_str, '%Y-%m-%d %H:%M')
except ValueError:
try:
create_date = datetime.strptime(create_date_str, '%Y-%m-%d')
except ValueError:
print(f"날짜 형식 오류 ({md_file}): {create_date_str}")
return None
date_prefix = create_date.strftime('%Y-%m-%d')
else:
print(f"create_date 없음 ({md_file})")
return None
# 새로운 파일 이름 생성
new_filename = f"{date_prefix}-{modified_filename}{ext}"
# 새로운 상대 경로 생성
new_relative_path = os.path.join(relative_dir, new_filename)
# 대상 파일의 전체 경로 생성
destination_path = os.path.join(destination_base, new_relative_path)
return destination_path
def synchronize_folders(folder_path, destination_base):
# 원본 폴더의 파일 목록 가져오기
md_files_with_metadata = get_md_files_with_blog_true(folder_path)
# 복사 폴더의 기존 파일 목록 가져오기
existing_files_in_destination = []
for root, dirs, files in os.walk(destination_base):
for file in files:
if file.endswith('.md'):
existing_files_in_destination.append(os.path.join(root, file))
# 원본 파일의 대상 경로 매핑 생성 (원본 파일 경로: (대상 파일 경로, 메타데이터, 내용))
source_to_destination = {}
# 링크 매핑 생성 (파일 제목: URL)
title_to_url = {}
for md_file, metadata, original_content in md_files_with_metadata:
destination_path = generate_destination_path(md_file, metadata, folder_path, destination_base)
if destination_path:
source_to_destination[md_file] = (destination_path, metadata, original_content)
# 파일 제목에서 띄어쓰기를 '-'로 대체하여 URL 생성
if 'title' in metadata:
title = metadata['title']
url_title = title.replace(' ', '-')
# URL 생성 (도메인 이름은 필요에 따라 변경하세요)
url = f"https://chanp5660.github.io/{url_title}"
title_to_url[title] = url
# 대상 파일의 원본 파일 경로 목록
destination_files = [dest_path for dest_path, _, _ in source_to_destination.values()]
# 복사 폴더에서 원본에 없는 파일 삭제
for existing_file in existing_files_in_destination:
if existing_file not in destination_files:
os.remove(existing_file)
print(f"삭제됨: {existing_file}")
# 파일 복사 및 업데이트
for md_file, (destination_path, metadata, original_content) in source_to_destination.items():
# 대상 디렉토리가 존재하지 않으면 생성
destination_dir = os.path.dirname(destination_path)
if not os.path.exists(destination_dir):
os.makedirs(destination_dir)
# 파일이 없거나 원본이 더 최신이면 복사
if (not os.path.exists(destination_path)) or (os.path.getmtime(md_file) > os.path.getmtime(destination_path)):
# YAML 프론트 매터 수정
# 'tags'를 'categories'로 변경
if 'tags' in metadata:
metadata['categories'] = metadata.pop('tags')
# 'mathjax: true'와 'layout: post' 추가
metadata['mathjax'] = True
metadata['layout'] = 'post'
# 수정된 YAML 프론트 매터를 문자열로 변환
new_yaml_content = yaml.dump(metadata, allow_unicode=True, sort_keys=False)
# YAML 프론트 매터 재구성
new_front_matter = f"---\n{new_yaml_content}---\n"
# 원본 내용에서 기존 YAML 프론트 매터를 수정된 것으로 대체
new_content = re.sub(r'^---\s*\n(.*?)\n---\s*\n?', new_front_matter, original_content, flags=re.DOTALL)
# 내용 중 링크 변경
# 패턴: [[파일 제목]] (단, [[#파일 제목]]은 제외)
def replace_link(match):
full_match = match.group(0)
link_text = match.group(1)
if link_text.startswith('#'):
# [[#파일 제목]] 형태는 변경하지 않음
return full_match
else:
# 링크 텍스트에서 앞뒤 공백 제거
link_text = link_text.strip()
if link_text in title_to_url:
url = title_to_url[link_text]
return f"[{link_text}]({url})"
else:
return full_match # 매핑이 없으면 변경하지 않음
new_content = re.sub(r'\[\[([^\[\]]+)\]\]', replace_link, new_content)
# 수정된 내용을 대상으로 파일에 작성
with open(destination_path, 'w', encoding='utf-8') as f:
f.write(new_content)
print(f"복사 및 내용 수정 완료: {md_file} -> {destination_path}")
else:
#print(f"최신 상태 유지: {destination_path}")
continue
# 실행 부분
folder_path = '원본 폴더 경로' # 원본 폴더 경로로 변경하세요.
destination_base = '복사 폴더 경로' # 복사 폴더 경로로 변경하세요.
synchronize_folders(folder_path, destination_base)
Enjoy Reading This Article?
Here are some more articles you might like to read next: