ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
Ontotext GraphDBのデスクトップ版を使用した際の空きディスク容量不足への対処

Ontotext GraphDBのデスクトップ版を使用した際の空きディスク容量不足への対処

概要 Ontotext GraphDBのデスクトップ版を使用した際、 https://www.ontotext.com/products/graphdb/ 空きディスク容量不足により、データのインポートなどができないことがありました。 File not loaded; Insufficient disk space to start a transaction for repository ‘xxx’ due to: The repository ‘abc’ is critically low on free disk space with 4.6% (xxx GB) free left 本記事では、この問題への一時的な対処方法の一例を紹介します。 マニュアル 以下に記載がありました。 https://graphdb.ontotext.com/documentation/11.0/low-disk-space-health-checks.html Claudeによる回答は以下でした。 GraphDB 11.0では新しいヘルスチェック機構が追加されており、これが従来の設定を上書きしています: Fatal状態: 5%または1GB以下で発動 現在の状況: 4.6%なのでFatal状態 結果: 新しいトランザクションが完全に阻止される 対応 以下のようなgraphdb.propertiesを新規に作成して、ヘルスチェック機構を無効化するオプションを追加しました。 # GraphDB 11.0 の新しいヘルスチェック機構を無効化 graphdb.health.minimal.free.storage.enabled=false graphdb.health.minimal.free.storage.asyncCheck=false そして、GraphDBを再起動します。結果、System Informationに設定が反映され、冒頭のエラーが解消しました。 まとめ 空きディスク容量不足に関する根本的な原因を解決すべきかと思いますが、一時的な対応として参考になりましたら幸いです。

AllegroGraphを使ってみる

AllegroGraphを使ってみる

概要 AllegroGraphを使ってみる機会がありましたので、備忘録です。 https://allegrograph.com/ 使い方 いくつかのセットアップ方法があるようですが、以下のクラウド版を利用してみます。 https://allegrograph.cloud/ セットアップ後、以下のように表示されます。 ログイン後、複数のRepositoriesが表示されます。 匿名アクセスを可能にする 例えば、リポジトリ「actors」のSPARQLエンドポイントは以下です。 https://ag1edt2www58hzzy.allegrograph.cloud/repositories/actors/sparql デフォルトでは、Basic認証がかかります。 そこで、anonymousユーザを作成します。ユーザ名を「anonymous」にすることで、パスワードの入力をスキップできました。 公式の説明は以下に記載があります。 https://franz.com/agraph/support/documentation/managing-users.html#anonymous-access そして、「actors」リポジトリへのREADを許可します。 この設定により、指定したリポジトリへ認証なしでアクセスできるようになります。以下は、yasguiでアクセスした例です。 https://yasgui.org/#query=PREFIX+rdf%3A+<http%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23> PREFIX+rdfs%3A+<http%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23> SELECT+*+WHERE+{ ++%3Fsub+%3Fpred+%3Fobj+. }+ LIMIT+10&contentTypeConstruct=text%2Fturtle&contentTypeSelect=application%2Fsparql-results%2Bjson&endpoint=https%3A%2F%2Fag1edt2www58hzzy.allegrograph.cloud%2Frepositories%2Factors%2Fsparql&requestMethod=POST&tabTitle=Query&headers={}&outputFormat=table リポジトリを追加してみる 「my_first_repository」というリポジトリを追加しました。RDFファイルを登録してみます。 校異源氏物語テキストDBで使用している以下のRDFファイルを登録してみます。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/blob/master/files/rdf/item_sets.rdf 登録時に、Graph URIを任意項目として登録することができます。入力例にしたがって、以下のように入力しました。 エクスポートする 「Repository Control」の「Archiving」からエクスポートできます。 「N-Quads」を選択して、エクスポートした結果が以下です。トリプルに加えて、先ほど登録したGraph URIが出力されていることが確認できます。 <https://w3id.org/kouigenjimonogatari/api/item_sets/31.json> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://jpsearch.go.jp/term/type/作品> <http://example.org> . <https://w3id.org/kouigenjimonogatari/api/item_sets/31.json> <http://purl.org/dc/terms/relation> <https://w3id.org/kouigenjimonogatari/tei/31.xml> <http://example.org> . <https://w3id.org/kouigenjimonogatari/api/item_sets/31.json> <https://w3id.org/kouigenjimonogatari/api/property/vol> "31"^^<http://www.w3.org/2001/XMLSchema#integer> <http://example.org> . <https://w3id.org/kouigenjimonogatari/api/item_sets/31.json> <http://www.w3.org/2000/01/rdf-schema#label> "まきはしら" <http://example.org> . ... SHACL Shapesを管理する Generate SHACL Shapesボタンを押すと、SHACLファイルが作成されます。 以下のようなJSONが作成されました。 { "@context": { "ns2": "https://jpsearch.go.jp/term/type/", "ns1": "http://www.w3.org/ns/shacl#", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, "@id": "ns2:WorkShape", "ns1:targetClass": "https://jpsearch.go.jp/term/type/Work", "ns1:property": [ { "ns1:nodeKind": "sh:IRI", "ns1:path": "rdf:type", "ns1:minCount": 1, "ns1:maxCount": 1 }, { "ns1:nodeKind": "sh:IRI", "ns1:path": "dcterms:relation", "ns1:minCount": 1, "ns1:maxCount": 1 }, { "ns1:nodeKind": "sh:IRI", "ns1:path": "rdfs:seeAlso", "ns1:minCount": 1, "ns1:maxCount": 1 }, { "ns1:nodeKind": "sh:IRI", "ns1:path": "https://w3id.org/kouigenjimonogatari/api/property/vol", "ns1:minCount": 1, "ns1:maxCount": 1 }, { "ns1:nodeKind": "sh:IRI", "ns1:path": "dcterms:rights", "ns1:minCount": 1, "ns1:maxCount": 1 }, { "ns1:nodeKind": "sh:literal", "ns1:datatype": "xs:string", "ns1:path": "rdfs:label", "ns1:minCount": 1, "ns1:maxCount": 1 } ], "@type": "ns1:NodeShape" } Queryを投げてみると、SHACLに関するトリプルも登録されていました。 ...

DHConvalidatorにおける'ref'に関する不具合への対応

DHConvalidatorにおける'ref'に関する不具合への対応

本記事は、一部AIが執筆しました。 概要 DHConvalidatorは、デジタル人文学(DH)会議の抄録を一貫したTEI(Text Encoding Initiative)テキストベースに変換するためのツールです。 https://github.com/ADHO/dhconvalidator このツールの利用において、Microsoft Word形式(DOCX)からTEI XML形式への変換処理中に以下のようなエラーが発生するケースがありました: ERROR: nu.xom.ParsingException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'ref' この原因と対処方法について共有します。 原因の特定 調査の結果、問題の原因はWord文書内に埋め込まれた INCLUDEPICTUREフィールドコード であることが判明しました。 具体的には、Googleドキュメントから画像をコピー&ペーストした際に、以下のようなフィールドコードが文書内に残存していました: INCLUDEPICTURE "https://lh7-rt.googleusercontent.com/docsz/..." \* MERGEFORMATINET これらの外部画像参照リンクがTEI変換プロセスで適切に処理されず、XML検証エラーを引き起こしていました。 解決方法 この問題を解決するため、DOCXファイル内の問題のあるフィールドコードを自動的に除去するPythonスクリプトを開発しました。 スクリプトの特徴 安全な処理 : 画像コンテンツ自体は保持し、フィールドコード部分のみを削除 ZIP形式対応 : DOCXファイルの内部構造(ZIP + XML)を適切に処理 名前空間対応 : Word文書のXML名前空間を考慮した正確な要素検索 主要な処理ロジック DOCXファイルを一時ディレクトリに展開 word/document.xml内のフィールドコード構造を解析 INCLUDEPICTUREを含むフィールドを特定 フィールド制御要素(begin/separate/end)のみを削除し、画像要素は保持 修正されたXMLで新しいDOCXファイルを生成 実装のポイント フィールドコード判定 def is_includepicture_field(field_runs, ns): for run in field_runs: instr_text = run.find('.//w:instrText', ns) if instr_text is not None and instr_text.text: if 'INCLUDEPICTURE' in instr_text.text: return True return False 削除対象の選別 def should_remove_run(run, ns): # フィールド制御要素を持つか確認 has_field_control = (run.find('.//w:fldChar', ns) is not None or run.find('.//w:instrText', ns) is not None) # 実際の画像コンテンツを持つか確認 has_image_content = (run.find('.//w:drawing', ns) is not None or run.find('.//w:pict', ns) is not None) # フィールド制御要素があり、画像コンテンツがない要素を削除 return has_field_control and not has_image_content 結果 このスクリプトにより、問題のあるフィールドコードが除去され、TEI変換プロセスが正常に完了するようになりました。画像は適切に文書内に埋め込まれた状態で保持されます。 ...

校異源氏物語テキストDBに対する検索を行うMCPサーバの構築

校異源氏物語テキストDBに対する検索を行うMCPサーバの構築

概要 校異源氏物語テキストDBに対する検索を行うMCPサーバの構築を行ったので、備忘録です。 一例として、Claude Desktopから以下のように使用することができます。 https://youtu.be/8s2R9V2hEvc?si=p9SW-IvhdNSzwTLN 背景 以下の記事で、校異源氏物語テキストDBに対する検索を行うAPIサーバの構築について紹介しました。 この応用として、MCPサーバを構築することで、AIエージェントとのやりとりを試してみます。 単純なものですが、GitHubのリポジトリは以下です。 https://github.com/nakamura196/genji-mcp-server 開発にあたっては、先述したAPIサーバで提供するOpenAPIの仕様をClaude Codeに渡すことで、テンプレートから効率機に開発してくれました。 なおswagger.jsonには、以下でアクセスいただけます。 https://genji-api.aws.ldas.jp/swagger.json 使い方 npmパッケージを以下で公開しています。 https://www.npmjs.com/package/@nakamura196/genji-mcp-server そこで、以下のような設定ファイルを作成して、Claude Desktopを再起動します。 { "mcpServers": { "genji": { "command": "npx", "args": ["-y", "@nakamura196/genji-mcp-server"] } } } 利用例 「夕顔が含まれる巻は?」などと入力すると、以下のように外部連携を使用するための許可が求められます。許可すると、問い合わせ結果に基づき、AIが回答を作成してくれます。 以下が、応答の例です。 『源氏物語』で夕顔が登場する巻について検索してみますね。検索結果から、夕顔が含まれる巻は以下の通りです: 「夕顔」が登場する巻: 第4巻「夕顔」 - 最も多く登場(7箇所) 第6巻「末摘花」 - 1箇所 第22巻「玉鬘」 - 3箇所 主人公である夕顔の女性は、当然ながら第4巻「夕顔」で中心的に描かれています。この巻では光源氏と夕顔の出会いから悲劇的な結末まが詳しく語られています。 その後、第6巻「末摘花」では回想として言及され、第22巻「玉鬘」では夕顔の娘である玉鬘の物語の中で、母親である夕顔への言及が複数回なされています。 つまり、夕顔という人物は第4巻で主人公として登場し、その後の巻でも重要な人物として言及され続けているということですね。 まとめ MCPサーバの作り方および使い方の確認を主としており、実際には色々と改善の余地がありますが、参考になる部分がありましたら幸いです。より便利な使い方を試してみたいと思います。

校異源氏物語テキストDBに対する検索を行うAPIサーバの構築

校異源氏物語テキストDBに対する検索を行うAPIサーバの構築

概要 校異源氏物語テキストDBに対する検索を行うAPIサーバの構築したので、備忘録です。 https://genji-api.aws.ldas.jp/ 背景 以下のページで、『校異源氏物語』のテキストデータをTEI/XMLに準拠した形で公開しています。 https://kouigenjimonogatari.github.io/ このテキストデータをElasticsearchに登録し、コマごとの検索を可能にするAPIを作成します。 使い方 以下のURLで、OpenAPIおよびSwaggerを用いた使い方の説明ページにアクセスできます。 https://genji-api.aws.ldas.jp/ 工夫点 検索語の展開 例えば以下のURLは、「夕顔」を検索キーワードとした例です。JSON:APIに準拠した入出力形式としています。 https://genji-api.aws.ldas.jp/search?q=夕顔&page[limit]=20&page[offset]=0&sort=page&filter[expandRepeatMarks]=true&filter[unifyKanjiKana]=true&filter[unifyHistoricalKana]=true&filter[unifyPhoneticChanges]=true&filter[unifyDakuon]=true&filter[vol_str]=04 夕顔 この時、以下のような結果が返却されます。入力したキーワード「夕顔」に対して、バリエーションを生成し、これらに基づく検索を行います。 { "data": [], "meta": { "query": "夕顔", "transformedQueries": [ "夕顔", "ゆうかお", "ゆふかお", "ゆふかほ", "ゆうかほ", "夕かお", "夕かほ", "ゆう顔", "ゆふ顔" ], "transformOptions": { "expandRepeatMarks": true, "unifyKanjiKana": true, "unifyHistoricalKana": true, "unifyPhoneticChanges": true, "unifyDakuon": true }, "filters": { "expandRepeatMarks": true, "unifyKanjiKana": true, "unifyHistoricalKana": true, "unifyPhoneticChanges": true, "unifyDakuon": true, "vol_str": "04 夕顔" }, "sort": "page", "limit": 20, "offset": 0, "total": 7, "aggregations": { "vol_str": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "04 夕顔", "doc_count": 7 } ] } } } } その結果、本文中に登場する「ゆふかほ」「夕かほ」「夕顔」を一度に検索することができます。 この検索キーワードの展開については、検索オプションをON/OFFを切り替えられるようにしています。詳細は、上述したSwagger UIでご確認ください。 ...

Minecraft Modでお城生成コマンドを作ってみた【Fabric 1.21 + Claude活用】

Minecraft Modでお城生成コマンドを作ってみた【Fabric 1.21 + Claude活用】

※ 本記事の大部分はAIが執筆しました。 はじめに Minecraft Modの学習を目的として、コマンド一つでお城を生成できるModを作ってみました。 開発環境 今回使用した技術スタック: Minecraft : 1.21 Modding Framework : Fabric Mod Java : 21 開発環境 : Cursor(AI統合エディタ) AI支援 : Claude 4 Sonnet 環境構築 Java 21のインストールが必要だったので、Homebrewで導入: brew install openjdk@21 プロジェクトの初期化は、Fabricの公式テンプレートをクローン: git clone https://github.com/FabricMC/fabric-example-mod.git castle-mod Cloning into 'castle-mod'... remote: Enumerating objects: 930, done. remote: Counting objects: 100% (47/47), done. remote: Compressing objects: 100% (30/30), done. remote: Total 930 (delta 33), reused 17 (delta 17), pack-reused 883 (from 3) Receiving objects: 100% (930/930), 588.77 KiB | 10.51 MiB/s, done. Resolving deltas: 100% (404/404), done. その後、Cursorで開発環境を起動: ...

デジタル文化財管理システム(試行版)のNFT対応

デジタル文化財管理システム(試行版)のNFT対応

お知らせ: 2025-06-14 開発の経過は以下にまとめています。 https://zenn.dev/nakamura196/books/41693d2d017082 概要 以下の記事をはじめとして、ブロックチェーンを用いたデジタル文化財管理システムの試作をしています。 今回、アップロードしたデータがNFTとして認識されるように改修しました。 勉強過程のため、不完全な点があるかと思いますが、参考になりましたら幸いです。 使い方ページ ファイルのアップロード方法はこれまでと同様です。アップロード後に表示される一覧ページにおいて、詳細ページへのリンクを追加しました。 リンクをクリックすると、以下のような詳細画面に遷移します。 実装方法 ※ この章は、AIが執筆しました。 1. コントラクトのNFT対応 既存のデジタル文化財管理コントラクトを、ERC721規格に準拠したNFTコントラクトに改修しました。 主な変更点: 1. OpenZeppelinライブラリの追加 import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; 2. コントラクトの継承構造を変更 contract DigitalHeritage is Initializable, OwnableUpgradeable, UUPSUpgradeable, ERC721Upgradeable, ERC721URIStorageUpgradeable { // ... } 3. 初期化関数の更新 function initialize() public initializer { __Ownable_init(msg.sender); __UUPSUpgradeable_init(); __ERC721_init("Digital Heritage", "DH"); __ERC721URIStorage_init(); } 4. 文化財登録時のNFTミント機能 function registerHeritage( string memory _name, string memory _description, string memory _imageUrl, string memory _tokenURI ) public { uint256 id = heritages.length; // 文化財データを保存 heritages.push(Heritage({ id: id, name: _name, description: _description, imageUrl: _imageUrl, owner: msg.sender, timestamp: block.timestamp, isDeleted: false })); // NFTとしてミント _safeMint(msg.sender, id); _setTokenURI(id, _tokenURI); emit HeritageRegistered(id, msg.sender, _name); } 2. メタデータ管理システムの実装 NFTの標準的なメタデータ形式に対応するため、サーバーサイドでのメタデータ生成・アップロード機能を実装しました。 ...

NDL古典籍OCR-Liteを用いて、IIIFマニフェストファイルからTEI/XMLファイルを作成する

NDL古典籍OCR-Liteを用いて、IIIFマニフェストファイルからTEI/XMLファイルを作成する

概要 NDL古典籍OCR-Liteを用いて、IIIFマニフェストファイルからTEI/XMLファイルを作成するGradioアプリの紹介です。 以下のURLからアクセスできます。 https://nakamura196-ndlkotenocr-lite-iiif.hf.space/ 背景 以下の記事の続きです。 これまでは、2つのアプリを使用する必要がありましたが、今回の改修により、単独のGradioアプリで変換作業が完結するようにしました。 また画像のコマ数が多いマニフェストファイルを処理する場合、進捗がわかりにくいことや、処理結果をコピーできない、といった不具合があったので、これらを修正しています。 画面の例 以下のように、「ページ 111/129 を処理中… - 79.7%」といった進捗を表示するように修正しました。 実装にあたっては、Progressを使用しています。 https://www.gradio.app/docs/gradio/progress またOCR完了後は、TEI/XMLファイルをダウンロードするためのリンクが表示されるようにしました。 まとめ Hugging Faceの無料で利用可能なCPUの制約上、OCRに時間がかかることがありますが、参考になりましたら幸いです。

ブロックチェーンとPinata IPFSを使用したデジタル文化財管理システムの試作

ブロックチェーンとPinata IPFSを使用したデジタル文化財管理システムの試作

お知らせ: 2025-06-14 開発の経過は以下にまとめています。 https://zenn.dev/nakamura196/books/41693d2d017082 概要 ブロックチェーンの学習にあたり、デジタル文化財の管理システムのプロトタイプを作成しました。ブロックチェーンの学習が目的のため、不足している機能などが多いですが、今後追加・改修を加えていく予定です。 https://digital-heritage-five.vercel.app/ 使用技術 EthereumのSepoliaネットワークを使用しています。ブロックチェーンの学習およびプロトタイプの開発が目的であるため、テストネットワークを使用します。 分散ファイルストレージIPFSのホスティングサービスとして、Pinataを使用しています。 https://pinata.cloud/ 準備 後述する本サイトの使用にあたり、MetaMaskのウォレットの作成や、ETHのSepoliaテストネットの作成などが必要です。また登録にあたっては、ガス代の支払いに必要なSepoliaETHが一定数必要です。 これらの方法については、別の記事で紹介したいと思いますが、インターネット上の記事を参考にしてください。 使い方 以下のURLにアクセスします。 https://digital-heritage-five.vercel.app/ MetaMaskがインストール済みの場合、以下のように表示されます。 「ウォレットを接続」ボタンを押すと、以下の画面が表示されます。 接続後、以下のような画面が表示されます。 サンプルとして、いらすとやさんの画像を利用させていただきます。 https://www.irasutoya.com/2020/12/blog-post_279.html 名前や説明、画像URLを入力して、登録ボタンを押します。 以下の画面が表示されます。確認ボタンを押します。 以下のようにデータが登録されます。 Transactionの確認 Etherscanを使って、取引の内容を確認することができます。 https://sepolia.etherscan.io/tx/0x1234567890abcdef…(例) Input Dataに入力されている文字列は、「スマートコントラクトの関数呼び出しのエンコードされたデータ」とのことです。以下の関数でデコードしてみます。 const ethers = require('ethers'); // デコードするインプットデータ const inputData = '0xb2f262e4...(実際の登録データの例)'; // インプットデータをデコード function decodeInput(input) { try { // 関数シグネチャを取得 const functionSignature = input.slice(0, 10); console.log('Function Signature:', functionSignature); // パラメータデータを取得(最初の4バイトを除く) const paramsData = '0x' + input.slice(10); // デコーダーを作成 const decoder = new ethers.AbiCoder(); // パラメータの型を定義 const types = ['string', 'string', 'string']; // データをデコード const decoded = decoder.decode(types, paramsData); // 結果を表示 console.log('\nDecoded Parameters:'); console.log('Name:', decoded[0]); console.log('Description:', decoded[1]); console.log('Image URL:', decoded[2]); } catch (error) { console.error('デコードエラー:', error); } } // デコードを実行 decodeInput(inputData); 結果、以下のように確認することができました。 ...

その2:NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成

その2:NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成

概要 以下の記事で、NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成について紹介しました。 上記について、説明が不十分な点が多かったため、改めて使い方を紹介いたします。 補足 今回の記事執筆に合わせて、以下の改修を加えました。 プロセス1: IIIFマニフェストファイルの作成 IIIF Presentation API v3に対応しました。 プロセス2: TEI/XMLファイルの作成 プロセス1との接続を考慮して、文字列を入力とするフォームを追加 使い方 プロセス1: IIIFマニフェストファイルの作成 以下にアクセスします。 https://nakamura196-ndlkotenocr-lite-iiif.hf.space/ 今回は、IIIF Presentation API v3でマニフェストファイルが公開されている「東北大学総合知デジタルアーカイブ」を対象とします。以下の「源氏物語湖月抄 本居宣長自筆付箋及書入」を対象とします。 https://touda.tohoku.ac.jp/portal/item/10010030012489 IIIFマニフェストファイルのURLは以下です。 https://touda.tohoku.ac.jp/collection/iiif/0/metadata/10010030012489/manifest.json 以下のように入力します。注意点として、「Image Width」を-1に設定してください。これにより、最大ピクセルの画像をダウンロードするようになります。(デフォルト値である1200ピクセルではエラーとなります。) 結果、OCRテキストをアノテーションとして持つIIIFマニフェストファイルのJSON文字列が画面右側に表示されます。以下の赤字で示すコピーボタンを押して、文字列をコピーしておきます。 プロセス2: TEI/XMLファイルの作成 以下にアクセスします。 https://iiif-tei-monorepo-web.vercel.app/ コピーしたJSON文字列を「Paste Manifest JSON」というフォームに貼り付け、Convert to TEI XMLボタンを押します。 結果、TEIに変換され、XMLファイルをダウンロードできます。 Oxygen XML EditorのAuthorモードで表示した例が以下です。 まとめ 使いにくい点も多いかと思いますが、OCRとIIIF・TEIの応用にあたり、参考になりましたら幸いです。

Omeka SのIIIF Serverモジュールを使用した階層構造を持つ目次の記述

Omeka SのIIIF Serverモジュールを使用した階層構造を持つ目次の記述

概要 Omeka SのIIIF Serverモジュールを使用し、階層構造を持つ目次の記述方法について紹介します。 マニュアル やや複雑な記述になっていますが、以下に説明があります。 https://github.com/Daniel-KM/Omeka-S-module-IiifServer?tab=readme-ov-file#input-format-of-the-property-for-structures-table-of-contents 単純な目次 「Toyo Bunko Media Repository」で公開されている以下を例とします。 https://app.toyobunko-lab.jp/s/main/document/9f9d95c2-d33d-7402-742b-47db12748688 以下のように、{RangeのID},{Rangeの名前},{Canvasのインデックス}を指定します。 r1,延享、寛延、宝暦,1 r2,明和,25 r3,安永一,55 r4,安永二,79 r5,天明一,110 r6,天明二,142 r7,寛政一,177 r8,寛政二,218 r9,享和,255 r10,文化一,279 r11,文化、文政、二,313 これにより、以下のように目次が表示されます。 階層構造を持つ目次 以下を例とします。 https://app.toyobunko-lab.jp/s/main/document/4797b8ca-530f-8aae-f252-7911ad64039b 階層構造を持つ目次を記述する場合には、以下のように4列でデータを用意します。 r0, 全体,-, r1;r2;r29;r55;r73 r1, 目次, 4-8, - r2, 第一、 蒙疆政府ノ司法制度…一頁, -, r3;r4;r9;r14;r15 r3, 一、 司法制度ノ沿革…一, 8-10, - r4, 二、 司法關係機關…四, -, r5;r6;r7;r8 r5, (一) 司法部…四, 10, - r6, (二) 法院…四, 10-11, - r7, (三) 縣旗司法機關…六, 11, - r8, (四) 行刑機關…七, 11-12, - r9, 三、 司法事務…八, -, r10;r11;r12;r13 r10, (一) 刑事事件…八, 12, - r11, (二) 民事事件…九, 12, - r12, (三) 行刑事務…九, 12-14, - r13, (四) 登記…一二, 14-15, - r14, 四、 司法經費…一四, 15-16, - 4列目に子要素となるRangeのIDを指定します。インデントを含めると、以下のような形になります。 ...

MCPサーバーを使って、Omeka Sにリソース(アイテムと画像)を登録する

MCPサーバーを使って、Omeka Sにリソース(アイテムと画像)を登録する

概要 MCPサーバーの勉強を兼ねて、Omeka Sにリソース(アイテムと画像)を登録するMCPサーバを作成しました。 https://github.com/nakamura196/omeka-s-mcp-sample 関連記事 以下の記事を参考にしています。 https://zenn.dev/himara2/articles/14eb2260c4f0e4 https://zenn.dev/meson_tech_blog/articles/simple-mcp-server 準備 MCP サーバをClaude Desktopで利用する方法については、他の記事に譲ります。以下のような設定を追加します。 { "mcpServers": { ... "omeka": { "command": "python", "args": [ "<絶対パス>/omeka_s_mcp_sample/server/omeka_server.py" ], "env": { "OMEKA_API_URL": "<Omeka SのURL>/api", "OMEKA_KEY_IDENTITY": "<OMEKA_KEY_IDENTITY>", "OMEKA_KEY_CREDENTIAL": "<OMEKA_KEY_CREDENTIAL>" } }, ... } } 結果、以下のようにツールが登録されます。 アイテムの登録 海に関するアイテムを登録して 海に関するアイテムをOmeka Sに登録いたします。「海」の項目が正常にOmeka Sに登録されました! 登録された項目の詳細: タイトル : 海 説明 : 地球の表面の約71%を占める広大な塩水の水域。生命の起源であり、気候調節、生態系の維持、人間の文化や経済活動において重要な役割を果たす。波の音、潮の香り、広がる水平線は多くの人々に癒しとインスピレーションを与える。 項目ID : 28 登録日時 : 2025年6月4日 23:11:49 (UTC) 海に関するアイテムが正常に作成されました。海の美しさや重要性について詳しく説明した内容で登録されています。必要に応じて、この項目にも海に関連する画像やメディアファイルを追加することができます。 海に関する画像も追加されますか?それとも他に何かご希望がありますか? 画像の登録 海に関する画像を3枚登録して 海に関する画像を3枚、先ほど作成した「海」の項目に登録いたします。海に関する画像3枚が正常にOmeka Sに登録されました! 登録された海の画像: 美しい海と空の景色 (メディアID: 29) 800×601ピクセル 登録日時: 2025年6月4日 23:12:22 (UTC) 海の波と海岸 (メディアID: 30) ...

DrupalのJSON:APIでcreatedやchangedに対するフィルタを適用する

DrupalのJSON:APIでcreatedやchangedに対するフィルタを適用する

概要 DrupalのJSON:APIでcreatedやchangedに対するフィルタを適用する方法の備忘録です。 背景 以下を参考にしました。 https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/filtering 例えば、6/2以降に更新されたものだけをフィルタリングしようとした際、以下のクエリでは適切に動作しませんでした。 ?filter[a-label][condition][path]=changed&filter[a-label][condition][operator]=%3E%3D&filter[a-label][condition][value]=2025-06-02 正しい方法 以下の記事が参考になりました。 https://www.reddit.com/r/drupal/comments/1bdvu61/json_api_drupal_filter_on_date/ Note that timestamp fields (like created or changed) currently must use a timestamp for filtering: タイムスタンプフィールド(createdやchangedなど)は現在、フィルタリングにタイムスタンプを使用する必要があります。 例えば、2025/6/2のタイムスタンプ1748790000を用いて、以下のようなクエリを使用することで、正しくフィルタリングできました。 ?filter[a-label][condition][path]=changed&filter[a-label][condition][operator]=%3E%3D&filter[a-label][condition][value]=1748790000 まとめ DrupalのJSON:APIで、createdやchangedに対するフィルタを適用する際にお役に立てば幸いです。

DTS Viewerの更新:ページネーションへの対応

DTS Viewerの更新:ページネーションへの対応

概要 DTS (Distributed Text Services)ビューアについて、ページネーションへの対応を行ったので、備忘録です。 https://dts-viewer.vercel.app/ja/ 背景 DTSで多数のリソースなどを提供する際に、以下のように、viewプロパティを使って、ページネーションに関する情報を提示するようでした。 https://distributed-text-services.github.io/specifications/versions/unstable/#collection-endpoint { "@context": "https://distributed-text-services.github.io/specifications/context/1-alpha1.json", "dtsVersion": "1-alpha", "@id" : "lettres_de_poilus", "@type" : "Collection", "collection": "/api/dts/collection/{?id,page,nav}", "totalParents": 1, "totalChildren": 10000, "title": "Lettres de Poilus", "dublinCore": { "publisher": ["École Nationale des Chartes", "https://viaf.org/viaf/167874585"], "title": [ {"lang": "fr", "value" : "Lettres de Poilus"} ] }, "member": [ "..." ], "view": { "@id": "/api/dts/collection/?id=lettres_de_poilus&page=19", "@type": "Pagination", "first": "/api/dts/collection/?id=lettres_de_poilus&page=1", "previous": "/api/dts/collection/?id=lettres_de_poilus&page=18", "next": "/api/dts/collection/?id=lettres_de_poilus&page=20", "last": "/api/dts/collection/?id=lettres_de_poilus&page=500" } } そこで、DTS Viewerについて、上記のviewプロパティに対応できるように改修しました。 表示例 コレクションがviewプロパティを持つ時、以下のように、ページネーションに関するボタンを表示するようにしました。 まとめ DTS (Distributed Text Services) APIを用いたデジタルテキストのコレクションの配信にあたり、参考になりましたら幸いです。

IIIF Presentation API v2のIIIFコレクションで、ページネーションを使う

IIIF Presentation API v2のIIIFコレクションで、ページネーションを使う

概要 IIIF Presentation API v2のIIIFコレクションで、ページネーションを使う機会がありましたので、備忘録です。 背景 IIIFコレクションでは、以下のように、複数のマニフェストファイル(およびコレクション)の一覧を提供することができます。 https://iiif.io/api/presentation/2.1/#collection { "@context": "http://iiif.io/api/presentation/2/context.json", "@id": "http://example.org/iiif/collection/top", "@type": "sc:Collection", "label": "Top Level Collection for Example Organization", "viewingHint": "top", "description": "Description of Collection", "attribution": "Provided by Example Organization", "manifests": [ { "@id": "http://example.org/iiif/book1/manifest", "@type": "sc:Manifest", "label": "Book 1" } ] } この時、対象とするマニフェストファイルが多数になった場合、一つのIIIFコレクションでは配信が難しくなりました。 これに対して、以下でページネーションに関する仕様がありましたので、こちらを使ってみます。 https://iiif.io/api/presentation/2.1/#paging ページネーション 上記のページでは、以下のような例が紹介されていました。 { "@context": "http://iiif.io/api/presentation/2/context.json", "@id": "http://example.org/iiif/collection/top", "@type": "sc:Collection", "label": "Example Big Collection", "total": 9316290, "first": "http://example.org/iiif/collection/c1" } { "@context": "http://iiif.io/api/presentation/2/context.json", "@id": "http://example.org/iiif/collection/c1", "@type": "sc:Collection", "within": "http://example.org/iiif/collection/top", "startIndex": 0, "next": "http://example.org/iiif/collection/c2", "manifests": [ // Manifests live here ... ] } まず、一つの目のJSONでコレクション全体のマニフェストファイル数totalを示し、さらにはじめの部分マニフェストファイル群へのリンクをfirstで提示します。 ...

Drupalで管理者以外のユーザーにも設定画面へのアクセスを許可する方法

Drupalで管理者以外のユーザーにも設定画面へのアクセスを許可する方法

本記事の一部はAIが作成しました。 概要 Drupalでカスタムモジュールの設定画面を作成する際、管理者以外のユーザーにもアクセスを許可したい場合があります。今回は、GitHub Webhookモジュールを例に、この問題の解決方法を説明します。 問題の発生 最初の状態では、以下のようなルーティング設定でした: # github_webhook.routing.yml github_webhook.settings: path: '/admin/config/github_webhook' defaults: _form: '\Drupal\github_webhook\Form\SettingsForm' _title: 'GitHub Webhook Settings' requirements: _permission: 'administer site configuration' この設定では、administer site configuration権限を持つ管理者のみがアクセス可能で、一般ユーザーはアクセスできませんでした。 解決方法1: 専用権限の作成 まず、専用の権限を作成します。github_webhook.permissions.ymlファイルを新規作成: access github webhook settings: title: 'Access GitHub Webhook Settings' description: 'Allow users to access GitHub webhook configuration.' そして、ルーティングファイルを更新: # github_webhook.routing.yml github_webhook.settings: path: '/admin/config/github_webhook' defaults: _form: '\Drupal\github_webhook\Form\SettingsForm' _title: 'GitHub Webhook Settings' requirements: _permission: 'access github webhook settings' 問題の発覚: /adminパスの制限 しかし、この変更だけでは解決しませんでした。Drupalでは/admin配下のパスは管理エリアとして扱われ、追加の権限チェックが行われるためです。 ...

NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成

NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成

お知らせ 本記事で紹介する流れをわかりやすくした記事を作成しました。以下も参考にしてください。 概要 NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成を行うツールを試作したので紹介します。 アノテーション付きIIIFマニフェストファイルの作成 まず、NDL古典籍OCR-Liteを用いて、IIIFマニフェストファイルを入力として、アノテーション付きIIIFマニフェストファイルを出力するGradioアプリを作成しました。Hugging FaceのSpaceを用いて公開しています。 https://nakamura196-ndlkotenocr-lite-iiif.hf.space/ 出力結果として、以下のようなアノテーション付きIIIFマニフェストファイルが得られます。 { "@context": "http://iiif.io/api/presentation/3/context.json", "id": "https://dl.ndl.go.jp/api/iiif/3437686/manifest.json", "type": "Manifest", "label": { "none": [ "校異源氏物語. 巻一" ] }, "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1", "type": "Canvas", "width": 6890, "height": 4706, "label": { "none": [ "1" ] }, "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/page", "type": "AnnotationPage", "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/page/imageanno", "type": "Annotation", "motivation": "sc:painting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1", "body": { "id": "https://dl.ndl.go.jp/api/iiif/3437686/R0000001/full/full/0/default.jpg", "type": "Image", "format": "image/jpeg", "width": 6890, "height": 4706, "service": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/R0000001", "type": "ImageService2", "profile": "level2" } ] } } ] } ], "annotations": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos", "type": "AnnotationPage", "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/0", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=5270,275,114,935", "body": { "type": "TextualBody", "value": "一・〇・・・・・・一一一一・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/1", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=5293,2009,218,424", "body": { "type": "TextualBody", "value": "○〇" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/2", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=5092,3272,63,80", "body": { "type": "TextualBody", "value": "一一" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/3", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=4375,304,103,1475", "body": { "type": "TextualBody", "value": "ス〇〇〇六〇〇〇一〇〇〇〇〇〇〇一一一〇〇〇一一一一〇〇〇〇〇〇〇〇〇〇一一・〇〇・・・・・・・の〇〇・・・・一・・・" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/4", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=4375,2853,45,522", "body": { "type": "TextualBody", "value": "□琉球□□□□□□□□□□□□□□□□□" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/5", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=4283,2756,63,252", "body": { "type": "TextualBody", "value": "〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇一〇〇一〇〇〇" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/6", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=694,499,310,2991", "body": { "type": "TextualBody", "value": "同校異源氏物巻一" } } ] } ] }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2", "type": "Canvas", "width": 6890, "height": 4706, "label": { "none": [ "2" ] }, "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2/page", "type": "AnnotationPage", "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2/page/imageanno", "type": "Annotation", "motivation": "sc:painting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2", "body": { "id": "https://dl.ndl.go.jp/api/iiif/3437686/R0000002/full/full/0/default.jpg", "type": "Image", "format": "image/jpeg", "width": 6890, "height": 4706, "service": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/R0000002", "type": "ImageService2", "profile": "level2" } ] } } ] } ], "annotations": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2/annos", "type": "AnnotationPage", "items": [] } ] } ] } TEI/XMLファイルの作成 上記で得られたアノテーション付きIIIFマニフェストファイルを入力として、TEI/XMLファイルを作成するライブラリを作成しました。 ...

IIIFマニフェストファイルから画像URLの一覧を含むCSVファイルを作成する

IIIFマニフェストファイルから画像URLの一覧を含むCSVファイルを作成する

概要 IIIFマニフェストファイルから画像URLの一覧を含むCSVファイルを作成するアプリを作成したので備忘録です。 以下からアクセスいただけます。 https://iiif-demo-next.vercel.app/csv-converter 使い方 国立国会図書館所蔵の「校異源氏物語. 巻一」を対象とします。 https://dl.ndl.go.jp/api/iiif/3437686/manifest.json 以下のフォームにマニフェストファイルのURLを入力し、「CSVをダウンロード」ボタンを押します。 結果、以下のように、URLやサイズの情報を含むCSVファイルがダウンロードされます。 url,width,height,canvas https://dl.ndl.go.jp/api/iiif/3437686/R0000001/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/1 https://dl.ndl.go.jp/api/iiif/3437686/R0000002/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/2 https://dl.ndl.go.jp/api/iiif/3437686/R0000003/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/3 https://dl.ndl.go.jp/api/iiif/3437686/R0000004/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/4 https://dl.ndl.go.jp/api/iiif/3437686/R0000005/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/5 https://dl.ndl.go.jp/api/iiif/3437686/R0000006/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/6 https://dl.ndl.go.jp/api/iiif/3437686/R0000007/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/7 https://dl.ndl.go.jp/api/iiif/3437686/R0000008/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/8 https://dl.ndl.go.jp/api/iiif/3437686/R0000009/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/9 https://dl.ndl.go.jp/api/iiif/3437686/R0000010/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/10 https://dl.ndl.go.jp/api/iiif/3437686/R0000011/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/11 https://dl.ndl.go.jp/api/iiif/3437686/R0000012/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/12 https://dl.ndl.go.jp/api/iiif/3437686/R0000013/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/13 https://dl.ndl.go.jp/api/iiif/3437686/R0000014/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/14 https://dl.ndl.go.jp/api/iiif/3437686/R0000015/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/15 https://dl.ndl.go.jp/api/iiif/3437686/R0000016/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/16 https://dl.ndl.go.jp/api/iiif/3437686/R0000017/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/17 https://dl.ndl.go.jp/api/iiif/3437686/R0000018/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/18 https://dl.ndl.go.jp/api/iiif/3437686/R0000019/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/19 https://dl.ndl.go.jp/api/iiif/3437686/R0000020/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/20 https://dl.ndl.go.jp/api/iiif/3437686/R0000021/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/21 https://dl.ndl.go.jp/api/iiif/3437686/R0000022/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/22 https://dl.ndl.go.jp/api/iiif/3437686/R0000023/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/23 https://dl.ndl.go.jp/api/iiif/3437686/R0000024/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/24 https://dl.ndl.go.jp/api/iiif/3437686/R0000025/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/25 https://dl.ndl.go.jp/api/iiif/3437686/R0000026/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/26 https://dl.ndl.go.jp/api/iiif/3437686/R0000027/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/27 https://dl.ndl.go.jp/api/iiif/3437686/R0000028/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/28 https://dl.ndl.go.jp/api/iiif/3437686/R0000029/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/29 https://dl.ndl.go.jp/api/iiif/3437686/R0000030/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/30 https://dl.ndl.go.jp/api/iiif/3437686/R0000031/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/31 https://dl.ndl.go.jp/api/iiif/3437686/R0000032/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/32 https://dl.ndl.go.jp/api/iiif/3437686/R0000033/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/33 https://dl.ndl.go.jp/api/iiif/3437686/R0000034/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/34 https://dl.ndl.go.jp/api/iiif/3437686/R0000035/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/35 https://dl.ndl.go.jp/api/iiif/3437686/R0000036/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/36 https://dl.ndl.go.jp/api/iiif/3437686/R0000037/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/37 https://dl.ndl.go.jp/api/iiif/3437686/R0000038/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/38 https://dl.ndl.go.jp/api/iiif/3437686/R0000039/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/39 https://dl.ndl.go.jp/api/iiif/3437686/R0000040/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/40 https://dl.ndl.go.jp/api/iiif/3437686/R0000041/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/41 https://dl.ndl.go.jp/api/iiif/3437686/R0000042/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/42 https://dl.ndl.go.jp/api/iiif/3437686/R0000043/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/43 https://dl.ndl.go.jp/api/iiif/3437686/R0000044/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/44 https://dl.ndl.go.jp/api/iiif/3437686/R0000045/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/45 https://dl.ndl.go.jp/api/iiif/3437686/R0000046/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/46 https://dl.ndl.go.jp/api/iiif/3437686/R0000047/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/47 https://dl.ndl.go.jp/api/iiif/3437686/R0000048/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/48 https://dl.ndl.go.jp/api/iiif/3437686/R0000049/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/49 https://dl.ndl.go.jp/api/iiif/3437686/R0000050/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/50 https://dl.ndl.go.jp/api/iiif/3437686/R0000051/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/51 https://dl.ndl.go.jp/api/iiif/3437686/R0000052/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/52 https://dl.ndl.go.jp/api/iiif/3437686/R0000053/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/53 https://dl.ndl.go.jp/api/iiif/3437686/R0000054/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/54 https://dl.ndl.go.jp/api/iiif/3437686/R0000055/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/55 https://dl.ndl.go.jp/api/iiif/3437686/R0000056/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/56 https://dl.ndl.go.jp/api/iiif/3437686/R0000057/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/57 https://dl.ndl.go.jp/api/iiif/3437686/R0000058/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/58 https://dl.ndl.go.jp/api/iiif/3437686/R0000059/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/59 https://dl.ndl.go.jp/api/iiif/3437686/R0000060/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/60 https://dl.ndl.go.jp/api/iiif/3437686/R0000061/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/61 https://dl.ndl.go.jp/api/iiif/3437686/R0000062/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/62 https://dl.ndl.go.jp/api/iiif/3437686/R0000063/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/63 https://dl.ndl.go.jp/api/iiif/3437686/R0000064/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/64 https://dl.ndl.go.jp/api/iiif/3437686/R0000065/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/65 https://dl.ndl.go.jp/api/iiif/3437686/R0000066/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/66 https://dl.ndl.go.jp/api/iiif/3437686/R0000067/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/67 https://dl.ndl.go.jp/api/iiif/3437686/R0000068/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/68 https://dl.ndl.go.jp/api/iiif/3437686/R0000069/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/69 https://dl.ndl.go.jp/api/iiif/3437686/R0000070/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/70 https://dl.ndl.go.jp/api/iiif/3437686/R0000071/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/71 https://dl.ndl.go.jp/api/iiif/3437686/R0000072/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/72 https://dl.ndl.go.jp/api/iiif/3437686/R0000073/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/73 https://dl.ndl.go.jp/api/iiif/3437686/R0000074/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/74 https://dl.ndl.go.jp/api/iiif/3437686/R0000075/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/75 https://dl.ndl.go.jp/api/iiif/3437686/R0000076/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/76 https://dl.ndl.go.jp/api/iiif/3437686/R0000077/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/77 https://dl.ndl.go.jp/api/iiif/3437686/R0000078/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/78 https://dl.ndl.go.jp/api/iiif/3437686/R0000079/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/79 https://dl.ndl.go.jp/api/iiif/3437686/R0000080/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/80 https://dl.ndl.go.jp/api/iiif/3437686/R0000081/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/81 https://dl.ndl.go.jp/api/iiif/3437686/R0000082/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/82 https://dl.ndl.go.jp/api/iiif/3437686/R0000083/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/83 https://dl.ndl.go.jp/api/iiif/3437686/R0000084/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/84 https://dl.ndl.go.jp/api/iiif/3437686/R0000085/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/85 https://dl.ndl.go.jp/api/iiif/3437686/R0000086/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/86 https://dl.ndl.go.jp/api/iiif/3437686/R0000087/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/87 https://dl.ndl.go.jp/api/iiif/3437686/R0000088/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/88 https://dl.ndl.go.jp/api/iiif/3437686/R0000089/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/89 https://dl.ndl.go.jp/api/iiif/3437686/R0000090/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/90 https://dl.ndl.go.jp/api/iiif/3437686/R0000091/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/91 https://dl.ndl.go.jp/api/iiif/3437686/R0000092/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/92 https://dl.ndl.go.jp/api/iiif/3437686/R0000093/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/93 https://dl.ndl.go.jp/api/iiif/3437686/R0000094/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/94 https://dl.ndl.go.jp/api/iiif/3437686/R0000095/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/95 https://dl.ndl.go.jp/api/iiif/3437686/R0000096/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/96 https://dl.ndl.go.jp/api/iiif/3437686/R0000097/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/97 https://dl.ndl.go.jp/api/iiif/3437686/R0000098/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/98 https://dl.ndl.go.jp/api/iiif/3437686/R0000099/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/99 https://dl.ndl.go.jp/api/iiif/3437686/R0000100/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/100 https://dl.ndl.go.jp/api/iiif/3437686/R0000101/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/101 https://dl.ndl.go.jp/api/iiif/3437686/R0000102/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/102 https://dl.ndl.go.jp/api/iiif/3437686/R0000103/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/103 https://dl.ndl.go.jp/api/iiif/3437686/R0000104/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/104 https://dl.ndl.go.jp/api/iiif/3437686/R0000105/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/105 https://dl.ndl.go.jp/api/iiif/3437686/R0000106/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/106 https://dl.ndl.go.jp/api/iiif/3437686/R0000107/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/107 https://dl.ndl.go.jp/api/iiif/3437686/R0000108/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/108 https://dl.ndl.go.jp/api/iiif/3437686/R0000109/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/109 https://dl.ndl.go.jp/api/iiif/3437686/R0000110/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/110 https://dl.ndl.go.jp/api/iiif/3437686/R0000111/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/111 https://dl.ndl.go.jp/api/iiif/3437686/R0000112/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/112 https://dl.ndl.go.jp/api/iiif/3437686/R0000113/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/113 https://dl.ndl.go.jp/api/iiif/3437686/R0000114/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/114 https://dl.ndl.go.jp/api/iiif/3437686/R0000115/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/115 https://dl.ndl.go.jp/api/iiif/3437686/R0000116/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/116 https://dl.ndl.go.jp/api/iiif/3437686/R0000117/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/117 https://dl.ndl.go.jp/api/iiif/3437686/R0000118/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/118 https://dl.ndl.go.jp/api/iiif/3437686/R0000119/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/119 https://dl.ndl.go.jp/api/iiif/3437686/R0000120/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/120 https://dl.ndl.go.jp/api/iiif/3437686/R0000121/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/121 https://dl.ndl.go.jp/api/iiif/3437686/R0000122/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/122 https://dl.ndl.go.jp/api/iiif/3437686/R0000123/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/123 https://dl.ndl.go.jp/api/iiif/3437686/R0000124/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/124 https://dl.ndl.go.jp/api/iiif/3437686/R0000125/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/125 https://dl.ndl.go.jp/api/iiif/3437686/R0000126/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/126 https://dl.ndl.go.jp/api/iiif/3437686/R0000127/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/127 https://dl.ndl.go.jp/api/iiif/3437686/R0000128/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/128 https://dl.ndl.go.jp/api/iiif/3437686/R0000129/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/129 https://dl.ndl.go.jp/api/iiif/3437686/R0000130/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/130 https://dl.ndl.go.jp/api/iiif/3437686/R0000131/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/131 https://dl.ndl.go.jp/api/iiif/3437686/R0000132/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/132 https://dl.ndl.go.jp/api/iiif/3437686/R0000133/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/133 https://dl.ndl.go.jp/api/iiif/3437686/R0000134/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/134 https://dl.ndl.go.jp/api/iiif/3437686/R0000135/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/135 https://dl.ndl.go.jp/api/iiif/3437686/R0000136/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/136 https://dl.ndl.go.jp/api/iiif/3437686/R0000137/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/137 https://dl.ndl.go.jp/api/iiif/3437686/R0000138/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/138 https://dl.ndl.go.jp/api/iiif/3437686/R0000139/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/139 https://dl.ndl.go.jp/api/iiif/3437686/R0000140/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/140 https://dl.ndl.go.jp/api/iiif/3437686/R0000141/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/141 https://dl.ndl.go.jp/api/iiif/3437686/R0000142/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/142 https://dl.ndl.go.jp/api/iiif/3437686/R0000143/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/143 https://dl.ndl.go.jp/api/iiif/3437686/R0000144/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/144 https://dl.ndl.go.jp/api/iiif/3437686/R0000145/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/145 https://dl.ndl.go.jp/api/iiif/3437686/R0000146/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/146 https://dl.ndl.go.jp/api/iiif/3437686/R0000147/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/147 https://dl.ndl.go.jp/api/iiif/3437686/R0000148/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/148 https://dl.ndl.go.jp/api/iiif/3437686/R0000149/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/149 https://dl.ndl.go.jp/api/iiif/3437686/R0000150/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/150 https://dl.ndl.go.jp/api/iiif/3437686/R0000151/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/151 https://dl.ndl.go.jp/api/iiif/3437686/R0000152/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/152 https://dl.ndl.go.jp/api/iiif/3437686/R0000153/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/153 https://dl.ndl.go.jp/api/iiif/3437686/R0000154/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/154 https://dl.ndl.go.jp/api/iiif/3437686/R0000155/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/155 https://dl.ndl.go.jp/api/iiif/3437686/R0000156/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/156 https://dl.ndl.go.jp/api/iiif/3437686/R0000157/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/157 https://dl.ndl.go.jp/api/iiif/3437686/R0000158/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/158 https://dl.ndl.go.jp/api/iiif/3437686/R0000159/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/159 https://dl.ndl.go.jp/api/iiif/3437686/R0000160/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/160 https://dl.ndl.go.jp/api/iiif/3437686/R0000161/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/161 https://dl.ndl.go.jp/api/iiif/3437686/R0000162/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/162 https://dl.ndl.go.jp/api/iiif/3437686/R0000163/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/163 https://dl.ndl.go.jp/api/iiif/3437686/R0000164/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/164 https://dl.ndl.go.jp/api/iiif/3437686/R0000165/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/165 https://dl.ndl.go.jp/api/iiif/3437686/R0000166/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/166 https://dl.ndl.go.jp/api/iiif/3437686/R0000167/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/167 https://dl.ndl.go.jp/api/iiif/3437686/R0000168/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/168 https://dl.ndl.go.jp/api/iiif/3437686/R0000169/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/169 https://dl.ndl.go.jp/api/iiif/3437686/R0000170/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/170 https://dl.ndl.go.jp/api/iiif/3437686/R0000171/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/171 https://dl.ndl.go.jp/api/iiif/3437686/R0000172/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/172 https://dl.ndl.go.jp/api/iiif/3437686/R0000173/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/173 https://dl.ndl.go.jp/api/iiif/3437686/R0000174/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/174 https://dl.ndl.go.jp/api/iiif/3437686/R0000175/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/175 https://dl.ndl.go.jp/api/iiif/3437686/R0000176/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/176 https://dl.ndl.go.jp/api/iiif/3437686/R0000177/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/177 https://dl.ndl.go.jp/api/iiif/3437686/R0000178/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/178 https://dl.ndl.go.jp/api/iiif/3437686/R0000179/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/179 https://dl.ndl.go.jp/api/iiif/3437686/R0000180/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/180 https://dl.ndl.go.jp/api/iiif/3437686/R0000181/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/181 https://dl.ndl.go.jp/api/iiif/3437686/R0000182/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/182 https://dl.ndl.go.jp/api/iiif/3437686/R0000183/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/183 https://dl.ndl.go.jp/api/iiif/3437686/R0000184/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/184 https://dl.ndl.go.jp/api/iiif/3437686/R0000185/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/185 https://dl.ndl.go.jp/api/iiif/3437686/R0000186/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/186 https://dl.ndl.go.jp/api/iiif/3437686/R0000187/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/187 https://dl.ndl.go.jp/api/iiif/3437686/R0000188/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/188 https://dl.ndl.go.jp/api/iiif/3437686/R0000189/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/189 https://dl.ndl.go.jp/api/iiif/3437686/R0000190/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/190 https://dl.ndl.go.jp/api/iiif/3437686/R0000191/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/191 https://dl.ndl.go.jp/api/iiif/3437686/R0000192/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/192 https://dl.ndl.go.jp/api/iiif/3437686/R0000193/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/193 https://dl.ndl.go.jp/api/iiif/3437686/R0000194/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/194 https://dl.ndl.go.jp/api/iiif/3437686/R0000195/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/195 https://dl.ndl.go.jp/api/iiif/3437686/R0000196/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/196 https://dl.ndl.go.jp/api/iiif/3437686/R0000197/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/197 https://dl.ndl.go.jp/api/iiif/3437686/R0000198/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/198 https://dl.ndl.go.jp/api/iiif/3437686/R0000199/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/199 https://dl.ndl.go.jp/api/iiif/3437686/R0000200/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/200 https://dl.ndl.go.jp/api/iiif/3437686/R0000201/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/201 https://dl.ndl.go.jp/api/iiif/3437686/R0000202/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/202 https://dl.ndl.go.jp/api/iiif/3437686/R0000203/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/203 https://dl.ndl.go.jp/api/iiif/3437686/R0000204/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/204 https://dl.ndl.go.jp/api/iiif/3437686/R0000205/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/205 https://dl.ndl.go.jp/api/iiif/3437686/R0000206/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/206 https://dl.ndl.go.jp/api/iiif/3437686/R0000207/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/207 https://dl.ndl.go.jp/api/iiif/3437686/R0000208/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/208 https://dl.ndl.go.jp/api/iiif/3437686/R0000209/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/209 https://dl.ndl.go.jp/api/iiif/3437686/R0000210/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/210 https://dl.ndl.go.jp/api/iiif/3437686/R0000211/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/211 https://dl.ndl.go.jp/api/iiif/3437686/R0000212/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/212 https://dl.ndl.go.jp/api/iiif/3437686/R0000213/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/213 https://dl.ndl.go.jp/api/iiif/3437686/R0000214/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/214 https://dl.ndl.go.jp/api/iiif/3437686/R0000215/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/215 https://dl.ndl.go.jp/api/iiif/3437686/R0000216/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/216 https://dl.ndl.go.jp/api/iiif/3437686/R0000217/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/217 https://dl.ndl.go.jp/api/iiif/3437686/R0000218/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/218 メモ 以下の記事で、@iiif/parserというnpmモジュールを紹介しました。 ...

DrupalでJSON形式のFieldを扱うための「JSON Field」モジュールを使用する

DrupalでJSON形式のFieldを扱うための「JSON Field」モジュールを使用する

概要 DrupalでJSON形式のFieldを扱うための「JSON Field」モジュールを使用する機会がありましたので、備忘録です。 https://www.drupal.org/project/json_field 結果、以下のようにエディタと共にJSONを扱えるようになりました。 インストール 以下により、ダウンロードします。 composer require 'drupal/json_field:^1.4' drush en json_field さらに、以下により、ウィジェットも有効します。 drush en json_field_widget GUIから有効にする場合には、以下の2つを有効にします。 設定 コンテンツタイプのフィールドの管理において、JSONフィールドを追加します。 そして、「フォームの表示管理」において、ウィジェットを選択します。 結果、コンテンツの編集画面で、以下のようなフォームが表示されます。 まとめ DrupalでJSONを管理するにあたり、参考になりましたら幸いです。

TEI/XMLファイルをS3互換のオブジェクトストレージでホストする

TEI/XMLファイルをS3互換のオブジェクトストレージでホストする

概要 TEI/XMLファイルをS3互換のオブジェクトストレージでホストする機会がありましたので、備忘録です。具体的には、mdx Iのオブジェクトストレージを対象にします。 https://mdx.jp/mdx1/p/about/system 背景 TEI/XMLファイルを読み込み、その内容を可視化するウェブアプリケーション(Next.js)を構築します。この時、ファイル数やサイズが小さい場合は、publicフォルダに格納していましたが、これらが大きくなった場合、別の場所でホストすることを考えました。 場所の選択肢は多々ありますが、今回はS3互換であるmdx Iのオブジェクトストレージを対象にします。 GUIを用いたオブジェクトストレージへのファイルアップロード オブジェクトストレージへTEI/XMLファイルをGUI経由でアップロードする方法も多々あります。その中で、これまではCyberduckを使用する方法や、GakunNin RDMを使用する方法などを紹介しました。 一方、今回の事例では、TEI/XML以外のコンテンツをDrupalで管理していました。そこで、Drupalとオブジェクトストレージを接続し、ユーザはDrupalの操作で完結できるようにしました。 Drupalとオブジェクトストレージの接続 以下のモジュールを使用します。 https://www.drupal.org/project/s3fs インストール後、環境設定のページ/admin/configから、S3 File Systemを選択します。 そして、アクセスキーや秘密鍵を登録し、さらにS3のバケット名を登録します。 またAdvanced Configuration OptionsのCustom Host Settingsにおいて、https://s3ds.mdx.jpを入力します。 これでオブジェクトストレージとの接続設定は完了です。 その後、各コンテンツタイプのフィード設定において、アップロード先として「S3 File System」を選択します。 また、今回はTEI/XMLファイルがアップロード対象となるため、「許可されている拡張子」として、xmlを入力します。 この結果、DrupalのGUIを介してアップロードしたTEI/XMLファイルが、mdx Iのオブジェクトストレージに格納されるようになりました。 (参考)DrupalのJSON:APIを用いたファイルの一括アップロード TEI/XMLの初期登録にあたり、Pythonを用いた一括登録を行いました。JSON:APIを用いたファイルの一括アップロードの方法は、以下の記事などが参考になりました。 https://www.drupal.org/node/3024331 一例ですが、以下のようなスクリプトで実現できました。 import requests import json import os from dotenv import load_dotenv from glob import glob from tqdm import tqdm class ApiClient: def __init__(self): load_dotenv(override=True) # DrupalサイトのURL(例) self.DRUPAL_BASE_URL = os.getenv("DRUPAL_BASE_URL") # エンドポイント(JSON:API) # self.JSONAPI_ENDPOINT = f"{self.DRUPAL_BASE_URL}/jsonapi/node/article" # 認証情報(Basic認証) self.USERNAME = os.getenv("DRUPAL_USERNAME") self.PASSWORD = os.getenv("DRUPAL_PASSWORD") def login(self): # ログインリクエスト login_url = f"{self.DRUPAL_BASE_URL}/user/login?_format=json" login_response = requests.post( login_url, json={"name": self.USERNAME, "pass": self.PASSWORD}, headers={"Content-Type": "application/json"} ) if login_response.status_code == 200: self.session_cookies = login_response.cookies def get_csrf_token(self): # CSRFトークンを取得 csrf_token_response = requests.get( f"{self.DRUPAL_BASE_URL}/session/token", cookies=self.session_cookies # ここでログインセッションを渡す ) if csrf_token_response.status_code == 200: # return csrf_token_response.text # self.csrf_token = csrf_token_response.text self.headers = { "Content-Type": "application/vnd.api+json", "Accept": "application/vnd.api+json", "X-CSRF-Token": csrf_token_response.text, } else: # raise Exception(f"CSRFトークン取得失敗: {csrf_token_response.status_code} {csrf_token_response.text}") self.csrf_token = None def upload_file(self, type, uuid, field, file_path, verbose=False): url = f"{self.DRUPAL_BASE_URL}/jsonapi/node/{type}/{uuid}/{field}" # ファイル名を取得 filename = os.path.basename(file_path) # ファイルをバイナリモードで読み込む with open(file_path, 'rb') as f: file_data = f.read() headers = self.headers.copy() headers['Content-Type'] = 'application/octet-stream' headers['Content-Disposition'] = f'attachment; filename="{filename}"' # ファイルをアップロード response = requests.post(url, headers=headers, cookies=self.session_cookies, data=file_data) if response.status_code == 200: if verbose: print(f"ファイルアップロード成功: {filename}") else: print(f"ファイルアップロード失敗: {response.status_code} {response.text}") すでに対象コンテンツが作成済みで、例えばfield_fileといったフィールドにファイルをアップロードする目的で使用することができます。 ...