新年の挨拶

新年あけましておめでとうございます。
本年もスプラウト株式会社をどうぞよろしくお願いいたします。

新年あけましておめでとうございます。
本年もスプラウト株式会社をどうぞよろしくお願いいたします。

今回はFigmaのちょっとした小技です。
おそらく知ってる人も多いかと思いますが、よく使う便利な機能なのでご紹介します。
Figmaでwebサイトなどをデザインする際に、どうしても実際にブラウザで表示するのとサイズ感や見え方が変わってしまい、実際の仕上がりイメージを把握しづらいことがあるかと思います。
今までは作成したデザインを一度画像としてエクスポートして、その画像をブラウザで表示することで表示確認をしていました。
この方法ではデザインを変更する度に画像をエクスポートする必要があり、毎回この作業をしなければならず地味にストレスになっていました。
そこでFigmaのライブビュー機能を利用します。使い方は非常に簡単です。
(1)デザインワークスペースの右上にある [▷] ボタンをクリックします。
(2)Figma上でプレビュー画面が新しいタブで開きます。
(3)タブ名を右クリックして[Copy Link]を選択。
(4)Google Chromeなどのブラウザでコピーしたリンクにアクセスします。
これでブラウザでFigmaでデザインしているデザインの表示確認が、リアルタイムに可能になります。
デュアルディスプレイ環境で作業している場合だと、右をFigma、左をブラウザなどにしておけばシームレスにデザインをしながらブラウザでの表示確認が可能となり、効率的にデザイン作業を行うことができます。
今までは画像をエクスポートしてブラウザに表示させて確認していたのですが、この方法を使えばその手間が省けて、作業の効率化を図ることができるようになりました。
また「ライブプレビュー」なので、Figmaでの変更がリアルタイムにブラウザでも確認できます。オンラインMTGなどでデザインを複数人で確認する場合などでも、プレビュー画面のURLを参加者に共有するだけで最新のデザインを確認・共有することができます。
その場でデザインの修正やアップデートができるので、メモを取ってあとからそれを見直しながらデザインを修正するという工程がなくなり、さらに修正漏れなどのミスも減らすことができます。
Figmaでデザインをしている方は、ぜひ使ってみてください!
ここ数年Laravelを使っているのですがとても味わい深いフレームワークです。普通に使う分には意識せずコードはかけますしこういった機能はないのか?と思って探してみると大体見つかりどんどん書き方が変わってきます。

今回は開発を続けていく上で同じようなコードが分散していかないようにする為の方法の1つを書き留めておきます。リレーションがたくさんできていくと同じコードを書いてしまうことがあります。最初はコピペで良くても後から振る舞いが少し変えるためには同じようなコードを全部修正する必要がでてきますし確認も大変です。
下記はブログとブログの記事の作成者の名前を取得する例のコードです。
class Blog extends Model { use UserTrait; } class BlogEntry extends Model { use UserTrait; } trait UserTrait { public function user() { return $this->belongsTo(User::class); } public function getUserNameAttribute() { if ($this->user) { // Userが存在するならユーザー名を返却 return $this->user->name; } // Userが存在しない場合 return ''; } }
こちら作成者が存在すれば名前をなければブランクを返すという簡単な流れです。Blog,BlogEntryともにuser_idで連結されており他にも同じようにuser_idによる連結がされる場合traitをuseするだけでいいので修正が楽です。こちらのいい所は途中でユーザーがいない場合ブランクではなく「退会されました」の文字列に連携するなどが容易なのに加えあとでユーザーに属性が追加されても呼び出す元は変更せずUserのTraitさえ変更すれば容易に追加できる点です。他にもAttribute以外にももちろんscopeやbootなど色々使えるでしょうしおすすめです。
東京オリンピックでの選手の活躍すごかったですね。(まだ開催されてないときに書いてます。)
マエダです。

みんな大好き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 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 を削除しました。