mines 0.0.1.alpha → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/mines CHANGED
@@ -2,16 +2,69 @@
2
2
  # coding: utf-8
3
3
 
4
4
  require 'thor'
5
- require_relative '../lib/generators/application'
5
+ require_relative '../lib/utilities'
6
+ require_relative '../lib/logging'
7
+ require_relative '../lib/mines'
8
+
9
+ # require all generators in lib
10
+ mines_root = File.expand_path(File.dirname(__FILE__)+'/..')
11
+ Dir[mines_root+'/lib/generators/*.rb'].each {|file| require file }
12
+
6
13
  module Mines
14
+
15
+ # The mines executable. It subclasses Thor and
16
+ # invocates generators according to parameters
7
17
  class Cli < Thor
18
+
19
+ include Logging
20
+
21
+ def initialize *args
22
+ super
23
+ end
24
+
25
+
8
26
  desc "new APP_NAME", "Create Application APP_NAME"
27
+ # Define the 'new' action. Invocate the new generator
28
+ # @param name The name of the new application
9
29
  def new(name)
10
- puts "Create App #{name}"
11
30
  ARGV.shift
31
+ log.debug "command 'new' with arguments: #{ARGV.join(', ')}"
12
32
  Generator::Application.start ARGV
13
33
  end
34
+
35
+ # help
36
+ def help *args
37
+ if args.empty?
38
+ log.debug "command 'help' with no arguments"
39
+ else
40
+ log.debug "command 'help' with arguments: #{args.join(', ').to_s}"
41
+ end
42
+ puts "Summary:"
43
+ super
44
+ puts "Now print my help :)\nYeah!"
45
+ end
46
+
47
+ # generate
48
+ desc "generate [twitter|network|process|metrics] NAME", "Create a twitter or network or process or metrics miner"
49
+ #method_option :evented, :type => :boolean, :default => false
50
+ # generate a miner
51
+ def generate(type,name)
52
+ Mines.mines_app_check #TODO Test
53
+ types = %w{twitter network process metrics}
54
+ unless types.include? type
55
+ puts "The type of the miner could be either twitter or network or process or metrics"
56
+ puts "you typed: #{type}"
57
+ exit 0
58
+ end
59
+ puts "Generate a #{type} miner with name: #{name}"
60
+
61
+ Generator::Miner.start [type, name]
62
+ end
14
63
  end
15
64
  end
16
65
 
66
+ # Check if 'mines' is invoked in the root directory of a Mines App
67
+ #Mines.mines_app_check #TODO This code can not be here
68
+
69
+ # Start client
17
70
  Mines::Cli.start ARGV
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+
3
+ # This module is providing the configuration DSL
4
+ module Application
5
+ # we don't want to instantiate this class - it's a singleton,
6
+ # so just keep it as a self-extended module
7
+ extend self
8
+
9
+ # Appdata provides a basic single-method DSL with .parameter method
10
+ # being used to define a set of available settings.
11
+ # This method takes one or more symbols, with each one being
12
+ # a name of the configuration option.
13
+ def parameter(*names)
14
+ names.each do |name|
15
+ attr_accessor name
16
+
17
+ # For each given symbol we generate accessor method that sets option's
18
+ # value being called with an argument, or returns option's current value
19
+ # when called without arguments
20
+ define_method name do |*values|
21
+ value = values.first
22
+ value ? self.send("#{name}=", value) : instance_variable_get("@#{name}")
23
+ end
24
+ end
25
+ end
26
+
27
+ # And we define a wrapper for the configuration block, that we'll use to set up
28
+ # our set of options
29
+ def config(&block)
30
+ instance_eval &block
31
+ end
32
+ end
33
+
34
+ require_relative '../config/application'
35
+
36
+ begin
37
+ require './config/application'
38
+ rescue
39
+ puts red "Warning: Configuration file ./config/application.rb is missing"
40
+ end
@@ -0,0 +1,43 @@
1
+ # coding: utf-8
2
+
3
+ # This module is providing the configuration DSL
4
+ module Application
5
+ # we don't want to instantiate this class - it's a singleton,
6
+ # so just keep it as a self-extended module
7
+ extend self
8
+
9
+ # Appdata provides a basic single-method DSL with .parameter method
10
+ # being used to define a set of available settings.
11
+ # This method takes one or more symbols, with each one being
12
+ # a name of the configuration option.
13
+ def parameter(*names)
14
+ names.each do |name|
15
+ attr_accessor name
16
+
17
+ # For each given symbol we generate accessor method that sets option's
18
+ # value being called with an argument, or returns option's current value
19
+ # when called without arguments
20
+ define_method name do |*values|
21
+ value = values.first
22
+ value ? self.send("#{name}=", value) : instance_variable_get("@#{name}")
23
+ end
24
+ end
25
+ end
26
+
27
+ # And we define a wrapper for the configuration block, that we'll use to set up
28
+ # our set of options
29
+ def config(&block)
30
+ instance_eval &block
31
+ end
32
+ end
33
+
34
+
35
+ # Load default configuration
36
+ require_relative '../config/application'
37
+
38
+ # Load user's configuration
39
+ begin
40
+ require './config/application'
41
+ rescue Exception
42
+ puts red "Warning: Configuration file ./config/application.rb is missing"
43
+ end
@@ -1,25 +1,49 @@
1
1
  # coding: utf-8
2
2
 
3
3
  require 'thor'
4
- module Generator
4
+ require 'colored'
5
+ require_relative '../logging'
6
+
7
+ # The Generator module is the namespace of all generators
8
+ # Namely:
9
+ # - Application
10
+ # - Miner
11
+ module Mines::Generator
12
+
13
+ # Application Generator creates the default file structure.
14
+ # Accepts as an argument the name of the new application. A new directory with this name will be created
5
15
  class Application < Thor::Group
6
16
  include Thor::Actions
17
+ include Mines::Logging
7
18
 
8
- desc "new APP_NAME"
9
-
10
19
  # Define arguments and options
11
20
  argument :name
12
-
21
+
22
+ # This is needed by thor. Returns the source root directory.
13
23
  def self.source_root
14
24
  File.dirname(__FILE__)
15
- puts File.dirname(__FILE__)
16
25
  end
17
26
 
27
+ # Create the default directory structure
28
+ # - Directories: miners, lib, log, config
29
+ # - Files: TODO
30
+ # also prints appropriate messages
18
31
  def create_directory_structure
32
+ log.info "Creating directory structure in dir: " + name
19
33
  empty_directory name
20
34
  empty_directory name + "/miners"
21
35
  empty_directory name + "/lib"
22
36
  empty_directory name + "/log"
37
+ empty_directory name + "/config"
38
+ template "templates/application_config.erb", "#{name}/config/application.rb"
39
+ puts "Application created successfully! ".green
40
+ print "Type "
41
+ print "'cd #{name}' ".yellow
42
+ print "to go to the applications root directory, and then "
43
+ print "'mines help' ".yellow
44
+ puts "to see all available commands and options."
23
45
  end
24
- end
25
- end
46
+
47
+ end # class
48
+
49
+ end # module
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+
3
+ require 'thor'
4
+ require_relative '../logging'
5
+
6
+ module Mines::Generator
7
+
8
+ # Miner Generator generates files with boilerblate code
9
+ # in the miners directory. According to arguments it generates the
10
+ # following types of miners:
11
+ # - Network
12
+ # - Process
13
+ # - Metrics
14
+ class Miner < Thor::Group
15
+ include Thor::Actions
16
+ include Mines::Logging
17
+
18
+ # Define arguments and options
19
+ argument :type, :desc => "The type of the miner, [Network,Process,Metrics]", :required => true
20
+ argument :name, :desc => "The name of the miner", :required => true
21
+ #class_option :evented, :type => :boolean, :default => false, :lazy_default => true
22
+
23
+ # Define the source template root
24
+ def self.source_root
25
+ File.dirname(__FILE__)
26
+ end
27
+
28
+ # Use the appropriate template file according to type
29
+ # and put the generated file in miners directory
30
+ def create_miner_file
31
+ puts "Copy miner template"
32
+ #puts options[:evented]
33
+ template "templates/#{type}_miner.erb", "miners/#{name}.rb"
34
+ end
35
+
36
+ end # class
37
+
38
+ end # module
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ ## Configuration file for your app
3
+
4
+ ## Declare the configuration parameters you want to use
5
+ Application.config do
6
+ parameter :var1
7
+ parameter :var2
8
+ parameter :var3
9
+ end
10
+
11
+ ## Change their values
12
+ Application.config do
13
+ var1 "value"
14
+ var2 ['one','two','three']
15
+ var3 { :one=>1, :two=>2 }
16
+ end
17
+
18
+ ## Usage example
19
+ # puts Application.var1
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require 'mines'
5
+
6
+ log_name :<%= name %>
7
+
@@ -0,0 +1,10 @@
1
+ # coding: utf-8
2
+
3
+ module Mines::Help
4
+ class << self
5
+ attr_accessor :new, :generate
6
+ def configure
7
+ yield self
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,69 @@
1
+ # coding: utf-8
2
+
3
+ require 'logger'
4
+
5
+ # Configuration
6
+ require_relative 'configuration'
7
+
8
+ #require_relative 'application' # needed by config/application
9
+
10
+ # ./config/application may not have been created yet
11
+ #begin
12
+ # require './config/application'
13
+ #rescue Exception => e
14
+ # require_relative '../config/application'
15
+ #end
16
+
17
+ unless defined?(Application.logname).nil?
18
+ @log ||= Logger.new "log/#{Application.logname}"
19
+ else
20
+ @log ||= Logger.new 'log/mines.log'
21
+ end
22
+
23
+ @log.datetime_format= "%H:%M:%S"
24
+ @log.formatter = proc do |severity, datetime, progname, msg|
25
+ "#{severity} #{datetime} #{msg}\n"
26
+ end
27
+
28
+ def log_name name
29
+ @log ||= Logger.new 'log/#{name}.log'
30
+ @log.datetime_format= "%H:%M:%S"
31
+ @log.formatter = proc do |severity, datetime, progname, msg|
32
+ "#{severity} #{datetime} #{msg}\n"
33
+ end
34
+ end
35
+
36
+ =begin
37
+
38
+ module Mines
39
+
40
+ # Use this module by including it in a class,
41
+ # it defines the log method that instantiates a logger if it does not already exist
42
+ # Reads the global configuration for options
43
+ module Logging
44
+
45
+ # instantiates a logger if it does not already exist or
46
+ # it returns the existing logger
47
+ def log
48
+ if defined?(@log).nil?
49
+ log_device = ""
50
+ if not defined?(Application.log).nil?
51
+ log_device = Application.log
52
+ elsif Dir.exists?('log')
53
+ log_device ='log/mines.log'
54
+ else
55
+ log_device = STDOUT
56
+ end
57
+ @log = Logger.new log_device
58
+ @log.datetime_format= "%H:%M:%S"
59
+ @log.formatter = proc do |severity, datetime, progname, msg|
60
+ "#{msg}\n".yellow
61
+ end
62
+ end
63
+ @log
64
+ end # end def
65
+ end # end module
66
+ end # end module
67
+
68
+ =end
69
+
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+
3
+ #require 'bundler/setup'
4
+ require_relative 'redis_store' # Redis Queues, etc
5
+ require_relative 'utilities' # Utilities
6
+ require_relative 'configuration' # Configuration
7
+ require_relative 'logging' # Logging
8
+
@@ -0,0 +1,135 @@
1
+ # coding: utf-8
2
+
3
+ require 'redis'
4
+ require 'hiredis'
5
+
6
+ def keygen
7
+ Time.now.strftime("ts:%Y:%m:%d:%H:%M")
8
+ end
9
+
10
+ class RedisConnection
11
+ attr_reader :redis
12
+ def initialize *args
13
+ #@key= key
14
+ $redis ||= Redis.new(:path => "/tmp/redis.sock",:driver => :hiredis)
15
+ @redis = $redis
16
+ # puts "Connected to Redis"
17
+ end # end initialize
18
+
19
+ def counters
20
+ @redis.hgetall "counters"
21
+ end
22
+ end
23
+
24
+ class MessageQueue < RedisConnection
25
+ attr_reader :key
26
+
27
+ def initialize key
28
+ @key = key
29
+ super
30
+ end
31
+
32
+ def pop()
33
+ @redis.blpop(@key)[1]
34
+ end # end pop
35
+
36
+ def push(item)
37
+ redis.pipelined do
38
+ @redis.hincrby "counters", @key, 1
39
+ #@redis.hincrby "ts:counters", keygen+"_count", 1
40
+ @redis.rpush(@key, item )
41
+ end
42
+ end # end push
43
+
44
+ def del
45
+ @redis.del @key
46
+ end
47
+
48
+ def size
49
+ @redis.llen @key
50
+ end
51
+
52
+ def info
53
+ out = "items in list:".ljust(25) + size.to_s + "\n"
54
+ out += "number of keys:".ljust(25) + @redis.dbsize.to_s + "\n"
55
+ %w{ used_memory_human used_memory_peak_human total_commands_processed}.each do |w|
56
+ out += "#{w.gsub("_", " ")}:".ljust(25)
57
+ out += @redis.info[w]
58
+ out += "\n"
59
+ end
60
+ return out
61
+ end
62
+
63
+ def to_s
64
+ @key
65
+ end
66
+
67
+ end
68
+
69
+
70
+ class ObjectQueue < MessageQueue
71
+
72
+ def pop()
73
+ Marshal.load(@redis.blpop(@key)[1])
74
+ end # end pop
75
+
76
+ def push(item)
77
+ redis.pipelined do
78
+ @redis.hincrby "counters", @key, 1
79
+ #@redis.incr(@key+"_count")
80
+ #@redis.incr(keygen+"_count")
81
+ @redis.rpush(@key, Marshal.dump(item) )
82
+ end
83
+ end # end push
84
+ end
85
+
86
+
87
+ class Counter < RedisConnection
88
+ attr_reader :key
89
+
90
+ def initialize key
91
+ @key = key
92
+ super
93
+ end
94
+
95
+ def incr
96
+ @redis.hincrby "counters", @key, 1
97
+ end
98
+
99
+ def del
100
+ @redis.hdel "counters", @key
101
+ end
102
+
103
+ def to_s
104
+ @redis.hget "counters", @key
105
+ end
106
+ end
107
+
108
+ class MessageChannel < RedisConnection
109
+ attr_reader :channel
110
+
111
+ def initialize channel
112
+ @channel = channel
113
+ super
114
+ end
115
+
116
+ def subscribe &proc
117
+ @redis.subscribe @channel do |on|
118
+ on.message &proc
119
+ end
120
+ end
121
+
122
+ def publish message
123
+ redis.pipelined do
124
+ @redis.hincrby "counters", @channel, 1
125
+ #@redis.hincrby "ts:counters", keygen+"_count", 1
126
+ @redis.publish(@channel, message )
127
+ end
128
+ end
129
+
130
+ def to_s
131
+ @channel
132
+ end
133
+
134
+ end
135
+
@@ -0,0 +1,111 @@
1
+ # coding: utf-8
2
+
3
+ require 'colored'
4
+
5
+ def green(text); "\033[32m#{text}\033[0m" end
6
+ def blue(text); "\033[34m#{text}\033[0m" end
7
+ def red(text); "\033[31m#{text}\033[0m" end
8
+ def yellow(text); "\033[33m#{text}\033[0m" end
9
+
10
+ module Mines
11
+ extend self
12
+
13
+ # Check if mines is executed inside a mines application directory
14
+ def in_app_root?
15
+ # simply check if basic dirs exist
16
+ %w{ miners lib log config config/application.rb}.each do |file|
17
+ return false if not File.exists?(file)
18
+ end
19
+ return true
20
+ end
21
+
22
+ # Exit if mines is invokated outside application root
23
+ def mines_app_check
24
+ if not in_app_root?
25
+ print "It seems your current directory: "
26
+ puts File.expand_path('.').yellow
27
+ puts "does not contains a Mines application."
28
+ puts "You can create one by invoking: " + "mines new APPNAME".blue.bold
29
+ exit 0
30
+ end
31
+ end
32
+ end
33
+
34
+
35
+ module Mines
36
+ extend self
37
+
38
+ # Examines if a gem axists
39
+ #
40
+ # @param gem [String] the gem's name
41
+ # @return [Boolean] If gem exists or not
42
+ def gem_exists? gem
43
+ ! Gem::Specification.find_all_by_name(gem).empty?
44
+ end
45
+
46
+ end
47
+
48
+ def print_tweet(user, text)
49
+ width = Integer(`tput cols`) - 18
50
+ sum = 0
51
+ print user.center(16).blue.bold
52
+ text.split.each do |word|
53
+ if (sum + word.size >= width)
54
+ puts ""
55
+ print "".ljust 16
56
+ sum=0
57
+ end
58
+ sum+=word.size+1
59
+ if word.include?("http")
60
+ print word.cyan.underline
61
+ elsif word.start_with? "@"
62
+ print word.blue.bold
63
+ elsif word.start_with? "#"
64
+ print yellow word
65
+ else
66
+ print word
67
+ end
68
+ print " "
69
+ end
70
+ puts ""
71
+ end
72
+
73
+ # TODO Is this still needed?
74
+ def ago_time(time)
75
+ ago = Time.now - time
76
+ if ago < 3600
77
+ return "#{ago.div(1)} minutes ago"
78
+ elsif ago < 3600 * 12
79
+ return "#{ago.div(3600)} hours ago"
80
+ elsif ago < 3600 * 24
81
+ return "Yesterday"
82
+ elsif ago < 3600 * 24 * 7
83
+ return "#{time.strftime('%A')}"
84
+ else
85
+ return "#{time.strftime('%A %-d %B %Y')}"
86
+ end
87
+ end
88
+
89
+ module Mines
90
+ module Utilities
91
+ extend self
92
+
93
+ def print_command(command, text)
94
+ width = Integer(`tput cols`) - 22
95
+ sum = 0
96
+ print " "+command.ljust(20).blue.bold
97
+ text.split.each do |word|
98
+ if (sum + word.size >= width)
99
+ puts ""
100
+ print "".ljust 22
101
+ sum=0
102
+ end
103
+ sum+=word.size+1
104
+ print " "
105
+ print word
106
+ end # end text.split
107
+ puts ""
108
+ end # end def
109
+
110
+ end # end module
111
+ end # end module
metadata CHANGED
@@ -1,16 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mines
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha
5
- prerelease: 6
4
+ version: 0.0.1
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Panayiotis Vlantis
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-27 00:00:00.000000000 Z
12
+ date: 2013-09-08 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
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: minitest
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
14
62
  - !ruby/object:Gem::Dependency
15
63
  name: thor
16
64
  requirement: !ruby/object:Gem::Requirement
@@ -27,6 +75,70 @@ dependencies:
27
75
  - - ! '>='
28
76
  - !ruby/object:Gem::Version
29
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: colored
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: redis
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: hiredis
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
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: twitter
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
30
142
  description: Ruby in Mines is a framework for creating data mining application prototypes
31
143
  that focus on processing near real-time human generated content.
32
144
  email: p.vlantis@di.uoa.gr
@@ -35,9 +147,19 @@ executables:
35
147
  extensions: []
36
148
  extra_rdoc_files: []
37
149
  files:
150
+ - lib/logging.rb
151
+ - lib/utilities.rb
152
+ - lib/mines.rb
153
+ - lib/redis_store.rb
154
+ - lib/help.rb
155
+ - lib/application.rb
156
+ - lib/configuration.rb
38
157
  - lib/generators/application.rb
158
+ - lib/generators/miner.rb
159
+ - lib/generators/templates/process_miner.erb
160
+ - lib/generators/templates/application_config.erb
39
161
  - bin/mines
40
- homepage:
162
+ homepage: https://github.com/panayiotis/mines
41
163
  licenses:
42
164
  - MIT
43
165
  post_install_message:
@@ -54,9 +176,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
176
  required_rubygems_version: !ruby/object:Gem::Requirement
55
177
  none: false
56
178
  requirements:
57
- - - ! '>'
179
+ - - ! '>='
58
180
  - !ruby/object:Gem::Version
59
- version: 1.3.1
181
+ version: '0'
60
182
  requirements: []
61
183
  rubyforge_project:
62
184
  rubygems_version: 1.8.25
@@ -64,3 +186,4 @@ signing_key:
64
186
  specification_version: 3
65
187
  summary: Data mining application framework.
66
188
  test_files: []
189
+ has_rdoc: