2 Commits

Author SHA1 Message Date
orrisroot 428be1289c chore(version): bump package version to 1.3.15
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-01 11:11:22 +09:00
orrisroot 4283481695 fix: apply NFC normalization to filenames and folder names sent to server
On macOS, local filenames and directory names may be in NFD encoding
(decomposed Unicode). Without normalization, files and folders are
created on the server with NFD names, inconsistent with the server's
NFC convention.

Apply normalize("NFC", ...) before sending names to the server in:
- FilesApi.create(): filename in multipart upload
- FilesApi.update(): filename in multipart upload
- UploadCommand: directory name in FoldersApi.create()

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 12:25:59 +09:00
3 changed files with 6 additions and 4 deletions
+3 -2
View File
@@ -1,6 +1,7 @@
import mimetypes
import os
from typing import Any, Final
from unicodedata import normalize
from pydantic import TypeAdapter
from pydantic.dataclasses import dataclass
@@ -53,7 +54,7 @@ class FilesApi(BaseApi):
try:
with open(os.path.realpath(path), mode="rb") as fp:
data = MultipartEncoder(
fields={"folder_id": folder_id, "file": (os.path.basename(path), fp, self._get_mime_type(path))}
fields={"folder_id": folder_id, "file": (normalize("NFC", os.path.basename(path)), fp, self._get_mime_type(path))}
)
response = self.connection.post(url, data=data, headers={"Content-Type": data.content_type})
self._raise_response_error(response)
@@ -75,7 +76,7 @@ class FilesApi(BaseApi):
# update file body
try:
with open(os.path.realpath(path), mode="rb") as fp:
data = MultipartEncoder(fields={"file": (os.path.basename(path), fp, self._get_mime_type(path))})
data = MultipartEncoder(fields={"file": (normalize("NFC", os.path.basename(path)), fp, self._get_mime_type(path))})
response = self.connection.put(url, data=data, headers={"Content-Type": data.content_type})
except OSError:
raise UnexpectedException(f"Could not open `{path}` file.")
+2 -1
View File
@@ -2,6 +2,7 @@ import os
from argparse import Namespace
from concurrent.futures import ThreadPoolExecutor
from typing import Any
from unicodedata import normalize
from pydantic.dataclasses import dataclass
@@ -81,7 +82,7 @@ class UploadCommand(BaseCommand):
if folder_map.get(d_dirname) is None:
d_folder = folder_map[d_parent_dirname].find_sub_folder(d_basename)
if d_folder is None:
d_folder_id = folder_api.create(d_basename, folder_map[d_parent_dirname].id)
d_folder_id = folder_api.create(normalize("NFC", d_basename), folder_map[d_parent_dirname].id)
else:
d_folder_id = d_folder.id
print(d_dirname)
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "mdrs-client-python"
version = "1.3.14"
version = "1.3.15"
description = "The mdrs-client-python is python library and a command-line client for up- and downloading files to and from MDRS based repository."
authors = ["Yoshihiro OKUMURA <yoshihiro.okumura@riken.jp>"]
license = "MIT"