AWS SESからS3へ受信してからのメール転送

東京オリンピックでの選手の活躍すごかったですね。(まだ開催されてないときに書いてます。)
マエダです。

みんな大好きAWSでメール受信はしたりしますよね。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ses-receive-inbound-emails/

S3にメールファイルが保存されたことをトリガーにpythonでメール転送する君を作成しました。
過去にどこからか(覚えておらず。。すみません。)参照させていただいたコードがpython2.7で動作するものだったのですが「AWS Lambda end of support for Python 2.7」なんてお知らせいただいたのでpython3.8で動作するように修正してみました。

import boto3
import email import re ORIGIN_TO = "(受信メールアドレス)" FORWARD_TO = "(転送先メールアドレス)" SES_REGION = "(SESリージョン)" S3_BUCKET = "(S3バケット名)" def parse_mail(raw_message): replaced_message = raw_message.replace(ORIGIN_TO, FORWARD_TO) replaced_message = re.sub("From:.+?\n", "From: %s\r\n" % ORIGIN_TO, replaced_message) replaced_message = re.sub("Return-Path:.+?\n", "Return-Path: %s\r\n" % ORIGIN_TO, replaced_message) return replaced_message def send_mail(message): ses = boto3.client('ses', region_name=SES_REGION) ses.send_raw_email( Source = ORIGIN_TO, Destinations=[ FORWARD_TO ], RawMessage={ 'Data': message } ) def lambda_handler(event, context): try: s3_key = event['Records'][0]['s3']['object']['key'] s3 = boto3.client('s3') response = s3.get_object( Bucket = S3_BUCKET, Key = s3_key ) raw_message = response['Body'].read().decode('utf-8') message = parse_mail(raw_message) send_mail(message) except Exception as e: print(e)

AWSをたのしもう。

[Solr] Nested Documents での部分更新

はじめに

以前はできなかった入れ子構造のドキュメントの部分的な更新が Solr 8.1 からはできるようになりました。この記事では入れ子構造のドキュメントの部分的な更新の動作を確認します。

更新前の状態

以下のプレイリストのデータを Solr に投入します。

[{
    "id":"list_1",
    "title_t":"list1",
    "songs":[
	{
	    "id":"l1!song1",
	    "title_t":"title1",
	    "artist_t":"artist1",
	    "trackNum_i":1
	},
	{
	    "id":"l1!song2",
	    "title_t":"title2",
	    "artist_t":"artist2",
	    "trackNum_i":2
	}
    ]
},
{
    "id":"list_2",
    "title_t":"list2",
    "songs":[
	{
	    "id":"l2!song1",
	    "title_t":"title3",
	    "artist_t":"artist3",
	    "trackNum_i":1
	},
	{
	    "id":"l2!song2",
	    "title_t":"title1",
	    "artist_t":"artist1",
	    "trackNum_i":2
	}
    ]
}
]

プレイリスト全体のデータで更新

以前はこのタイプの更新しかサポートされていませんでした。

$ cat update.json 
[{
    "id":"list_1",
    "title_t":"LIST1",
    "songs":[
	{
	    "id":"l1!song1",
	    "title_t":"TITLE1",
	    "artist_t":"ARTIST1",
	    "trackNum_i":1
	},
	{
	    "id":"l1!song2",
	    "title_t":"TITLE2",
	    "artist_t":"ARTIST2",
	    "trackNum_i":2
	}
    ]
}]
$ curl --user solr:SolrRocks 'http://localhost:8983/solr/nestedDocuments/update?commit=true&wt=json' --data-binary @update.json -H 'Content-Type: application/json'
{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":90}}
$ curl -s 'http://localhost:8983/solr/nestedDocuments/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="id:list_1 -_nest_path_:*"}' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"list_1",
        "title_t":"LIST1",
        "_version_":1698469478122127360,
        "songs":[
          {
            "id":"l1!song1",
            "title_t":"TITLE1",
            "artist_t":"ARTIST1",
            "trackNum_i":1,
            "_version_":1698469478122127360},
          
          {
            "id":"l1!song2",
            "title_t":"TITLE2",
            "artist_t":"ARTIST2",
            "trackNum_i":2,
            "_version_":1698469478122127360}]}]
  }}

タイトルとアーティスト名を大文字にしてみました。

曲データだけを更新

_root_ フィールドで親ドキュメント(この場合プレイリストデータ)の id を指定します。

$ cat update2.json 
[
    {
	"id":"l1!song1",
	"_root_":"list_1",
	"title_t":{set:"title1"},
	"artist_t":{set:"artist1"}
    }
]
$ curl --user solr:SolrRocks 'http://localhost:8983/solr/nestedDocuments/update?commit=true&wt=json' --data-binary @update2.json -H 'Content-Type: application/json'
{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":131}}
$ curl -s 'http://localhost:8983/solr/nestedDocuments/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="id:list_1 -_nest_path_:*"}' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"list_1",
        "title_t":"LIST1",
        "_version_":1698470257771937792,
        "songs":[
          {
            "id":"l1!song1",
            "title_t":"title1",
            "artist_t":"artist1",
            "trackNum_i":1,
            "_version_":1698470257771937792},
          
          {
            "id":"l1!song2",
            "title_t":"TITLE2",
            "artist_t":"ARTIST2",
            "trackNum_i":2,
            "_version_":1698470257771937792}]}]
  }}

l1!song1の曲名とアーティスト名を小文字に戻しました。

プレイリストに曲を追加

親ドキュメントの id を指定して、songs フィールドに対する add を実行します。

$ cat add.json 
[
    {
	"id":"list_1",
	"_root_":"list_1",
	"songs":{"add":{"id":"l1!song3",
		       "title_t":"title4",
		       "artist_t":"artist4",
		       "trackNum_i":3
		      }}
    }
]
$ curl --user solr:SolrRocks 'http://localhost:8983/solr/nestedDocuments/update?commit=true&wt=json' --data-binary @add.json -H 'Content-Type: application/json'
{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":67}}
$ curl -s 'http://localhost:8983/solr/nestedDocuments/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="id:list_1 -_nest_path_:*"}' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"list_1",
        "title_t":"LIST1",
        "_version_":1698470937227165696,
        "songs":[
          {
            "id":"l1!song1",
            "title_t":"title1",
            "artist_t":"artist1",
            "trackNum_i":1,
            "_version_":1698470937227165696},
          
          {
            "id":"l1!song2",
            "title_t":"TITLE2",
            "artist_t":"ARTIST2",
            "trackNum_i":2,
            "_version_":1698470937227165696},
          
          {
            "id":"l1!song3",
            "title_t":"title4",
            "artist_t":"artist4",
            "trackNum_i":3,
            "_version_":1698470937227165696}]}]
  }}

プレイリスト list_1 に3曲目を追加しました。

プレイリストから曲を削除

親ドキュメントの id を指定して、songs フィールドに対する remove を実行します。

$ cat remove.json 
[
    {
	"id":"list_1",
	"_root_":"list_1",
	"songs":{"remove":{"id":"l1!song3"}}
    }
]
$ curl --user solr:SolrRocks 'http://localhost:8983/solr/nestedDocuments/update?commit=true&wt=json' --data-binary @remove.json -H 'Content-Type: application/json'
{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":50}}
$ curl -s 'http://localhost:8983/solr/nestedDocuments/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="id:list_1 -_nest_path_:*"}' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"list_1",
        "title_t":"LIST1",
        "_version_":1698471464250900480,
        "songs":[
          {
            "id":"l1!song1",
            "title_t":"title1",
            "artist_t":"artist1",
            "trackNum_i":1,
            "_version_":1698471464250900480},
          
          {
            "id":"l1!song2",
            "title_t":"TITLE2",
            "artist_t":"ARTIST2",
            "trackNum_i":2,
            "_version_":1698471464250900480}]}]
  }}

先程追加した l1!song3 を削除しました。

ハロウィンを楽しみました

ハロウィンでの一番お楽しみは、「ハロウィン ケーキ」で検索することです。
(この記事を書いているのはハロウィン前)
ケーキだけではなく、菓子類も奇抜な見た目をしていてとても面白いです。

というわけで、今年のハロウィン。

無理をしたコラージュ画像

エビフライコロッケのハンバーガー作りました。
レンジで温めたポテトもあったのでバーガーセットですね。

ハロウィンにバーガー?と思うかもしれませんが、特に意味はありません。
近くのマ○クが改装中で食べられなかったことがショックで発作が起きてしまいました。

お菓子は、洋菓子のお店で買ったマドレーヌやクッキーがあったのですが、
食べてしまったので入れ物だったカボチャとゴーストのポーチを撮りました。

年間通してみても、
蜘蛛や蝙蝠、血や目玉に寛容なイベントはハロウィンくらいではないでしょうか。

アレンジや独自の工夫により、
合体事故を起こしてしまったものが生まれることもありますが、
それもハロウィンの楽しみの一つです。

とはいえ、今年は閉店してしまったお店も少し増えたように感じます。

今年もハロウィンの変わったお菓子が食べられることに感謝👏

Realistic Paint Studioで遊んでみた

Twitterで、Realistic Paint Studioというアプリが紹介されているのを見かけたので、有料のアプリでしたが購入してiPadにダウンロードしてみました。

絵の描き方が学べる

これはチュートリアルの一部なのですが、なんとツール自体の使い方のチュートリアルではなく、水彩画の描き方をチュートリアルで教えてくれるのです。

実際の水彩画も、大体このような手順で描いていたと記憶しています。

リアルすぎる

ツールの見た目がかなりガチ

これはツール選択画面です。

私は文房具や画材の類が大好きなので、これだけでもかなりテンションが上がります…!

アナログ画材っぽい書き心地のソフトなどはこれまでも色々とありましたが、ここまで画材自体のビジュアルが推されているお絵描きツールは初めて見ました。

仕事などで絵を描く時はシンプルで使いやすいUIのアプリの方がいいですが、ゆっくり時間をかけて好きなように描きたい時にはこのUIは筆や絵具を選ぶ楽しさも味わえて良いかもしれません。

時々思い出したように襲い来る「アナログの画材触りたい!!!」の欲求は、このアプリでもだいぶ満たすことができそうです。

水彩画の他に、素描モードと油彩モードがあります。

値段は1,480円と、絵に全く興味のない人が試しに入れてみるアプリとしては少し高いかも…

ですが、画材やアナログ絵画が好きな人や、アナログ画材を試してみたい人はかなり満足できると思います!

(アナログ画材を実際に買うと1,480円では全く済まないので…)

今のところ水彩モードしかまだ触れていないので、ゆっくり他二つのモードも試してみたいと思います!