flydata 0.0.1.nc1

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.
@@ -0,0 +1,88 @@
1
+ module Flydata
2
+ class Cron
3
+ FLYDATA_HOME=Flydata::HOME_DIR
4
+ CRON_TMP_PATH="#{FLYDATA_HOME}/cron_list.tmp"
5
+ CRON_BACKUP_PATH="#{FLYDATA_HOME}/cron_list.back"
6
+ LOG_PATH="#{FLYDATA_HOME}/flydata_cron.log"
7
+ ROUTINE_BASE_COMMAND="#{FLYDATA_HOME}/bin/flydata routine >> #{LOG_PATH} 2>&1"
8
+ if ENV['FLYDATA_API_HOST'] and ENV['FLYDATA_API_HOST'] != ""
9
+ ROUTINE_COMMAND="export FLYDATA_API_HOST=#{ENV['FLYDATA_API_HOST']} && #{ROUTINE_BASE_COMMAND}"
10
+ else
11
+ ROUTINE_COMMAND=ROUTINE_BASE_COMMAND
12
+ end
13
+
14
+ CRON_LINE="15 4 * * * #{ROUTINE_COMMAND}"
15
+ #CRON_LINE="* * * * * #{ROUTINE_COMMAND}"
16
+ REMOVE_OPTION="-r"
17
+
18
+ def initialize
19
+ end
20
+ def update(option=nil)
21
+ arg = option ? option : ''
22
+
23
+ # Check condition
24
+ check_crontab_command
25
+ dump_cron_setting
26
+ reagistered = check_cron_setting
27
+
28
+ # Remove mode
29
+ if arg == REMOVE_OPTION
30
+ unless reagistered
31
+ puts "Skip removing. There are no flydata jobs in crontab."
32
+ else
33
+ remove_cron_setting
34
+ puts "Updated crontab to remove the deletion of your log data."
35
+ end
36
+ # Add mode
37
+ else
38
+ if reagistered
39
+ puts "Skip register. Already cron setup done."
40
+ else
41
+ add_cron_setting
42
+ puts "Updated crontab to manage the deletion of your log data."
43
+ end
44
+ end
45
+ true
46
+ end
47
+
48
+ private
49
+ def check_crontab_command
50
+ raise "Failed to update. Crontab is not installed." unless system("which crontab > /dev/null")
51
+ end
52
+ def dump_cron_setting
53
+ system("crontab -l > #{CRON_BACKUP_PATH}")
54
+ end
55
+ def check_cron_setting
56
+ already_exist = false
57
+ File.open(CRON_BACKUP_PATH, 'r') { |file|
58
+ while l = file.gets
59
+ if l =~ /#{ROUTINE_COMMAND}/
60
+ already_exist = true
61
+ break
62
+ end
63
+ end
64
+ }
65
+ already_exist
66
+ end
67
+ def add_cron_setting
68
+ FileUtils.copy(CRON_BACKUP_PATH, CRON_TMP_PATH)
69
+ File.open(CRON_TMP_PATH, "a") { |file|
70
+ file.puts(CRON_LINE)
71
+ }
72
+ ret = system("crontab #{CRON_TMP_PATH}")
73
+ raise "Failed to register flydata routine job to crontab." unless ret
74
+ end
75
+ def remove_cron_setting
76
+ File.open(CRON_TMP_PATH, "w") { |dst|
77
+ File.open(CRON_BACKUP_PATH, 'r') { |src|
78
+ while l = src.gets
79
+ dst.puts(l) unless l =~ /#{ROUTINE_COMMAND}/
80
+ end
81
+ }
82
+ }
83
+ ret = system("crontab #{CRON_TMP_PATH}")
84
+ raise "Failed to remove flydata routine job from crontab." unless ret
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,116 @@
1
+ #!/bin/bash
2
+
3
+ # Usage:
4
+ # flydata_crontab
5
+
6
+ ######## Parameters
7
+ FLYDATA_HOME=~/".flydata"
8
+ CRON_TMP_PATH="$FLYDATA_HOME/cron_list.tmp"
9
+ CRON_BACKUP_PATH="$FLYDATA_HOME/cron_list.back"
10
+ LOG_PATH="$FLYDATA_HOME/flydata_cron.log"
11
+ ROUTINE_COMMAND="$FLYDATA_HOME/bin/flydata routine >> $LOG_PATH 2>&1"
12
+ if [[ "$FLYDATA_API_HOST" != "" ]]; then
13
+ ROUTINE_COMMAND="export FLYDATA_API_HOST=$FLYDATA_API_HOST && $ROUTINE_COMMAND"
14
+ fi
15
+ #CRON_LINE='15 4 * * *'" $ROUTINE_COMMAND"
16
+ CRON_LINE='* * * * *'" $ROUTINE_COMMAND"
17
+
18
+ ARG=$1
19
+ REMOVE_OPTION="-r"
20
+ CRON_SETTING_DONE=0 # flag
21
+
22
+
23
+ ######## Functions
24
+ check_flydata_setup_done()
25
+ {
26
+ which flydata > /dev/null
27
+ if [ "$?" -ne "0" ]; then
28
+ echo "flydata command not found. Flydata setup has not been done, yet."
29
+ exit -1
30
+ fi
31
+ if [ ! -w $FLYDATA_HOME ]; then
32
+ echo "Flydata setup has not been done, yet. Run setup command."
33
+ echo " -> flydata setup"
34
+ exit -1
35
+ fi
36
+ }
37
+
38
+ check_crontab_commnad()
39
+ {
40
+ which crontab > /dev/null
41
+ if [ "$?" -ne "0" ]; then
42
+ echo "No crontab command. Please install cron."
43
+ exit -2
44
+ fi
45
+ }
46
+
47
+ check_crond_process()
48
+ {
49
+ crond_exist=`ps aux | grep crond | grep -v grep | wc -l`
50
+ echo $crond_exist
51
+ if [ "$crond_exist" -ne "1" ]; then
52
+ echo "No crond process. Please start crond process."
53
+ exit -3
54
+ fi
55
+ }
56
+
57
+ dump_cron_setting()
58
+ {
59
+ crontab -l > $CRON_BACKUP_PATH
60
+ }
61
+
62
+ check_cron_setting()
63
+ {
64
+ CRON_SETTING_DONE=`cat $CRON_BACKUP_PATH | grep "flydata routine" | wc -l`
65
+ if [ "$?" -ne "0" ]; then
66
+ echo "Failed to check cron setting file."
67
+ exit -5
68
+ fi
69
+ }
70
+
71
+ add_cron_setting()
72
+ {
73
+ cat $CRON_BACKUP_PATH > $CRON_TMP_PATH
74
+ echo "$CRON_LINE" >> $CRON_TMP_PATH
75
+ crontab $CRON_TMP_PATH
76
+ if [ "$?" -ne "0" ]; then
77
+ echo "Failed to register flydata routine job to crontab."
78
+ exit -6
79
+ fi
80
+ }
81
+
82
+ remove_cron_setting()
83
+ {
84
+ cat "$CRON_BACKUP_PATH" | grep -v "flydata routine" > $CRON_TMP_PATH
85
+ crontab $CRON_TMP_PATH
86
+ if [ "$?" -ne "0" ]; then
87
+ echo "Failed to remove flydata routine job from crontab."
88
+ exit -7
89
+ fi
90
+ }
91
+
92
+
93
+ ######## Main
94
+ ARG="$1"
95
+ check_flydata_setup_done
96
+ check_crontab_commnad
97
+ # check_crond_process
98
+ dump_cron_setting
99
+ check_cron_setting
100
+
101
+ # Skip If add mode and registered
102
+ if [[ "$ARG" != "$REMOVE_OPTION" && $CRON_SETTING_DONE -gt 0 ]]; then
103
+ echo "Skip. Already cron setup done."
104
+ exit 0
105
+ fi
106
+
107
+ # Remove mode -> remove setting
108
+ if [ "$ARG" == "$REMOVE_OPTION" ]; then
109
+ remove_cron_setting
110
+ exit 0
111
+ fi
112
+
113
+ # Add mode -> add setting
114
+ add_cron_setting
115
+ echo "Updated crontab to manage the deletion of your log data."
116
+ exit 0
@@ -0,0 +1,20 @@
1
+ module Flydata
2
+ module Helpers
3
+ module_function
4
+ def parse_command(cmd)
5
+ klass = Flydata::Command::Base
6
+ method = cmd
7
+ if cmd.include?(':')
8
+ class_name, method = cmd.split(':')
9
+ klass = to_command_class(class_name)
10
+ end
11
+ [klass, method]
12
+ end
13
+ def to_command_class(class_name)
14
+ eval("Flydata::Command::#{class_name.camelcase}")
15
+ end
16
+ def home_directory
17
+ ENV['HOME'] || Dir.pwd
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,93 @@
1
+ module Flydata
2
+ # Directory structure
3
+ # log_dir
4
+ # - log_path
5
+ # + .flydata
6
+ # + [log_file_name]
7
+ # + trash <- temprary directory
8
+ # - [log_archived_files]
9
+ # + backup <- backup archive files when initialize
10
+ # - [log_archived_files]
11
+ class LogMonitor
12
+ FLYDATA_DIR = '.flydata'
13
+ TRASH_DIR = 'trash'
14
+ BACKUP_DIR = 'backup'
15
+ DEFAULT_DAYS_TO_TRASH = 7 #days
16
+ DEFAULT_DAYS_TO_DELETE = DEFAULT_DAYS_TO_TRASH + 7 #days
17
+
18
+ def initialize(log_path, options={})
19
+ # check arguments
20
+ raise "Cannot access to log path... #{log_path}" unless File.exist?(log_path)
21
+ @log_path = log_path
22
+ @options = options
23
+ @days_to_trash = @options[:days_to_trash] ?
24
+ @options[:days_to_trash] : DEFAULT_DAYS_TO_TRASH
25
+ @days_to_delete = @options[:days_to_delete] ?
26
+ @options[:days_to_delete] : DEFAULT_DAYS_TO_DELETE
27
+ @setup_flag = false
28
+ # initialize paths
29
+ @flydata_path = File.join(File.dirname(@log_path),
30
+ FLYDATA_DIR,
31
+ File.basename(@log_path) + ".d")
32
+ @backup_path = File.join(@flydata_path, BACKUP_DIR)
33
+ @trash_path = File.join(@flydata_path, TRASH_DIR)
34
+ end
35
+ def setup
36
+ # create directories
37
+ FileUtils.mkdir_p(@flydata_path)
38
+ FileUtils.mkdir_p(@backup_path)
39
+ # backup_files to avoid to delete non-uploaded files
40
+ backup_files
41
+ @setup_flag = true
42
+ self
43
+ end
44
+ def rotate
45
+ check_setup_done
46
+ # move files to trash
47
+ trash_files
48
+ # delete trashed files
49
+ delete_files
50
+ end
51
+
52
+ private
53
+ def check_setup_done
54
+ raise "Setup hasn't been done, yet." unless @setup_flag
55
+ end
56
+ def archived_files
57
+ Dir::glob("#{@log_path}?*")
58
+ end
59
+ def trashed_files
60
+ Dir::glob("#{File.join(@trash_path, File.basename(@log_path))}?*")
61
+ end
62
+ def backup_files
63
+ # use trash dir as checkpoint to backup initial archive files
64
+ unless File.exist?(@trash_path)
65
+ archived_files.each {|f|
66
+ puts "buckup file: #{f} -> #{@backup_path}"
67
+ FileUtils.mv(f, @backup_path)
68
+ }
69
+ FileUtils.mkdir_p(@trash_path)
70
+ end
71
+ end
72
+ def trash_files
73
+ archived_files.each {|f|
74
+ # check date and trash
75
+ if @days_to_trash.days.ago > File.stat(f).mtime
76
+ to_path = File.join(@trash_path, File.basename(f))
77
+ to_path = "#{to_path}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" if File.exist?(to_path)
78
+ puts "trash file: #{f} -> #{to_path}"
79
+ FileUtils.mv(f, File.join(@trash_path, File.basename(f)))
80
+ end
81
+ }
82
+ end
83
+ def delete_files
84
+ trashed_files.each {|f|
85
+ if @days_to_delete.days.ago > File.stat(f).mtime
86
+ file_path = File.join(@trash_path, File.basename(f))
87
+ puts "delete file: #{file_path}"
88
+ FileUtils.rm(file_path)
89
+ end
90
+ }
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,16 @@
1
+ module Hapyrus
2
+ class Proxy
3
+ attr_accessor :command_class
4
+ def run_command(method, *args)
5
+ args.flatten!
6
+ if args.size > 0
7
+ @command_class.new.send(method, *args)
8
+ else
9
+ @command_class.new.send(method)
10
+ end
11
+ end
12
+ def method_missing(method, *args)
13
+ run_command(method, args)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module Flydata
4
+ module Api
5
+ describe DataEntry do
6
+ describe '#create' do
7
+ it 'creates data entry' do
8
+ api_client = double('api_client')
9
+ api_client.stub(:post)
10
+
11
+ api = DataEntry.new(api_client)
12
+ api.create(data_port_id: 1, log_path: 'log-path')
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ module Flydata
4
+ module Command
5
+ describe Sender do
6
+ before :each do
7
+ @sender = Sender.new
8
+ end
9
+ describe '#start' do
10
+ it 'starts fluentd' do
11
+ api_client = double('api_client')
12
+ api_client.stub_chain(:data_port, :get, :[]).and_return 'active'
13
+ ApiClient.stub(:new).and_return api_client
14
+
15
+ @sender.start
16
+ end
17
+ end
18
+ describe '#stop' do
19
+ it 'stops fluentd' do
20
+ @sender.stop
21
+ end
22
+ end
23
+ describe '#restart' do
24
+ before :all do
25
+ @sender = Sender.new
26
+ @sender.start
27
+ end
28
+ it 'restart fluentd' do
29
+ @sender.restart
30
+ end
31
+ after :all do
32
+ @sender.stop
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Flydata" do
4
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'flydata'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,291 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flydata
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.nc1
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Koichi Fujikawa
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: i18n
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: activesupport
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: json
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: highline
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: fluentd
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: bundler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: jeweler
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: rspec
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: autotest
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ - !ruby/object:Gem::Dependency
175
+ name: autotest-standalone
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ - !ruby/object:Gem::Dependency
191
+ name: autotest-notification
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ! '>='
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ - !ruby/object:Gem::Dependency
207
+ name: ZenTest
208
+ requirement: !ruby/object:Gem::Requirement
209
+ none: false
210
+ requirements:
211
+ - - ! '>='
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ type: :development
215
+ prerelease: false
216
+ version_requirements: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ! '>='
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ description: FlyData Command Line Interface
223
+ email: sysadmin@flydata.co
224
+ executables:
225
+ - flydata
226
+ extensions: []
227
+ extra_rdoc_files: []
228
+ files:
229
+ - .gitignore
230
+ - .rspec
231
+ - Gemfile
232
+ - Gemfile.lock
233
+ - Rakefile
234
+ - VERSION
235
+ - bin/flydata
236
+ - flydata.gemspec
237
+ - lib/flydata.rb
238
+ - lib/flydata/api/base.rb
239
+ - lib/flydata/api/data_entry.rb
240
+ - lib/flydata/api/data_port.rb
241
+ - lib/flydata/api_client.rb
242
+ - lib/flydata/cli.rb
243
+ - lib/flydata/command/base.rb
244
+ - lib/flydata/command/crontab.rb
245
+ - lib/flydata/command/login.rb
246
+ - lib/flydata/command/restart.rb
247
+ - lib/flydata/command/routine.rb
248
+ - lib/flydata/command/sender.rb
249
+ - lib/flydata/command/setlogdel.rb
250
+ - lib/flydata/command/setup.rb
251
+ - lib/flydata/command/start.rb
252
+ - lib/flydata/command/stop.rb
253
+ - lib/flydata/credentials.rb
254
+ - lib/flydata/cron.rb
255
+ - lib/flydata/flydata_crontab.sh
256
+ - lib/flydata/helpers.rb
257
+ - lib/flydata/log_monitor.rb
258
+ - lib/flydata/proxy.rb
259
+ - spec/flydata/api/data_entry_spec.rb
260
+ - spec/flydata/command/sender_spec.rb
261
+ - spec/flydata_spec.rb
262
+ - spec/spec_helper.rb
263
+ homepage: http://flydata.co/
264
+ licenses:
265
+ - All right reserved.
266
+ post_install_message:
267
+ rdoc_options: []
268
+ require_paths:
269
+ - lib
270
+ required_ruby_version: !ruby/object:Gem::Requirement
271
+ none: false
272
+ requirements:
273
+ - - ! '>='
274
+ - !ruby/object:Gem::Version
275
+ version: '0'
276
+ segments:
277
+ - 0
278
+ hash: 1073163683650031342
279
+ required_rubygems_version: !ruby/object:Gem::Requirement
280
+ none: false
281
+ requirements:
282
+ - - ! '>'
283
+ - !ruby/object:Gem::Version
284
+ version: 1.3.1
285
+ requirements: []
286
+ rubyforge_project:
287
+ rubygems_version: 1.8.23
288
+ signing_key:
289
+ specification_version: 3
290
+ summary: FlyData CLI
291
+ test_files: []