34 Commits
Author SHA1 Message Date
orrisroot e5c28835b8 feat(auth): send a request again when its token lapsed in the queue
A request can wait to be served for longer than the access token it was
sent with lives, and comes back refused for a token that was valid when
it left. Uploads that take minutes make that wait ordinary.

- tell an expired token apart from any other refusal by the code the
  API returns, and retry only that one, once
- prefer a token another process left behind over minting a second: it
  saves a round trip, and a rotating provider would retire one that is
  still in use. Assign it rather than read it, since the setter is what
  rewrites the session header the retry will carry
- settle the token before the request so the one compared afterwards is
  the one that was actually sent
- report an overloaded server when the second attempt is refused too,
  and let API errors out of the upload path with their own type
2026-08-14 18:37:41 +09:00
orrisroot 0cac30ccf8 fix(auth): serialise the token refresh across processes
The login cache is shared by every mdrs process, but the refresh was
guarded by a lock that only reaches inside one. Concurrent runs each
sent the same refresh token, and a provider that rotates them accepts
the first and refuses the rest.

- hold a lock that spans processes across the whole read-refresh-
  write, checking cheaply first so ordinary requests never take it
- write the cache through a temporary file: opening it for writing
  truncates it, and a reader landing in that window found it empty
  and threw the session away
- take the lock for every write, not just the refresh, so a login
  running beside one cannot be silently reverted
- wait for a busy lock on Windows rather than giving up after the ten
  attempts msvcrt allows, and retry the rename it refuses while a
  reader still holds the file open
- bound the refresh request on its own, so a provider that goes quiet
  cannot hold the lock indefinitely
- accept bare hostnames such as localhost, store URLs without the
  trailing slash, and join download paths through one helper
2026-08-14 16:36:50 +09:00
orrisroot 36cad6db52 refactor: extract MdrsClient service layer for library portability
To improve the tool's portability as a Python library, the core logic
has been decoupled from the CLI interface. This allows developers to
programmatically interact with MDRS without relying on CLI-specific
argument parsing or local file-based caches.

- Introduce `MdrsClient` service layer to handle core operations.
- Abstract authentication state using `CacheInterface` and `InMemoryCache`.
- Migrate all CLI commands to utilize `MdrsClient` for execution.
- Separate `Doi` data model from API responses and move to `models/doi.py`.
- Update `README.md` to include Python API usage examples.
- Bump package version to 1.3.17.
2026-07-02 13:07:18 +09:00
orrisroot 5bdf837941 feat(doi): add DOI-based path access for commands
Support accessing repositories using DOI strings with optional subpaths
across ls, download, metadata, and file-metadata commands.

- Implement GET v3/doi/{id}/ API model and client calls
- Parse and resolve DOI paths into respective folder and files
- Extract common folder and file resolution logic to shared helpers
- Update README with example DOI-based shell commands
2026-06-12 01:28:40 +09:00
orrisroot 04c0003a61 fix(connection): support absolute download urls for public data 2026-06-11 21:04:28 +09:00
orrisrootandCopilot 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
pw-serizawa 95f22ea5f9 fix for file.list api pagination 2025-06-26 17:13:06 +09:00
orrisroot 8a5e1b68b7 follow-up fixes due to recent User API specification changes. 2025-01-21 18:30:22 +09:00
orrisroot 0d8deb02d7 add token check for file download operation. 2024-07-08 18:07:26 +09:00
orrisroot c2a67aa861 removed debug code. 2024-07-04 15:21:45 +09:00
orrisroot 020ef8835a fixed bug to upload large file. 2024-07-04 12:33:57 +09:00
orrisroot ce0a608db2 fixed bug to resolve local files for recursive file upload. 2023-12-20 19:42:06 +09:00
orrisroot 9284346153 real path should not be used when creating distination file list. 2023-12-18 16:23:46 +09:00
orrisroot 292ca1df27 changed API endpoint from v2 to v3. 2023-12-12 20:05:46 +09:00
orrisroot f10b42a1f2 updated auth token handling using new users api. 2023-12-07 14:46:57 +09:00
orrisroot 79f1b708cb followup recent updates around auth api. 2023-10-04 11:30:16 +09:00
orrisroot 4641b9304e set destination folder name using name attribute of folder copy api. 2023-07-26 19:59:07 +09:00
orrisroot 4d87b55b40 add new command cp. 2023-07-20 11:43:07 +09:00
orrisroot 08d8a0626a fixed type errors when pylance type checking mode is strict. 2023-07-19 21:47:47 +09:00
orrisroot 23025bd679 migrate obsoleted function parse_obj_as to TypeAdapter().validate_python(). 2023-07-19 14:43:16 +09:00
orrisroot b569c20b6e support case insensitive and normalized file and folder names. 2023-07-19 13:46:23 +09:00
orrisroot 1ffafd25ba sort laboratory list by name and hide numeric id. 2023-06-04 18:53:21 +09:00
orrisroot 593caa82ec keep up with folder auth api changes. 2023-06-01 16:52:41 +09:00
orrisroot 1a0a26d7b3 support 'recursive' flag to recursively delete folders. 2023-05-26 17:58:25 +09:00
orrisroot 9d62d3fb6a follow changes to auth api on 2023-05-22. 2023-05-22 13:48:38 +09:00
orrisroot b028c86b20 implemented to change folder access level chacl command. 2023-05-11 17:00:14 +09:00
orrisroot 995e4cc467 add -p option for support to open PW_OPEN folder. 2023-05-10 20:10:43 +09:00
orrisroot dd0b0ba68f optimize class dependencies. 2023-05-10 14:46:08 +09:00
orrisroot 0281dd2ccb update document and remove debug code. 2023-05-09 19:45:03 +09:00
orrisroot 35defa39a6 introduce mutex to avoid multiple token refresh when using threads. 2023-05-09 19:30:07 +09:00
orrisroot fd2238f5ca implemented to move or rename file/folder command mv 2023-05-09 18:38:58 +09:00
orrisroot e7197673fc implemented mutiple download feature. 2023-05-09 14:38:13 +09:00
orrisroot c724af538b use concurrent for the multiple file uploads instead of multiprocess. 2023-05-09 13:08:50 +09:00
orrisroot 819c4a6a07 first commit 2023-05-01 20:00:32 +09:00