melissadata 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +31 -0
- data/Gemfile.lock +69 -0
- data/Guardfile +6 -0
- data/README.md +5 -0
- data/Rakefile +47 -0
- data/Vagrantfile +17 -0
- data/bin/md +4 -0
- data/bin/md-rpc +9 -0
- data/bin/md-server +18 -0
- data/bin/melissadata +4 -0
- data/lib/md.rb +4 -0
- data/lib/melissadata.rb +2 -0
- data/lib/melissadata/cli.rb +45 -0
- data/lib/melissadata/command.rb +9 -0
- data/lib/melissadata/command/base.rb +104 -0
- data/lib/melissadata/command/helpers.rb +12 -0
- data/lib/melissadata/command/package.rb +83 -0
- data/lib/melissadata/constants.rb +14 -0
- data/lib/melissadata/env.rb +92 -0
- data/lib/melissadata/errors.rb +83 -0
- data/lib/melissadata/melissadata.rb +164 -0
- data/lib/melissadata/native_object.rb +19 -0
- data/lib/melissadata/native_object/address.rb +124 -0
- data/lib/melissadata/native_object/base.rb +79 -0
- data/lib/melissadata/native_object/client.rb +33 -0
- data/lib/melissadata/native_object/email.rb +61 -0
- data/lib/melissadata/native_object/geo.rb +61 -0
- data/lib/melissadata/native_object/ip_locator.rb +41 -0
- data/lib/melissadata/native_object/name.rb +74 -0
- data/lib/melissadata/native_object/phone.rb +96 -0
- data/lib/melissadata/prev/command_old.rb +80 -0
- data/lib/melissadata/prev/shared_objects.rb +54 -0
- data/lib/melissadata/rpc.rb +39 -0
- data/lib/melissadata/version.rb +3 -0
- data/melissadata.gemspec +40 -0
- data/pkg/melissa-data-0.0.1.gem +0 -0
- data/pkg/melissa-data-0.0.2.gem +0 -0
- data/pkg/melissa-data-0.0.3.gem +0 -0
- data/pkg/melissadata-0.0.1.gem +0 -0
- data/spec/locales/en.yml +8 -0
- data/spec/melissadata/cli_spec.rb +34 -0
- data/spec/melissadata/command/package_spec.rb +22 -0
- data/spec/melissadata/env_spec.rb +55 -0
- data/spec/spec_helper.rb +33 -0
- data/templates/config.rb +20 -0
- data/templates/locales/en.yml +4 -0
- metadata +316 -0
data/Gemfile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
# #############################################################################
|
6
|
+
# # Dependencies in this Gemfile are managed through the gemspec. Add/remove
|
7
|
+
# # depenencies there, rather than editing this file ex:
|
8
|
+
# #
|
9
|
+
# # Gem::Specification.new do |s|
|
10
|
+
# # ...
|
11
|
+
# # s.add_dependency("sinatra")
|
12
|
+
# # s.add_development_dependency("rack-test")
|
13
|
+
# # end
|
14
|
+
# #
|
15
|
+
# #############################################################################
|
16
|
+
# source "http://rubygems.org"
|
17
|
+
|
18
|
+
# project_dir = File.expand_path('..', __FILE__)
|
19
|
+
# gemspec_path = File.expand_path('melissa-data.gemspec', project_dir)
|
20
|
+
|
21
|
+
# #
|
22
|
+
# # Setup gemspec dependencies
|
23
|
+
# #
|
24
|
+
|
25
|
+
# gemspec = eval(File.read(gemspec_path))
|
26
|
+
# gemspec.dependencies.each do |dep|
|
27
|
+
# group = dep.type == :development ? :development : :default
|
28
|
+
# gem dep.name, dep.requirement, :group => group
|
29
|
+
# end
|
30
|
+
# gem(gemspec.name, gemspec.version, :path => project_dir)
|
31
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
melissadata (0.0.1)
|
5
|
+
activesupport
|
6
|
+
awesome_print
|
7
|
+
cloudfiles
|
8
|
+
i18n
|
9
|
+
msgpack-rpc
|
10
|
+
multi_json
|
11
|
+
thor
|
12
|
+
yajl-ruby
|
13
|
+
|
14
|
+
GEM
|
15
|
+
remote: http://rubygems.org/
|
16
|
+
specs:
|
17
|
+
activesupport (3.0.9)
|
18
|
+
awesome_print (0.4.0)
|
19
|
+
cloudfiles (1.4.17)
|
20
|
+
mime-types (>= 1.16)
|
21
|
+
columnize (0.3.4)
|
22
|
+
diff-lcs (1.1.2)
|
23
|
+
growl (1.0.3)
|
24
|
+
guard (0.5.1)
|
25
|
+
thor (~> 0.14.6)
|
26
|
+
guard-rspec (0.4.0)
|
27
|
+
guard (>= 0.4.0)
|
28
|
+
i18n (0.6.0)
|
29
|
+
iobuffer (1.0.0)
|
30
|
+
linecache (0.46)
|
31
|
+
rbx-require-relative (> 0.0.4)
|
32
|
+
mime-types (1.16)
|
33
|
+
msgpack (0.4.5)
|
34
|
+
msgpack-rpc (0.4.5)
|
35
|
+
msgpack (>= 0.4.4)
|
36
|
+
rev (>= 0.3.0)
|
37
|
+
multi_json (1.0.3)
|
38
|
+
rake (0.8.7)
|
39
|
+
rbx-require-relative (0.0.5)
|
40
|
+
rcov (0.9.9)
|
41
|
+
rev (0.3.2)
|
42
|
+
iobuffer (>= 0.1.3)
|
43
|
+
rspec (2.6.0)
|
44
|
+
rspec-core (~> 2.6.0)
|
45
|
+
rspec-expectations (~> 2.6.0)
|
46
|
+
rspec-mocks (~> 2.6.0)
|
47
|
+
rspec-core (2.6.4)
|
48
|
+
rspec-expectations (2.6.0)
|
49
|
+
diff-lcs (~> 1.1.2)
|
50
|
+
rspec-mocks (2.6.0)
|
51
|
+
ruby-debug (0.10.4)
|
52
|
+
columnize (>= 0.1)
|
53
|
+
ruby-debug-base (~> 0.10.4.0)
|
54
|
+
ruby-debug-base (0.10.4)
|
55
|
+
linecache (>= 0.3)
|
56
|
+
thor (0.14.6)
|
57
|
+
yajl-ruby (0.8.2)
|
58
|
+
|
59
|
+
PLATFORMS
|
60
|
+
ruby
|
61
|
+
|
62
|
+
DEPENDENCIES
|
63
|
+
growl
|
64
|
+
guard-rspec
|
65
|
+
melissadata!
|
66
|
+
rake (= 0.8.7)
|
67
|
+
rcov
|
68
|
+
rspec (> 2.4)
|
69
|
+
ruby-debug
|
data/Guardfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
bundler_installed = !!(%x[gem list] =~ /^bundler/) && File.exists?('Gemfile.lock')
|
2
|
+
|
3
|
+
desc "Setup the local environment"
|
4
|
+
task :setup do
|
5
|
+
sh %Q!gem install bundler --no-ri --no-rdoc! unless bundler_installed
|
6
|
+
output = `bundle check 2>&1`
|
7
|
+
unless $?.to_i == 0
|
8
|
+
# puts output
|
9
|
+
sh "bundle install"
|
10
|
+
# puts
|
11
|
+
end
|
12
|
+
|
13
|
+
# Dir['config/*.example'].each do |example_file|
|
14
|
+
# config_file = example_file.gsub(/\.example/,'')
|
15
|
+
# sh %Q!cp #{example_file} #{config_file}! unless File.exists?(config_file)
|
16
|
+
# end
|
17
|
+
|
18
|
+
puts "Done!\n\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
if bundler_installed
|
22
|
+
require 'bundler'
|
23
|
+
Bundler::GemHelper.install_tasks
|
24
|
+
|
25
|
+
require 'rspec/core/rake_task'
|
26
|
+
|
27
|
+
task :default => [:spec]
|
28
|
+
task :test => [:spec]
|
29
|
+
|
30
|
+
desc "Run specs"
|
31
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
32
|
+
t.rspec_opts = ['--backtrace', '--format', 'documentation']
|
33
|
+
t.pattern = 'spec/**/*_spec.rb'
|
34
|
+
end
|
35
|
+
|
36
|
+
if RUBY_VERSION !~ /^1\.9/
|
37
|
+
namespace :spec do
|
38
|
+
desc "Run specs with RCov"
|
39
|
+
RSpec::Core::RakeTask.new('rcov') do |t|
|
40
|
+
t.pattern = 'spec/**/*_spec.rb'
|
41
|
+
t.rspec_opts = ['--backtrace', '--format', 'documentation']
|
42
|
+
t.rcov = true
|
43
|
+
# t.rcov_opts = ['--exclude', 'some/path']
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/Vagrantfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Vagrant::Config.run do |config|
|
2
|
+
config.vm.box = 'melissa_data'
|
3
|
+
config.vm.forward_port 'http', 80, 8888
|
4
|
+
config.vm.forward_port 'melissa_data', 23456, 23457
|
5
|
+
|
6
|
+
config.vm.customize do |vm|
|
7
|
+
vm.memory_size = 1024
|
8
|
+
vm.cpu_count = 2
|
9
|
+
end
|
10
|
+
|
11
|
+
# config.vm.provision :chef_solo do |chef|
|
12
|
+
# chef.roles_path = '../aha_roles'
|
13
|
+
# chef.cookbooks_path = ['../aha_cookbooks']
|
14
|
+
# chef.add_role 'vagrant'
|
15
|
+
# chef.add_recipe 'melissa_data'
|
16
|
+
# end
|
17
|
+
end
|
data/bin/md
ADDED
data/bin/md-rpc
ADDED
data/bin/md-server
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.expand_path('../lib', File.dirname(__FILE__))
|
3
|
+
|
4
|
+
license = ARGV.first || 'INVALID LICENSE'
|
5
|
+
require 'melissa-data/rpc'
|
6
|
+
require 'melissa-data/shared_objects'
|
7
|
+
require 'msgpack/rpc/transport/unix'
|
8
|
+
|
9
|
+
host = MelissaData::RPC::DEFAULT_ADDRESS
|
10
|
+
port = 23456 # MelissaData::RPC::DEFAULT_PORT
|
11
|
+
address = "/tmp/melissa-data"
|
12
|
+
listener = MessagePack::RPC::UNIXServerTransport.new(address)
|
13
|
+
api = MelissaData::SharedObjects::Client.new(license)
|
14
|
+
|
15
|
+
svr = MessagePack::RPC::Server.new
|
16
|
+
svr.listen(listener, api)
|
17
|
+
puts "== RPC listening on #{host}:#{port}"
|
18
|
+
svr.run
|
data/bin/melissadata
ADDED
data/lib/md.rb
ADDED
data/lib/melissadata.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module MelissaData
|
2
|
+
# Entrypoint for the MelissaData CLI. This class should never be
|
3
|
+
# initialized directly (like a typical Thor class). Instead,
|
4
|
+
# use {Environment#cli} to invoke the CLI.
|
5
|
+
#
|
6
|
+
# # Defining Custom CLI Commands
|
7
|
+
#
|
8
|
+
# If you're looking to define custom CLI commands, then look at
|
9
|
+
# one of the two following classes:
|
10
|
+
#
|
11
|
+
# * {Command::Base} - Implementing a single command such as `melissadata up`, e.g.
|
12
|
+
# one without subcommands. Also take a look at {Command::NamedBase}.
|
13
|
+
# * {Command::GroupBase} - Implementing a command with subcommands, such as
|
14
|
+
# `melissadata box`, which has the `list`, `add`, etc. subcommands.
|
15
|
+
#
|
16
|
+
# The above linked classes contain the main documentation for each
|
17
|
+
# type of command.
|
18
|
+
class CLI < Thor
|
19
|
+
# Registers the given class with the CLI so it can be accessed.
|
20
|
+
# The class must be a subclass of {Command::Base}
|
21
|
+
# Don't call this method directly, instead call the {Command::Base.register}
|
22
|
+
#
|
23
|
+
# @param [Class] klass Command class
|
24
|
+
# @param [String] name Command name, accessed at `melissadata NAME`
|
25
|
+
# @param [String] usage Command usage, such as "melissadata NAME [--option]"
|
26
|
+
# @param [String] description Description of the command shown during the
|
27
|
+
# command listing.
|
28
|
+
# @param [Hash] opts Other options (not gone into detail here, look at
|
29
|
+
# the source instead).
|
30
|
+
def self.register(klass, name, usage, description, opts=nil)
|
31
|
+
opts ||= {}
|
32
|
+
|
33
|
+
# A subclass of Base is a single command, since it
|
34
|
+
# is invoked as a whole (as Thor::Group)
|
35
|
+
desc usage, description, opts
|
36
|
+
define_method(name) { |*args| invoke klass, args }
|
37
|
+
|
38
|
+
if opts[:alias]
|
39
|
+
# Alises are defined for this command, so properly alias the
|
40
|
+
# newly defined method/subcommand:
|
41
|
+
map opts[:alias] => name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
|
2
|
+
module MelissaData
|
3
|
+
module Command
|
4
|
+
# A {Base} is the superclass for all commands which are single
|
5
|
+
# commands, e.g. `melissadata init`, `melissadata up`. Not commands like
|
6
|
+
# `melissadata box add`. For commands which have more subcommands, use
|
7
|
+
# a {GroupBase}.
|
8
|
+
#
|
9
|
+
# A {Base} is a subclass of `Thor::Group`, so view the documentation
|
10
|
+
# there on how to add arguments, descriptions etc. The important note
|
11
|
+
# about this is that when invoked, _all public methods_ will be called
|
12
|
+
# in the order they are defined. If you don't want a method called when
|
13
|
+
# the command is invoked, it must be made `protected` or `private`.
|
14
|
+
#
|
15
|
+
# The best way to get examples of how to create your own command is to
|
16
|
+
# view the various MelissaData commands, which are relatively simple, and
|
17
|
+
# can be found in the MelissaData source tree at `lib/melissadata/command/`.
|
18
|
+
#
|
19
|
+
# # Defining a New Command
|
20
|
+
#
|
21
|
+
# To define a new single command, create a new class which inherits
|
22
|
+
# from this class, then call {register} to register the command. That's
|
23
|
+
# it! When the command is invoked, _all public methods_ will be called.
|
24
|
+
# Below is an example `SayHello` class:
|
25
|
+
#
|
26
|
+
# class SayHello < MelissaData::Command::Base
|
27
|
+
# register "hello", "Says hello"
|
28
|
+
#
|
29
|
+
# def hello
|
30
|
+
# env.ui.info "Hello"
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# In this case, the above class is invokable via `melissadata hello`. To give
|
35
|
+
# this a try, just copy and paste the above into a MelissaDatafile somewhere.
|
36
|
+
# The command will be available for that project!
|
37
|
+
#
|
38
|
+
# Also note that the above example uses `env.ui` to output. It is recommended
|
39
|
+
# you use this instead of raw "puts" since it is configurable and provides
|
40
|
+
# additional functionality, such as colors and asking for user input. See
|
41
|
+
# the {UI} class for more information.
|
42
|
+
#
|
43
|
+
# ## Defining Command-line Options
|
44
|
+
#
|
45
|
+
# Most command line actions won't be as simple as `melissadata hello`, and will
|
46
|
+
# probably require parameters or switches. Luckily, Thor makes adding these
|
47
|
+
# easy:
|
48
|
+
#
|
49
|
+
# class SayHello < MelissaData::Command::Base
|
50
|
+
# register "hello", "Says hello"
|
51
|
+
# argument :name, :type => :string
|
52
|
+
#
|
53
|
+
# def hello
|
54
|
+
# env.ui.info "Hello, #{name}"
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# Then, the above can be invoked with `melissadata hello Mitchell` which would
|
59
|
+
# output "Hello, Mitchell." If instead you're looking for switches, such as
|
60
|
+
# "--name Mitchell", then take a look at `class_option`, an example of which
|
61
|
+
# can be found in the {PackageCommand}.
|
62
|
+
class Base < Thor::Group
|
63
|
+
include Thor::Actions
|
64
|
+
include Helpers
|
65
|
+
|
66
|
+
attr_reader :env
|
67
|
+
|
68
|
+
# Register the command with the main MelissaData CLI under the
|
69
|
+
# given name. The name will be used for accessing it from the CLI,
|
70
|
+
# so if you name it "lamp", then the command to invoke this
|
71
|
+
# will be `melissadata lamp`.
|
72
|
+
#
|
73
|
+
# The description is used when the help is listed, and is meant to be
|
74
|
+
# a brief (one sentence) description of what the command does.
|
75
|
+
#
|
76
|
+
# Some additional options may be passed in as the last parameter:
|
77
|
+
#
|
78
|
+
# * `:alias` - If given as an array or string, these will be aliases
|
79
|
+
# for the same command. For example, `melissadata version` is also
|
80
|
+
# `melissadata --version` and `melissadata -v`
|
81
|
+
#
|
82
|
+
# @param [String] usage
|
83
|
+
# @param [String] description
|
84
|
+
# @param [Hash] opts
|
85
|
+
def self.register(usage, description, opts=nil)
|
86
|
+
desc description
|
87
|
+
CLI.register(self, extract_name_from_usage(usage), usage, desc, opts)
|
88
|
+
end
|
89
|
+
|
90
|
+
# def initialize(*args)
|
91
|
+
# super
|
92
|
+
# initialize_environment(*args)
|
93
|
+
# end
|
94
|
+
|
95
|
+
protected
|
96
|
+
|
97
|
+
# Extracts the name of the command from a usage string. Example:
|
98
|
+
# `init [box_name] [box_url]` becomes just `init`.
|
99
|
+
def self.extract_name_from_usage(usage)
|
100
|
+
/^([-_a-zA-Z0-9]+)(\s+(.+?))?$/.match(usage).to_a[1]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module MelissaData
|
2
|
+
module Command
|
3
|
+
module Helpers
|
4
|
+
# Initializes the environment by pulling the environment out of
|
5
|
+
# the configuration hash and sets up the UI if necessary.
|
6
|
+
def initialize_environment(args, options, config)
|
7
|
+
# raise Errors::CLIMissingEnvironment if !config[:env]
|
8
|
+
@env = config[:env]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module MelissaData
|
2
|
+
module Command
|
3
|
+
class PackageCommand < Base
|
4
|
+
# class_option :base, :type => :string, :default => nil
|
5
|
+
# class_option :output, :type => :string, :default => nil
|
6
|
+
# class_option :include, :type => :array, :default => nil
|
7
|
+
# class_option :melissadatafile, :type => :string, :default => nil
|
8
|
+
register "package", "Package up the MelissaData databases"
|
9
|
+
|
10
|
+
def execute
|
11
|
+
|
12
|
+
|
13
|
+
# desc "package", "Zips up data files from DVD and uploads them to remote servers"
|
14
|
+
# # method_option :path, :type => :string, :default => '/usr/lib/ruby/1.8/x86_64-linux', :desc => "Path to MelissaData DVD"
|
15
|
+
# method_option :username, :aliases => '-u', :type => :string, :required => true, :desc => "CloudFiles Username"
|
16
|
+
# method_option :api_key, :aliases => '-a', :type => :string, :required => true, :desc => "CloudFiles API Key"
|
17
|
+
# method_option :bucket_name, :aliases => '-b', :type => :string, :desc => "CloudFiles Bucket name"
|
18
|
+
|
19
|
+
# def package
|
20
|
+
source_dir = Dir['/Volumes/*'].detect{ |path| path =~ /DVD-\d{4}-\d{2}$/ }
|
21
|
+
raise Errors::DiscNotFound if source_dir.blank?
|
22
|
+
|
23
|
+
# dest_dir = "/tmp"
|
24
|
+
|
25
|
+
# possible_objects = %w[ address email name phone ]
|
26
|
+
# # objects = Dir.entries(source_dir).select{ |path| possible_objects.include?(path) }
|
27
|
+
# objects = %w[ email name ]
|
28
|
+
|
29
|
+
# objects.each do |obj|
|
30
|
+
# data_file = "#{dest_dir}/#{obj}.tgz"
|
31
|
+
# inside "#{source_dir}/#{obj}" do
|
32
|
+
# run "tar czf #{data_file} data"
|
33
|
+
# end
|
34
|
+
|
35
|
+
# say_status :upload, "#{obj}.tgz to #{options[:bucket_name]}"
|
36
|
+
# cf = CloudFiles::Connection.new(:username => options[:username], :api_key => options[:api_key])
|
37
|
+
# cont = cf.container options[:bucket_name]
|
38
|
+
# remote_object = cont.create_object "#{obj}.tgz", false
|
39
|
+
# remote_object.load_from_filename data_file
|
40
|
+
|
41
|
+
# # "#{source_dir}/#{obj}/linux/gcc34_64bit/*.h" => /opt/melissadata/src/
|
42
|
+
# # "#{source_dir}/#{obj}/linux/gcc34_64bit/libmdEmail.so" => /opt/melissadata/lib/
|
43
|
+
# # "#{source_dir}/#{obj}/linux/interfaces/ruby/mdEmailRubyWrapper.cpp" => /opt/melissadata/lib/
|
44
|
+
|
45
|
+
# # inside "#{source_dir}/#{obj}/linux/gcc34_64bit" do
|
46
|
+
# # run "tar czf #{data_file} data"
|
47
|
+
# # end
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
# return package_base if options[:base]
|
54
|
+
# package_target
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
# def package_base
|
60
|
+
# vm = VM.find(options[:base], env)
|
61
|
+
# raise Errors::BaseVMNotFound, :name => options[:base] if !vm.created?
|
62
|
+
# package_vm(vm)
|
63
|
+
# end
|
64
|
+
|
65
|
+
# def package_target
|
66
|
+
# raise Errors::MultiVMTargetRequired, :command => "package" if target_vms.length > 1
|
67
|
+
# vm = target_vms.first
|
68
|
+
# raise Errors::VMNotCreatedError if !vm.created?
|
69
|
+
# package_vm(vm)
|
70
|
+
# end
|
71
|
+
|
72
|
+
# def package_vm(vm)
|
73
|
+
# opts = options.inject({}) do |acc, data|
|
74
|
+
# k,v = data
|
75
|
+
# acc["package.#{k}"] = v
|
76
|
+
# acc
|
77
|
+
# end
|
78
|
+
|
79
|
+
# vm.package(opts)
|
80
|
+
# end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|