たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 2722
どうもこんばんわ。
AWSってことでAmazonのはなしでも、
手持ちのイヤホンの電池が本当に持たなくなってしまったので、買ってみた、Echo Buds。
セールで半額!、この値段でノイズキャンセリングいいじゃんって。
数日しか経ってないけど感想!
S3の画像をCloudFrontで配信しているわけですが、
ブラウザの画像を新しいタブで開くを押すと何故かダウンロードウィンドウになってしまう。
画像を開いてくれるんじゃないの。。。?
デカく見たいよね?
MDNに書いてありました。どうやら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() // エントリーポイントを呼び出す変数埋めたら、以下のコマンドを叩く。 これで、各ファイルに対して上書きでメタデータが付与されているはずです。
できた!
どーぞー
今回のコード、上書きする順番はバラバラなので、一覧表示とかしていると壊れるかも。