Railsで一番シンプルな検索の実装

数分できたので多分最高にシンプル。

コントローラにクラスメソッド追加。

def index
  @commands = Pipe.search(params[:q]).paginate(page: params[:page])
end

モデルにロジック記述。ポイントはCase insensitiveにしているところとOR検索してるところ。

  def self.search(query)
    if query.present?
      q = query.downcase
      Pipe.where('lower(title) LIKE ?', "%#{q}%").or(Pipe.where('lower(line) LIKE ?', "%#{q}%"))
    else
      Pipe.all
    end
  end

Viewはこんな感じ。

<%= form_with(url: '/cmds', method: 'get', local: true) do %>
  <%= text_field_tag(:q, "", class: "uk-input uk-form-width-medium") %>
  <%= submit_tag("Search", class: "uk-button uk-button-default") %>
<% end %>

 

なるべく費用を抑えて一眼レフのWebカメラでビデオ会議(Zoom)に参加する方法

ビデオ会議用のカメラを探していたところ、LogicoolのWebcamは3万円以上する、しかも在庫がないという状態だったので、同じような予算で一眼レフを実現できないかと模索。

ググってみると一眼レフをWebcamとして使うというサイトが沢山があるが、そもそもカメラ(高級!)を持っている人がそれをWebカメラとして使うといったものが多く低予算ではできるのかと調べてみました。Cannonは最近Webカメラ用途のソフトウェアを出しているらしいが、対応機種が高級カメラなので厳しい)

手っ取り早く実現するには下記が必要であることがわかった。

  • 一眼レフのデジタルカメラ (HDMI out がclean出力可能)
  • ビデオキャプチャーのデバイス
  • 明るいレンズ(f1.4ぐらいあればよさそう)

HDMI outがCleanとは、映像のみ出力できること。昔の機種では、レンズの状態の情報なども同時に出力されてしまうとか。OBSというソフトでCropもできるようだが、できればそのプロセスを踏みたくない。

カメラ

安さ重視なのでなるべく型番が古くて、かつHDMI cleanな製品を探すとSonyのα5100がよさそうだとわかった。Amazonの中古で購入。ボディのみ。25,800円

電源

ビデオ会議中にバッテリー切れで中断できないので、電源アダブタを買う。Sony純正は高いので互換製品(at your own risk)をAmazonで。2999円

レンズ

とにかく明るいレンズ。昔使ってたカメラもf1.4で綺麗な写真がとれたので。オートフォーカスは高いのでマニュアル。ビデオ会議だとあまり前後に動かないのでマニュアルで十分と判断。将来はオートフォーカス欲しいけど。。で、中華レンズが安いことがわかった。 メルカリで購入。7000円(新品でも9000円の安さ! f1.2!)

HDMIキャプチャカード

これも中国製品で安いのがある。調べると1000円ぐらいだったみたいだが、リモート需要か3000円しました。

キャプチャカードとカメラの接続に使うケーブル。カメラ側はマイクロタイプDオスで繋ぐ。

接続

特にドライバも入れる必要なくZoomで利用できた。16:9で出力して、Zoom側のカメラの設定のHDの項目にチェックを入れれば良い。

結果

ボケがでる!段違いに高画質。ドヤ感半端ない。結局4万かかったけど、、明るいカメラも同時購入したと思えば問題なし。

Cloudfront経由でS3にID/Pass認証(Basic Authentication)をかける(CORSの場合は、かけない)方法

まる二日間格闘して設定が完了した。かなりの試行錯誤したので備忘録としてまとめてみる。

Goal

  • s3上のファイルにパスワードをかけて直接ファイルをダウンロードできなくする。
  • Webサービスにログインしているユーザは、ファイルをダウンロードできる。

結論

結論から先に書くと、下記のような感じ。前提として、https + Basic authenticationを信頼する(http + basic authはダメ)。

  • Clientにcrossorigin="anonymous"をセットし、http requestにorignを含ませる。
  • Cloudfront+LambdaでBasic Authでフィルタリングする。Originを含む場合はパスワード必要としない。
  • S3とCloudfrontではCORS関係のヘッダをパススルーする。

クライアント(Web browser/HTML)の設定

今回は動画ファイルのダウンロード・再生のUIだったので、下記のようにcrossoriginを設定する。

<video width="100%" height="75%" controls="" crossorigin="anonymous" src="https://my.example.com/xxxxxxx/yy.mp4">
</video>

ちなみに<source src=”“>だとうまくoriginが送信されなかった。

S3のCORSの設定

いつも悩むCORSの設定。AllowedOriginでソースを限定しておくと安心。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://our.example.com</AllowedOrigin>
    <AllowedOrigin>https://our.staging.example.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

AWS Lambdaの設定

Requestヘッダにoriginがある場合は、Basic Authは適用せずそのままレスポンスを返す行を追加した。これによし、サーバからのアクセスは許可させる。

ハマりポイントは、リージョン。S3が東京にあってもバージニアにしないといけない。しかし、ログのCloudwatchは東京リージョンにある。

exports.handler = (event, context, callback) => {

  // Get the request and its headers
  const request = event.Records[0].cf.request;
  const headers = request.headers;
  
  console.log(headers)
  // if it's from our produciton and stating, no need to do authentication
  const originHost = typeof headers.origin == 'undefined' ? null :  headers.origin[0].value;
  
  if(originHost){
    if(/my\.example\.com/.test(originHost) || /my\.staging\.example\.com/.test(originHost)) {
      callback(null, request);
    }
  }
    

  // Specify the username and password to be used
  const user = 'xxxxxxxxxxxxxxxxxxxxx';
  const pw = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

  // Build a Basic Authentication string
  const authString = 'Basic ' + new Buffer(user + ':' + pw).toString('base64');

  // Challenge for auth if auth credentials are absent or incorrect
  if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
    const response = {
      status: '401',
      statusDescription: 'Unauthorized',
      body: 'Unauthorized',
      headers: {
        'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
      },
    };
    callback(null, response);
  }

  // User has authenticated
  callback(null, request);
};

Cloudfrontの設定

  • Basic Authなのでhttpsオンリー
  • CORSにOPTIONSが必要なときがあるらしいので追加
  • whitelistでCORS関連を配信
  • TTLはゼロでテスト
  • 下記では省いたが、DNSなどを設定した。デフォルトのCloudfrontのホスト名ではなく自ドメインでアクセスできるように。
  • ViewリクエストにLambdaのARNを追加。ハマりポイントは、Lambdaのバージョンによって、最後の数字が変わること。Lamdaをpublishしたあとは変更の必要あり。

S3のパーミッション変更

ここまででCloudfront経由でのアクセスはできるはず。S3に外部からアクセスさせなくするために下記を確認。

  • Block all public accessのチェックを外す
  • Block public access to buckets and objects granted through new public bucket or access point policies -> On
  • Block public and cross-account access to buckets and objects through any public bucket or access point policies  -> On
  • Access Control Listにeveryone等権限がないか確認

S3-Cloudfront間の設定

CloudfrontのOriginのタブからOriginを編集する。

  • Restrict Bucket Accessにチェック
  • Original Access Identityで必要ならば新しいものを作成
  • Grand read permissions on Bucketで"Yes, Update Bucket Polity"をチェック

まとめ

上記でうまくいくはず。デバッグはChromeのdevelopper toolのNetwork tabでHTTP request を確認、consoleエラーがないか確認、lambdaのconsole.logで確認とデータの中身を追っていく必要がある。

 

不眠を解消するシンプルなチェックリスト

Kindle unlimitedで睡眠に関する本を数冊読むと、だいたい書いてあることは同じ。睡眠時間は人・年齢によってそれぞれ。7時間半が理想という記事が多いが、当人にとって生活に支障がなければ問題ないという風にあまり考えすぎないことを前提として、下記のリストを挙げる。

  1. 眠くなってから寝る
  2. 15分ねむれなかったら寝室を出る
  3. 寝る前・夜中に起きたときはあまり明るくしない
  4. 最初の90分のレム睡眠がホルモン等で大事なのでそこを意識する
  5. 寝る前の決まりごとを作る。(ストレッチ、水を飲むなど)
  6. 朝日を浴びる
  7. カフェインは5−7時間効く可能性があるので意識する
  8. 寝室では寝ることだけの場所にする(スマホ・読書をベットでしない)