fox 0.0.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +196 -14
  3. data/bin/fox +28 -8
  4. data/fox.gemspec +41 -3
  5. data/lib/fox.rb +23 -10
  6. data/lib/fox/cli.rb +17 -0
  7. data/lib/fox/configuration.rb +48 -0
  8. data/lib/fox/core_ext.rb +8 -0
  9. data/lib/fox/core_ext/array.rb +51 -0
  10. data/lib/fox/core_ext/hash.rb +17 -0
  11. data/lib/fox/core_ext/io_binary_read.rb +20 -0
  12. data/lib/fox/error.rb +8 -0
  13. data/lib/fox/error/errors.rb +232 -0
  14. data/lib/fox/interface/thor/all.rb +34 -0
  15. data/lib/fox/interface/thor/configuration.rb +71 -0
  16. data/lib/fox/interface/thor/create.rb +49 -0
  17. data/lib/fox/interface/thor/default.rb +67 -0
  18. data/lib/fox/interface/thor/init.rb +57 -0
  19. data/lib/fox/interface/thor/mixin/config_choice.rb +3 -3
  20. data/lib/fox/interface/thor/mixin/configuration.rb +1 -1
  21. data/lib/fox/interface/thor/mixin/database.rb +129 -0
  22. data/lib/fox/interface/thor/mixin/default.rb +6 -0
  23. data/lib/fox/interface/thor/mixin/default_model.rb +13 -0
  24. data/lib/fox/interface/thor/mixin/generators/base_generator.rb +35 -0
  25. data/lib/fox/interface/thor/mixin/generators/structure.rb +41 -0
  26. data/lib/fox/interface/thor/mixin/generators/template_loader.rb +48 -0
  27. data/lib/fox/interface/thor/mixin/history.rb +12 -0
  28. data/lib/fox/interface/thor/mixin/logger.rb +2 -2
  29. data/lib/fox/interface/thor/mixin/model.rb +19 -0
  30. data/lib/fox/interface/thor/new.thor +74 -0
  31. data/lib/fox/interface/thor/version.rb +59 -0
  32. data/lib/fox/library/choice.rb +160 -0
  33. data/lib/fox/library/logger.rb +175 -0
  34. data/lib/fox/library/project_builder.rb +83 -0
  35. data/lib/fox/library/secure_config.rb +114 -0
  36. metadata +298 -7
  37. data/lib/fox/interface/thor/version.thor +0 -33
@@ -0,0 +1,12 @@
1
+ require 'data_mapper'
2
+
3
+ # @class class History
4
+ # @brief mapper for History table, save information about commands
5
+ class History
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+ property :command, String
10
+ property :arguments, String
11
+ end # of class History
12
+
@@ -6,7 +6,7 @@ require 'thor'
6
6
  require 'andand'
7
7
 
8
8
  # Custom includes
9
- # require File.expand_path( File.dirname( __FILE__ ) + '/../../../library/logger' )
9
+ require File.expand_path( File.dirname( __FILE__ ) + '/../../../library/logger' )
10
10
 
11
11
 
12
12
  # @module module Mixin
@@ -24,7 +24,7 @@ module Mixin
24
24
  def initialize *args
25
25
  super
26
26
 
27
- @logger = ::Fox::Logger.instance
27
+ @logger = ::ClothesNetwork::Logger.instance
28
28
 
29
29
  @logger.color = options[ :colorize ]
30
30
  @logger.silent = options[ :silent ]
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # System
4
+ require 'data_mapper'
5
+
6
+
7
+ # @class class Model
8
+ # @brief mapper for Model table, save information about all created Models
9
+ class Model
10
+
11
+ include DataMapper::Resource
12
+
13
+ property :id, Serial
14
+ property :name, String
15
+ property :version, String
16
+ property :uuid, String
17
+
18
+ end # of class Model
19
+
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ # System includes
5
+ require 'ostruct'
6
+ require 'andand'
7
+ require 'tempfile'
8
+ require 'os'
9
+
10
+ # Custom includes
11
+ require File.expand_path( File.dirname( __FILE__ ) + '/mixin/logger' )
12
+ require File.expand_path( File.dirname( __FILE__ ) + '/../../library/project_builder' )
13
+
14
+
15
+ # @class New command class
16
+ # @brief Forks new paper projects
17
+ class New < Thor
18
+
19
+ # Include various partials
20
+ include Thor::Actions
21
+ include ::Mixin::Logger
22
+
23
+ class_option :'ieee-icra', :type => :boolean, :desc => "IEEE Robotics & Automation Society (ICRA)", :default => false
24
+
25
+
26
+ # @fn def new projectname {{{
27
+ # @brief Generates new project with given PROJECTNAME
28
+ desc "generate PROJECTNAME", "Creates new project PROJECTNAME"
29
+ def generate projectname
30
+
31
+ @logger.message :info, "Generating project '#{projectname.to_s}' in folder './#{projectname.to_s}'"
32
+
33
+ type = select_type
34
+ @logger.message :info, "Using #{type.to_s} type"
35
+
36
+ template = File.expand_path( File.dirname(__FILE__) + '/../../template/document/' + type.to_s + "/" + type.to_s + ".fox" )
37
+ ProjectBuilder.load( projectname.to_s, template )
38
+
39
+ end # }}}
40
+
41
+
42
+ private
43
+
44
+ no_tasks do
45
+
46
+ # @fn def select_type {{{
47
+ # @brief Checks selected type with user and returns value for further processing
48
+ def select_type
49
+
50
+ # Default containers
51
+ type = ""
52
+
53
+ # Set if default switch given
54
+ type = "ieee-icra" if( options[:'ieee-icra'] )
55
+
56
+ if type.empty?
57
+ type = ( yes?( "Use IEEE Robotics & Automation Society (ICRA) Template? [y/n]" ) ) ? ( 'ieee-icra' ) : ( '' )
58
+ end
59
+
60
+ # Post-condition check
61
+ if type.empty?
62
+ @logger.message :error, "Could not determine the type of document you want to generate"
63
+ abort
64
+ end
65
+
66
+ return type
67
+ end # }}}
68
+
69
+ end # of no_tasks do
70
+
71
+ end # of Class New
72
+
73
+
74
+ # vim:ts=2:tw=100:wm=100:syntax=ruby
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Custom includes
4
+ require File.expand_path( File.dirname(__FILE__) + '../../../version' )
5
+ require File.expand_path( File.dirname( __FILE__ ) + '/mixin/logger' )
6
+ require File.expand_path( File.dirname( __FILE__ ) + '/mixin/database' )
7
+
8
+ # @class Server command class
9
+ # @brief Implements the server command
10
+ class Version < Thor
11
+
12
+ default_task :show
13
+
14
+ include ::Mixin::Logger
15
+ include ::Mixin::Database
16
+
17
+ ## API
18
+
19
+ # @fn def show {{{
20
+ # @brief Show version string of app
21
+ desc 'show', 'Show version of this app'
22
+ def show
23
+ version = Fox::VERSION
24
+ puts version
25
+ end # }}}
26
+
27
+
28
+ # @fn def set version {{{
29
+ # @brief Set Version for default Model
30
+ desc 'set VERSION', 'Set Version for default Model'
31
+ def set version
32
+
33
+ @logger.message :info, "Running Fox Version #set for #{version}"
34
+
35
+ abort("Default model not defined! Run `fox default <ModelName>` for set default model") if !default_model_defined?
36
+
37
+ current_default_model = get_default_model
38
+
39
+ if ! ( check_if_version_available_for_model current_default_model.name, version )
40
+ available_versions = all_models.find_all do |model|
41
+ model.name == current_default_model.name
42
+ end.map(&:version).join("\n")
43
+ abort("Not Found #{version} for #{current_default_model.name}. Available Versions for #{current_default_model.name}:\n#{available_versions}")
44
+ end
45
+
46
+ set_default_model_version version
47
+ @logger.message :info, "Set Default Version #{version} for #{current_default_model.name}"
48
+ end # end of set }}}
49
+
50
+ no_tasks do
51
+
52
+ ## Actions
53
+
54
+ end # of no_tasks do
55
+
56
+ end # of Class Version
57
+
58
+
59
+ # vim:ts=2:tw=100:wm=100:syntax=ruby
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ # Custom includes
5
+ # require_relative 'logger'
6
+
7
+
8
+ class Choice
9
+
10
+ # @fn def initialize # {{{
11
+ # @brief Default constructor
12
+ def initialize
13
+ # 0 = most dislike ; 5 = most like
14
+ # This scale may have an statistical bias
15
+ @likert_scale = [
16
+ "Strongly dislike",
17
+ "Dislike",
18
+ "Neither like nor dislike",
19
+ "Like",
20
+ "Strongly like"
21
+ ]
22
+
23
+ @phrase_completion_scale = [
24
+ "Definition of not xxxxx",
25
+ "Strongly not xxxxx",
26
+ "Stupid",
27
+ "Not xxxxx at all",
28
+ "Not so xxxxx",
29
+ "Neutral",
30
+ "A little bit xxxxx",
31
+ "Rather xxxxx",
32
+ "Really xxxxx",
33
+ "Hilarious",
34
+ "The most xxxxx ever",
35
+ ]
36
+
37
+ @percent_scale = [ 0, 100 ]
38
+
39
+ end # of def initialize # }}}
40
+
41
+ # @fn def get_choice_from_bipolar question, allowed_answers = %w[ y n ] # {{{
42
+ # @brief The function ask will take a simple string query it on the CMD and wait for an answer e.g. "y" (or enter)
43
+ #
44
+ # @param [String] question String, representing the question you want to query.
45
+ # @param [Array] allowed_answers Array, representing the allowed answers
46
+ # @returns [Boolean] Boolean, true for yes, false for no
47
+ def get_choice_from_bipolar question, allowed_answers = %w[ y n ]
48
+ print "#{question.to_s} [#{allowed_answers.join(", ")}] : "
49
+ answer = STDIN.gets.to_s.chop
50
+ return true if( answer =~ %r{y}i )
51
+ return false if( answer =~ %r{n}i )
52
+ end # of def get_choice_from_bipolar question, allowed_answers = %w[ y n ] # }}}
53
+
54
+ # @fn def get_choice_from_listing question, data # {{{
55
+ # @brief The function get_choice_from_listing asks the user to answer a according to a given listing sequence
56
+ #
57
+ # @param [String] question String, representing the question which the user should be asked together with this listing.
58
+ # @param [Array] data Array, consisting of values, [ value, ... ]
59
+ #
60
+ # @returns [Integer] Integer, representing the choice the user entered
61
+ def get_choice_from_listing question, data
62
+
63
+ selection = nil
64
+
65
+ while( selection.nil? )
66
+
67
+ print "#{question.to_s} : \n"
68
+
69
+ data.each_with_index do |d, i|
70
+ printf( "(%-2i) %s\n", i, d )
71
+ end
72
+
73
+ print "\n>> "
74
+ selection = ( ( STDIN.gets ).chomp )
75
+
76
+ end
77
+
78
+ selection
79
+ end # of def get_choice_from_listing }}}
80
+
81
+ # @fn def get_choice_from_range question, from = @percent_scale.first, to = @percent_scale.last # {{{
82
+ # @brief The function takes a numerical range argument and asks the user to select from it
83
+ #
84
+ # @param [String] question String, representing the question which the user should be asked together with this listing.
85
+ # @param [Integer] from Integer, representing the start of the numerical range
86
+ # @param [Integer] to Integer, representing the end of the numerical range
87
+ # @returns [Integer] Integer, representing the desired percentage
88
+ def get_choice_from_range question, from = @percent_scale.first, to = @percent_scale.last
89
+ selection = nil
90
+ finished = false
91
+
92
+ while( not finished )
93
+
94
+ print "#{question.to_s} "
95
+
96
+ printf( "(%i-%i) : ", from, to )
97
+ STDOUT.flush
98
+ selection = ( ( STDIN.gets ).chomp )
99
+
100
+ if( selection == "" )
101
+ # puts "The selection needs to be of type integer!"
102
+ finished = true
103
+ else
104
+ if( selection.tr( "0-9", "" ) == "" )
105
+ selection = selection.to_i
106
+ if( selection >= from and selection <= to )
107
+ finished = true
108
+ else
109
+ puts "The selection needs to be inside the range from #{from.to_s} to #{to.to_s}!"
110
+ end
111
+ else
112
+ puts "The input can only be of type integer"
113
+ end
114
+ end
115
+
116
+ end # of while
117
+
118
+ selection
119
+ end # of def get_choice_from_range }}}
120
+
121
+ # @fn def ask question, type # {{{
122
+ # @brief The ask function takes a question and a type argument of the desired question type (e.g. :likert, :phrase, :percent)
123
+ #
124
+ # @param [String] question String, representing the question which the user should be asked together with this listing.
125
+ # @param [Symbol] type Symbol, one of either: :likert, :phrase, :percent, :bipolar
126
+ def ask question, type
127
+
128
+ allowed = [:bipolar, :likert, :phrase, :percent]
129
+ answer = nil
130
+
131
+ # Pre-condition check # {{{
132
+ raise ArgumentError, "The type (#{type.to_s}) is not among the allowed types (#{allowed.join(", ")})" unless( allowed.include?( type ) )
133
+ raise ArgumentError, "The question needs to be of type string but is (#{question.class.to_s})" unless( question.is_a?(String) )
134
+ # }}}
135
+
136
+ # Main
137
+ case type
138
+ when :bipolar
139
+ answer = get_choice_from_bipolar( question )
140
+ when :likert
141
+ answer = get_choice_from_listing( question, @likert_scale )
142
+ when :phrase
143
+ answer = get_choice_from_listing( question, @phrase_completion_scale )
144
+ when :percent
145
+ answer = get_choice_from_range( question )
146
+ end
147
+
148
+ # Post condition check
149
+
150
+ answer
151
+ end # }}}
152
+
153
+ end # of class Choice
154
+
155
+
156
+ # Direct Invocation
157
+ if __FILE__ == $0
158
+ end # of if __FILE__ == $0
159
+
160
+ # vim:ts=2:tw=100:wm=100
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ # System
5
+ require 'ostruct'
6
+ require 'singleton'
7
+
8
+ # XMPP (jabber) support
9
+ # require 'xmpp4r'
10
+ # require 'xmpp4r-simple'
11
+ # require 'xmpp4log'
12
+
13
+ # AMQP support
14
+ # equire 'amqp'
15
+
16
+
17
+ module ClothesNetwork
18
+
19
+ class Logger
20
+
21
+ include Singleton
22
+
23
+ # @fn def initialize options = nil # {{{
24
+ # @brief Default constuctor
25
+ def initialize
26
+
27
+ @symbols = {
28
+ :unknown => [ "(UU)", "LightBlue" ],
29
+ :trace => [ "(**)", "LightBlue" ],
30
+ :debug => [ "(++)", "LightBlue" ],
31
+ :info => [ "(--)", "Brown" ],
32
+ :notice => [ "(==)", "Brown" ],
33
+ :warning => [ "(WW)", "Yellow" ],
34
+ :error => [ "(EE)", "LightRed" ],
35
+ :critical => [ "(!!)", "LightRed" ],
36
+ :alert => [ "(!!)", "LightRed" ],
37
+ :fatal => [ "(!!)", "LightRed" ],
38
+
39
+ :success => [ "(II)", "LightGreen" ],
40
+ :question => [ "(??)", "LightCyan" ]
41
+ }
42
+
43
+ @color = true
44
+ @silent = false
45
+
46
+ # # Determine what levels are relevant for XMPP based on @options.xmpp_message_level
47
+ # levels = @symbols.keys.to_a
48
+ # @xmpp_relevant = levels.slice( levels.index( @options.xmpp_message_level ), levels.length ) unless( @xmpp.nil? )
49
+
50
+ # # Handle XMPP Setup
51
+ # @xmpp = nil
52
+
53
+ # if( @options.xmpp )
54
+ # # FIXME: Re-write wrapper to a more proper form
55
+ # # @xmpp = XMPPLogger.new( @options.server_xmpp_id, @options.server_xmpp_password, @options.client_xmpp_ids )
56
+ # # @xmpp.level = Logger::ERROR # default level on which messages will be sent
57
+ # # @xmpp.error "Houston, we have a problem"
58
+
59
+ # @xmpp = Jabber::Simple.new( @options.server_xmpp_id, @options.server_xmpp_password )
60
+ # end
61
+ end # }}}
62
+
63
+ # @fn def colorize color, message # {{{
64
+ # @brief The function colorize takes a message and wraps it into standard color commands such as for baih.
65
+ #
66
+ # @param [String] color The colorname in plain english. e.g. "LightGray", "Gray", "Red", "BrightRed"
67
+ # @param [String] message The message which should be wrapped
68
+ #
69
+ # @return [String] Colorized message string
70
+ #
71
+ # @note This might not work for your terminal
72
+ #
73
+ # Black 0;30 Dark Gray 1;30
74
+ # Blue 0;34 Light Blue 1;34
75
+ # Green 0;32 Light Green 1;32
76
+ # Cyan 0;36 Light Cyan 1;36
77
+ # Red 0;31 Light Red 1;31
78
+ # Purple 0;35 Light Purple 1;35
79
+ # Brown 0;33 Yellow 1;33
80
+ # Light Gray 0;37 White 1;37
81
+ #
82
+ def colorize color, message
83
+
84
+ colors = {
85
+ "Gray" => "\e[1;30m",
86
+ "LightGray" => "\e[0;37m",
87
+ "Cyan" => "\e[0;36m",
88
+ "LightCyan" => "\e[1;36m",
89
+ "Blue" => "\e[0;34m",
90
+ "LightBlue" => "\e[1;34m",
91
+ "Green" => "\e[0;32m",
92
+ "LightGreen" => "\e[1;32m",
93
+ "Red" => "\e[0;31m",
94
+ "LightRed" => "\e[1;31m",
95
+ "Purple" => "\e[0;35m",
96
+ "LightPurple" => "\e[1;35m",
97
+ "Brown" => "\e[0;33m",
98
+ "Yellow" => "\e[1;33m",
99
+ "White" => "\e[1;37m",
100
+ "NoColor" => "\e[0m"
101
+ }
102
+
103
+ raise ArgumentError, "Function arguments cannot be nil" if( color.nil? or message.nil? )
104
+ raise ArgumentError, "Unknown color" unless( colors.keys.include?( color ) )
105
+
106
+ colors[ color ] + message + colors[ "NoColor" ]
107
+ end # of def colorize }}}
108
+
109
+ # @fn def message level, msg, colorize = @options.colorize # {{{
110
+ # @brief The function message will take a message as argument as well as a level (e.g.
111
+ # "info", "ok", "error", "question", "debug") which then would print ( "(--) msg..", "(II)
112
+ # msg..", "(EE) msg..", "(??) msg..")
113
+ #
114
+ # @param [Symbol] level Ruby symbol, can either be :info, :success, :error or :question
115
+ # @param [String] msg String, which represents the message you want to send to stdout (info, ok, question) stderr (error)
116
+ #
117
+ # Helpers: colorize
118
+ #
119
+ def message level, msg #, colorize = @options.colorize, silent = @options.silent
120
+
121
+ # return if( silent )
122
+
123
+ raise ArugmentError, "Can't find the corresponding symbol for this message level (#{level.to_s}) - is the spelling wrong?" unless( @symbols.key?( level ) )
124
+
125
+ print = []
126
+
127
+ output = ( level == :error ) ? ( "STDERR.puts" ) : ( "STDOUT.puts" )
128
+ print << output
129
+ print << "colorize(" if( @color )
130
+ print << "\"" + @symbols[ level ].last + "\"," if( @color )
131
+ print << "\"#{@symbols[ level ].first.to_s} #{msg.to_s}\""
132
+ print << ")" if( @color )
133
+
134
+ print.clear if( @silent )
135
+
136
+ eval( print.join( " " ) )
137
+
138
+ # # Send messages also to XMPP clients if activated and in level of interest
139
+ # if( @options.xmpp )
140
+
141
+ # @options.client_xmpp_ids.each do |address|
142
+ # next unless( @xmpp_relevant.include?( level ) )
143
+
144
+ # @xmpp.deliver( address, @symbols[level].first.to_s + " " + msg.to_s )
145
+ # end
146
+ # end
147
+
148
+ # # Send messages also to AMQP queue if activated and in the level of interest
149
+ # if( @options.amqp )
150
+
151
+ # EventMachine.next_tick do
152
+ # AMQP.channel ||= AMQP::Channel.new(AMQP.connection)
153
+
154
+ # # Durable -> http://rubydoc.info/github/ruby-amqp/amqp/master/AMQP/Channel
155
+ # AMQP.channel.queue("#{@options.amqp_server_routing_key_base.to_s}.logger", :durable => true)
156
+
157
+ # 3.times do |i|
158
+ # puts "[auth][after_fork/amqp] Publishing a warmup message ##{i}"
159
+
160
+ # AMQP.channel.default_exchange.publish( @symbols[level].first.to_s + " " + msg.to_s, :routing_key => "#{@options.amqp_server_routing_key_base.to_s}.logger")
161
+ # end # of 3.times
162
+ # end # of EventMachine
163
+
164
+ # end # of if( @options.amqp )
165
+
166
+ end # of def message }}}
167
+
168
+ attr_accessor :color, :silent
169
+
170
+ end # of class Logger
171
+
172
+ end # of module ClothesNetwork
173
+
174
+
175
+ # vim:ts=2:tw=100:wm=100