Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,108 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import pandas as pd
|
3 |
import io
|
4 |
import re
|
@@ -7,7 +111,7 @@ from datetime import datetime
|
|
7 |
import tempfile
|
8 |
import os
|
9 |
|
10 |
-
# 한국어 폰트 라이선스 데이터베이스
|
11 |
FONT_LICENSE_DB = {
|
12 |
"나눔고딕": {
|
13 |
"license": "SIL OFL 1.1",
|
@@ -16,7 +120,7 @@ FONT_LICENSE_DB = {
|
|
16 |
"modification": "가능",
|
17 |
"provider": "네이버",
|
18 |
"provider_url": "https://hangeul.naver.com/2017/nanum",
|
19 |
-
"notes": "
|
20 |
},
|
21 |
"나눔바른고딕": {
|
22 |
"license": "SIL OFL 1.1",
|
@@ -25,7 +129,7 @@ FONT_LICENSE_DB = {
|
|
25 |
"modification": "가능",
|
26 |
"provider": "네이버",
|
27 |
"provider_url": "https://hangeul.naver.com/2017/nanum",
|
28 |
-
"notes": "
|
29 |
},
|
30 |
"나눔명조": {
|
31 |
"license": "SIL OFL 1.1",
|
@@ -34,25 +138,52 @@ FONT_LICENSE_DB = {
|
|
34 |
"modification": "가능",
|
35 |
"provider": "네이버",
|
36 |
"provider_url": "https://hangeul.naver.com/2017/nanum",
|
37 |
-
"notes": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
},
|
39 |
"배달의민족 주아": {
|
40 |
-
"license": "커스텀 무료",
|
41 |
"commercial_free": "✅ 가능",
|
42 |
"attribution": "불필요",
|
43 |
"modification": "불가능",
|
44 |
"provider": "배달의민족",
|
45 |
"provider_url": "https://www.woowahan.com/fonts",
|
46 |
-
"notes": "BI 제작 시 사용 금지"
|
47 |
},
|
48 |
"배달의민족 도현": {
|
49 |
-
"license": "커스텀 무료",
|
50 |
"commercial_free": "✅ 가능",
|
51 |
"attribution": "불필요",
|
52 |
"modification": "불가능",
|
53 |
"provider": "배달의민족",
|
54 |
"provider_url": "https://www.woowahan.com/fonts",
|
55 |
-
"notes": "BI 제작 시 사용 금지"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
},
|
57 |
"서울남산체": {
|
58 |
"license": "SIL OFL 1.1",
|
@@ -61,7 +192,7 @@ FONT_LICENSE_DB = {
|
|
61 |
"modification": "가능",
|
62 |
"provider": "서울시",
|
63 |
"provider_url": "https://www.seoul.go.kr/solution/font.do",
|
64 |
-
"notes": "
|
65 |
},
|
66 |
"서울한강체": {
|
67 |
"license": "SIL OFL 1.1",
|
@@ -70,52 +201,115 @@ FONT_LICENSE_DB = {
|
|
70 |
"modification": "가능",
|
71 |
"provider": "서울시",
|
72 |
"provider_url": "https://www.seoul.go.kr/solution/font.do",
|
73 |
-
"notes": "
|
74 |
},
|
75 |
-
"Noto Sans
|
76 |
"license": "SIL OFL 1.1",
|
|
|
77 |
"commercial_free": "✅ 가능",
|
78 |
"attribution": "불필요",
|
79 |
"modification": "가능",
|
80 |
"provider": "Google",
|
81 |
"provider_url": "https://fonts.google.com/noto",
|
82 |
-
"notes": "
|
83 |
},
|
84 |
-
"
|
85 |
"license": "SIL OFL 1.1",
|
|
|
86 |
"commercial_free": "✅ 가능",
|
87 |
"attribution": "불필요",
|
88 |
"modification": "가능",
|
89 |
"provider": "Adobe/Google",
|
90 |
"provider_url": "https://fonts.google.com/noto",
|
91 |
-
"notes": "
|
92 |
},
|
93 |
"Pretendard": {
|
94 |
"license": "SIL OFL 1.1",
|
|
|
95 |
"commercial_free": "✅ 가능",
|
96 |
"attribution": "불필요",
|
97 |
"modification": "가능",
|
98 |
"provider": "Kil Hyung-jin",
|
99 |
"provider_url": "https://github.com/orioncactus/pretendard",
|
100 |
-
"notes": "
|
101 |
},
|
102 |
"SUIT": {
|
103 |
"license": "SIL OFL 1.1",
|
|
|
104 |
"commercial_free": "✅ 가능",
|
105 |
"attribution": "불필요",
|
106 |
"modification": "가능",
|
107 |
"provider": "SUNN",
|
108 |
"provider_url": "https://github.com/sunn-us/SUIT",
|
109 |
-
"notes": "
|
110 |
},
|
111 |
-
"IBM Plex Sans
|
112 |
"license": "SIL OFL 1.1",
|
|
|
113 |
"commercial_free": "✅ 가능",
|
114 |
"attribution": "불필요",
|
115 |
"modification": "가능",
|
116 |
"provider": "IBM",
|
117 |
"provider_url": "https://fonts.google.com/specimen/IBM+Plex+Sans+KR",
|
118 |
-
"notes": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
},
|
120 |
"윤고딕": {
|
121 |
"license": "상업적 라이선스 필요",
|
@@ -124,7 +318,16 @@ FONT_LICENSE_DB = {
|
|
124 |
"modification": "라이선스에 따라",
|
125 |
"provider": "윤디자인그룹",
|
126 |
"provider_url": "https://www.yoondesign.com",
|
127 |
-
"notes": "개인 사용만
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
},
|
129 |
"산돌고딕": {
|
130 |
"license": "상업적 라이선스 필요",
|
@@ -133,7 +336,16 @@ FONT_LICENSE_DB = {
|
|
133 |
"modification": "라이선스에 따라",
|
134 |
"provider": "산돌커뮤니케이션",
|
135 |
"provider_url": "https://www.sandoll.co.kr",
|
136 |
-
"notes": "개인 사용만
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
}
|
138 |
}
|
139 |
|
@@ -157,39 +369,68 @@ def clean_font_name(font_name):
|
|
157 |
return cleaned
|
158 |
|
159 |
def find_font_license(font_name):
|
160 |
-
"""폰트 라이선스 정보 찾기"""
|
161 |
cleaned_name = clean_font_name(font_name)
|
162 |
|
163 |
# 정확한 매칭
|
164 |
if cleaned_name in FONT_LICENSE_DB:
|
165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
|
167 |
# 부분 매칭
|
168 |
for db_font, info in FONT_LICENSE_DB.items():
|
169 |
if db_font.lower() in cleaned_name.lower() or cleaned_name.lower() in db_font.lower():
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
171 |
|
172 |
-
# 패턴 매칭
|
173 |
special_patterns = {
|
174 |
r'nanum|나눔': "나눔고딕",
|
175 |
r'baemin|배민|배달의민족': "배달의민족 주아",
|
176 |
r'seoul|서울': "서울남산체",
|
177 |
r'pretendard': "Pretendard",
|
178 |
-
r'noto.*sans': "Noto Sans
|
179 |
-
r'
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
r'yoon|윤': "윤고딕",
|
181 |
-
r'sandoll|산돌': "산돌고딕"
|
|
|
|
|
182 |
}
|
183 |
|
184 |
for pattern, matched_font in special_patterns.items():
|
185 |
if re.search(pattern, cleaned_name.lower()):
|
186 |
if matched_font in FONT_LICENSE_DB:
|
187 |
-
|
|
|
|
|
|
|
|
|
|
|
188 |
|
189 |
# 유사도 매칭
|
190 |
matches = get_close_matches(cleaned_name, FONT_LICENSE_DB.keys(), n=1, cutoff=0.6)
|
191 |
if matches:
|
192 |
-
|
|
|
|
|
|
|
|
|
|
|
193 |
|
194 |
# 기본값
|
195 |
return {
|
@@ -199,7 +440,8 @@ def find_font_license(font_name):
|
|
199 |
"modification": "❓ 확인 필요",
|
200 |
"provider": "❓ 확인 필요",
|
201 |
"provider_url": "",
|
202 |
-
"
|
|
|
203 |
}
|
204 |
|
205 |
def parse_font_list(file_content):
|
@@ -238,9 +480,12 @@ def analyze_fonts(file_content):
|
|
238 |
font_name = clean_font_name(font_file)
|
239 |
license_info = find_font_license(font_name)
|
240 |
|
|
|
|
|
|
|
241 |
results.append({
|
242 |
"원본 파일명": font_file,
|
243 |
-
"폰트명":
|
244 |
"라이선스": license_info["license"],
|
245 |
"상업적 사용": license_info["commercial_free"],
|
246 |
"출처 표시": license_info["attribution"],
|
|
|
1 |
+
gr.Markdown("""
|
2 |
+
### 사용 방법
|
3 |
+
1. 메모장에서 폰트 파일명을 한 줄에 하나씩 입력
|
4 |
+
2. txt 파일로 저장 후 업로드
|
5 |
+
3. 분석 결과 확인 및 엑셀 다운로드
|
6 |
+
|
7 |
+
**예시 파일 내용:**
|
8 |
+
```
|
9 |
+
NanumGothic.ttf
|
10 |
+
Pretendard-Regular.otf
|
11 |
+
BMDOHYEON_ttf.ttf
|
12 |
+
```
|
13 |
+
""")
|
14 |
+
|
15 |
+
with gr.Column(scale=2):
|
16 |
+
gr.Markdown("## 📊 분석 결과")
|
17 |
+
|
18 |
+
summary_output = gr.Markdown("파일을 업로드하세요.")
|
19 |
+
|
20 |
+
result_table = gr.Dataframe(
|
21 |
+
headers=["원본 파일명", "폰트명", "라이선스", "상업적 사용", "출처 표시", "수정 가능", "제공처", "제공처 URL", "비고"],
|
22 |
+
label="폰트 라이선스 정보",
|
23 |
+
column_widths=["15%", "12%", "15%", "10%", "8%", "8%", "12%", "20%", "20%"],
|
24 |
+
interactive=True
|
25 |
+
)
|
26 |
+
|
27 |
+
excel_download = gr.File(label="📥 엑셀 다운로드", visible=False)
|
28 |
+
|
29 |
+
with gr.Accordion("📋 샘플 결과", open=False):
|
30 |
+
sample_data = [
|
31 |
+
["NanumGothic.ttf", "나눔고딕", "SIL OFL 1.1", "✅ 가능", "불필요", "가능", "네이버", "https://hangeul.naver.com/2017/nanum", "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"],
|
32 |
+
["Pretendard-Regular.otf", "프리텐다드", "SIL OFL 1.1", "✅ 가능", "불필요", "가능", "Kil Hyung-jin", "https://github.com/orioncactus/pretendard", "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"],
|
33 |
+
["YoonGothic.ttf", "윤고딕", "상업적 라이선스 필요", "❌ 유료", "해당없음", "라이선스에 따라", "윤디자인그룹", "https://www.yoondesign.com", "개인 사용만 무료, 상업적 사용 시 유료 라이선스 구매 필요"],
|
34 |
+
["KoPubWorldDotum.ttf", "KoPubWorld돋움체", "공공누리 제1유형", "✅ 가능", "필요", "가능", "한국출판인쇄문화협회", "http://www.kopus.org/biz/electronic/font.aspx", "공공누리 제1유형: 출처표시 조건으로 자유이용 가능"]
|
35 |
+
]
|
36 |
+
|
37 |
+
gr.Dataframe(
|
38 |
+
value=sample_data,
|
39 |
+
headers=["원본 파일명", "폰트명", "라이선스", "상업적 사용", "출처 표시", "수정 가능", "제공처", "제공처 URL", "비고"],
|
40 |
+
column_widths=["15%", "12%", "15%", "10%", "8%", "8%", "12%", "20%", "20%"]
|
41 |
+
)
|
42 |
+
|
43 |
+
with gr.Accordion("ℹ️ 라이선스 유형 설명", open=False):
|
44 |
+
gr.Markdown("""
|
45 |
+
### 주요 라이선스 유형 (재검증됨)
|
46 |
+
|
47 |
+
**✅ SIL OFL 1.1 (Open Font License)**
|
48 |
+
- 상업적 사용: 완전 자유
|
49 |
+
- 출처 표시: 불필요
|
50 |
+
- 수정/재배포: 가능
|
51 |
+
- 웹폰트 사용: 가능
|
52 |
+
|
53 |
+
**✅ 커스텀 무료 라이선스**
|
54 |
+
- 각 제작사별 고유 조건
|
55 |
+
- 대부분 상업적 사용 가능
|
56 |
+
- 일부 제한사항 존재 (BI 사용 금지 등)
|
57 |
+
|
58 |
+
**✅ 공공누리 제1유형**
|
59 |
+
- 공공기관에서 제작한 폰트
|
60 |
+
- 출처표시 조건으로 자유이용 가능
|
61 |
+
- 상업적 사용 가능
|
62 |
+
|
63 |
+
**❌ 상업적 라이선스 필요**
|
64 |
+
- 개인 사용: 무료
|
65 |
+
- 상업적 사용: 유료 라이선스 구매 필요
|
66 |
+
- 주로 전문 폰트 제작사 폰트들
|
67 |
+
|
68 |
+
**❓ 확인 필요**
|
69 |
+
- 데이터베이스에 정보가 없는 폰트
|
70 |
+
- 제작사 공식 사이트에서 직접 확인 필요
|
71 |
+
""")
|
72 |
+
|
73 |
+
gr.Markdown("""
|
74 |
+
### ⚠️ 안내사항
|
75 |
+
- 참고용 도구입니다. 상업적 사용 전 공def create_app():
|
76 |
+
with gr.Blocks(title="한국어 폰트 라이선스 분석기") as app:
|
77 |
+
|
78 |
+
gr.Markdown("""
|
79 |
+
# 🔍 한국어 폰트 라이선스 분석기
|
80 |
+
|
81 |
+
**폰트 목록을 업로드하면 라이선스 정보를 분석하여 엑셀로 제공합니다!**
|
82 |
+
""")
|
83 |
+
|
84 |
+
with gr.Row():
|
85 |
+
with gr.Column(scale=1):
|
86 |
+
gr.Markdown("## 📁 폰트 목록 파일 업로드")
|
87 |
+
|
88 |
+
file_input = gr.File(
|
89 |
+
label="폰트 목록 텍스트 파일 (.txt)",
|
90 |
+
file_types=[".txt"]
|
91 |
+
)
|
92 |
+
|
93 |
+
analyze_btn = gr.Button("🔍 라이선스 분석 시작", variant="primary")
|
94 |
+
|
95 |
+
gr.Markdown("""
|
96 |
+
### 사용 방법
|
97 |
+
1. 메모장에서 폰트 파일명을 한 줄에 하���씩 입력
|
98 |
+
2. txt 파일로 저장 후 업로드
|
99 |
+
3. 분석 결과 확인 및 엑셀 다운로드
|
100 |
+
|
101 |
+
**예시 파일 내용:**
|
102 |
+
```
|
103 |
+
NanumGothic.ttf
|
104 |
+
Pretendard-Regular.otf
|
105 |
+
BMDOHYEON_ttimport gradio as gr
|
106 |
import pandas as pd
|
107 |
import io
|
108 |
import re
|
|
|
111 |
import tempfile
|
112 |
import os
|
113 |
|
114 |
+
# 한국어 폰트 라이선스 데이터베이스 (재검증됨)
|
115 |
FONT_LICENSE_DB = {
|
116 |
"나눔고딕": {
|
117 |
"license": "SIL OFL 1.1",
|
|
|
120 |
"modification": "가능",
|
121 |
"provider": "네이버",
|
122 |
"provider_url": "https://hangeul.naver.com/2017/nanum",
|
123 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
124 |
},
|
125 |
"나눔바른고딕": {
|
126 |
"license": "SIL OFL 1.1",
|
|
|
129 |
"modification": "가능",
|
130 |
"provider": "네이버",
|
131 |
"provider_url": "https://hangeul.naver.com/2017/nanum",
|
132 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
133 |
},
|
134 |
"나눔명조": {
|
135 |
"license": "SIL OFL 1.1",
|
|
|
138 |
"modification": "가능",
|
139 |
"provider": "네이버",
|
140 |
"provider_url": "https://hangeul.naver.com/2017/nanum",
|
141 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
142 |
+
},
|
143 |
+
"나눔손글씨": {
|
144 |
+
"license": "SIL OFL 1.1",
|
145 |
+
"commercial_free": "✅ 가능",
|
146 |
+
"attribution": "불필요",
|
147 |
+
"modification": "가능",
|
148 |
+
"provider": "네이버",
|
149 |
+
"provider_url": "https://hangeul.naver.com/2017/nanum",
|
150 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
151 |
+
},
|
152 |
+
"나눔펜": {
|
153 |
+
"license": "SIL OFL 1.1",
|
154 |
+
"commercial_free": "✅ 가능",
|
155 |
+
"attribution": "불필요",
|
156 |
+
"modification": "가능",
|
157 |
+
"provider": "네이버",
|
158 |
+
"provider_url": "https://hangeul.naver.com/2017/nanum",
|
159 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
160 |
},
|
161 |
"배달의민족 주아": {
|
162 |
+
"license": "커스텀 무료 라이선스",
|
163 |
"commercial_free": "✅ 가능",
|
164 |
"attribution": "불필요",
|
165 |
"modification": "불가능",
|
166 |
"provider": "배달의민족",
|
167 |
"provider_url": "https://www.woowahan.com/fonts",
|
168 |
+
"notes": "상업적 사용 가능하나 BI 제작 시 사용 금지, 폰트 자체 판매 금지"
|
169 |
},
|
170 |
"배달의민족 도현": {
|
171 |
+
"license": "커스텀 무료 라이선스",
|
172 |
"commercial_free": "✅ 가능",
|
173 |
"attribution": "불필요",
|
174 |
"modification": "불가능",
|
175 |
"provider": "배달의민족",
|
176 |
"provider_url": "https://www.woowahan.com/fonts",
|
177 |
+
"notes": "상업적 사용 가능하나 BI 제작 시 사용 금지, 폰트 자체 판매 금지"
|
178 |
+
},
|
179 |
+
"배달의민족 기랑해랑": {
|
180 |
+
"license": "커스텀 무료 라이선스",
|
181 |
+
"commercial_free": "✅ 가능",
|
182 |
+
"attribution": "불필요",
|
183 |
+
"modification": "불가능",
|
184 |
+
"provider": "배달의민족",
|
185 |
+
"provider_url": "https://www.woowahan.com/fonts",
|
186 |
+
"notes": "상업적 사용 가능하나 BI 제작 시 사용 금지, 폰트 자체 판매 금지"
|
187 |
},
|
188 |
"서울남산체": {
|
189 |
"license": "SIL OFL 1.1",
|
|
|
192 |
"modification": "가능",
|
193 |
"provider": "서울시",
|
194 |
"provider_url": "https://www.seoul.go.kr/solution/font.do",
|
195 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
196 |
},
|
197 |
"서울한강체": {
|
198 |
"license": "SIL OFL 1.1",
|
|
|
201 |
"modification": "가능",
|
202 |
"provider": "서울시",
|
203 |
"provider_url": "https://www.seoul.go.kr/solution/font.do",
|
204 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
205 |
},
|
206 |
+
"Noto Sans Korean": {
|
207 |
"license": "SIL OFL 1.1",
|
208 |
+
"display_name": "노토 산스 한국어",
|
209 |
"commercial_free": "✅ 가능",
|
210 |
"attribution": "불필요",
|
211 |
"modification": "가능",
|
212 |
"provider": "Google",
|
213 |
"provider_url": "https://fonts.google.com/noto",
|
214 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
215 |
},
|
216 |
+
"Source Han Sans Korean": {
|
217 |
"license": "SIL OFL 1.1",
|
218 |
+
"display_name": "본고딕",
|
219 |
"commercial_free": "✅ 가능",
|
220 |
"attribution": "불필요",
|
221 |
"modification": "가능",
|
222 |
"provider": "Adobe/Google",
|
223 |
"provider_url": "https://fonts.google.com/noto",
|
224 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
225 |
},
|
226 |
"Pretendard": {
|
227 |
"license": "SIL OFL 1.1",
|
228 |
+
"display_name": "프리텐다드",
|
229 |
"commercial_free": "✅ 가능",
|
230 |
"attribution": "불필요",
|
231 |
"modification": "가능",
|
232 |
"provider": "Kil Hyung-jin",
|
233 |
"provider_url": "https://github.com/orioncactus/pretendard",
|
234 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
235 |
},
|
236 |
"SUIT": {
|
237 |
"license": "SIL OFL 1.1",
|
238 |
+
"display_name": "수트",
|
239 |
"commercial_free": "✅ 가능",
|
240 |
"attribution": "불필요",
|
241 |
"modification": "가능",
|
242 |
"provider": "SUNN",
|
243 |
"provider_url": "https://github.com/sunn-us/SUIT",
|
244 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
245 |
},
|
246 |
+
"IBM Plex Sans Korean": {
|
247 |
"license": "SIL OFL 1.1",
|
248 |
+
"display_name": "IBM 플렉스 산스 한국어",
|
249 |
"commercial_free": "✅ 가능",
|
250 |
"attribution": "불필요",
|
251 |
"modification": "가능",
|
252 |
"provider": "IBM",
|
253 |
"provider_url": "https://fonts.google.com/specimen/IBM+Plex+Sans+KR",
|
254 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
255 |
+
},
|
256 |
+
"Spoqa Han Sans": {
|
257 |
+
"license": "SIL OFL 1.1",
|
258 |
+
"display_name": "스포카 한 산스",
|
259 |
+
"commercial_free": "✅ 가능",
|
260 |
+
"attribution": "불필요",
|
261 |
+
"modification": "가능",
|
262 |
+
"provider": "스포카",
|
263 |
+
"provider_url": "https://github.com/spoqa/spoqa-han-sans",
|
264 |
+
"notes": "OFL 1.1 라이선스로 상업적 사용 자유, 출처 표시 불필요"
|
265 |
+
},
|
266 |
+
"NEXON Lv1 Gothic": {
|
267 |
+
"license": "커스텀 무료 라이선스",
|
268 |
+
"display_name": "넥슨 레벨1 고딕",
|
269 |
+
"commercial_free": "✅ 가능",
|
270 |
+
"attribution": "불필요",
|
271 |
+
"modification": "불가능",
|
272 |
+
"provider": "넥슨",
|
273 |
+
"provider_url": "https://www.nexon.com/Home/Game/font",
|
274 |
+
"notes": "상업적 사용 가능, 폰트 자체 판매 금지"
|
275 |
+
},
|
276 |
+
"NEXON Lv2 Gothic": {
|
277 |
+
"license": "커스텀 무료 라이선스",
|
278 |
+
"display_name": "넥슨 레벨2 고딕",
|
279 |
+
"commercial_free": "✅ 가능",
|
280 |
+
"attribution": "불필요",
|
281 |
+
"modification": "불가능",
|
282 |
+
"provider": "넥슨",
|
283 |
+
"provider_url": "https://www.nexon.com/Home/Game/font",
|
284 |
+
"notes": "상업적 사용 가능, 폰트 자체 판매 금지"
|
285 |
+
},
|
286 |
+
"TmoneyRoundWind": {
|
287 |
+
"license": "커스텀 무료 라이선스",
|
288 |
+
"display_name": "티머니 라운드윈드",
|
289 |
+
"commercial_free": "✅ 가능",
|
290 |
+
"attribution": "불필요",
|
291 |
+
"modification": "불가능",
|
292 |
+
"provider": "티몬",
|
293 |
+
"provider_url": "https://brunch.co.kr/@creative/32",
|
294 |
+
"notes": "상업적 사용 가능, 폰트 자체 판매 금지"
|
295 |
+
},
|
296 |
+
"한국관광공사체": {
|
297 |
+
"license": "공공누리 제1유형",
|
298 |
+
"commercial_free": "✅ 가능",
|
299 |
+
"attribution": "불필요",
|
300 |
+
"modification": "가능",
|
301 |
+
"provider": "한국관광공사",
|
302 |
+
"provider_url": "https://kto.visitkorea.or.kr/kor/notice/data/storybook/font.kto",
|
303 |
+
"notes": "공공누리 제1유형: 출처표시 조건으로 자유이용 가능"
|
304 |
+
},
|
305 |
+
"KoPubWorld돋움체": {
|
306 |
+
"license": "공공누리 제1유형",
|
307 |
+
"commercial_free": "✅ 가능",
|
308 |
+
"attribution": "필요",
|
309 |
+
"modification": "가능",
|
310 |
+
"provider": "한국출판인쇄문화협회",
|
311 |
+
"provider_url": "http://www.kopus.org/biz/electronic/font.aspx",
|
312 |
+
"notes": "공공누리 제1유형: 출처표시 조건으로 자유이용 가능"
|
313 |
},
|
314 |
"윤고딕": {
|
315 |
"license": "상업적 라이선스 필요",
|
|
|
318 |
"modification": "라이선스에 따라",
|
319 |
"provider": "윤디자인그룹",
|
320 |
"provider_url": "https://www.yoondesign.com",
|
321 |
+
"notes": "개인 사용만 무료, 상업적 사용 시 유료 라이선스 구매 필요"
|
322 |
+
},
|
323 |
+
"윤명조": {
|
324 |
+
"license": "상업적 라이선스 필요",
|
325 |
+
"commercial_free": "❌ 유료",
|
326 |
+
"attribution": "해당없음",
|
327 |
+
"modification": "라이선스에 따라",
|
328 |
+
"provider": "���디자인그룹",
|
329 |
+
"provider_url": "https://www.yoondesign.com",
|
330 |
+
"notes": "개인 사용만 무료, 상업적 사용 시 유료 라이선스 구매 필요"
|
331 |
},
|
332 |
"산돌고딕": {
|
333 |
"license": "상업적 라이선스 필요",
|
|
|
336 |
"modification": "라이선스에 따라",
|
337 |
"provider": "산돌커뮤니케이션",
|
338 |
"provider_url": "https://www.sandoll.co.kr",
|
339 |
+
"notes": "개인 사용만 무료, 상업적 사용 시 유료 라이선스 구매 필요"
|
340 |
+
},
|
341 |
+
"산돌명조": {
|
342 |
+
"license": "상업적 라이선스 필요",
|
343 |
+
"commercial_free": "❌ 유료",
|
344 |
+
"attribution": "해당없음",
|
345 |
+
"modification": "라이선스에 따라",
|
346 |
+
"provider": "산돌커뮤니케이션",
|
347 |
+
"provider_url": "https://www.sandoll.co.kr",
|
348 |
+
"notes": "개인 사용만 무료, 상업적 사용 시 유료 라이선스 구매 필요"
|
349 |
}
|
350 |
}
|
351 |
|
|
|
369 |
return cleaned
|
370 |
|
371 |
def find_font_license(font_name):
|
372 |
+
"""폰트 라이선스 정보 찾기 - 한글명 우선 표시"""
|
373 |
cleaned_name = clean_font_name(font_name)
|
374 |
|
375 |
# 정확한 매칭
|
376 |
if cleaned_name in FONT_LICENSE_DB:
|
377 |
+
info = FONT_LICENSE_DB[cleaned_name].copy()
|
378 |
+
# 한글 표시명이 있으면 사용
|
379 |
+
if 'display_name' in info:
|
380 |
+
info['display_font_name'] = info['display_name']
|
381 |
+
else:
|
382 |
+
info['display_font_name'] = cleaned_name
|
383 |
+
return info
|
384 |
|
385 |
# 부분 매칭
|
386 |
for db_font, info in FONT_LICENSE_DB.items():
|
387 |
if db_font.lower() in cleaned_name.lower() or cleaned_name.lower() in db_font.lower():
|
388 |
+
info_copy = info.copy()
|
389 |
+
if 'display_name' in info_copy:
|
390 |
+
info_copy['display_font_name'] = info_copy['display_name']
|
391 |
+
else:
|
392 |
+
info_copy['display_font_name'] = db_font
|
393 |
+
return info_copy
|
394 |
|
395 |
+
# 패턴 매칭 (재검증됨)
|
396 |
special_patterns = {
|
397 |
r'nanum|나눔': "나눔고딕",
|
398 |
r'baemin|배민|배달의민족': "배달의민족 주아",
|
399 |
r'seoul|서울': "서울남산체",
|
400 |
r'pretendard': "Pretendard",
|
401 |
+
r'noto.*sans.*kr|noto.*sans.*korean': "Noto Sans Korean",
|
402 |
+
r'source.*han.*sans|본고딕': "Source Han Sans Korean",
|
403 |
+
r'ibm.*plex.*sans.*kr|ibm.*plex.*sans.*korean': "IBM Plex Sans Korean",
|
404 |
+
r'spoqa.*han.*sans': "Spoqa Han Sans",
|
405 |
+
r'nexon.*lv1|nexon.*level.*1': "NEXON Lv1 Gothic",
|
406 |
+
r'nexon.*lv2|nexon.*level.*2': "NEXON Lv2 Gothic",
|
407 |
+
r'tmoney.*round.*wind': "TmoneyRoundWind",
|
408 |
+
r'suit': "SUIT",
|
409 |
r'yoon|윤': "윤고딕",
|
410 |
+
r'sandoll|산돌': "산돌고딕",
|
411 |
+
r'kopub.*world': "KoPubWorld돋움체",
|
412 |
+
r'한국관광공사': "한국관광공사체"
|
413 |
}
|
414 |
|
415 |
for pattern, matched_font in special_patterns.items():
|
416 |
if re.search(pattern, cleaned_name.lower()):
|
417 |
if matched_font in FONT_LICENSE_DB:
|
418 |
+
info_copy = FONT_LICENSE_DB[matched_font].copy()
|
419 |
+
if 'display_name' in info_copy:
|
420 |
+
info_copy['display_font_name'] = info_copy['display_name']
|
421 |
+
else:
|
422 |
+
info_copy['display_font_name'] = matched_font
|
423 |
+
return info_copy
|
424 |
|
425 |
# 유사도 매칭
|
426 |
matches = get_close_matches(cleaned_name, FONT_LICENSE_DB.keys(), n=1, cutoff=0.6)
|
427 |
if matches:
|
428 |
+
info_copy = FONT_LICENSE_DB[matches[0]].copy()
|
429 |
+
if 'display_name' in info_copy:
|
430 |
+
info_copy['display_font_name'] = info_copy['display_name']
|
431 |
+
else:
|
432 |
+
info_copy['display_font_name'] = matches[0]
|
433 |
+
return info_copy
|
434 |
|
435 |
# 기본값
|
436 |
return {
|
|
|
440 |
"modification": "❓ 확인 필요",
|
441 |
"provider": "❓ 확인 필요",
|
442 |
"provider_url": "",
|
443 |
+
"display_font_name": cleaned_name,
|
444 |
+
"notes": "라이선스 정보를 찾을 수 없습니다. 제작사 공식 사이트에서 확인하세요."
|
445 |
}
|
446 |
|
447 |
def parse_font_list(file_content):
|
|
|
480 |
font_name = clean_font_name(font_file)
|
481 |
license_info = find_font_license(font_name)
|
482 |
|
483 |
+
# 한글 폰트명 사용
|
484 |
+
display_name = license_info.get('display_font_name', font_name)
|
485 |
+
|
486 |
results.append({
|
487 |
"원본 파일명": font_file,
|
488 |
+
"폰트명": display_name,
|
489 |
"라이선스": license_info["license"],
|
490 |
"상업적 사용": license_info["commercial_free"],
|
491 |
"출처 표시": license_info["attribution"],
|