LEAF WriterとGakuNin RDMを用いたTEI/XMLファイルの編集環境の試作
概要
LEAF WriterとGakuNin RDMを用いたTEI/XMLファイルの編集環境の試作を行いましたので、備忘録です。
参考
以下の記事で、LEAF WriterをNext.jsから使用する方法を紹介しました。
特に、以下のnpmパッケージを使用しています。
上記で編集対象とするTEI/XMLファイルの入出力にあたり、GakuNin RDMを使用してみます。GakuNin RDMのAPIをJavaScriptから使用する方法について、以下も参考になりましたら幸いです。
使い方
以下がプロトタイプシステムのURLです。(色々と不具合が含まれる点にご注意ください。)
UIはClaude 3.7 Sonnetに作成してもらっています。
「サインイン」ボタンを押すと、認証画面に進むので、ログインします。
ログイン後、リダイレクトされ、プロジェクトの一覧が表示されます。
TEI/XMLファイルが含まれるディレクトリまで移動します。ファイル名に「.xml」が含まれる場合、「Leaf Writer」の列に「編集」ボタンが表示されます。
LEAF Writerの編集画面に遷移するので、テキストを編集します。作業が完了したら、画面右上の「保存」ボタンを押します。
GakuNin RDMのUIから確認してみると、バージョンごとに保存されていることが確認できます。
実装
GakuNin RDMからのファイルの取得および更新は以下で行っています。
/**
* ファイルの内容を取得する
*/
export async function fetchFileContent(
url: string,
accessToken: string
): Promise<string> {
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
if (!response.ok) {
throw new Error(
`ファイルの取得に失敗しました。ステータスコード: ${response.status}`
);
}
return await response.text();
}
/**
* ファイルの内容を更新する
*/
export async function updateFileContent(
url: string,
content: string,
accessToken: string,
contentType: string = "application/xml"
): Promise<void> {
const blob = new Blob([content], { type: contentType });
const response = await fetch(url, {
method: "PUT",
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: blob,
});
if (!response.ok) {
const errorText = await response.text();
console.error("保存に失敗しました。ステータスコード:", response.status);
console.error("レスポンス:", errorText);
throw new Error(`保存に失敗しました。ステータスコード: ${response.status}`);
}
}
上記で使用するURLは以下です。
const url = `https://files.rdm.nii.ac.jp/v1/resources/${project}/providers/${provider}/${id}?kind=file`;
以下のAPIから取得可能なJSONデータから、値を確認できます。(以下のURLには権限の関係でアクセスいただけないはずです。)
https://api.rdm.nii.ac.jp/v2/files/67da847416000900109e0454/
{
"data": {
"id": "67da847416000900109e0454",
"type": "files",
"attributes": {
"guid": "b45mp",
"checkout": null,
"name": "01.xml",
"kind": "file",
"path": "/67da847416000900109e0454",
"size": 72093,
"provider": "osfstorage",
"materialized_path": "/01.xml",
"last_touched": null,
"date_modified": "2025-03-21T00:29:59.408950Z",
"date_created": "2025-03-19T08:46:44.636107Z",
"extra": {
"hashes": {
"md5": "a49f7d8fafd3a8c01cb82fe4b9442d9a",
"sha256": "3de7d4d948e9d11ad3fe169f3d7a7786e668baf8e56c347b50bbb80d258c52af"
},
"downloads": 0
},
"tags": [],
"current_user_can_comment": true,
"current_version": 16
},
"relationships": {
"parent_folder": {
"links": {
"related": {
"href": "https://api.rdm.nii.ac.jp/v2/files/674034a483bdc200108b8a95/?format=json",
"meta": {}
}
},
"data": {
"id": "674034a483bdc200108b8a95",
"type": "files"
}
},
"versions": {
"links": {
"related": {
"href": "https://api.rdm.nii.ac.jp/v2/files/67da847416000900109e0454/versions/?format=json",
"meta": {}
}
}
},
"comments": {
"links": {
"related": {
"href": "https://api.rdm.nii.ac.jp/v2/nodes/wzv9g/comments/?format=json&filter%5Btarget%5D=b45mp",
"meta": {}
}
}
},
"metadata_records": {
"links": {
"related": {
"href": "https://api.rdm.nii.ac.jp/v2/files/67da847416000900109e0454/metadata_records/?format=json",
"meta": {}
}
}
},
"node": {
"links": {
"related": {
"href": "https://api.rdm.nii.ac.jp/v2/nodes/wzv9g/?format=json",
"meta": {}
}
},
"data": {
"id": "wzv9g",
"type": "nodes"
}
},
"target": {
"links": {
"related": {
"href": "https://api.rdm.nii.ac.jp/v2/nodes/wzv9g/",
"meta": {
"type": "node"
}
}
},
"data": {
"type": "node",
"id": "wzv9g"
}
}
},
"links": {
"info": "https://api.rdm.nii.ac.jp/v2/files/67da847416000900109e0454/",
"move": "https://files.rdm.nii.ac.jp/v1/resources/wzv9g/providers/osfstorage/67da847416000900109e0454",
"upload": "https://files.rdm.nii.ac.jp/v1/resources/wzv9g/providers/osfstorage/67da847416000900109e0454",
"delete": "https://files.rdm.nii.ac.jp/v1/resources/wzv9g/providers/osfstorage/67da847416000900109e0454",
"download": "https://rdm.nii.ac.jp/download/b45mp/",
"render": "https://mfr.rdm.nii.ac.jp/render?url=https://rdm.nii.ac.jp/download/b45mp/?direct%26mode=render",
"html": "https://rdm.nii.ac.jp/wzv9g/files/osfstorage/67da847416000900109e0454",
"self": "https://api.rdm.nii.ac.jp/v2/files/67da847416000900109e0454/"
}
}
}
まとめ
LEAF-Writer Commonsについては、GitHubをデフォルトのストレージおよび認証システムとして使用しています。
今回開発したシステムは、GitHubの代わりにGakuNin RDMを使用しているといった関係です。
LEAF Writerをnpmパッケージとして公開してくださっている方々に感謝いたします。
Discussion