Skip to content

Commit

Permalink
Origcmd: データベース抽象化の実装・
Browse files Browse the repository at this point in the history
configurable_generator.rb に、データベースを使う場合の設定メソッドを書いた。
プラグイン Origcmd に、SDBM を使う場合のデータベースへの保存を実装した。

プラグイン Origcmd で定義するコマンド、create/delete/show の管理用3つと、作ったコマンドの実行機能を実装した。

ToDo:
ログに実行内容(出力内容・コマンドの作成など)を記録できるようにする。
  • Loading branch information
koi-chan committed Jul 23, 2015
1 parent 593f749 commit ede2a69
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 47 deletions.
20 changes: 19 additions & 1 deletion lib/rgrb/plugin/configurable_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def initialize
def root_path=(root_path)
@root_path = root_path
@data_path = "#{root_path}/data/#{@plugin_name_underscore}"
@plugin_script_path = "#{root_path}/lib/rgrb/plugin/#{@plugin_name_underscore}"

root_path
end
Expand All @@ -28,9 +29,26 @@ def root_path=(root_path)
#
# 標準では何も行わない。
# @return [self]
def configure(*)
def configure(config_data)
@dbconfig= config_data['Database'] || ''
self
end

# 使用する DB 名の接頭語を決め、DB 固有のファイルを読み込む
# @return [Boolean]
def prepare_database
options = {
dbname_prefix: "rgrb_plugin_#{@plugin_name_underscore}",
data_path: @data_path,
config: @dbconfig
}
require "#{@plugin_script_path}/db_#{@dbconfig['Type']}"

class_name_tree = self.class.name.split('::')
class_name_tree[-1] = 'Database'
database_class = Object.const_get(class_name_tree.join('::'))
@db = database_class.new(options)
end
end
end
end
22 changes: 14 additions & 8 deletions lib/rgrb/plugin/origcmd/db_sdbm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@ module Plugin
module Origcmd
class Database

def initialize
dbm = SDBM.open(filename)
# SDBM データベースを開く
# @param [Hash] options DB に関する設定
# @option options [String] :data_path データファイルのパス
# @option options [String] :config データベースに関する設定ファイルでの指定
# @option options:config [String] Type データベースの種類
# @return [true]
def initialize(options)
@dbm = SDBM.open("#{options[:data_path]}/cmds")
true
end

# SDBM データベースへ書き込む
Expand All @@ -29,15 +36,15 @@ def write(nick, channel, cmdname, delkey, reply)
date: Date.today
}

dbm[cmdname] = JSON.dump(data)
true
@dbm[cmdname] = JSON.dump(data)
read(cmdname)
end

# SDBM データベースから指定されたコマンド名のデータを読み込む
# @param [String] cmdname 読み込むコマンド名
# @return [Hash]
def read(cmdname)
data = JSON.parse(dbm[cmdname], {:symbolize_names => true})
data = JSON.parse(@dbm[cmdname], {:symbolize_names => true})
data[:date] = Date.parse(data[:date])

data
Expand All @@ -47,17 +54,16 @@ def read(cmdname)
# @param [String] cmdname
# @return [nil]
def remove(cmdname)
dbm.delete(cmdname)
@dbm.delete(cmdname)
nil
end

# SDBM データベースに指定したコマンド名が登録されているか調べる
# @param [String] cmdname
# @return [Boolean]
def cmd_exist?(cmdname)
dbm.has_key?(cmdname)
@dbm.has_key?(cmdname)
end

end
end
end
Expand Down
52 changes: 39 additions & 13 deletions lib/rgrb/plugin/origcmd/generator.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# vim: fileencoding=utf-8

require 'uri'
require 'rgrb/plugin/configurable_generator'

module RGRB
Expand All @@ -13,22 +12,19 @@ class Generator

# 新しい Origcmd::Generator インスタンスを返す
def initialize
super
end

# 設定データを解釈してプラグインの設定を行う
# @param [Hash] config_data 設定データのハッシュ
# @return [self]
def configure(config_data)
dbtype = config_data['DBtype'] || 'sdbm'
db_initialize
super
prepare_database

self
end

def db_initialize

end

# オリジナルコマンドを作成する
# @param [String] nick
# @param [String] channel
Expand All @@ -37,13 +33,15 @@ def db_initialize
# @param [String] reply
# @return [String]
def create(nick, channel, cmdname, delkey, reply)
return '[error] 既に同名のコマンドが登録されています。' if cmdname_exist?
return '[error] 既に同名のコマンドが登録されています。' if @db.cmd_exist?(cmdname)
return '[error] コマンド名に使用できない文字が含まれています。' until cmdname == cmdname.match(CMD_RE).to_s
return '[error] 削除キーに使用できない文字が含まれています。' until delkey == delkey.match(CMD_RE).to_s

@db.write(nick, channel, cmdname, delkey, reply)
cmd = @db.write(nick, channel, cmdname, delkey, reply)

"#{cmdname} を登録しました。変更・削除するための" \
"削除キー #{delkey} を紛失しないようにしてください。\n" \
"コマンド応答例: &#{cmd[:reply]}"
"コマンド応答例: #{cmd[:reply]}"
end

# オリジナルコマンドを削除します
Expand All @@ -66,7 +64,8 @@ def show(cmdname)
return '[error] コマンドが存在しません' until @db.cmd_exist?(cmdname)

cmd = @db.read(cmdname)
"#{cmd[:cmdname]} 作者:#{cmd[:nick]}(#{cmd[:channel]}) 登録日:#{cmd[:date]}"
"#{cmd[:cmdname]} 作者:#{cmd[:nick]}(#{cmd[:channel]}) 登録日:#{cmd[:date]}\n" \
"コマンド応答例: #{cmd[:reply]}"
end

# オリジナルコマンドを上書き作成します
Expand All @@ -81,12 +80,39 @@ def edit(nick, channel, cmdname, delkey, reply)
create(nick, channel, cmdname, delkey, reply)
end

# オリジナルコマンドを呼び出して実行します
# @param [] m
# @param [String] cmdname
# @param [String] args
# @return [false] コマンドが存在しなかった時
# @return [String] コマンドが存在した時、呼び出した結果
def cmdcall(m, cmdname, args)
return until @db.cmd_exist?(cmdname)
arg = args.split(/[  ]/)

result = @db.read(cmdname).fetch(:reply)
arg = args.split(/[  ]+/, result.scan(/%[we]/).size)

result.gsub(/%[wecdtu1-9%]/) { |match|
case match
when '%w'
arg.shift
when '%e'
URI.encode_www_form_component(arg.shift)
when '%c'
m.channel.to_s
when '%d'
Date.today
when '%t'
Time.now.strftime('%T')
when '%u'
m.user.nick
when /%([1-9])/
Random.rand(1..$1.to_i)
when '%%'
'%'
end
}
end

# コマンドの削除キーが一致するか調べます
# @param [String] cmdname
# @param [String] delkey
Expand Down
75 changes: 50 additions & 25 deletions lib/rgrb/plugin/origcmd/irc_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'cinch'
require 'rgrb/plugin/configurable_adapter'
require 'rgrb/plugin/origcmd/constants'
require 'rgrb/plugin/origcmd/generator'

module RGRB
Expand All @@ -13,17 +14,17 @@ class IrcAdapter
include ConfigurableAdapter

set(plugin_name: 'Origcmd')
self.prefix = '.origcmd'
match(/create (#{CMD_RE}) (#{CMD_RE})[  ]+(.+)/, method: :create)
match(/remove (#{CMD_RE}) (#{CMD_RE})[  ]+(.+)/, method: :remove)
match(/show (#{CMD_RE})[  ]+(.+)/, method: :show)
self.prefix = '.origcmd '
match(/create[  ]+(.+)/, method: :create)
match(/remove (#{CMD_RE})(.*)/, method: :remove)
match(/show (#{CMD_RE})/, method: :show)
match(/edit (#{CMD_RE}) (#{CMD_RE})[  ]+(.+)/, method: :edit)

match(/\+ (#{CMD_RE}) (#{CMD_RE})[  ]+(.+)/, method: :create, :prefix => '.oc')
match(/- (#{CMD_RE}) (#{CMD_RE})[  ]+(.+)/, method: :remove, :prefix => '.oc')
match(/\? (#{CMD_RE})[  ]+(.+)/, method: :show, :prefix => '.oc')
match(/\+[  ]+(.+)/, method: :create, :prefix => '.oc')
match(/- (#{CMD_RE})(.*)/, method: :remove, :prefix => '.oc')
match(/\? (#{CMD_RE})/, method: :show, :prefix => '.oc')

match(/(#{CMD_RE})[  ]+(.+)/i, method: :cmdcall, :prefix => '&')
match(/(#{CMD_RE})(.*)/i, method: :cmdcall, :prefix => '&')

def initialize(*args)
super
Expand All @@ -36,33 +37,49 @@ def initialize(*args)
def create(m, args)
nick = m.user.nick
channel = m.channel.to_s
cmdname, delkey, reply = args.split(/[  ]/, 3)
mes =
if cmdname.match(CMD_RE).to_s != cmdname
'cmdname error'
elsif delkey.match(CMD_RE).to_s != delkey
'delkey error'
cmdname, delkey, reply = args.split(/[  ]+/, 3)

result =
if cmdname == nil
'cmdname is empty'
elsif delkey == nil or delkey == ''
'delkey is empty'
elsif reply == nil or reply == ''
'reply is empty'
else
@generator.create(nick, channel, cmdname, delkey, reply)
end

m.target.send("origcmd[#{nick}]<CREATE>: #{mes}", true)
p result
result.each_line do |line|
message = "origcmd[#{nick}]<CREATE>: #{line.chomp}"
p message
m.target.send(message, true)
#log_notice(m.target, message)
end
end

# オリジナルコマンドを削除する
# .origcmd remove CMDNAME DELKEY
# @return [void]
def remove(m, cmdname, delkey)
header = "origcmd[#{m.user.nick}]<REMOVE>: "
m.target.send(header + @generator.remove(cmdname, delkey), true)
def remove(m, cmdname, args)
delkey = args.split(/[  ]+/).at(1)
message =
if delkey == nil or delkey == ''
'[error] 削除キーが入力されていません'
else
"origcmd[#{m.user.nick}]<REMOVE>: #{@generator.remove(cmdname, delkey)}"
end
m.target.send(message, true)
#log_notice(m.target, message)
end

# オリジナルコマンドの設定内容を表示する
# .origcmd show CMDNAME
# @return [void]
def show(m, cmdname)
header = "origcmd[#{m.user.nick}]<SHOW>: "
m.target.send(header + @generator.show(cmdname), true)
message = "origcmd[#{m.user.nick}]<SHOW>: #{@generator.show(cmdname)}"
m.target.send(message, true)
#log_notice(m.target, message)
end

# オリジナルコマンドを編集する(上書き登録する)
Expand All @@ -71,13 +88,21 @@ def show(m, cmdname)
def edit(m, cmdname, delkey, reply)
nick = m.user.nick
channel = m.channel.to_s
header = "origcmd[#{m.user.nick}]<EDIT>: "
m.target.send(header + @generator.edit(nick, channel, cmdname, delkey, reply), true)
@generator.edit(nick, channel, cmdname, delkey, reply).each_line do |line|
message = "origcmd[#{m.user.nick}]<EDIT>: #{line.chomp}"
m.target.send(message, true)
#log_notice(m.target, message)
end
end

def cmdcall(m, cmdname, args)
header = "&cmdname[#{m.user.nick}]: "
m.target.send(header + @generator.cmdcall(m, cmdname, args), true)
args.slice!(/[  ]+/)
return until result = @generator.cmdcall(m, cmdname, args)
result.each_line do |line|
message = "&#{cmdname}[#{m.user.nick}]: #{line.chomp}"
m.target.send(message, true)
#log_notice(m.target, message)
end
end
end
end
Expand Down

0 comments on commit ede2a69

Please sign in to comment.