gfspark 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +50 -0
- data/Rakefile +1 -0
- data/bin/gfspark +7 -0
- data/gfspark.gemspec +23 -0
- data/lib/gfspark.rb +52 -0
- data/lib/gfspark/app.rb +48 -0
- data/lib/gfspark/config.rb +123 -0
- data/lib/gfspark/connection.rb +94 -0
- data/lib/gfspark/graph.rb +74 -0
- data/lib/gfspark/version.rb +3 -0
- metadata +121 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Tomohito Ozaki
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# gfspark
|
2
|
+
|
3
|
+
Growth Forecast on Terminal.
|
4
|
+
|
5
|
+
gfspark is CLI graph viewer for Growth Forecast.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'gfspark'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install gfspark
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
usage: gfspark <url|path|service_name> [section_name] [graph_name]
|
24
|
+
|
25
|
+
Examples:
|
26
|
+
gfspark http://your.gf.com/view_graph/your_service/your_section/your_graph?t=h
|
27
|
+
gfspark your_service/your_section/your_graph h --url=http://your.gf.com/view_graph
|
28
|
+
gfspark your_service your_section your_graph h --url=http://your.gf.com/view_graph
|
29
|
+
|
30
|
+
Options:
|
31
|
+
--url=VALUE Your GrowthForecast URL
|
32
|
+
-u, --user=USER
|
33
|
+
-p, --pass=PASS
|
34
|
+
-t=VALUE Range of Graph
|
35
|
+
--from=VALUE Start date of graph.(2011/12/08 12:10:00) required if t=c or sc
|
36
|
+
--to=VALUE End date of graph.(2011/12/08 12:10:00) required if t=c or sc
|
37
|
+
-h, --height=VALUE graph height.(default 10
|
38
|
+
-w, --width=VALUE graph width.(default is deteced from $COLUMNS
|
39
|
+
-c, --color=VALUE Color of graph bar
|
40
|
+
--sslnoverify don't verify SSL
|
41
|
+
--sslcacert=v SSL CA CERT
|
42
|
+
--debug debug print
|
43
|
+
|
44
|
+
## Contributing
|
45
|
+
|
46
|
+
1. Fork it
|
47
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
48
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
49
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
50
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/gfspark
ADDED
data/gfspark.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'gfspark/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "gfspark"
|
8
|
+
gem.version = Gfspark::VERSION
|
9
|
+
gem.authors = ["Tomohito Ozaki"]
|
10
|
+
gem.email = ["ozaki@yuroyoro.com"]
|
11
|
+
gem.description = %q{GrowthForecast on Terminal}
|
12
|
+
gem.summary = %q{GrowthForecast Graph viewer on Terminal}
|
13
|
+
gem.homepage = "http://yuroyoro.github.io/gfspark/"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'json'
|
21
|
+
gem.add_dependency 'term-ansicolor'
|
22
|
+
gem.add_development_dependency 'rake'
|
23
|
+
end
|
data/lib/gfspark.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require "gfspark/version"
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
if RUBY_VERSION < '1.9.0'
|
5
|
+
$KCODE = "UTF8"
|
6
|
+
else
|
7
|
+
Encoding.default_external = Encoding.find('UTF-8')
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'pp'
|
11
|
+
require 'rubygems'
|
12
|
+
require 'uri'
|
13
|
+
require 'open-uri'
|
14
|
+
require "net/http"
|
15
|
+
require "net/https"
|
16
|
+
require "uri"
|
17
|
+
require 'fileutils'
|
18
|
+
require 'json'
|
19
|
+
require 'optparse'
|
20
|
+
require 'yaml'
|
21
|
+
require 'term/ansicolor'
|
22
|
+
|
23
|
+
module Gfspark
|
24
|
+
def self.main(argv)
|
25
|
+
status = true
|
26
|
+
|
27
|
+
app = nil
|
28
|
+
begin
|
29
|
+
app = Gfspark::App.new(argv)
|
30
|
+
if app.valid
|
31
|
+
status = app.execute
|
32
|
+
else
|
33
|
+
app.help
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
rescue => e
|
37
|
+
puts e
|
38
|
+
if app && app.debug
|
39
|
+
puts e.backtrace.join("\n")
|
40
|
+
pp app.options
|
41
|
+
end
|
42
|
+
status = false
|
43
|
+
end
|
44
|
+
|
45
|
+
exit(status)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
require File.dirname(__FILE__) + '/gfspark/config'
|
50
|
+
require File.dirname(__FILE__) + '/gfspark/connection'
|
51
|
+
require File.dirname(__FILE__) + '/gfspark/graph'
|
52
|
+
require File.dirname(__FILE__) + '/gfspark/app'
|
data/lib/gfspark/app.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
class Gfspark::App
|
2
|
+
include Term::ANSIColor
|
3
|
+
include ::Gfspark::Config
|
4
|
+
include ::Gfspark::Connection
|
5
|
+
include ::Gfspark::Graph
|
6
|
+
|
7
|
+
attr_accessor :debug, :options, :valid
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
@opt_parse_obj = opt_parser
|
11
|
+
|
12
|
+
if args.nil? || args.empty?
|
13
|
+
@valid = false
|
14
|
+
return
|
15
|
+
end
|
16
|
+
|
17
|
+
@options = load_default_settings
|
18
|
+
try_url(args) || try_path(args) || try_default(args)
|
19
|
+
|
20
|
+
unless @url && @service && @section && @graph
|
21
|
+
puts "Invalid Arguments"
|
22
|
+
@valid = false
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
detect_width_and_height!
|
27
|
+
set_ssl_options!
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute
|
31
|
+
json = fetch(:xport)
|
32
|
+
summary = fetch(:summary)
|
33
|
+
|
34
|
+
render(json, summary)
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def fetch(api)
|
39
|
+
url = "#{@url}/#{api.to_s}/#{@service}/#{@section}/#{@graph}"
|
40
|
+
queries = {}
|
41
|
+
queries[:t] = @options[:t] || "d"
|
42
|
+
queries[:width] = @width
|
43
|
+
queries[:from] = @options[:from] if @options[:from].nil?
|
44
|
+
queries[:to] = @options[:to] if @options[:to].nil?
|
45
|
+
|
46
|
+
json = fetch_json(url, {}, queries)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Gfspark::Config
|
2
|
+
|
3
|
+
def try_url(args)
|
4
|
+
return false unless args.first =~ /http?/
|
5
|
+
|
6
|
+
u = URI.parse(args.shift)
|
7
|
+
@url = u.to_s.gsub(u.request_uri, '')
|
8
|
+
@graph, @section, @service = u.path.split('/').reverse
|
9
|
+
if u.query
|
10
|
+
queries = Hash[*u.query.split("&").map{|_| k,v = _.split("=");[k.to_sym, v]}.flatten]
|
11
|
+
@options.merge!(queries)
|
12
|
+
end
|
13
|
+
parse_options(args)
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def try_path(args)
|
18
|
+
return false unless args.first=~ %r(^([^/]+)/([^/]+)/([^/]+)$)
|
19
|
+
@service = $1
|
20
|
+
@section = $2
|
21
|
+
@graph = $3
|
22
|
+
|
23
|
+
args.shift
|
24
|
+
@options[:t] = args.shift if range_arg?(args.first)
|
25
|
+
|
26
|
+
parse_options(args)
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def try_default(args)
|
31
|
+
@service = args.shift
|
32
|
+
@section = args.shift
|
33
|
+
@graph = args.shift
|
34
|
+
|
35
|
+
@options[:t] = args.shift if range_arg?(args.first)
|
36
|
+
|
37
|
+
parse_options(args)
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_ssl_options!
|
42
|
+
@ssl_options = {}
|
43
|
+
if @options.key?(:sslNoVerify) && RUBY_VERSION < "1.9.0"
|
44
|
+
@ssl_options[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE
|
45
|
+
end
|
46
|
+
if @options.key?(:sslCaCert)
|
47
|
+
@ssl_options[:ssl_ca_cert] = @options[:sslCaCert]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def help(options = {})
|
52
|
+
puts @opt_parse_obj.banner
|
53
|
+
puts <<-MSG
|
54
|
+
|
55
|
+
Examples:
|
56
|
+
gfspark http://your.gf.com/view_graph/your_service/your_section/your_graph?t=h
|
57
|
+
gfspark your_service/your_section/your_graph h --url=http://your.gf.com/view_graph
|
58
|
+
gfspark your_service your_section your_graph h --url=http://your.gf.com/view_graph
|
59
|
+
|
60
|
+
MSG
|
61
|
+
puts " Options:"
|
62
|
+
puts @opt_parse_obj.summarize
|
63
|
+
end
|
64
|
+
|
65
|
+
def parse_options(args)
|
66
|
+
@opt_parse_obj.parse!(args)
|
67
|
+
args
|
68
|
+
end
|
69
|
+
|
70
|
+
def detect_width_and_height!
|
71
|
+
@stty_height, @stty_width = `stty size`.split.map(&:to_i)
|
72
|
+
|
73
|
+
width = ((@stty_width - 12) / 2).floor
|
74
|
+
@options[:width] ||= width
|
75
|
+
@width = @options[:width].to_i
|
76
|
+
height = @options[:height].to_i
|
77
|
+
@height = height.zero? ? 10 : height
|
78
|
+
end
|
79
|
+
|
80
|
+
def load_default_settings
|
81
|
+
settings = load_default_settings_with_traversing_to_root ||
|
82
|
+
load_default_settings_from_home || {}
|
83
|
+
|
84
|
+
settings = Hash[*settings.map{|k,v| [k.to_sym, v]}.flatten]
|
85
|
+
@url = settings[:url] if settings[:url]
|
86
|
+
@service = settings[:service] if settings[:service]
|
87
|
+
@section = settings[:section] if settings[:section]
|
88
|
+
@graph = settings[:graph] if settings[:graph]
|
89
|
+
settings
|
90
|
+
end
|
91
|
+
|
92
|
+
def load_default_settings_with_traversing_to_root(dir = Dir::pwd)
|
93
|
+
filename = File.join(dir, '.gfspark')
|
94
|
+
return YAML.load_file filename if File.exists? filename
|
95
|
+
|
96
|
+
parent = File.dirname dir
|
97
|
+
load_default_settings_with_traversing_to_root(parent) unless dir == parent
|
98
|
+
end
|
99
|
+
|
100
|
+
def load_default_settings_from_home
|
101
|
+
filename = File.join("~/", ".gfspark")
|
102
|
+
return YAML.load_file filename if File.exists? filename
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def opt_parser
|
107
|
+
OptionParser.new{|opts|
|
108
|
+
opts.banner = "gfspark : Growth Forecast on Terminal\n\nusage: gfspark <url|path|service_name> [section_name] [graph_name]"
|
109
|
+
opts.on("--url=VALUE", "Your GrowthForecast URL"){|v| @options[:url] = v}
|
110
|
+
opts.on('-u=USER', '--user=USER'){|v| @options[:username] = v }
|
111
|
+
opts.on('-p=PASS', '--pass=PASS'){|v| @options[:password] = v }
|
112
|
+
opts.on("-t=VALUE", "Range of Graph"){|v| @options[:t] = v}
|
113
|
+
opts.on("--from=VALUE", "Start date of graph.(2011/12/08 12:10:00) required if t=c or sc"){|v| @options[:from] = v}
|
114
|
+
opts.on("--to=VALUE", "End date of graph.(2011/12/08 12:10:00) required if t=c or sc"){|v| @options[:to] = v}
|
115
|
+
opts.on("-h=VALUE", "--height=VALUE", "graph height.(default 10"){|v| @options[:height] = v}
|
116
|
+
opts.on("-w=VALUE", "--width=VALUE", "graph width.(default is deteced from $COLUMNS"){|v| @options[:width] = v}
|
117
|
+
opts.on("-c=VALUE", "--color=VALUE", "Color of graph bar"){|v| @options[:color] = v}
|
118
|
+
opts.on("--sslnoverify", "don't verify SSL"){|v| @options[:sslNoVerify] = true}
|
119
|
+
opts.on("--sslcacert=v", "SSL CA CERT"){|v| @options[:sslCaCert] = v}
|
120
|
+
opts.on("--debug", "debug print"){@debug= true }
|
121
|
+
}
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Gfspark::Connection
|
2
|
+
@ssl_options = {}
|
3
|
+
|
4
|
+
def connection(host, port)
|
5
|
+
env = ENV['http_proxy'] || ENV['HTTP_PROXY']
|
6
|
+
if env
|
7
|
+
uri = URI(env)
|
8
|
+
proxy_host, proxy_port = uri.host, uri.port
|
9
|
+
Net::HTTP::Proxy(proxy_host, proxy_port).new(host, port)
|
10
|
+
else
|
11
|
+
Net::HTTP.new(host, port)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch_json(url, options = {}, params = {})
|
16
|
+
response = send_request(url, {},options, params, :get)
|
17
|
+
raise response.code unless response_success?(response)
|
18
|
+
json = JSON.parse(response.body)
|
19
|
+
|
20
|
+
if @debug
|
21
|
+
puts '-' * 80
|
22
|
+
puts url
|
23
|
+
pp json
|
24
|
+
puts '-' * 80
|
25
|
+
end
|
26
|
+
|
27
|
+
json
|
28
|
+
end
|
29
|
+
|
30
|
+
def send_request(url, json = {}, options = {}, params = {}, method = :post)
|
31
|
+
url = "#{url}"
|
32
|
+
uri = URI.parse(url)
|
33
|
+
|
34
|
+
if @debug
|
35
|
+
puts '-' * 80
|
36
|
+
puts url
|
37
|
+
pp json
|
38
|
+
puts '-' * 80
|
39
|
+
end
|
40
|
+
|
41
|
+
https = connection(uri.host, uri.port)
|
42
|
+
https.use_ssl = true
|
43
|
+
https.verify_mode = @ssl_options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_NONE
|
44
|
+
|
45
|
+
store = OpenSSL::X509::Store.new
|
46
|
+
unless @ssl_options[:ssl_ca_cert].nil?
|
47
|
+
if File.directory? @ssl_options[:ssl_ca_cert]
|
48
|
+
store.add_path @ssl_options[:ssl_ca_cert]
|
49
|
+
else
|
50
|
+
store.add_file @ssl_options[:ssl_ca_cert]
|
51
|
+
end
|
52
|
+
http.cert_store = store
|
53
|
+
else
|
54
|
+
store.set_default_paths
|
55
|
+
end
|
56
|
+
https.cert_store = store
|
57
|
+
|
58
|
+
https.set_debug_output $stderr if @debug && https.respond_to?(:set_debug_output)
|
59
|
+
|
60
|
+
https.start{|http|
|
61
|
+
|
62
|
+
path = "#{uri.path}"
|
63
|
+
path += "?" + params.map{|k,v| "#{k}=#{v}"}.join("&") unless params.empty?
|
64
|
+
|
65
|
+
request = case method
|
66
|
+
when :post then Net::HTTP::Post.new(path)
|
67
|
+
when :put then Net::HTTP::Put.new(path)
|
68
|
+
when :get then Net::HTTP::Get.new(path)
|
69
|
+
else raise "unknown method #{method}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# add basic auth header...
|
73
|
+
if @options[:username] && @options[:password]
|
74
|
+
request.basic_auth @options[:username], @options[:password]
|
75
|
+
end
|
76
|
+
|
77
|
+
request.set_content_type("application/json")
|
78
|
+
request.body = json.to_json unless json.nil?
|
79
|
+
|
80
|
+
response = http.request(request)
|
81
|
+
if @debug
|
82
|
+
puts "#{response.code}: #{response.msg}"
|
83
|
+
puts response.body
|
84
|
+
end
|
85
|
+
|
86
|
+
response
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def response_success?(response)
|
91
|
+
code = response.code.to_i
|
92
|
+
code >= 200 && code < 300
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Gfspark::Graph
|
2
|
+
@height = 20
|
3
|
+
|
4
|
+
BARS = [" ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" ]
|
5
|
+
def bar(val, unit)
|
6
|
+
n = (val.to_f/unit).ceil
|
7
|
+
@height.times.map{|i|
|
8
|
+
x = n - (i * 8)
|
9
|
+
(x > 0) ? (x < 8) ? BARS[x] : BARS.last : " "
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def render(json, summary)
|
14
|
+
rows = json['rows']
|
15
|
+
max = rows.flatten.compact.max
|
16
|
+
max_val = (max / 8).ceil * 8
|
17
|
+
unit = max_val / (@height * 8).to_f
|
18
|
+
|
19
|
+
s = Time.at(json["start_timestamp"].to_i).strftime("%Y-%m-%d %H:%M:%S")
|
20
|
+
e = Time.at(json["end_timestamp"].to_i).strftime("%Y-%m-%d %H:%M:%S")
|
21
|
+
|
22
|
+
puts " #{blue(json["column_names"].first)}"
|
23
|
+
puts ""
|
24
|
+
puts " #{period_title} #{s} - #{e}"
|
25
|
+
puts ""
|
26
|
+
|
27
|
+
result = []
|
28
|
+
rows.flatten.map{|row| bar(row, unit)}.transpose.reverse.each_with_index do |row, i|
|
29
|
+
i = (@height- i)
|
30
|
+
label = i.even? ? sprintf("%.1f", unit * i * 8) : ""
|
31
|
+
line = row.join
|
32
|
+
if color = @options[:color]
|
33
|
+
line = Term::ANSIColor.send(color, line)
|
34
|
+
end
|
35
|
+
result << "#{sprintf("%10s", label)} | #{line} |"
|
36
|
+
end
|
37
|
+
puts result.join("\n")
|
38
|
+
puts ""
|
39
|
+
|
40
|
+
sums = summary.first.last
|
41
|
+
puts " #{sprintf("cur: %.1f ave: %.1f max: %.1f min %.1f", *sums)}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def period_title
|
45
|
+
case @options[:t]
|
46
|
+
when "c", "sc" then sprintf(RANGES[@options[:t]], @options[:from], @options[:to])
|
47
|
+
else RANGES[@options[:t]]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
RANGES = {
|
52
|
+
"y" => 'Year (1day avg)',
|
53
|
+
"m" => 'Month (2hour avg)',
|
54
|
+
"w" => 'Week (30min avg)',
|
55
|
+
"3d" => '3 Days (5min avg)',
|
56
|
+
"s3d" => '3 Days (5min avg)',
|
57
|
+
"d" => 'Day (5min avg)',
|
58
|
+
"sd" => 'Day (1min avg)' ,
|
59
|
+
"8h" => '8 Hours (5min avg)',
|
60
|
+
"s8h" => '8 Hours (1min avg)' ,
|
61
|
+
"4h" => '4 Hours (5min avg)',
|
62
|
+
"s4h" => '4 Hours (1min avg)' ,
|
63
|
+
"h" => 'Hour (5min avg), ',
|
64
|
+
"sh" => 'Hour (1min avg)' ,
|
65
|
+
"n" => 'Half Day (5min avg)',
|
66
|
+
"sn" => 'Half Day (1min avg)',
|
67
|
+
"c" => "%s to $s",
|
68
|
+
"sc" => "%s to $s"
|
69
|
+
}
|
70
|
+
|
71
|
+
def range_arg?(t)
|
72
|
+
RANGES.keys.include? t
|
73
|
+
end
|
74
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gfspark
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Tomohito Ozaki
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-05-28 00:00:00 +09:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
prerelease: false
|
23
|
+
name: json
|
24
|
+
type: :runtime
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
prerelease: false
|
37
|
+
name: term-ansicolor
|
38
|
+
type: :runtime
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
prerelease: false
|
51
|
+
name: rake
|
52
|
+
type: :development
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
version_requirements: *id003
|
63
|
+
description: GrowthForecast on Terminal
|
64
|
+
email:
|
65
|
+
- ozaki@yuroyoro.com
|
66
|
+
executables:
|
67
|
+
- gfspark
|
68
|
+
extensions: []
|
69
|
+
|
70
|
+
extra_rdoc_files: []
|
71
|
+
|
72
|
+
files:
|
73
|
+
- .gitignore
|
74
|
+
- Gemfile
|
75
|
+
- LICENSE.txt
|
76
|
+
- README.md
|
77
|
+
- Rakefile
|
78
|
+
- bin/gfspark
|
79
|
+
- gfspark.gemspec
|
80
|
+
- lib/gfspark.rb
|
81
|
+
- lib/gfspark/app.rb
|
82
|
+
- lib/gfspark/config.rb
|
83
|
+
- lib/gfspark/connection.rb
|
84
|
+
- lib/gfspark/graph.rb
|
85
|
+
- lib/gfspark/version.rb
|
86
|
+
has_rdoc: true
|
87
|
+
homepage: http://yuroyoro.github.io/gfspark/
|
88
|
+
licenses: []
|
89
|
+
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 3
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
version: "0"
|
113
|
+
requirements: []
|
114
|
+
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 1.5.2
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: GrowthForecast Graph viewer on Terminal
|
120
|
+
test_files: []
|
121
|
+
|