metric_tools 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'google_drive', '~>0'
4
+ gem 'hirb', '~>0'
5
+ gem 'aws-s3', '~>0'
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ faraday (0.8.4)
5
+ multipart-post (~> 1.1)
6
+ google_drive (0.3.2)
7
+ nokogiri (>= 1.4.4, != 1.5.2, != 1.5.1)
8
+ oauth (>= 0.3.6)
9
+ oauth2 (>= 0.5.0)
10
+ httpauth (0.2.0)
11
+ jwt (0.1.5)
12
+ multi_json (>= 1.0)
13
+ multi_json (1.5.0)
14
+ multipart-post (1.1.5)
15
+ nokogiri (1.5.6)
16
+ oauth (0.4.7)
17
+ oauth2 (0.8.0)
18
+ faraday (~> 0.8)
19
+ httpauth (~> 0.1)
20
+ jwt (~> 0.1.4)
21
+ multi_json (~> 1.0)
22
+ rack (~> 1.2)
23
+ rack (1.5.1)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ google_drive (~> 0)
data/README.md ADDED
@@ -0,0 +1,13 @@
1
+ #metric_tools
2
+
3
+ 各種指標を観察したり、データを先方に共有したりといった時によく使う便利なユーティリティをまとめました
4
+
5
+ ---
6
+
7
+ ##Install
8
+
9
+ gem install metric_tools
10
+
11
+
12
+ ##Version Info
13
+ - 0.0.0 (2013/2/1 commited)
@@ -0,0 +1,9 @@
1
+ root_path = File.expand_path("#{File.dirname(__FILE__)}/../")
2
+ require File.join(root_path, "config", "pref.rb")
3
+
4
+ lib_path = File.join(File.dirname(__FILE__), "/metric_tools")
5
+ Dir["#{File.join(lib_path, '/*.rb')}"].each {|f| require f }
6
+
7
+ module MetricTools
8
+ include Pref
9
+ end
@@ -0,0 +1,78 @@
1
+ require 'json'
2
+
3
+ module MetricTools
4
+
5
+ #
6
+ # Tree構造のHash
7
+ #
8
+ class IndexTree
9
+
10
+ def initialize(hash_or_json=nil)
11
+ if hash_or_json.kind_of? Hash
12
+ build_with_hash(hash_or_json)
13
+ elsif hash_or_json.kind_of? String
14
+ build_with_json(hash_or_json)
15
+ else
16
+ @_hash = {}
17
+ end
18
+ end
19
+
20
+
21
+ def [](*args)
22
+ ret = nil
23
+ process_tracing_keys(@_hash, args) {|obj, key, is_leaf|
24
+ ret = obj[key] if is_leaf
25
+ }
26
+ ret
27
+ end
28
+
29
+ def []=(*args)
30
+ val = args.pop
31
+ process_tracing_keys(@_hash, args) {|obj, key, is_leaf|
32
+ if is_leaf
33
+ obj[key] = val
34
+ else
35
+ obj[key] ||= {}
36
+ end
37
+ }
38
+ end
39
+
40
+ def clear
41
+ @_hash = {}
42
+ end
43
+
44
+ def to_s
45
+ @_hash.to_s
46
+ end
47
+
48
+ def to_json(option={})
49
+ if option[:pretty]
50
+ JSON.pretty_generate(@_hash)
51
+ else
52
+ JSON.generate(@_hash)
53
+ end
54
+ end
55
+
56
+ protected
57
+ def build_with_hash(hash)
58
+ @_hash = hash
59
+ end
60
+
61
+ def build_with_json(json)
62
+ @_hash = JSON.parse(json)
63
+ end
64
+
65
+ private
66
+ def process_tracing_keys(obj, keys, &proc)
67
+ current_obj = obj
68
+ keys.each_with_index{|current_key, index|
69
+ break if current_obj.nil?
70
+
71
+ proc.call(current_obj, current_key, index == keys.length-1)
72
+ current_obj = current_obj[current_key]
73
+ }
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,87 @@
1
+ require 'aws/s3'
2
+ require 'fileutils'
3
+
4
+ module MetricTools
5
+
6
+ #
7
+ # S3からログなどをDownloadするためのクラスです
8
+ #
9
+ class S3
10
+
11
+ class << self
12
+
13
+ public
14
+ #
15
+ # access_key, secret_key, bucket_nameを指定してログインします。
16
+ #
17
+ def login(key, secret, bucket_name)
18
+ @key = key
19
+ @secret = secret
20
+ @bucket_name = bucket_name
21
+
22
+ AWS::S3::Base.establish_connection!(
23
+ :access_key_id => key,
24
+ :secret_access_key => secret,
25
+ )
26
+ @bucket = AWS::S3::Service.buckets.find{|b| b.name == @bucket_name}
27
+ raise "The bucket named '#{@bucket_name}' doesn't exist." if @bucket.nil?
28
+ end
29
+
30
+ #
31
+ # loginしているかどうかを返します
32
+ #
33
+ def login?
34
+ return !bucket.nil?
35
+ end
36
+
37
+ #
38
+ # file_keyを指定してファイルをダウンロードします。
39
+ # target_dirが存在しない場合は、勝手に作成します。
40
+ # hierarchy=trueにすると、S3上のディレクトリ構造を保持してDownloadします。
41
+ #
42
+ def download(file_key, target_dir, hierarchy=false)
43
+ file_path = File.join(target_dir, hierarchy ? file_key : File.basename(file_key))
44
+ mkdir_for_file(file_path)
45
+ puts "Downloading from S3 : #{file_key} => #{file_path}"
46
+
47
+ File.open(file_path, "w") {|fp|
48
+ AWS::S3::S3Object.stream(file_key, @bucket.name) {|chunk|
49
+ fp.write chunk
50
+ }
51
+ }
52
+ end
53
+
54
+ #
55
+ # 指定されたdir_key以下のファイル/ディレクトリをすべてDLします。
56
+ # force_all=falseにすると、既にローカルにファイルが有る場合はDLしません。
57
+ #
58
+ def fetch_all(dir_key, target_dir, force_all=false, &condition)
59
+ remote_files = @bucket
60
+ .select{|obj|
61
+ key = obj.key
62
+ is_dir = (key[key.length-1] == '/')
63
+ name = key.include? dir_key
64
+ cond = condition.nil? ? true : condition.call(obj)
65
+ !is_dir && name && cond }
66
+ .collect{|obj| obj.key }
67
+ local_files = Dir.glob(File.join(target_dir, "**/*"))
68
+
69
+ remote_files.each {|key|
70
+ if force_all || !local_files.include?(File.basename(key))
71
+ download(key, target_dir, true)
72
+ end
73
+ }
74
+
75
+ end
76
+
77
+ private
78
+ def mkdir_for_file(file_path)
79
+ dir_path = File.dirname(file_path)
80
+ FileUtils.mkdir_p(dir_path) unless File.exists?(dir_path)
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,68 @@
1
+ require 'rb-skypemac'
2
+
3
+ module MetricTools
4
+
5
+ #
6
+ # Skypeのチャットにメッセージをpostするクラスです。
7
+ # 使用するMac上でSkype for Mac OSXが起動していて、
8
+ # 対象のチャットルームに発言できるアカウントでログインされている必要があります。
9
+ #
10
+ class Skype
11
+
12
+ class << self
13
+
14
+ #
15
+ # nameで指定したチャットルームに発言出来る状態にします。
16
+ # login_chat("[GREE] パンカク連絡チャット")
17
+ #
18
+ def login_chat(name)
19
+ chats = SkypeMac::Skype.send_(:command => 'SEARCH RECENTCHATS')
20
+ chats = chats.sub("CHATS ","").split(/,/)
21
+
22
+ for id in chats
23
+ chat_info = SkypeMac::Skype.send_(:command => 'GET CHAT %s FRIENDLYNAME' % id).split(' ')
24
+ friendly_name = chat_info[3]
25
+
26
+ if friendly_name.include?(name)
27
+ @chat_id = chat_info[1]
28
+ @chat_name = friendly_name
29
+ end
30
+ end
31
+
32
+ raise "not existing chat room : #{name}" if @chat_id.nil?
33
+ @chat_id
34
+ end
35
+
36
+ def logout
37
+ @chat_id = nil
38
+ @chat_name = nil
39
+ end
40
+
41
+ #
42
+ # 現在のチャットルームのidを返します
43
+ #
44
+ def current_chat_id
45
+ @chat_id
46
+ end
47
+
48
+ #
49
+ # 現在のチャットルームの表示名を返します
50
+ #
51
+ def current_chat_name
52
+ @chat_name
53
+ end
54
+
55
+ #
56
+ # 現在のチャットルームに発言します
57
+ #
58
+ def post(message)
59
+ return puts 'please login before.' if current_chat_id.nil?
60
+
61
+ SkypeMac::Skype.send_(:command => "CHATMESSAGE #{current_chat_id} #{message}");
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,108 @@
1
+ require 'google_drive'
2
+
3
+ module MetricTools
4
+
5
+ #
6
+ # Google DocsのSpreadSheetを更新するためのクラス
7
+ # (gem google_driveのラッパーです)
8
+ #
9
+ class SpreadSheet
10
+
11
+ class << self
12
+ attr_accessor :mail, :password, :key
13
+
14
+ # session lifetime
15
+
16
+ #
17
+ # mail, passwordでログインし, 該当するkeyのspreadsheetを編集可能にします
18
+ #
19
+ def login(mail, password, key)
20
+ @mail = mail
21
+ @password = password
22
+ @key = key
23
+
24
+ @session = GoogleDrive.login(@mail, @password)
25
+ @spread_sheet = @session.spreadsheet_by_key(@key)
26
+ end
27
+
28
+ #
29
+ # ログアウトします
30
+ #
31
+ def logout
32
+ @session = nil
33
+ @spread_sheet = nil
34
+ @worksheet = nil
35
+ end
36
+
37
+ #
38
+ # ログイン状態かどうかを返します
39
+ #
40
+ def login?
41
+ return !@session.nil? && !@spread_sheet.nil?
42
+ end
43
+
44
+ #worksheet
45
+
46
+ def current_worksheet_title
47
+ return nil if @worksheet.nil?
48
+
49
+ @worksheet.title
50
+ end
51
+
52
+ def change_worksheet_by_title(title)
53
+ @worksheet = @spread_sheet.worksheet_by_title(title)
54
+ @worksheet = @spread_sheet.add_worksheet(title) if @worksheet.nil?
55
+
56
+ @worksheet
57
+ end
58
+
59
+ # editing
60
+
61
+ #
62
+ # インデクサを使用して値にアクセスします
63
+ #
64
+ def [](i, j)
65
+ check_worksheet_seleced_or_raise_error()
66
+
67
+ return @worksheet[i+1, j+1]
68
+ end
69
+
70
+ #
71
+ # インデクサを使用して値をアサインします
72
+ #
73
+ def []=(i, j, val)
74
+ check_worksheet_seleced_or_raise_error()
75
+
76
+ return @worksheet[i+1, j+1] = val
77
+ end
78
+
79
+ #
80
+ # Tableクラスの内容を、スプレッドシートに書き出します。
81
+ #
82
+ def set_value_table(table)
83
+ check_worksheet_seleced_or_raise_error()
84
+
85
+ raise 'can receive Table class only' unless table.kind_of? MetricTools::Table
86
+ table.each_with_index{|cell, i, j|
87
+ self[i, j] = cell
88
+ }
89
+ end
90
+
91
+ #
92
+ # スプレッドシートにここまでの変更を反映します。
93
+ # saveを呼ぶまでは、実際にスプレッドシートには書き込まれません。
94
+ #
95
+ def save
96
+ check_worksheet_seleced_or_raise_error()
97
+
98
+ @worksheet.synchronize
99
+ end
100
+
101
+ def check_worksheet_seleced_or_raise_error
102
+ raise "call 'change_worksheet_by_title' before." if @worksheet.nil?
103
+ end
104
+ end
105
+
106
+ end
107
+
108
+ end
@@ -0,0 +1,244 @@
1
+ require 'Hirb'
2
+
3
+ module MetricTools
4
+
5
+ #
6
+ # 2次元配列のデータ構造を簡単に扱うためのクラス
7
+ #
8
+ class Table
9
+
10
+ def initialize
11
+ @_inner_data = {}
12
+ end
13
+
14
+ class << self
15
+ # Tableクラスのインスタンスを生成します
16
+ #
17
+ # 表の幅、高さを指定し、内容をブロックで指定します。
18
+ # ブロックの返り値が、表の(i, j)の位置に入ります。
19
+ #
20
+ # Table.create(10, 5) {|i, j|
21
+ # return "set to (#{i}, #{j})"
22
+ # }
23
+ def create(rows, cols, &proc)
24
+ table = Table.new
25
+ table.build(rows, cols, &proc)
26
+ end
27
+
28
+ # Tableクラスのインスタンスを生成します
29
+ #
30
+ # 2次元配列を元にTableクラスに変換します。
31
+ #
32
+ # array = [[1, 2, 3], [4, 5, 6], [9, 0, '#']]
33
+ # Table.create_with_array(array)
34
+ def create_with_array(array)
35
+ Table.create(array[0].length, array.length) {|i, j|
36
+ array[j][i]
37
+ }
38
+ end
39
+ end
40
+
41
+ public
42
+ #
43
+ # インデクサを用いてアクセスします
44
+ # 表の大きさを超えていると nilが返ります。
45
+ #
46
+ # table[1, 10]
47
+ def [](i, j)
48
+ @_inner_data[index_to_key(i, j)]
49
+ end
50
+
51
+ #
52
+ # インデクサを用いてアクセスします
53
+ # 表の大きさを超えているとき、自動的に拡張します
54
+ #
55
+ # table[1, 10] = val
56
+ def []=(i, j, val)
57
+ raise "can't specify negative number for position." if i < 0 || j < 0
58
+
59
+ @_inner_data[index_to_key(i, j)] = val
60
+ end
61
+
62
+ #
63
+ # tableの幅(列数)を取得します
64
+ #
65
+ def width
66
+ max = 0
67
+ for key in @_inner_data.keys
68
+ i, j = key_to_index(key)
69
+ max = j if max < j
70
+ end
71
+ return max + 1
72
+ end
73
+
74
+ #
75
+ # tableの幅(列数)を取得します
76
+ #
77
+ def cols
78
+ self.width
79
+ end
80
+
81
+ #
82
+ # tableの高さ(行数)を取得します
83
+ #
84
+ def height
85
+ max = 0
86
+ for key in @_inner_data.keys
87
+ i, j = key_to_index(key)
88
+ max = i if max < i
89
+ end
90
+ return max + 1
91
+ end
92
+
93
+ #
94
+ # tableの高さ(行数)を取得します
95
+ #
96
+ def rows
97
+ self.height
98
+ end
99
+
100
+ def add_below(table)
101
+ table.each_with_index{|cell, i, j|
102
+ self[i, j+self.height] = cell
103
+ }
104
+ self
105
+ end
106
+
107
+ #
108
+ # 2次元配列を返します。自身は変更されません。
109
+ #
110
+ # table.to_a => [[1,2,3], [4,5,6], [9,0,'#']]
111
+ def to_a
112
+ ret = []
113
+ @_inner_data.each{|key, val|
114
+ i, j = key_to_index(key)
115
+
116
+ ret[i] ||= []
117
+ ret[i][j] = val
118
+ }
119
+ ret
120
+ end
121
+
122
+ #
123
+ # 全データに対して処理を行います
124
+ #
125
+ # table.each {|cell|
126
+ # cell += 10
127
+ # }
128
+ def each(&proc)
129
+ @_inner_data.keys.each{|key|
130
+ proc.call(@_inner_data[key])
131
+ }
132
+ end
133
+
134
+ #
135
+ # 全データに対して処理を行います。(i, j)にデータの座標が入ります。
136
+ #
137
+ # table.each {|cell, i, j|
138
+ # cell = i + j * table.width
139
+ # }
140
+ def each_with_index(&proc)
141
+ @_inner_data.keys.each{|key|
142
+ i, j = key_to_index(key)
143
+ proc.call(@_inner_data[key], i, j)
144
+ }
145
+ end
146
+
147
+ def collect(&proc)
148
+ new_one = Table.create(self.rows, self.cols){|i, j|
149
+ proc.call(self[i, j], i, j)
150
+ }
151
+ new_one
152
+ end
153
+
154
+ # output console methods
155
+
156
+ #
157
+ # コンソールに綺麗な表形式で出力します(Hirbを使用)
158
+ #
159
+ def print_pretty
160
+ puts Hirb::Helpers::Table.render @data, :headers => @headers, :resize => false
161
+ end
162
+
163
+ #
164
+ # コンソールにcsv形式で出力します
165
+ #
166
+ def print_csv
167
+ print_with_seperator(",")
168
+ end
169
+
170
+ #
171
+ # コンソールにtsv形式で出力します
172
+ #
173
+ def print_for_docs
174
+ print_with_seperator("\t")
175
+ end
176
+
177
+ def print_with_seperator(s)
178
+ to_a.each{|row|
179
+ puts row.join(s)
180
+ }
181
+ end
182
+
183
+ #
184
+ # csvファイルとして出力します
185
+ #
186
+ def output_csv_file(path)
187
+ output_file_with_seperator(",", path)
188
+ end
189
+
190
+ #
191
+ # tsvファイルとして出力します
192
+ #
193
+ def output_tsv_file(path)
194
+ output_file_with_seperator("\t", path)
195
+ end
196
+
197
+ def output_file_with_seperator(s, path)
198
+ puts "start output >> #{path}..."
199
+
200
+ ret = ''
201
+ to_a.each{|row|
202
+ ret << row.join(s) + "\n"
203
+ }
204
+
205
+ File.open(path, 'w') {|fp|
206
+ fp.write ret
207
+ }
208
+ puts "finish"
209
+ end
210
+
211
+ def build(rows, cols, &proc)
212
+ for i in 0..rows-1
213
+ for j in 0..cols-1
214
+ @_inner_data[index_to_key(i, j)] = proc.call(i, j)
215
+ end
216
+ end
217
+ self
218
+ end
219
+
220
+
221
+ private
222
+
223
+ def index_to_key(i, j)
224
+ "#{i}-#{j}"
225
+ end
226
+
227
+ def key_to_index(key)
228
+ i, j = key.split('-')
229
+ [i.to_i, j.to_i]
230
+ end
231
+
232
+ def move_cell(i, j, delta_x, delta_y)
233
+ raise "can't specify negative number for position." if i < 0 || j < 0
234
+ raise "can't move to negative position." if i + delta_x < 0 || j + delta_y < 0
235
+
236
+ src_key = index_to_key(i, j)
237
+ dst_key = index_to_key(i + delta_x, j + delta_y)
238
+
239
+ @_inner_data[dst_key] = @_inner_data[src_key]
240
+ @_inner_data.delete(src_key)
241
+ end
242
+ end
243
+
244
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: metric_tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Masaori Hirono
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2010-04-28 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Utilities for analyzing metrics
15
+ email: masaori@pankaku.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/metric_tools/index_tree.rb
21
+ - lib/metric_tools/s3.rb
22
+ - lib/metric_tools/skype.rb
23
+ - lib/metric_tools/spread_sheet.rb
24
+ - lib/metric_tools/table.rb
25
+ - lib/metric_tools.rb
26
+ - Gemfile
27
+ - Gemfile.lock
28
+ - README.md
29
+ homepage: http://google.com/
30
+ licenses: []
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 1.8.25
50
+ signing_key:
51
+ specification_version: 3
52
+ summary: Utilities for analyzing metrics
53
+ test_files: []