aiteamutils 0.2.160__py3-none-any.whl → 0.2.162__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiteamutils/base_model.py +13 -3
- aiteamutils/base_service.py +2 -0
- aiteamutils/exceptions.py +6 -0
- aiteamutils/files.py +35 -5
- aiteamutils/version.py +1 -1
- {aiteamutils-0.2.160.dist-info → aiteamutils-0.2.162.dist-info}/METADATA +1 -1
- aiteamutils-0.2.162.dist-info/RECORD +16 -0
- aiteamutils/models.py +0 -1
- aiteamutils-0.2.160.dist-info/RECORD +0 -17
- {aiteamutils-0.2.160.dist-info → aiteamutils-0.2.162.dist-info}/WHEEL +0 -0
aiteamutils/base_model.py
CHANGED
@@ -126,15 +126,25 @@ class BaseFileModel(BaseColumn):
|
|
126
126
|
)
|
127
127
|
mime_type: Mapped[str] = mapped_column(
|
128
128
|
String,
|
129
|
-
nullable=
|
129
|
+
nullable=True,
|
130
130
|
doc="MIME 타입"
|
131
131
|
)
|
132
|
+
mime_type_main: Mapped[str] = mapped_column(
|
133
|
+
String,
|
134
|
+
nullable=True,
|
135
|
+
doc="MIME 타입 주 분류 (예: image, video, application 등)"
|
136
|
+
)
|
137
|
+
mime_type_sub: Mapped[str] = mapped_column(
|
138
|
+
String,
|
139
|
+
nullable=True,
|
140
|
+
doc="MIME 타입 부 분류 (예: jpeg, mp4, pdf 등)"
|
141
|
+
)
|
132
142
|
size: Mapped[int] = mapped_column(
|
133
|
-
nullable=
|
143
|
+
nullable=True,
|
134
144
|
doc="파일 크기(bytes)"
|
135
145
|
)
|
136
146
|
checksum: Mapped[str] = mapped_column(
|
137
147
|
String,
|
138
|
-
nullable=
|
148
|
+
nullable=True,
|
139
149
|
doc="파일 체크섬"
|
140
150
|
)
|
aiteamutils/base_service.py
CHANGED
@@ -130,6 +130,8 @@ class BaseService(Generic[ModelType]):
|
|
130
130
|
'original_name': f['original_name'],
|
131
131
|
'storage_path': f['storage_path'],
|
132
132
|
'mime_type': f['mime_type'],
|
133
|
+
'mime_type_main': f['mime_type_main'],
|
134
|
+
'mime_type_sub': f['mime_type_sub'],
|
133
135
|
'size': f['size'],
|
134
136
|
'checksum': f['checksum'],
|
135
137
|
'column_name': f['column_name']
|
aiteamutils/exceptions.py
CHANGED
@@ -77,6 +77,12 @@ class ErrorCode(Enum):
|
|
77
77
|
TOKEN_ERROR = ErrorResponse(5005, "TOKEN_ERROR", 401, "토큰 오류")
|
78
78
|
DELETE_ERROR = ErrorResponse(5006, "DELETE_ERROR", 400, "삭제 오류")
|
79
79
|
|
80
|
+
# File 관련 에러: 6000번대
|
81
|
+
FILE_NOT_FOUND = ErrorResponse(6001, "FILE_NOT_FOUND", 404, "파일을 찾을 수 없습니다")
|
82
|
+
FILE_UPLOAD_ERROR = ErrorResponse(6002, "FILE_UPLOAD_ERROR", 500, "파일 업로드 오류")
|
83
|
+
FILE_DOWNLOAD_ERROR = ErrorResponse(6003, "FILE_DOWNLOAD_ERROR", 500, "파일 다운로드 오류")
|
84
|
+
FILE_DELETE_ERROR = ErrorResponse(6004, "FILE_DELETE_ERROR", 500, "파일 삭제 오류")
|
85
|
+
FILE_PROCESSING_ERROR = ErrorResponse(6005, "FILE_PROCESSING_ERROR", 500, "파일 처리 오류")
|
80
86
|
|
81
87
|
class CustomException(Exception):
|
82
88
|
"""사용자 정의 예외 클래스"""
|
aiteamutils/files.py
CHANGED
@@ -48,6 +48,25 @@ class FileHandler:
|
|
48
48
|
original_error=e
|
49
49
|
)
|
50
50
|
|
51
|
+
@staticmethod
|
52
|
+
def _split_mime_type(mime_type: str) -> Tuple[str, str]:
|
53
|
+
"""MIME 타입을 주 타입과 부 타입으로 분리
|
54
|
+
|
55
|
+
Args:
|
56
|
+
mime_type (str): MIME 타입 문자열 (예: "image/jpeg")
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
Tuple[str, str]: (주 타입, 부 타입) 튜플
|
60
|
+
"""
|
61
|
+
try:
|
62
|
+
if not mime_type or '/' not in mime_type:
|
63
|
+
return 'application', 'octet-stream'
|
64
|
+
main_type, sub_type = mime_type.split('/', 1)
|
65
|
+
return main_type.lower(), sub_type.lower()
|
66
|
+
except Exception as e:
|
67
|
+
logger.error(f"[MIME 타입 분리 실패] {mime_type}: {str(e)}")
|
68
|
+
return 'application', 'octet-stream'
|
69
|
+
|
51
70
|
@staticmethod
|
52
71
|
async def _calculate_checksum(file: BinaryIO) -> str:
|
53
72
|
"""파일의 SHA-256 체크섬 계산
|
@@ -131,10 +150,17 @@ class FileHandler:
|
|
131
150
|
# 파일 포인터 복구
|
132
151
|
file.seek(current_position)
|
133
152
|
|
153
|
+
# MIME 타입 처리
|
154
|
+
mime_type = FileHandler._get_mime_type(original_name)
|
155
|
+
mime_type_main, mime_type_sub = FileHandler._split_mime_type(mime_type)
|
156
|
+
logger.info(f"[MIME 타입 분리] {mime_type} -> {mime_type_main}/{mime_type_sub}")
|
157
|
+
|
134
158
|
file_info = {
|
135
159
|
"original_name": original_name,
|
136
160
|
"storage_path": storage_path,
|
137
|
-
"mime_type":
|
161
|
+
"mime_type": mime_type,
|
162
|
+
"mime_type_main": mime_type_main,
|
163
|
+
"mime_type_sub": mime_type_sub,
|
138
164
|
"size": os.path.getsize(storage_path),
|
139
165
|
"checksum": checksum,
|
140
166
|
"entity_name": entity_name,
|
@@ -202,12 +228,12 @@ class FileHandler:
|
|
202
228
|
text("""
|
203
229
|
INSERT INTO files (
|
204
230
|
ulid, entity_name, entity_ulid, original_name, storage_path,
|
205
|
-
mime_type,
|
206
|
-
is_deleted
|
231
|
+
mime_type, mime_type_main, mime_type_sub, size, checksum,
|
232
|
+
column_name, created_at, updated_at, is_deleted
|
207
233
|
) VALUES (
|
208
234
|
:ulid, :entity_name, :entity_ulid, :original_name, :storage_path,
|
209
|
-
:mime_type, :
|
210
|
-
:is_deleted
|
235
|
+
:mime_type, :mime_type_main, :mime_type_sub, :size, :checksum,
|
236
|
+
:column_name, :created_at, :updated_at, :is_deleted
|
211
237
|
) RETURNING *
|
212
238
|
"""),
|
213
239
|
{
|
@@ -217,6 +243,8 @@ class FileHandler:
|
|
217
243
|
"original_name": file_info["original_name"],
|
218
244
|
"storage_path": file_info["storage_path"],
|
219
245
|
"mime_type": file_info["mime_type"],
|
246
|
+
"mime_type_main": file_info["mime_type_main"],
|
247
|
+
"mime_type_sub": file_info["mime_type_sub"],
|
220
248
|
"size": file_info["size"],
|
221
249
|
"checksum": file_info["checksum"],
|
222
250
|
"column_name": column_name,
|
@@ -234,6 +262,8 @@ class FileHandler:
|
|
234
262
|
"original_name": row.original_name,
|
235
263
|
"storage_path": row.storage_path,
|
236
264
|
"mime_type": row.mime_type,
|
265
|
+
"mime_type_main": row.mime_type_main,
|
266
|
+
"mime_type_sub": row.mime_type_sub,
|
237
267
|
"size": row.size,
|
238
268
|
"checksum": row.checksum,
|
239
269
|
"column_name": row.column_name,
|
aiteamutils/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
"""버전 정보"""
|
2
|
-
__version__ = "0.2.
|
2
|
+
__version__ = "0.2.162"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
aiteamutils/__init__.py,sha256=kRBpRjark0M8ZwFfmKiMFol6CbIILN3WE4f6_P6iIq0,1089
|
2
|
+
aiteamutils/base_model.py,sha256=Jw5Fyfrtdc_jyg-LmC35c-D6w3-2_dh2CBeiKjM9GPE,4497
|
3
|
+
aiteamutils/base_repository.py,sha256=Oy2zE1i5qx60Xf1tnsaKLyFWapiPqt5JH8NejwNrPWg,4647
|
4
|
+
aiteamutils/base_service.py,sha256=JIeRtFn1Ll4Qcq3v88pgS9lmEQLQoVyyOKqYR8n02S4,21192
|
5
|
+
aiteamutils/cache.py,sha256=07xBGlgAwOTAdY5mnMOQJ5EBxVwe8glVD7DkGEkxCtw,1373
|
6
|
+
aiteamutils/config.py,sha256=YdalpJb70-txhGJAS4aaKglEZAFVWgfzw5BXSWpkUz4,3232
|
7
|
+
aiteamutils/database.py,sha256=msvBKtxWeQVOo0v2Q9i2azuTNtnUItuNNar52gdRZTo,20418
|
8
|
+
aiteamutils/enums.py,sha256=7WLqlcJqQWtETAga2WAxNp3dJTQIAd2TW-4WzkoHHa8,2498
|
9
|
+
aiteamutils/exceptions.py,sha256=sgIVulllKMM9InTltaB7VD6i7DiQvCoycexsV-BiIBY,16570
|
10
|
+
aiteamutils/files.py,sha256=fxnCu9rErd4vCovMi0jy4adLUiA7rx_q4RdOL4wSgsU,14258
|
11
|
+
aiteamutils/security.py,sha256=McUl3t5Z5SyUDVUHymHdDkYyF4YSeg4g9fFMML4W6Kw,11630
|
12
|
+
aiteamutils/validators.py,sha256=_WHN6jqJQzKM5uPTg-Da8U2qqevS84XeKMkCCF4C_lY,9591
|
13
|
+
aiteamutils/version.py,sha256=vAvqE9V77cH7vOSwbqingOdyP4KA12olJ1Dj_9Br2jQ,43
|
14
|
+
aiteamutils-0.2.162.dist-info/METADATA,sha256=LS01DV_fpROE_i2VnNwkeRx0KQ82VBeRAi4XveycukA,1743
|
15
|
+
aiteamutils-0.2.162.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
16
|
+
aiteamutils-0.2.162.dist-info/RECORD,,
|
aiteamutils/models.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
|
@@ -1,17 +0,0 @@
|
|
1
|
-
aiteamutils/__init__.py,sha256=kRBpRjark0M8ZwFfmKiMFol6CbIILN3WE4f6_P6iIq0,1089
|
2
|
-
aiteamutils/base_model.py,sha256=yBZqzTDF9PA4wCAvmYfG12FdVwLtxOEUCcA3z2i6fXU,4176
|
3
|
-
aiteamutils/base_repository.py,sha256=Oy2zE1i5qx60Xf1tnsaKLyFWapiPqt5JH8NejwNrPWg,4647
|
4
|
-
aiteamutils/base_service.py,sha256=5YSRpulLI-tO6zQ75LBTsyzYoMzayPITWhE5-8rie3s,21068
|
5
|
-
aiteamutils/cache.py,sha256=07xBGlgAwOTAdY5mnMOQJ5EBxVwe8glVD7DkGEkxCtw,1373
|
6
|
-
aiteamutils/config.py,sha256=YdalpJb70-txhGJAS4aaKglEZAFVWgfzw5BXSWpkUz4,3232
|
7
|
-
aiteamutils/database.py,sha256=msvBKtxWeQVOo0v2Q9i2azuTNtnUItuNNar52gdRZTo,20418
|
8
|
-
aiteamutils/enums.py,sha256=7WLqlcJqQWtETAga2WAxNp3dJTQIAd2TW-4WzkoHHa8,2498
|
9
|
-
aiteamutils/exceptions.py,sha256=pgf3ersezObyl17wAO3I2fb8m9t2OzWDX1mSjwAWm2Y,16035
|
10
|
-
aiteamutils/files.py,sha256=Qq2w3VAEOzvsDirYtxRTN48LnIzf4TPUH2LftmyYtQk,12831
|
11
|
-
aiteamutils/models.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
12
|
-
aiteamutils/security.py,sha256=McUl3t5Z5SyUDVUHymHdDkYyF4YSeg4g9fFMML4W6Kw,11630
|
13
|
-
aiteamutils/validators.py,sha256=_WHN6jqJQzKM5uPTg-Da8U2qqevS84XeKMkCCF4C_lY,9591
|
14
|
-
aiteamutils/version.py,sha256=Dv_RPFPM_ljwt7FQn4GsgrSYOBxg7SL2-aDSf-jrp30,43
|
15
|
-
aiteamutils-0.2.160.dist-info/METADATA,sha256=-mvX5XwdZbNh-6odVtUghcR6k9YU_P2eOv8XruEj5Gg,1743
|
16
|
-
aiteamutils-0.2.160.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
17
|
-
aiteamutils-0.2.160.dist-info/RECORD,,
|
File without changes
|