たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 2722
どうもこんばんわ。
AWS
ってことでAmazon
のはなしでも、
手持ちのイヤホンの電池が本当に持たなくなってしまったので、買ってみた、Echo Buds
。
セールで半額!、この値段でノイズキャンセリングいいじゃんって。
数日しか経ってないけど感想!
S3
の画像をCloudFront
で配信しているわけですが、
ブラウザの画像を新しいタブで開く
を押すと何故かダウンロードウィンドウになってしまう。
画像を開いてくれるんじゃないの。。。?
デカく見たいよね?
どうやらContent-Type
のデフォルトがバイナリデータとして扱われ(まあそうか)、
バイナリの場合ブラウザはダウンロードのダイアログを出すだけをするらしい。
たとえ中身が画像だとしても、そのたとえすらもしない。出すだけ。
いいえ、ブラウザからアップロードする場合や、CLI
の場合はついてそう。
一方、CDK
を使う場合は明示的にContent-Type
を指定しないと、バイナリデータのくくりになってしまうそうです。
というわけで、今回は既にS3
にある写真に対して、Content-Type
を付与していこうというという記事です。metadata directive replace
とかで検索すればいっぱい出てくると思います。
Kotlin/JVM
で書こうって思ったんだけど、直近までNext.js
書いてたしで、
この程度ならesbuild
でTypeScript
をトランスパイルしてNode.js
で実行でいいか、て。
なまえ | あたい |
---|---|
言語 | TypeScript |
Node.js | v20.9.0 |
Node.js
から読者さんのAWS S3
を操作できるように、API
につけるアクセスキーを払い出してもらいます。
省略しますが、IAM ユーザー
作成→S3 の権限付与
→アクセスキーを発行
の流れになると思います。
アクセスキー、シークレットアクセスキーが入手できたら完了です。
(ぜったい秘密に!!)
多分typescript
も入れないといけない気がするが、もうそこまでしたくないので、、、
適当にフォルダを作って、esbuild
と、CDK
を入れます。
npm init -y
npm install --save-exact --save-dev esbuild
npm i @aws-sdk/client-s3
検索の上の方ででてくるaws-sdk
はV2
で、これはメンテナンスモードなので、
ちゃんとV3
の方を入れましょう。
できたら、package.json
にesbuild
のトランスパイル+Node.js
で実行、をやってくれるコマンドを書きます。"start":
の一行ですね。これでesbuild
がTS
をJS
に変換してくれて、出来たのをNode.js
で実行。
{
"name": "aws-s3-metadata-edit",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "esbuild index.ts --bundle --outfile=out.js && node out.js"
},
全部張ります。
BUCKET_NAME
には、メタデータを変更したいファイルが入っているS3 Bucket
の名前、ACCESS_KEY_ID
にはアクセスキーの値を、SECRET_ACCESS_KEY
にはシークレットアクセスキーの値を入れてください。
リージョンも東京以外を選んでいる場合は直してください。
やっていることは、S3 Bucket
の中身一覧を取得し、for
で回し各Key
を得ます。あとはCopyObjectCommand
で上書きしていく感じです。MetadataDirective
ですね。
Content-Type
、今回は拡張子から取得していますが、拡張子すら無くなってしまった場合は、
バイナリデータからMIME-Type
を推測する何かが必要になりそう。マジックナンバーってやつかな。
import {
S3Client,
ListObjectsV2Command,
CopyObjectCommand
} from "@aws-sdk/client-s3"
// ここは各自変更してください
const BUCKET_NAME = ""
const ACCESS_KEY_ID = ""
const SECRET_ACCESS_KEY = ""
// ここまで
async function main() {
// 認証
const s3Client = new S3Client({
region: 'ap-northeast-1',
credentials: {
accessKeyId: ACCESS_KEY_ID,
secretAccessKey: SECRET_ACCESS_KEY
}
})
// 取得
const response = await s3Client.send(
new ListObjectsV2Command({ Bucket: BUCKET_NAME })
)
// 成功してれば
if (response.Contents) {
for (const obj of response.Contents) {
// 今回は拡張子を入れているので、それから Content-Type を探す
let mimeType = 'application/octet-stream'
switch (obj.Key?.split('.')[1]) {
case "jpg":
mimeType = 'image/jpeg'
break
case "png":
mimeType = 'image/png'
break
}
// 実行
await s3Client.send(
new CopyObjectCommand({
Bucket: BUCKET_NAME,
CopySource: `${BUCKET_NAME}/${obj.Key}`,
Key: obj.Key,
ContentType: mimeType, // これ!!
MetadataDirective: 'REPLACE'
})
)
console.log(`完了 ${obj.Key}`)
}
}
}
main() // エントリーポイントを呼び出す
変数埋めたら、以下のコマンドを叩く。 これで、各ファイルに対して上書きでメタデータが付与されているはずです。
できた!
どーぞー
今回のコード、上書きする順番はバラバラなので、一覧表示とかしていると壊れるかも。