田舎の技術者が奮闘中

php ruby node.js javascript などのスクリプト言語とサーバー(Chef、Vagrant)に関して書きます。

rubyでURL先が本当に存在するか確認する方法

DESIGN HUNTER

連続投稿です。
URLが本当に存在するか確認するプログラムを実装してみました。

早速プログラムです。
リダイレクトにも対応しているので結構使えると思います。
また無限ループも回避しています。

require 'net/http'

def url_request(url, limit = 10)
  if limit == 0
    return false
  end
  begin
    response = Net::HTTP.get_response(URI.parse(url))
  rescue
    return false
  else
    case response
    when Net::HTTPSuccess
      return true
    when Net::HTTPRedirection
      url_request(response['location'], limit - 1)
    else
      return false
    end
  end
end

url_request("http://piko.hateblo.jp")

rubyとAWS SDKでDynamoDBを操作する。ページング編

前回簡単な、DynamoDBの操作方法を記事に書きました。
今回はページングを実装してみます。

DESIGN HUNTERではこのように実装しています。
f:id:pikonori:20130525205228p:plain

クリックすると以下のように展開されます。

f:id:pikonori:20130525205300p:plain

DynamoDBはリクエストの上限やリミットを明記すると、次のハッシュキーを返します。
その帰ってきたハッシュキーを元に再度DynamoDBにリクエストかければOKです。

早速プログラムです。

gem install aws-sdk
require 'aws-sdk'

AWS.config(
           :access_key_id => '***',
           :secret_access_key => '***',
           :dynamo_db_endpoint => 'dynamodb.ap-northeast-1.amazonaws.com'
           )

dynamo_db = AWS::DynamoDB.new
table = dynamo_db.tables["table"]
table.hash_key = [:id, :string]

# DynamoDBに30ほど登録されているとする。
# もし残りのデータが存在するするのであれば、次のハッシュキーを渡す。
hash_key_element = table.items.where(:create_at).begins_with(date).select(:limit => 10)

# 次から検索したい場合はhash_key_elementをexclusive_start_keyに渡す。
table.items.where(:create_at).begins_with(date).select(:limit => 10, :exclusive_start_key => hash_key_element)

あとはif文とかで制御するだけでいいと思います。
結構簡単に出来ますね。

rubyとAWS SDKでDynamoDBを操作する。

DESIGN HUNTER | デザインハンター | ホームページデザイン ウェブデザイン まとめ | デザイン解析

新しいサービスを作成した際にものすごくDynamoDBにハマったので、同じくハマっている人のためにブログに残しておきます。

まずいちばん問題だったのが、まったく参考サイトが無いということ。
AWSのAPIドキュメントとか確認しながらやったのですが、なんせ英語が弱いのでかなり苦労しました。
あとは、実際のSDKのコードを追いながらこまめに動作確認してました。

DESIGN HUNTER | デザインハンター | ホームページデザイン ウェブデザイン まとめ | デザイン解析でDynamoDBを使おうと思った背景ですが、使ってみたかったという好奇心が一番でした。

で、使ってみて率直な感想ですが、結構癖があるんじゃないか?と思いました。
と言ってもKVSなんてmongoDB(そもそもmongoDBはRDBに近い要素もあるので、使いやすかったです。)ぐらいしか使ったことなかったので、癖があるかどうかはよく判りません・・・
でも、発想を駆使すればDynamoDBだけでもサイトが構築できる!と感じました。


問題点もいくつかあります。
そこは諦めるか、プログラムで回避するしかありません。

問題点1
ORDER BYが無い!
探したのですが、結局ORDER BYに関する情報は見当たりませんでした。orz
実は方法がありました。別記事としてまとめてます。
DynamoDBのorder byに関して - 田舎の技術者が奮闘中

問題点2
DynamoDBに値を入れる際に、入れた順番でデータが入ってくれません。日付順とかも出来ませんでした。そこはプログラムで回避しなさいということでしょうか・・判りませんが・・

問題点3
リレーション出来ない。
KVSだったら普通なんですけれど、これも一応問題点として上げておきます。
プログラムで回避するしか方法はありません。

他にもあると思いますが、自分が構築していく上では3点だけでした。


まずAWSのコンソール画面からDynamoDBのテーブルを作らないといけませんが、その部分は省略します。(もちろんプログラムでもテーブル作成出来ます。)
今回はテーブル名を「table」にし、ハッシュキーを「id」にします。レンジキーは使いません。

ここからプログラムになります。
これが正しいかどうか判りませんが動作します。
もっと良い書き方があるのであれば教えて下さい><

SDKインストール

gem install aws-sdk

キーの読み込み

access_key_idとsecret_access_keyの説明は省略します。
dynamo_db_endpointは日本のDynamoDBを見に行くような設定です。
必ず設定して下さい。

AWS.config(
           :access_key_id => '***',
           :secret_access_key => '***',
           :dynamo_db_endpoint => 'dynamodb.ap-northeast-1.amazonaws.com'
           )

テーブル名の設定とスキーマを設定する。

こちらの設定も必須となります。
スキーマはハッシュキーだけ設定しておけばOKです。

dynamo_db = AWS::DynamoDB.new
table = dynamo_db.tables["table"]
table.hash_key = [:id, :string]

データを書き込む

追加したいカラムがあったら追加するだけです。ここはRDBと違って便利ですね。

table.items.create({:id => "a1234", :title => "hogehoge"})
# 新たにkeywordというカラムを追加したい場合は
table.items.create({:id => "a1234", :title => "hogehoge", :keyword =>"keyword"})

データをアップデートする(ハッシュキーからの更新)

table.items["a1234"].attributes.update do |u|
  u.set :title => "hugahuga"
end
# 複数カラム更新の場合
table.items["a1234"].attributes.update do |u|
  u.set :title => "hogehoge_update"
  u.set :keyword => "keyword_update"
end

データをアップデートする(ハッシュキー以外から更新)

table.items.where(:title).contains("hogehoge").each{ |u|
   u.attributes.update do |i|
      i.set :title => "hogehoge_update"
  end
}

データを削除する

table.items["a1234"].delete

データをまとめて削除する。

titleが「hogehoge」とマッチするレコードを削除します。

table.items.where(:title).contains("hogehoge").each do |u|
  u.delete
end

他にもありますが、基本的なことはこれだけで出来ます。
色々とハマりましたが、一つ一つメソッドを確認しながら対応すれば、確実に実装できると思います。

次回はページングでもやりますかね・・・

ruby クラスメソッドを一気に定義する

毎回メソッドに対してselfってやつをつけてたんですけど、一括で定義する方法があったので、メモっておきます。

class Hoge
  class << self
    def method_1
      print "method_1"
    end

    def method_2
      print "method_2"
    end
  end
end

Hoge.method_1 #method_1
Hoge.method_2 #method_2

実はこれ特異クラスなんですけれど、自分自身を特異クラスとして宣言しているから、結局はクラスメソッドになるってことですね。便利なのか複雑なのか・・・

rubyからRMagickで加工してS3に画像をアップする。

RubyからS3に画像をアップするサンプルです。
普通はサムネイル画像などを作成してアップすると思いますが、意外とサンプルが無かったのでメモ代わりに書きます。
処理の順番としては、サーバーにある画像をRMagickで加工→バイナリでS3にアップします
S3にアップする方法は3通りほどありますが、今回はメモリ上にバイナリデータとして保持し処理を行います。(いままで、画像を加工してサーバーに一度保存してからS3にアップしてました・・・)

準備するもの

  1. AWSのアカウント
  2. S3バケットの準備
  3. imageMagicのインストール
  4. RMagickとaws-sdk

コード

require 'RMagick'
require 'aws-sdk'

AWS.config(
           :access_key_id => '************',
           :secret_access_key => '************'
           )

s3 = AWS::S3.new
bucket = s3.buckets['my_bucket']
image = Magick::Image.read('image.png').first

thumbnail_image = image.resize_to_fill('300', '300', Magick::NorthWestGravity).to_blob
object = bucket.objects['s3_image.png']
object.write(thumbnail_image)

ここで重要なのは「to_blob」というメソッドです。
これを書くだけで、いけちゃいます。

ubuntuにrvmを入れる

ubuntuにrvmを入れました。
昔と違って、めちゃくちゃ簡単になっててびっくりです。
コマンド一発で行けます。

curl -L https://get.rvm.io | bash -s stable --ruby

あとは

source ~/.rvm/scripts/rvm

をやって設定ファイルを再読み込みすればOKです。
簡単ですね。