sumikko engineer blog

すみっこが落ち着くエンジニアのブログです。

net/sftp

net/sftpを利用する機会があったので作ってみました。ファイルの存在チェックができるメソッドがなかったので微妙な実装。

class Sftp

    # ファイルの存在チェック
    def self.file_exists?(dir, file_name)
        file_exists = false
        exec do |sftp|
            file_names = []
            sftp.dir.foreach(dir) {|f| file_names << f.name}
            file_exists = file_names.any?{|fn| fn != "." && fn != ".." && fn == file_name}
        end
        file_exists
    end

    # ファイルのダウンロード
    # ファイルがない場合は例外が発生します。
    def self.download!(remote_file_path, local_file_path)
        exec do |sftp|
            sftp.download!(remote_file_path, local_file_path)
        end
    end

    private
        def self.exec(&block)
            Net::SFTP.start("domain", "user", password: "password") do |sftp|
                yield(sftp)
            end
        end
end

公式github

github.com

rails migration

migrationするたびに調べるのがめんどくさいのでメモ。optionも使う場合はapi documentを見る。

  • コマンド
rails generate migration <migration_name>
  • テーブル追加
# 簡単に書けるやり方
create_table(:members) do |t|
  t.column :name, :string, limit: 60
end

# ひとつずつやるやり方
create_table(:members)
add_column(:members, :name, :string, {limit: 60})
  • 既存テーブルにカラム追加
add_column(:members, :address, :string, {limit: 200})
  • カラム削除
remove_column(members, address)
  • カラムのデータ型修正
change_column(:members, :name, :string, limit: 400)

rubyで営業日を取得する

メンテナンスされるかわからないgemを使いたくなかったので簡単に自作しました。 祝日、年末やその他の休みを好き勝手に入れたい場合はpublic_holidaysをメンテをしていく。

月~金までが営業日 祝日、年末は休み

require 'singleton'
require 'date'

class BusinessDate
  include Singleton
  @@public_holidays = [
    "2021-11-3",
    "2021-11-23",
    "2021-12-30",
    "2021-12-31",
    "2022-1-1",
    "2022-1-2",
    "2022-1-3",
    "2022-1-4"
  ]

  def initialize
    @today = Date.today
  end

  def public_holiday?(_date)
    @@public_holidays.include?("#{_date.year}-#{_date.month}-#{_date.day}")
  end

  def holiday?(_date)
    _date.sunday? || _date.saturday?
  end

  def business_date?(_date)
    !holiday?(_date) && !public_holiday?(_date)
  end

  def business_beginning_of_month?(_date)
    target_business_date = _date.beginning_of_month
    if target_business_date == _date
      return true if business_date?(_date)
      return false
    end

    while !business_date?(target_business_date)
      target_business_date = target_business_date + 1
    end

    return true if target_business_date == _date
    false
  end

  def prev_business_date(_date)
    target_date = _date
    if business_date?(target_date)
      if target_date.monday?
        # 月曜日の場合は金曜日を取得する
        target_date = target_date - 3
      else
        target_date = target_date - 1
      end
    end

    while !business_date?(target_date)
      target_date = target_date - 1
    end
    target_date
  end

end
メソッド名 内容
public_holiday? 祝日か判定する。@@public_holidaysのメンテが必要
holiday? 休日か判定する。土日休み
business_date? 営業日か判定する。祝日、土日以外は営業日
business_beginning_of_month? 営業月初か判定する。月初が土日、祝日なら遡って営業月初を取得する
prev_business_date 前日の営業日を取得する。月曜日の場合は金曜日。金曜日が祝日なら遡って営業日を取得する

Slackに投稿する

たまに書くのでコピペできるようにしておく。

Google Apps Script

class Slack {
  constructor() {
    this.slackUrl = "slackのパス"
    this.channel = "#channel"
    this.icon = ":penguin"
    this.userName = 'penguin'
  }

  sendMessage(text) {
    var payload={
      "text": text,
      "channel" : this.channel,
      "username": this.userName,
      "icon_emoji": this.icon
    };
    var options = {
      "method" : "POST",
      "payload" : JSON.stringify(payload),
      "muteHttpExceptions": false,
    }
    UrlFetchApp.fetch(this.slackUrl, options);
  }
}

Ruby

require 'singleton'
require 'uri'
require 'net/http'
require 'openssl'

class Slack
  include Singleton

  def initialize(channel, icon_emoji)
    @channel = channel
    @icon_emoji = icon_emoji
    @url = "slackのパス(configとかにでも定義しておく)"
  end

  def send_message(message)
    slack_params = {
      text: message,
      channel: @channel,
      icon_emoji: @icon_emoji
    }
    uri  = URI.parse(@url)
    http = Net::HTTP.new(uri.host, uri.port)
    if uri.scheme == "https"
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end
    http.start do
      request = Net::HTTP::Post.new(uri.path)
      request.set_form_data(payload: slack_params.to_json)
      http.request(request)
    end
  end
end

scpでコピーしたくないファイル・ディレクトリを除外する

Google検索してもrsync使えば?という記事が多いのでメモ。 lsコマンド実行後にgrepで除外してscpの引数に入れることで対応。

scp -r `ls | grep -v not_published_file_name | grep -v .not_published_file_directory` ${HOST_USER}@${HOST}:${PATH}