simpleconsoleで1行メモ帳

http://d.hatena.ne.jp/shokai/20081126/1227721485 の続き。SimpleConsoleで手軽に使える1行メモ帳を作った


コマンド引数からControllerを選んでViewに流すしくみはSimpleConsoleが作ってくれたので、modelをActiveRecordで実装してみた。


できたもの↓ とりあえず読み書き削除はできる。そのうちメールに吐き出す機能などを付ける。



引数無しで初回起動時に ~/.mem/db が作られる

sho@shomb% mem
initialize db..
==  CreatePosts: migrating ====================================================
-- create_table(:posts)
   -> 0.0585s
==  CreatePosts: migrated (0.0589s) ===========================================

success!
usage:
  mem post -m "メモメモ"
  mem log               :postの表示
  mem head              :最新のpost
  mem delete_all        :削除
  mem delete -id 1      :IDを指定して削除
  mem init_db            (~/.mem/dbを削除してから)
sho@shomb% mem

post -m 本文 で日時付きでどんどん書ける

sho@shomb% mem post -m "てすとてすと"
posted: てすとてすと
(1:mem_console@Thu Nov 27 08:30:44 +0900 2008) てすとてすと
sho@shomb% mem post -m "postできたぞ"
posted: postできたぞ
(2:mem_console@Thu Nov 27 08:30:53 +0900 2008) postできたぞ
(1:mem_console@Thu Nov 27 08:30:44 +0900 2008) てすとてすと
sho@shomb% mem post -m ほあああ
posted: ほあああ
(3:mem_console@Thu Nov 27 08:30:59 +0900 2008) ほあああ
(2:mem_console@Thu Nov 27 08:30:53 +0900 2008) postできたぞ
(1:mem_console@Thu Nov 27 08:30:44 +0900 2008) てすとてすと
sho@shomb% mem log                                      [~]
(3:mem_console@Thu Nov 27 08:30:59 +0900 2008) ほあああ
(2:mem_console@Thu Nov 27 08:30:53 +0900 2008) postできたぞ
(1:mem_console@Thu Nov 27 08:30:44 +0900 2008) てすとてすと


logで全post、headで最新10post表示

sho@shomb% mem head                                [~]
(11:mem_console@Thu Nov 27 08:35:22 +0900 2008) headは10postだけ表示
(10:mem_console@Thu Nov 27 08:35:09 +0900 2008) 10post目
(9:mem_console@Thu Nov 27 08:34:59 +0900 2008) 眠いよ
(8:mem_console@Thu Nov 27 08:34:49 +0900 2008) 餃
(7:mem_console@Thu Nov 27 08:34:45 +0900 2008) 子
(6:mem_console@Thu Nov 27 08:34:40 +0900 2008) の
(5:mem_console@Thu Nov 27 08:34:36 +0900 2008) 王
(4:mem_console@Thu Nov 27 08:34:31 +0900 2008) 将
(3:mem_console@Thu Nov 27 08:30:59 +0900 2008) ほあああ
(2:mem_console@Thu Nov 27 08:30:53 +0900 2008) postできたぞ
sho@shomb% mem log                                   [~]
(11:mem_console@Thu Nov 27 08:35:22 +0900 2008) headは10postだけ表示
(10:mem_console@Thu Nov 27 08:35:09 +0900 2008) 10post目
(9:mem_console@Thu Nov 27 08:34:59 +0900 2008) 眠いよ
(8:mem_console@Thu Nov 27 08:34:49 +0900 2008) 餃
(7:mem_console@Thu Nov 27 08:34:45 +0900 2008) 子
(6:mem_console@Thu Nov 27 08:34:40 +0900 2008) の
(5:mem_console@Thu Nov 27 08:34:36 +0900 2008) 王
(4:mem_console@Thu Nov 27 08:34:31 +0900 2008) 将
(3:mem_console@Thu Nov 27 08:30:59 +0900 2008) ほあああ
(2:mem_console@Thu Nov 27 08:30:53 +0900 2008) postできたぞ
(1:mem_console@Thu Nov 27 08:30:44 +0900 2008) てすとてすと


delete -i idでIDを指定してpost削除、delete_allで全削除

sho@shomb% mem delete -i 5                        [~]
sho@shomb% mem log                                [~]
(11:mem_console@Thu Nov 27 08:35:22 +0900 2008) headは10postだけ表示
(10:mem_console@Thu Nov 27 08:35:09 +0900 2008) 10post目
(9:mem_console@Thu Nov 27 08:34:59 +0900 2008) 眠いよ
(8:mem_console@Thu Nov 27 08:34:49 +0900 2008) 餃
(7:mem_console@Thu Nov 27 08:34:45 +0900 2008) 子
(6:mem_console@Thu Nov 27 08:34:40 +0900 2008) の
(4:mem_console@Thu Nov 27 08:34:31 +0900 2008) 将
(3:mem_console@Thu Nov 27 08:30:59 +0900 2008) ほあああ
(2:mem_console@Thu Nov 27 08:30:53 +0900 2008) postできたぞ
(1:mem_console@Thu Nov 27 08:30:44 +0900 2008) てすとてすと
sho@shomb% mem delete_all                         [~]
sho@shomb% mem log                                [~]
no posts

simcon singleでgenerateされたファイルを編集したもの
activerecordのmodelはpost.rbに、SQLiteとの接続などはdb.rbに書いた。
postした後にheadを出すとか、headとlogでViewを共通にするとかができて楽だったかも
http://www.bitbucket.org/shokai/mem/src/77f8aeacf76d/mem

#!/usr/bin/env ruby
require "rubygems"
require "simpleconsole"
require "activerecord"
require File.dirname(__FILE__) + "/post.rb"
require File.dirname(__FILE__) + "/db.rb"

class Controller < SimpleConsole::Controller
  params :string => {:m => :message},
         :int => {:i => :id}

  def default
    Data.connect_db
    init_db if !File.exist?(Data.db_path)
  end
  
  def post
    @message = params[:message] or exit(0)
    Data.connect_db
    Post.create(:message => @message,
                :from => 'mem_console')
    @posts = head
  end
  
  def log
    Data.connect_db
    @posts = Post.find(:all, :order=>"updated_at desc")
  end
  
  def head
    Data.connect_db
    @posts = Post.find(:all, :order=>"updated_at desc", :limit => 10)
  end

  def delete_all
    Data.connect_db
    Post.delete_all
  end
  
  def delete
    Data.connect_db
    @id = params[:id]
    @delete_num = Post.delete(@id)
  end
  
  def init_db
    Data.connect_db
    Data.init_db # 初期化
  end
  
end

class View < SimpleConsole::View
  
  def usage
    puts <<EOF
usage:
  mem post -m "メモメモ"
  mem log               :postの表示
  mem head              :最新のpost
  mem delete_all        :削除
  mem delete -id 1      :IDを指定して削除
  mem init_db            (~/.mem/dbを削除してから)
EOF
  end
  
  def default
    usage
  end
  
  def post
    puts 'posted: ' + @message
    head
  end
  
  def log
    if @posts.length < 1
      puts 'no posts'
      return
    end
    @posts.each{ |post|
      puts post.to_s
    }
  end

  def head
    log
  end
  
  def delete
    puts 'error: ID not found' if @delete_num < 1
  end
  
  def init_db
    puts 'finished'
  end

end

SimpleConsole::Application.run(ARGV, Controller, View)

Post modelのクラス
http://www.bitbucket.org/shokai/mem/src/77f8aeacf76d/post.rb

# model
class Post < ActiveRecord::Base
  def to_s
    return  "(#{id}:#{from}@#{updated_at}) #{message}"
  end
end

DBとのやりとりを任せるクラス
http://www.bitbucket.org/shokai/mem/src/77f8aeacf76d/db.rb

class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table(:posts){|t|
      t.string :message
      t.string :from
      t.timestamps
     }
  end

  def self.down
    drop_table :posts
  end
end


class Data
  home = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
  @dbdir = home+'/.mem/'
  @dbfile = @dbdir+'db'
  
  def Data.db_path
    return @dbfile
  end
  
  def Data.connect_db
    if !ActiveRecord::Base.connected?
      ActiveRecord::Base.establish_connection(:adapter => 'sqlite3',
                                              :dbfile => @dbfile)
    end
  end
  
  def Data.init_db
    puts 'initialize db..'
    begin
      Dir::mkdir(@dbdir) if !File.exist?(@dbdir)
      CreatePosts.migrate(:up)
    rescue
      puts 'error'
      exit(0)
    else
      puts 'success!'
    end
  end
  
end