ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
RSS English

最新の記事

ZoteroのAPIとStreamlitを使ったアプリ開発

ZoteroのAPIとStreamlitを使ったアプリ開発

概要 ZoteroのAPIとStreamlitを使ったアプリを試作しました。 https://nakamura196-zotero.streamlit.app/ 本記事は、このアプリ開発におけるメモです。 Streamlit 以下の記事がとても参考になりました。 https://qiita.com/sypn/items/80962d84126be4092d3c ZoteroのAPI ZoteroのAPIについて、以下で説明されています。 https://www.zotero.org/support/dev/web_api/v3/start 今回は上記のページで紹介されている以下のライブラリを使用しました。 https://github.com/urschrei/pyzotero APIの利用にあたっては、personal library IDやAPI keyを取得する必要がありますが、READMEのQuickstartの手順に従うと、それらを取得することができました。 以下は、API keyを発行した際の画面です。 Streamlitを用いた開発 以下のリポジトリでソースコードを公開しています。 https://github.com/nakamura196/zotero_streamlit 機密情報 機密情報は、/.streamlit/secrets.tomlというファイルを作成し、そこに記載するようでした。.gitignoreに記載することも忘れないようにしてください。 [zotero] library_id="xxx" library_type="user" api_key="xxx" そして、以下のように呼び出すことができました。 def init_zotero(): library_id = st.secrets["zotero"]["library_id"] library_type = st.secrets["zotero"]["library_type"] api_key = st.secrets["zotero"]["api_key"] return zotero.Zotero(library_id, library_type, api_key) Zoteroライブラリのコレクション一覧の取得 以下ので、Zoteroライブラリからコレクションの一覧を取得することができました。 def fetch_collections(zot): """ Zoteroライブラリからコレクション一覧を取得する """ collections = zot.collections() # 各コレクションからタイトルとキー(ID)を取得 collection_list = [{"name": collection['data']['name'], "key": collection['data']['key']} for collection in collections] return collection_list コレクション内のアイテムの取得 以下でコレクション内のアイテムを取得できました。itemTypeがattachmentのものはスキップする処理を加えています。 # 文献データをDataFrameに変換 def create_df(zot, collection_id): if not collection_id: return pd.DataFrame() try: items = zot.collection_items(collection_id) rows = [{ 'title': item['data']['title'], "itemType": item['data']['itemType'], "creators": ", ".join(f"{creator['firstName']} {creator['lastName']}" for creator in item['data'].get('creators', [])), "date": item['data'].get('date', "") } for item in items if item['data']['itemType'] != "attachment"] return pd.DataFrame(rows) except Exception as e: st.error(f"Failed to load items from collection: {e}") return pd.DataFrame() メタタグ設定 以下のような形で、タイトルなどのページ設定を行うことができました。 ...

字幕付きの音声ファイルをIIIFビューアで表示する

字幕付きの音声ファイルをIIIFビューアで表示する

概要 字幕付きの音声ファイルをIIIFビューアで表示する機会がありましたので、備忘録です。 国立国会図書館 歴史的音源で公開されている「日本のアクセントと言葉調子(下)」を対象に、OpenAIのSpeech to textを使用しています。文字起こし結果には誤りが含まれていますので、その点はご注意ください。 以下は、Rampでの表示例です。 https://ramp.avalonmediasystem.org/?iiif-content=https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json 以下は、Cloverでの表示例です。 https://samvera-labs.github.io/clover-iiif/docs/viewer/demo?iiif-content=https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json 以下は、Aviaryでの表示例です。こちらについては、残念ながら今回使用したマニフェストファイルの形式では、文字起こしテキストは表示できませんでした。 https://iiif.aviaryplatform.com/player?manifest=https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json 以下、これらのマニフェストファイルの作成方法について紹介します。 mp4ファイルの準備 以下の記事を参考に、mp4ファイルを取得します。 vttファイルの作成 OpenAIのAPIを使用して、文字起こしを行います。 from openai import OpenAI client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) audio_file= open(output_mp4_path, "rb") transcript = client.audio.transcriptions.create( model="whisper-1", file=audio_file, response_format="vtt") with open(output_vtt_path, "w", encoding="utf-8") as file: file.write(transcript) マニフェストファイルの作成 不完全なコードですが、以下のようなプログラムによって、マニフェストファイルを作成します。 from iiif_prezi3 import Manifest, AnnotationPage, Annotation, ResourceItem, config from moviepy.editor import VideoFileClip def get_video_duration(filename): with VideoFileClip(filename) as video: return video.duration config.configs['helpers.auto_fields.AutoLang'].auto_lang = "ja" duration=get_video_duration(mp4_path) manifest = Manifest(id=f"{prefix}/manifest.json", label=label) canvas = manifest.make_canvas(id=f"{prefix}/canvas", duration=duration) anno_body = ResourceItem(id=mp4_url, type="Sound", format="audio/mp4", duration=duration) anno_page = AnnotationPage(id=f"{prefix}/canvas/page") anno = Annotation(id=f"{prefix}/canvas/page/annotation", motivation="painting", body=anno_body, target=canvas.id) anno_page.add_item(anno) canvas.add_item(anno_page) # VTT URLを追加 vtt_body = ResourceItem(id=vtt_url, type="Text", format="text/vtt") vtt_anno = Annotation( id=f"{prefix}/canvas/annotation/webvtt", motivation="supplementing", body=vtt_body, target=canvas.id, label = "WebVTT Transcript (machine-generated)" ) vtt_anno_page = AnnotationPage(id=f"{prefix}/canvas/page/2") vtt_anno_page.add_item(vtt_anno) canvas.annotations = [vtt_anno_page] with open(output_path, "w") as f: f.write(manifest.json(indent=2)) ライブラリとして、iiif-prezi3を使用しています。以下の記事も参考にしてください。 ...

mdx.jpのオブジェクトストレージに複数ファイルをアップロードする

mdx.jpのオブジェクトストレージに複数ファイルをアップロードする

概要 mdx.jpのオブジェクトストレージに複数ファイルをアップロードする方法の備忘録です。以下の動画を参考にしています。 https://youtu.be/IN_4NS9hO2Y 準備 macOSで作業します。 brew install s3cmd 設定(内容は動画を確認してください。) s3cmd --configure 一括登録(同期) 以下は、ローカルのrekionフォルダ内のファイルをs3://rekion/iiif/と同期します。 s3cmd sync docs/rekion/ s3://rekion/iiif/ --exclude '.DS_Store' 参考 find . -name '.DS_Store' -type f -delete aclの一括変更 s3cmd setacl s3://rekion/iiif/ --acl-public --recursive 注意(corsの許可) 以下のxmlファイルを用意して、corsの許可を試みました。 <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration> ただし、以下の結果となり、この方法ではcorsの許可ができませんでした。 s3cmd setcors cors.xml s3://rekion/ ERROR: S3 error: 501 (NotImplemented): A header or parameter you provided implies functionality that is not implemented. 設定方法について、引き続き調べたいと思います。 まとめ mdx.jpのオブジェクトストレージの利用にあたり、参考になりましたら幸いです。

国立国会図書館 歴史的音源で公開されている音声をmp4に変換する

国立国会図書館 歴史的音源で公開されている音声をmp4に変換する

概要 国立国会図書館 歴史的音源(以下、れきおん)で公開されている音声をmp4に変換する機会がありましたので、備忘録です。 れきおんの提供形式 れきおんでは、m3u8形式のファイルが公開されていました。 例えば、以下の「講演:道徳、経済合一論(一)Union of Morality of Economy」を確認してみます。 https://rekion.dl.ndl.go.jp/pid/3574643 開発者ツールなどで確認すると、以下のURLからアクセスできることが確認できます。 https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8 このURLを構成するIDなどは、以下のAPIの返却結果の中で確認できました。 https://rekion.dl.ndl.go.jp/api/item/search/info:ndljp/pid/3574643 pidから上記のURLを取得するAPIの開発 上記のJSONを処理することで、m3u8ファイルのURLを取得します。 この部分をAPI化したので、試していただけますと幸いです。 https://iiif-demo-next.vercel.app/api/rekion/3574643 以下のような結果が得られます。 { "data": { "type": "rekion", "id": "3574643", "attributes": { "title": "講演:道徳、経済合一論(一)Union of Morality of Economy", "url": "https://rekion.dl.ndl.go.jp/pid/3574643", "hls": "https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8" } } } ソースコードは以下です。 https://github.com/nakamura196/iiif-demo-next/blob/main/src/app/api/rekion/[id]/route.ts ffmpegを使ってmp4に変換する 以下のようなコマンドにより、m3u8ファイルをmp4形式に変換できました。 ffmpeg -i "https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8" -c copy 3574643.mp4 まとめ 音声ファイルの利用にあたり、参考になりましたら幸いです。

Rampをカスタマイズする

Rampをカスタマイズする

概要 Rampのカスタマイズ方法に関する備忘録です。カスタマイズの結果、以下のように、UIの一部を日本語化し、メディアプレイヤーとメタデータおよび文字起こしを左右に並べて表示します。また、クエリパラメータtを使って、音声の再生開始時間を指定できるようにします。 例えば、以下のURLから、140秒時点から再生することができます。 https://ramp-iiif.vercel.app/?iiif-content=https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json&t=140 以下がカスタマイズ前です。 セットアップ 以下の記事の参考にしてください。 カスタマイズ 音声の再生開始時間の指定 以下のマニュアルにおいて、startCanvasTimeプロパティが使えることがわかります。 https://samvera-labs.github.io/ramp/#!/IIIFPlayer そこで、以下のindex.jsファイルに対して、startCanvasTimeをクエリパラメータから取得する処理を追加します。 import React from 'react'; import ReactDOM from 'react-dom'; import App from './app'; // import config from './config'; const manifestURL = () => { const params = new URLSearchParams(window.location.search); // let url = `${config.url}/manifests/${config.env}/lunchroom_manners.json`; let url = "https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json" if (params.has('iiif-content')) { url = params.get('iiif-content'); } return url; }; const startCanvasTime = () => { const params = new URLSearchParams(window.location.search); if (params.has('t')) { return parseFloat(params.get('t')); } return 0; } ReactDOM.render(<App manifestURL={manifestURL()} startCanvasTime={startCanvasTime()} />, document.getElementById('root')); そして、app.jsに対して、startCanvasTimeプロパティを与えます。これにより、クエリパラメータから、メディアの再生開始時間を指定できます。 ... <IIIFPlayer manifestUrl={manifestUrl} startCanvasTime={canvasTime} > ... 日本語化およびレイアウトの変更 上記と同様、demo/app.jsファイルを編集することで、日本語化およびレイアウトの変更を行うことができます。 Vercelへのデプロイ Build & Development Settingsを以下のように指定します。 Build Commandにnpm run demo:build、Output Directoryにdemo/distを設定します。 また、Node.js Versionを18.xにする必要がありました。20.xの場合、パッケージのインストール時にエラーが発生しました。 まとめ Rampの開発に関わる方々に感謝いたします。RampおよびIIIF Presentation API v3の利用にあたり、参考になりましたら幸いです。 ...

Rampをローカルで起動する

Rampをローカルで起動する

概要 Rampをローカルで起動してみましたので、備忘録です。 背景 Rampは以下のように説明されています。 Interactive, IIIF powered audio/video media player React components library. (日本語訳)インタラクティブな、IIIF対応のオーディオ/ビデオメディアプレイヤーReactコンポーネントライブラリ 以下のGitHubリポジトリでソースコードが公開されています。 https://github.com/samvera-labs/ramp 起動 以下で起動できました。 git clone https://github.com/samvera-labs/ramp pnpm i pnpm demo 以下に記載があります。 https://github.com/samvera-labs/ramp?tab=readme-ov-file#styleguidist-development 以下の場合は、スタイルガイドのページが表示されますので、ご注意ください。 pnpm dev まとめ 参考になりましたら幸いです。

URLの引数で指定したIIIFマニフェストに対して、Mirador 3のannotationsプラグインを試す

URLの引数で指定したIIIFマニフェストに対して、Mirador 3のannotationsプラグインを試す

概要 URLの引数で指定したIIIFマニフェストに対して、Mirador 3のannotationsプラグインを試すことができるデモページを用意しました。 https://mirador-annotations.vercel.app/ iiif-contentまたはmanifest引数を使用することで、指定したIIIFマニフェストを対象にすることができます。 https://mirador-annotations.vercel.app/?iiif-content=https://dl.ndl.go.jp/api/iiif/1301543/manifest.json 本記事は、このデモページの作成に関する備忘録です。 背景 Mirador 3向けのアノテーション付与プラグインとして、mirador-annotationsがあります。 https://github.com/ProjectMirador/mirador-annotations 以下の記事で使い方の例を紹介しています。 そして、以下のデモページがすでに用意されていますが、URLの引数にIIIFマニフェストファイルを指定する機能は提供されていません。 https://mirador-annotations.netlify.app/ フォークと修正 URLの引数にIIIFマニフェストファイルを指定する機能の追加にあたり、上記のリポジトリをクローンしました。 https://github.com/nakamura196/mirador-annotations そして、以下の修正を加えました。 https://github.com/nakamura196/mirador-annotations/commit/18848ccb1fa51df821335ed76e7b9f4e974527d0 特に、以下の修正を加えています。 ... var params = new URL(document.location).searchParams; var manifest = params.get('iiif-content') || params.get('manifest') || 'https://iiif.harvardartmuseums.org/manifests/object/299843' var windows = []; if (manifest) { windows.push({ manifestId: manifest }); } ... これは、以下の実装を参考にしています。iiif-contentまたはmanifest引数でIIIFマニフェストファイルを参照するようでした。 https://projectmirador.org/embed/?iiif-content=https://iiif.io/api/cookbook/recipe/0001-mvm-image/manifest.json Vercelへのデプロイ設定 フォークしたリポジトリのソースコードをビルドした結果を、Vercelにデプロイしています。 デプロイにあたり、以下のような修正を加えました。 Output Directory、Install CommandおよびNode.jsのVersionを16.xに変更しています。 まとめ Mirador 3の利用にあたり、参考になりましたら幸いです。

mdx.jpのオブジェクトストレージとCantaloupe Image Serverを使ってIIIF画像を配信する

mdx.jpのオブジェクトストレージとCantaloupe Image Serverを使ってIIIF画像を配信する

概要 mdx.jpのオブジェクトストレージとIIIFイメージサーバの一つであるCantaloupe Image Serverを使ってIIIF画像を配信する方法に関する備忘録です。 背景 以下の記事で、mdx.jpのオブジェクトストレージを使った画像の配信方法について紹介しました。 また以下の記事で、Cantaloupe Image Serverで、Amazon S3に格納した画像を配信する方法について紹介しました。 これらを組み合わせることにより、デジタルアーカイブにおけるIIIF画像配信コストの課題の解決を目指します。 方法 以下の記事で紹介したDocker版Cantaloupeを使用します。 以下のリポジトリから、ソースコードをダウンロードいただけます。 https://github.com/nakamura196/docker_cantaloupe_s3 同梱されている.env.sampleを.envファイルにリネームし、設定を変更します。 # aws s3 CANTALOUPE_S3SOURCE_ENDPOINT= # mdx.jp # CANTALOUPE_S3SOURCE_ENDPOINT=https://s3ds.mdx.jp CANTALOUPE_S3SOURCE_ACCESS_KEY_ID= CANTALOUPE_S3SOURCE_SECRET_KEY= CANTALOUPE_S3SOURCE_REGION= CANTALOUPE_S3SOURCE_BASICLOOKUPSTRATEGY_BUCKET_NAME= ポイントはCANTALOUPE_S3SOURCE_ENDPOINTです。ここに、https://s3ds.mdx.jpを与えて、取得したACCESS_KEY_IDやSECRET_KEY、作成したBUCKET_NAMEやREGIONを設定します。 デモ 冒頭の記事でも使用した、いらすとやさんの画像を利用します。 https://www.irasutoya.com/2016/09/blog-post_810.html 以下、上記でアップロードした同じ画像ファイルを、Cantaloupeを使って配信している例です。 info.json https://cantaloupe.aws.ldas.jp/iiif/3/baby_asia_boy.png/info.json グレー化: full/max/0/gray.jpg https://cantaloupe.aws.ldas.jp/iiif/3/baby_asia_boy.png/full/max/0/gray.jpg なお、Cantaloupeを使って画像配信を行う場合には、上記の記事で実施したACLの設定(EveryoneにRead権限を与える)は不要です。デフォルトの設定を使用することで、オブジェクトストレージ上の画像ファイルへの直接アクセスは不可としつつ、Cantaloupeを介したアクセスのみを許可できるかと思います。 以下の記事で紹介したようなCantaloupe側のAccess Control設定を組み合わせることで、アクセス制御を実現することになるかと思います。 まとめ Amazon S3に格納した画像をIIIF画像として配信する方法として、以下の方法もあります。これが、Amazon S3以外のオブジェクトストレージにも対応しているのか、今後調査してみたいと思います。 IIIF画像の配信にあたり、参考になりましたら幸いです。

mdxのオブジェクトストレージを使用する(Cyberduckの利用)

mdxのオブジェクトストレージを使用する(Cyberduckの利用)

概要 mdxのオブジェクトストレージを使用する機会がありましたので、備忘録です。 https://mdx.jp/ 料金 2024年度の料金は以下のようになっています。 https://mdx.jp/guide/charge 1GBあたり、0.01ポイント(円)/日となっており、おおよそ1GBあたり、0.3円/月となっています。 申請方法 & s3cmdを用いた使い方 以下の公式チュートリアル動画が参考になりました。 https://www.youtube.com/watch?v=IN_4NS9hO2Y Cyberduckを使う 上記の動画ではコマンドラインツールによるファイル操作方法が紹介されています。 ここでは、Cyberduckを使用して、GUIを使ってファイル操作を行います。 AWS S3に対するCyberduckの操作方法を以下の記事で紹介しています。以下の方法を参考に、mdxのオブジェクトストレージに接続してみます。 接続設定 「新規接続」から接続設定を行います。 「Amazon S3」を選択して、サーバに「s3ds.mdx.jp」を入力します。 そして、発行された「アクセスキーID」および「シークレットアクセスキー」を入力します。 バケットの作成 右クリック > 「新規フォルダ」でバケットを作成できます。 ファイルのアップロード 以下のいらすとやさんの画像を使用します。 https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNuMuIaXnIW5QJXkLiV1ojUeUiIwNQF1O0lp2LgG2LGJUbIU8j4bFAyLyKq3BiYp53p0Yc8AtMsEykJAQgEx4SJyFvKY4OyNeDBFopPb4lnV7_wtZNkr91qwj6-m-8s-sl1aadYMhrpuoI/s800/baby_asia_boy.png 「satoru196」フォルダにドラッグ&ドロップでアップロードすることができます。 上述した公式チュートリアルでも言及されていますが、このままでは以下のURLにアクセスしても、表示ができません。 https://s3ds.mdx.jp/satoru196/baby_asia_boy.png 以下のようなエラーコードが表示されます。 <Error> <script/> <Code>AccessDenied</Code> <Message>Access Denied</Message> <RequestId>...</RequestId> <HostId>00000000000000000</HostId> </Error> ACLの変更 ファイルを右クリックして、「情報」をクリックします。 以下のように、Everyoneを選択して、 READ権限を付与します。 この結果、以下のURLから画像を閲覧することができます。 https://s3ds.mdx.jp/satoru196/baby_asia_boy.png まとめ mdxのオブジェクトストレージを活用することで、様々な用途がありますが、例えばメディアを安価に公開することができそうです。特に、デジタルアーカイブにおけるメディアの公開元として、有力なインフラになり得るかと思います。 mdxのs3互換のオブジェクトストレージの利用にあたり、参考になりましたら幸いです。

Mirador 3でScroll Viewを使う

Mirador 3でScroll Viewを使う

概要 Mirador 3でScroll Viewを使う方法についての備忘録です。 以下、「鹿児嶋征討記之内 高瀬口河通ノ戦争野津公聯隊旗を取返ス図(国立国会図書館所蔵)」を例としています。 このIIIFマニフェストは3つのキャンバス(画像)から構成されており、通常の表示方法(Single, 単一モード)では、画像ごとに表示されます。 これを3つ繋げて表示することを目指します。 デモ 以下からお試しいただけます。 https://nakamura196.github.io/mirador-multi-image/ IIIFマニフェストファイルについては、国立国会図書館で公開されているIIIFマニフェストファイルを一部変更しています。 変更前 https://dl.ndl.go.jp/api/iiif/1301543/manifest.json 変更後 https://nakamura196.github.io/mirador-multi-image/manifest.json 変更箇所として、今回の記事の目的であるScroll表示と直接関係がありませんが、画像が右から左に表示されるように、"viewingDirection": "right-to-left"を追加しています。 Miradorの設定 Mirador 2では事前設定なしにScroll Viewが使えましたが、Mirador 3のデフォルト設定では、Scroll Viewは無効化されているようでした。 https://projectmirador.org/embed/?iiif-content=https://nakamura196.github.io/mirador-multi-image/manifest.json そこで、Mirador 3の初期設定を以下のように修正します。 https://github.com/nakamura196/mirador-multi-image/blob/main/docs/index.html const config = { id: "mirador", windows: [ { manifestId: "./manifest.json", }, ], language: "ja", window: { sideBarOpenByDefault: true, defaultSideBarPanel: "info", defaultView: "scroll", views: [{ key: "single" }, { key: "gallery" }, { key: "scroll" }], }, }; Mirador.viewer(config); ポイントは、views: [{ key: "single" }, { key: "gallery" }, { key: "scroll" }]です。ここで、Scroll Viewを追加することで、以下のように選択肢として表示されるようになりました。 参考 defaultView未指定時のバグ デフォルト表示を未指定の場合、上記の例ではSingle(単一)表示が使用されますが、その状態からScroll Viewボタンを押すと、表示がうまく切り替わらないケースがありました。 この問題について、上記のように、defaultView: "scroll"を設定しておくことで回避できました。根本的な解決方法は改めて調査したいと思います。 ...

Docker + Traefikで運用するDrupalのリバースプロキシ設定

Docker + Traefikで運用するDrupalのリバースプロキシ設定

概要 以下の記事で紹介したDocker + Traefikを用いて、HTTPS化したDrupalを運用していました。 この時、Drupalのデフォルト設定の場合、以下のように、httpのURLが設定されていました。 この問題として、以下の記事になるように、例えばGoogleアカウントでログインするようにした際、リダイレクトURLがhttpから始まるURLとなり、Google Cloud コンソールにはhttpsから始まるURLを入力する必要があり、この齟齬によって、認証ができないケースなどがありました。 https://drupalfan.com/【drupal】googleアカウントでログインできるようにする/ 本記事では、この問題に対処するための方法についてメモします。 方法 以下の記事が参考になりました。 https://www.58bits.com/blog/canonical-urls-https-and-drupal-89-reverse-proxy-settings 以下の3行を追加することで、Drupalの内部的にもhttpsから始まるURLに設定されました。 ... $settings['reverse_proxy'] = TRUE; $settings['reverse_proxy_addresses'] = array($_SERVER['REMOTE_ADDR']); $settings['reverse_proxy_trusted_headers'] = \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PORT; ... まとめ 考慮不足の点があるかもしれませんが、参考になりましたら幸いです。

Traefikでhttpsにリダイレクトさせる

Traefikでhttpsにリダイレクトさせる

概要 以下の記事でTraefikを使ったhttps化したコンテナの運用例を紹介しました。 ただ、(現在は修正済み)http接続をhttps接続にリダイレクトする設定が漏れており、80ポートにアクセスすると、not foundになっていました。 この点の修正方法に関する備忘録です。 変更前 log: # level: DEBUG entryPoints: web: address: :80 websecure: address: :443 api: dashboard: true providers: docker: exposedByDefault: false certificatesResolvers: myresolver: acme: email: aaa@bbb storage: /acme.json caServer: https://acme-v02.api.letsencrypt.org/directory # caServer: https://acme-staging-v02.api.letsencrypt.org/directory httpChallenge: entryPoint: web 変更後 log: # level: DEBUG entryPoints: web: address: :80 http: redirections: entryPoint: to: websecure schema: https permanent: true websecure: address: :443 api: dashboard: true providers: docker: exposedByDefault: false certificatesResolvers: myresolver: acme: email: na.kamura.1263@gmail.com storage: /acme.json caServer: https://acme-v02.api.letsencrypt.org/directory # caServer: https://acme-staging-v02.api.letsencrypt.org/directory httpChallenge: entryPoint: web entryPointsの部分について、以下のようにリダイレクトの設定を追加しています。 ...

IIIF対応ビューアの一覧の調査例

IIIF対応ビューアの一覧の調査例

概要 IIIF対応のビューアの一覧にあたり、調べてみた例を共有します。不足している点も多いかと思いますが、参考になりましたら幸いです。 Name URL Icon Mirador https://projectmirador.org/embed/?iiif-content= mirador3.svg Universal Viewer https://uv-v3.netlify.app/#?manifest= uv.jpg Annona https://ncsu-libraries.github.io/annona/tools/#/display?url= annoa.png Clover https://samvera-labs.github.io/clover-iiif/docs/viewer/demo?iiif-content= clover.png Glycerine Viewer https://demo.viewer.glycerine.io/viewer?iiif-content= glycerine.jpg IIIF Curation Viewer http://codh.rois.ac.jp/software/iiif-curation-viewer/demo/?manifest= icp-logo.svg Image Annotator https://www.kanzaki.com/works/2016/pub/image-annotator?u= ia-logo.png TIFY https://tify.rocks/?manifest= tify-logo.svg 参考 以下のIIIF 3.0 Viewer Matrix などが参考になりました。 https://iiif.io/api/cookbook/recipe/matrix/#basic-recipes

Chromeでサイズが大きい動画が再生できない

Chromeでサイズが大きい動画が再生できない

概要 Chromeにおいて、サイズが大きい動画が再生できないことがありました。一方、Safariでは再生できました。 開発者ツールで確認すると、ダウンロードがキャンセルされていました。 ビューア部分は以下のようになっています。 <video controls="controls" preload="none" style="width: 620px; height: 465px;" width="100%" height="100%"> <source src="https://omeka.aws.ldas.jp/files/original/c486fe4ae8d926034678fa11b0d6b2fd55b0e695.mp4" type="video/quicktime" title="undefined"> </video> このHTMLは、以下の記事で紹介した、Omeka S + IIIF Serverの組み合わせによって作成されたものです。 原因 先ほどのhtmlを確認すると、type="video/quicktime"となっており、拡張子はmp4となっていますが、中身は異なる(movファイル?)ことがわかります。 おそらく動画の拡張子のみが変更され、Omeka Sに登録された際、Omeka Sが中身からtypeを指定したように思われます。 Safariで再生できたのも、これが原因かと思われます。 対処法 例えば、macの場合は、以下によりmp4に変換できます。 brew install ffmpeg ffmpeg -i aaa.mov aaa.mp4 まとめ Omeka Sなどで動画ファイルを配信する際の参考になりましたら幸いです。

Omeka SのSetEnv APPLICATION_ENVのproductionとdevelopmentの違い

Omeka SのSetEnv APPLICATION_ENVのproductionとdevelopmentの違い

Omeka Sでのエラー詳細の表示を有効にする手順は次の通りです。この設定を行うことで、「Omeka S has encountered an error」というページに具体的なエラーメッセージと詳細が表示されるようになります。また、PHPレベルのエラーや警告もページ上に表示されるようになります。これは開発中に問題の特定と解決を容易にするためのものですが、セキュリティ上の理由から本番環境では使用しないことが推奨されます。 エラー詳細の表示を有効にする手順 .htaccessファイルを見つける : Omeka Sのインストールフォルダのメインディレクトリに.htaccessファイルがあります。このファイルはWebサーバーの設定をカスタマイズするために使用されるものです。 .htaccessファイルを編集する : .htaccess ファイルをテキストエディタで開きます。 ファイル内の次の行を探します。 SetEnv APPLICATION_ENV "production" * この行を次のように変更します。 SetEnv APPLICATION_ENV "development" 変更を保存してサーバーを再起動する : 変更を保存した後、Webサーバーを再起動する必要がある場合があります。これはサーバーの設定に依存します。 この変更により、Omeka Sは「開発」モードで実行されるようになり、エラーが発生した際には詳細な情報が表示されるようになります。これは問題の診断と解決に非常に役立ちますが、セキュリティ上のリスクも伴うため、公開環境では使用しないようにしてください。

TraefikでHTTPS化した複数コンテナを運用する

TraefikでHTTPS化した複数コンテナを運用する

概要 TraefikでHTTPS化した複数コンテナを運用する方法に関する備忘録です。 https://github.com/traefik/traefik 背景 これまで、jwilder/nginx-proxyとjrcs/letsencrypt-nginx-proxy-companionを使い、以下のような構成で運用していました。 プロキシ version: '3' # proxy services: nginx-proxy: image: jwilder/nginx-proxy container_name: nginx-proxy ports: - "80:80" - "443:443" volumes: - html:/usr/share/nginx/html - dhparam:/etc/nginx/dhparam - vhost:/etc/nginx/vhost.d - certs:/etc/nginx/certs:ro - /var/run/docker.sock:/tmp/docker.sock:ro - /srv/docker/nginx-proxy-with-encrypt/log:/var/log/nginx labels: - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy" restart: always letsencrypt: image: jrcs/letsencrypt-nginx-proxy-companion container_name: nginx-proxy-lets-encrypt depends_on: - "nginx-proxy" volumes: - certs:/etc/nginx/certs:rw - vhost:/etc/nginx/vhost.d - html:/usr/share/nginx/html - /var/run/docker.sock:/var/run/docker.sock:ro volumes: certs: html: vhost: dhparam: networks: default: external: name: common_link コンテナ 以下は、Djangoの例です。 ...

Omeka S GoogleAnalyticsモジュールの不具合対応

Omeka S GoogleAnalyticsモジュールの不具合対応

概要 Omeka Sにおいて、Google Analyticsを有効するにするためのモジュールとして、Google Analyticsがあります。 https://github.com/Libnamic/Omeka-S-GoogleAnalytics/ 本モジュールを有効化した際、以下のエラーメッセージが表示されるケースがありました。 Undefined index: additional_snippet in (...) /modules/GoogleAnalytics/Module.php on line 316 これについて、以下のIssueも上がっていました。 https://github.com/Libnamic/Omeka-S-GoogleAnalytics/issues/9 本件の対応方法について共有します。 対応方法 以下のように変更します。 https://github.com/Libnamic/Omeka-S-GoogleAnalytics/pull/10/commits/0123ce557d0f38834c5c37fa1ac9c986c87cbc90 具体的には、以下です。 変更前 if (empty($extra_snippet)) { $settings = $this->getServiceLocator()->get('Omeka\Settings'); $settings = $settings->get('googleanalytics', ''); if ($settings != null) $extra_snippet = $settings['additional_snippet']; } if (empty($extra_snippet)) { $settings = $this->getServiceLocator()->get('Omeka\Settings'); $settings = $settings->get('googleanalytics', ''); if ($settings != null) $extra_snippet = $settings['additional_snippet']; } 変更後 if (empty($extra_snippet)) { $settings = $this->getServiceLocator()->get('Omeka\Settings'); $settings = $settings->get('googleanalytics', ''); if ($settings != null) // Assuming this is part of the code where you handle the extra snippet if (isset($settings['additional_snippet']) && !empty($settings['additional_snippet'])) { $extra_snippet = $settings['additional_snippet']; } else { $extra_snippet = ''; // Default value if 'additional_snippet' key is not set } } if (empty($extra_snippet)) { $settings = $this->getServiceLocator()->get('Omeka\Settings'); $settings = $settings->get('googleanalytics', ''); if ($settings != null) // Assuming this is part of the code where you handle the extra snippet if (isset($settings['additional_snippet']) && !empty($settings['additional_snippet'])) { $extra_snippet = $settings['additional_snippet']; } else { $extra_snippet = ''; // Default value if 'additional_snippet' key is not set } } まとめ 上記の変更が完全に正しいか自信はありませんが、プルリクエストも出しておきました。 ...

Amazon S3とRoute 53を使ってリダイレクトする

Amazon S3とRoute 53を使ってリダイレクトする

概要 あるURLから他のURLにリダイレクトさせる必要があり、Amazon S3とRoute 53を使用して実現することができたので、備忘録です。 方法 この方法では、S3バケットを使ってリダイレクトを行い、DNS設定にはRoute 53を使用します。以下にその手順を説明します。 ステップ1: Amazon S3バケットの設定 Amazon S3で新しいバケットを作成します。バケット名はリダイレクトさせたいドメイン名と一致させます(例:example.com)。 バケットのプロパティで「静的ウェブサイトホスティング」を選択します。 「静的ウェブサイトホスティング」のオプションで、「リダイレクト要求」を選び、リダイレクト先のURL(http://example.net など)を入力します。 ステップ2: Route 53でのDNS設定 Route 53で、リダイレクトするドメイン名のホストゾーンを開きます。 新しいレコードセットを作成します。レコードのタイプは A を選択します。 「エイリアス」を「はい」に設定します。 エイリアスターゲットとして、ステップ1で設定したS3バケットの静的ウェブサイトホスティングのエンドポイントを選択します(例:example.com.s3-website-us-east-1.amazonaws.com)。 これで、指定したドメインにアクセスがあった場合、設定したURLにリダイレクトされるようになります。この方法は、簡単でありながら効果的にドメインから別のURLへのリダイレクトを実現することができます。 まとめ 参考になりましたら幸いです。

Docker版のOmeka SでCORS対応を行う

Docker版のOmeka SでCORS対応を行う

概要 Docker版のOmeka Sで、以下の記事のようにCORS対応を実施した際、サーバエラーが発生しました。その備忘録を記載します。 Dockerfile 以下のようなDockerfileを対象とします。 FROM php:apache LABEL maintainer="Satoru Nakamura <na.kamura.1263@gmail.com>" RUN a2enmod rewrite ENV DEBIAN_FRONTEND noninteractive RUN apt-get -qq update && apt-get -qq -y upgrade RUN apt-get install -y \ zlib1g-dev \ libpng-dev \ libjpeg-dev \ libfreetype6-dev \ imagemagick \ unzip \ wget # PHP extensions RUN docker-php-ext-install -j$(nproc) iconv pdo pdo_mysql mysqli gd RUN docker-php-ext-configure gd --with-jpeg=/usr/include/ --with-freetype=/usr/include/ # Download Omeka-s ARG version=4.1.1 RUN wget https://github.com/omeka/omeka-s/releases/download/v${version}/omeka-s-${version}.zip -O /var/www/omeka-s-${version}.zip \ && unzip -q /var/www/omeka-s-${version}.zip -d /var/www/ \ && rm /var/www/omeka-s-${version}.zip \ && rm -rf /var/www/html/ \ && mv /var/www/omeka-s/ /var/www/html/ COPY ./.htaccess /var/www/html/.htaccess # Configure volumes and permissions COPY ./database.ini /var/www/html/volume/config/ RUN mkdir -p /var/www/html/volume/files/ \ && rm /var/www/html/config/database.ini \ && ln -s /var/www/html/volume/config/database.ini /var/www/html/config/database.ini \ && rm -Rf /var/www/html/files/ \ && ln -s /var/www/html/volume/files/ /var/www/html/files \ && chown -R www-data:www-data /var/www/html/ \ && find /var/www/html/volume/ -type f -exec chmod 600 {} \; VOLUME /var/www/html/volume/ CMD ["apache2-foreground"] 原因と対策 以下を追記する必要がありました。 ...

IIIFのCanvas URIなどを一括置換する際のコマンド

IIIFのCanvas URIなどを一括置換する際のコマンド

複数のIIIFマニフェストファイルに対して、Canvas URIを一括置換したい場合があります。 例えばカレントディレクトリ以下のJSONファイルに対して、www.dl.ndl.go.jpをdl.ndl.go.jpに置換したい場合のコマンドは以下です。-i ''オプションは macOS 特有の構文です。 find . -type f -name "*.json" -exec sed -i '' 's/www\.dl\.ndl\.go\.jp/dl\.ndl\.go\.jp/g' {} + 注意: このスクリプトはファイルを直接変更します。重要なデータに対して使用する前には、必ずバックアップを取るなどの対策をお勧めします。また、バイナリファイル(画像や実行ファイルなど)に対してテキスト置換を行うとファイルが壊れる可能性があるため、適用するファイルの種類には注意してください。 参考になりましたら幸いです。