トップ «前の日(11-13) 最新 次の日(11-15)» 追記   RSS 1.0 FEED  

Journal InTime


2011-11-14 (Mon)

_ 次女の治療方針

次女の治療方針について主治医の先生の話を聞いた。 その話では、まだ手術が必要と決まったわけではなく、2週間後までに治らないようであれば、という話とのことで、急に手術と言われても困るだろうから事前に少しずつ説明をしているということだった。 2度の熱傷でも深い方で、話を聞いた印象としては手術が必要な可能性は五分五分くらいという感じ。

湿潤治療についても聞いてみたが、「今やっていることだ。乾燥させてかさぶたを作るわけでなく、適度なうるおいを保つようにしている。完全に閉鎖すると感染の畏れがある。」というだいたい想定どおりの回答。たぶん何回か同じ質問を受けているのだろう。

包帯交換の時の処置方法を観察していると、

  1. 患部を水で洗う
  2. 網状のガーゼ(?)で患部を覆う
  3. ワセリンを塗る
  4. ガーゼで患部を覆う
  5. 包帯を巻く

という手順のようだ。湿潤治療のサイトや本で紹介されている感じとは異なるが、消毒を使ってないのと、クリーム系の軟膏でなくワセリンを使っていることから、それほど大きな違いはないように感じた。何より、処置中に娘が痛がっていないし、処置が終わった後も痛がる様子が見られないのは安心材料だと思う。 また手術についても、100%リスクがないとはいえないので手術しないで済めばそれにこしたことはない、という率直な話を聞くことができた。 主治医の先生自身も生後10か月くらいの時に熱傷を受けて今も左腕にその痕が残っていて、患者の立場で考えてもらっているように思う。

とりあえず、しばらくこのまま様子を見ることにしたい。

Tags: 家族
本日のツッコミ(全2件) [ツッコミを入れる]

_ keyesberry [たどり着いているかもしれませんが、貼っておきます。よくなるといいです。 http://detail.chiebuku..]

_ shugo [ありがとうございます。]


2020-11-14 (Sat)

_ スタッドレスタイヤ

スタッドレスタイヤ

先日パンクしてタイヤ交換したばかりだが、スタッドレスタイヤに交換した。

MAZDA3はエクシーガと同じ205/60R16のタイヤが履けるので、前に履いていたヨコハマのIG50 PLUSにしたが、オフセットが違うし前のホイールは随分古くなっていたので、ホイールだけSCHNEIDER STAGという格安のやつ(4本で28355円)に換えた。

安いわりにかっこいいし、インチダウンの効果で乗り心地も良くなったような。サマータイヤもオプションでインチダウンしといたらよかったかも。

Tags: MAZDA3

2023-11-14 (Tue)

_ esaのwebhookでJekyllのページを更新する

会社のサイトをリニューアルしたので、esaのGitHub webhookでニュースの更新をしようとしたけど、ファイル名やfrontmatterが決め打ちでJekyllではうまく行かなかったので、AWS Lambdaで自前のWebhookを実装して更新するようにした。

雑だけど画像の添付にも対応している(弊社は外部からesaの画像を見えない設定にしているので、webhookでダウンロードしてリポジトリにcommitするようにした)。

GitHubの認証はFine-grained personal access tokenを使ったけど、有効期限が最長1年なので更新を忘れそう。

require "openssl"
require "json"
require "rack"
require "octokit"
require "esa"

def lambda_handler(event:, context:)
  body = event["body"]
  sig = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), ENV["ESA_SECRET"], body)
  header_sig = event["headers"]["x-esa-signature"].delete_prefix("sha256=")
  unless Rack::Utils.secure_compare(sig, header_sig)
    STDERR.puts("Invalid signature: #{sig} != #{header_sig}")
    return { statusCode: 400, body: "Invalid signature" }
  end
  json = JSON.parse(body)
  case json["kind"]
  when "post_create", "post_update"
    if json["post"]["wip"]
      puts("WIP: do nothing")
    else
      year, month, day, title =
        json["post"]["name"].scan(%r"Public/News/(\d+)/(\d+)/(\d+)/(.*)")[0]
      number = json["post"]["number"]
      filename = "news/_posts/#{year}-#{month}-#{day}-#{number}.md"
      post_news_entry(filename, title, json["post"]["body_md"])
    end
  end
  { statusCode: 200, body: "Posted a news entry" }
end

def post_news_entry(filename, title, content)
  github = Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"])
  esa = Esa::Client.new(access_token: ENV["ESA_TOKEN"], current_team: "nacl")
  repo = "NaCl-Ltd/www.netlab.jp"
  ref = "heads/main"

  sha_latest_commit = github.ref(repo, ref).object.sha
  sha_base_tree = github.commit(repo, sha_latest_commit).commit.tree.sha

  img_files = []
  s = content.gsub(%r'src="(https://files.esa.io/uploads/.*?)"') {
    basename = File.basename($1)
    path = "img/news/#{basename}"
    url = esa.signed_url(URI.parse($1).path).body["url"]
    data = Net::HTTP.get(URI(url))
    sha = github.create_blob(repo, [data].pack("m"), "base64")
    img_files << {
      :path => path,
      :mode => "100644", 
      :type => "blob", 
      :sha => sha
    }
    "src=\"/#{path}\""
  }

  body = <<EOF
---
title: #{title}
layout: news
---

#{s}
EOF
  blob_sha = github.create_blob(repo, [body].pack("m"), "base64")
  
  sha_new_tree = github.create_tree(
    repo, 
    [
      {
        :path => filename, 
        :mode => "100644", 
        :type => "blob", 
        :sha => blob_sha
      },
      *img_files
    ], 
    {:base_tree => sha_base_tree }
  ).sha
  commit_message = "Committed via esa webhook"
  sha_new_commit = github.create_commit(repo, commit_message, sha_new_tree, sha_latest_commit).sha
  github.update_ref(repo, ref, sha_new_commit)
end
Tags: Ruby

_ 採用エントリーフォームをAWS Lambda + Amazon SESで作った

採用エントリーフォームをデザイン会社さんがPHPで作ろうとされていたので、自分で作りますんで……ということでAWS Lambda (Ruby 3.2) + Amazon SESで作った。

gemを使うとメンテナンスが面倒だなと思ってmultipart/form-dataのパースやMIMEメールの整形を雑に自前で書いたけど、esaのwebhookの方で結局gemを使うことになってしまったので、こちらもgemを使ってもよかったかもしれない。

require 'json'
require 'uri'
require 'securerandom'
require 'aws-sdk-ses'

Part = Data.define(:name, :value)
Attachment = Data.define(:filename, :body)

def lambda_handler(event:, context:)
  form = parse_multipart(event["body"].unpack1("m"))
  validate(form)
  result = send_email(form)
  { statusCode: 302, headers: { Location: ENV["SUCCESS_URL"] } }
rescue => e
  STDERR.puts({
    errorMessage: e.message,
    errorType: e.class.name,
    stackTrace: e.backtrace
  }.to_json)
  { statusCode: 302, headers: { Location: ENV["ERROR_URL"] } }
end

def parse_multipart(s)
  boundary = s.slice(/\A--.*?\r\n/)
  parts = s.byteslice(boundary.bytesize, s.bytesize - 2 - 2 * boundary.bytesize - 2).split("\r\n" + boundary)
  parts.each_with_object({}) { |s, h|
    part = parse_part(s)
    h[part.name] = part.value
  }
end

def parse_part(s)
  header, value = s.split(/^\r\n/)
  cd_params = header.slice(/^Content-Disposition: *form-data;([^\r\n]*)\r\n/)
  name = cd_params.slice(/name="(.*?)"/, 1)
  filename = cd_params.slice(/filename="(.*?)"/, 1)
  if filename
    filename.force_encoding("utf-8")
    v = Attachment.new(filename, value)
  else
    value.force_encoding("utf-8")
    v = value
  end
  Part.new(name, v)
end

def validate(form)
  %w(name email message).each do |name|
    if form[name].nil? || form[name].empty?
      raise "#{name} is missing"
    end
  end
  if !form["file"].is_a?(Attachment)
    raise "file should be an attachment"
  end
end

def send_email(form)
  sender = ENV["MAIL_SENDER"]
  recipient = ENV["MAIL_RECIPIENT"]
  subject = '=?UTF-8?B?5o6h55So5b+c5Yuf?='

  boundary = SecureRandom.hex
  encoded_file, encoded_filename, file_type = encode_file(form["file"])

  raw_message = <<EOF
From: #{sender}
To: #{recipient}
Subject: =?UTF-8?B?5o6h55So5b+c5Yuf?=
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=#{boundary}

--#{boundary}
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

お名前: #{form["name"]}
メールアドレス: #{form["email"]}
メッセージ・自己PR:
#{form["message"]}
--#{boundary}
Content-Type: #{file_type}
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename*=#{encoded_filename}

#{encoded_file}
EOF

  encoded_file2, encoded_filename2, file_type2 = encode_file(form["file2"])
  if encoded_file2
    raw_message << <<EOF
--#{boundary}
Content-Type: #{file_type2}
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename*=#{encoded_filename2}

#{encoded_file2}
EOF
  end

  raw_message << "--#{boundary}--\n"
  raw_message.gsub!(/\n/, "\r\n")
  
  ses = Aws::SES::Client.new(region: 'ap-northeast-1')

  ses.send_raw_email(
    destinations: [recipient],
    raw_message: {
      data: raw_message
    },
    source: sender
  )
  puts 'Email sent to ' + recipient
end

def encode_file(file)
  return nil if file.nil? || file.body.nil? || file.filename.nil?
  encoded_file = [file.body].pack("m")
  encoded_filename = "utf8''" + URI.encode_www_form_component(file.filename)
  file_type = file.filename.match?(/.pdf\z/i) ?
    "application/pdf" : "appliation/octet-stream"
  return encoded_file, encoded_filename, file_type
end
Tags: Ruby