chimps 0.1.9 → 0.2.0
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.
- data/LICENSE +20 -107
- data/VERSION +1 -1
- data/bin/chimps +1 -1
- data/lib/chimps/cli.rb +8 -85
- data/lib/chimps/commands/base.rb +9 -61
- data/lib/chimps/commands/batch.rb +2 -30
- data/lib/chimps/commands/create.rb +1 -3
- data/lib/chimps/commands/destroy.rb +1 -3
- data/lib/chimps/commands/download.rb +15 -45
- data/lib/chimps/commands/help.rb +16 -5
- data/lib/chimps/commands/list.rb +3 -16
- data/lib/chimps/commands/query.rb +5 -11
- data/lib/chimps/commands/search.rb +6 -17
- data/lib/chimps/commands/show.rb +1 -3
- data/lib/chimps/commands/test.rb +2 -3
- data/lib/chimps/commands/update.rb +1 -3
- data/lib/chimps/commands/upload.rb +6 -25
- data/lib/chimps/commands.rb +106 -27
- data/lib/chimps/config.rb +35 -72
- data/lib/chimps/request.rb +14 -14
- data/lib/chimps/typewriter.rb +4 -0
- data/lib/chimps/utils/log.rb +5 -7
- data/lib/chimps/utils/uses_model.rb +3 -20
- data/lib/chimps/utils/uses_yaml_data.rb +5 -13
- data/lib/chimps/workflows/upload/bundler.rb +3 -3
- data/lib/chimps/workflows/upload/notifier.rb +1 -1
- data/lib/chimps.rb +7 -1
- metadata +65 -31
- data/spec/chimps/cli_spec.rb +0 -22
- data/spec/chimps/commands/base_spec.rb +0 -25
- data/spec/chimps/commands/list_spec.rb +0 -25
@@ -5,10 +5,12 @@ module Chimps
|
|
5
5
|
# Infochimps.
|
6
6
|
class Search < Chimps::Command
|
7
7
|
|
8
|
+
# Describes usage of search command.
|
9
|
+
USAGE = "usage: chimps search [OPTIONS] QUERY"
|
10
|
+
|
8
11
|
# Default number of search results returned.
|
9
12
|
# DEFAULT_LIMIT = 20
|
10
13
|
|
11
|
-
BANNER = "usage: chimps search [OPTIONS] QUERY"
|
12
14
|
HELP = <<EOF
|
13
15
|
|
14
16
|
Perform a search on Infochimps. By default the search will be of
|
@@ -18,8 +20,6 @@ EOF
|
|
18
20
|
# Path to search resource
|
19
21
|
PATH = 'search.json'
|
20
22
|
|
21
|
-
# Models this command applies to (default first)
|
22
|
-
MODELS = %w[dataset collection source license]
|
23
23
|
include Chimps::Utils::UsesModel
|
24
24
|
|
25
25
|
# FIXME have to implement this on the server side.
|
@@ -27,20 +27,9 @@ EOF
|
|
27
27
|
# @limit ||= DEFAULT_LIMIT
|
28
28
|
# end
|
29
29
|
|
30
|
-
def define_options
|
31
|
-
# on_tail("-n", "--num-results NUM", "Return the given number of results instead of the default #{DEFAULT_LIMIT}") do |n|
|
32
|
-
# @limit = n.to_i
|
33
|
-
# end
|
34
|
-
|
35
|
-
on_tail("-s", "--[no-]skip-column-names", "don't print column names in output.") do |s|
|
36
|
-
@skip_column_names = s
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
30
|
def query
|
42
|
-
raise CLIError.new("Must provide a query to search for") if argv.blank?
|
43
|
-
argv.join(' ')
|
31
|
+
raise CLIError.new("Must provide a query to search for") if config.argv.blank?
|
32
|
+
config.argv.join(' ')
|
44
33
|
end
|
45
34
|
|
46
35
|
def params
|
@@ -51,7 +40,7 @@ EOF
|
|
51
40
|
end
|
52
41
|
|
53
42
|
def execute!
|
54
|
-
Chimps::Request.new(PATH, :params => params).get.print(:skip_column_names =>
|
43
|
+
Chimps::Request.new(PATH, :params => params).get.print(:skip_column_names => config[:skip_column_names])
|
55
44
|
end
|
56
45
|
end
|
57
46
|
end
|
data/lib/chimps/commands/show.rb
CHANGED
@@ -3,15 +3,13 @@ module Chimps
|
|
3
3
|
|
4
4
|
class Show < Chimps::Command
|
5
5
|
|
6
|
-
|
6
|
+
USAGE = "usage: chimps show [OPTIONS] ID_OR_HANDLE"
|
7
7
|
HELP = <<EOF
|
8
8
|
|
9
9
|
Return a description of the resource (defaults to dataset) with the
|
10
10
|
given ID or HANDLE
|
11
11
|
EOF
|
12
12
|
|
13
|
-
# Models this command applies to (default first)
|
14
|
-
MODELS = %w[dataset collection source license tag category]
|
15
13
|
include Chimps::Utils::UsesModel
|
16
14
|
|
17
15
|
# The path of the URL to send a Request to.
|
data/lib/chimps/commands/test.rb
CHANGED
@@ -5,7 +5,7 @@ module Chimps
|
|
5
5
|
# working.
|
6
6
|
class Test < Chimps::Command
|
7
7
|
|
8
|
-
|
8
|
+
USAGE = "usage: chimps test"
|
9
9
|
HELP = <<EOF
|
10
10
|
|
11
11
|
Print diagnostic information on the API credentials being used by chimps
|
@@ -16,12 +16,11 @@ EOF
|
|
16
16
|
|
17
17
|
# Path to submit test requests to.
|
18
18
|
def path
|
19
|
-
"api_accounts/#{Chimps::
|
19
|
+
"api_accounts/#{Chimps::Config[:site][:key]}"
|
20
20
|
end
|
21
21
|
|
22
22
|
# Issue the request.
|
23
23
|
def execute!
|
24
|
-
puts "Reading identity file at #{CONFIG[:identity_file]}" if Chimps.verbose?
|
25
24
|
response = Chimps::Request.new(path, :sign => true).get
|
26
25
|
if response.error?
|
27
26
|
case
|
@@ -5,7 +5,7 @@ module Chimps
|
|
5
5
|
# Infochimps.
|
6
6
|
class Update < Chimps::Command
|
7
7
|
|
8
|
-
|
8
|
+
USAGE = "usage: chimps update [OPTIONS] ID_OR_HANDLE [PROP=VALUE] ..."
|
9
9
|
HELP = <<EOF
|
10
10
|
|
11
11
|
Updates a single resource of a given type (defaults to dataset)
|
@@ -16,8 +16,6 @@ from an input YAML file, or multiple YAML documents streamed in via
|
|
16
16
|
STDIN, in order of decreasing precedence.
|
17
17
|
EOF
|
18
18
|
|
19
|
-
# Models this command applies to (default first)
|
20
|
-
MODELS = %w[dataset source license]
|
21
19
|
include Chimps::Utils::UsesModel
|
22
20
|
include Chimps::Utils::UsesYamlData
|
23
21
|
def ignore_first_arg_on_command_line
|
@@ -4,7 +4,7 @@ module Chimps
|
|
4
4
|
# A command for uploading data to Infochimps.
|
5
5
|
class Upload < Chimps::Command
|
6
6
|
|
7
|
-
|
7
|
+
USAGE = "usage: chimps upload [OPTIONS] ID_OR_HANDLE PATH [PATH] ..."
|
8
8
|
HELP = <<EOF
|
9
9
|
|
10
10
|
Upload data from your local machine for an existing dataset identified
|
@@ -24,44 +24,25 @@ Supplied paths are allowed to be remote files so someting like
|
|
24
24
|
will work.
|
25
25
|
EOF
|
26
26
|
|
27
|
-
# The path to the archive
|
28
|
-
attr_reader :archive
|
29
|
-
|
30
|
-
# The data format to annotate the upload with.
|
31
|
-
#
|
32
|
-
# Chimps will try to guess if this isn't given.
|
33
|
-
attr_reader :fmt
|
34
|
-
|
35
27
|
# The ID or handle of the dataset to upload data for.
|
36
28
|
#
|
37
29
|
# @return [String]
|
38
30
|
def dataset
|
39
|
-
raise CLIError.new("Must provide an ID or URL-escaped handle as the first argument") if argv.first.blank?
|
40
|
-
argv.first
|
31
|
+
raise CLIError.new("Must provide an ID or URL-escaped handle as the first argument") if config.argv.first.blank?
|
32
|
+
config.argv.first
|
41
33
|
end
|
42
34
|
|
43
35
|
# A list of paths to upload.
|
44
36
|
#
|
45
37
|
# @return [Array<String>]
|
46
38
|
def paths
|
47
|
-
raise CLIError.new("Must provide some paths to upload") if argv.length < 2
|
48
|
-
argv[1..-1]
|
39
|
+
raise CLIError.new("Must provide some paths to upload") if config.argv.length < 2
|
40
|
+
config.argv[1..-1]
|
49
41
|
end
|
50
42
|
|
51
|
-
def define_upload_options
|
52
|
-
on_tail("-a", "--archive-path", "Path to the archive to be created. Defaults to a timestamped ZIP file named after the dataset in the current directory.") do |path|
|
53
|
-
@archive = path
|
54
|
-
end
|
55
|
-
|
56
|
-
on_tail("-f", "--format FORMAT", "Data format to annotate upload with. Tries to guess if not given.") do |f|
|
57
|
-
@fmt = f
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
43
|
# Upload the data.
|
63
44
|
def execute!
|
64
|
-
Chimps::Workflows::Up.new(:dataset => dataset, :archive => archive, :paths => paths, :fmt =>
|
45
|
+
Chimps::Workflows::Up.new(:dataset => dataset, :archive => config[:archive], :paths => paths, :fmt => config[:format]).execute!.print
|
65
46
|
end
|
66
47
|
end
|
67
48
|
end
|
data/lib/chimps/commands.rb
CHANGED
@@ -1,46 +1,125 @@
|
|
1
|
+
require 'configliere'
|
2
|
+
|
1
3
|
module Chimps
|
2
4
|
|
5
|
+
Config.use :commands
|
6
|
+
|
3
7
|
# A namespace to hold the various commands Chimps defines.
|
4
8
|
module Commands
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
def self.class_for name
|
11
|
+
"Chimps::Commands::#{name.to_s.capitalize}".constantize
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.included obj
|
15
|
+
obj.extend(ClassMethods)
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
# Create a new command from the given +command_name+. The
|
20
|
+
# resulting command will be initialized but will not have been
|
21
|
+
# executed.
|
22
|
+
#
|
23
|
+
# @return [Chimps::Command]
|
24
|
+
def command
|
25
|
+
raise Chimps::CLIError.new("Must specify a command. Try `chimps help'.") unless Chimps::Config.command
|
26
|
+
Chimps::Config.command_settings.resolve!
|
27
|
+
Chimps::Commands.class_for(Chimps::Config.command_name).new(Chimps::Config.command_settings)
|
16
28
|
end
|
17
|
-
raise CLIError.new("Invalid command: #{command_name}. Try running `chimps help'")
|
18
29
|
end
|
19
30
|
|
20
|
-
|
21
|
-
|
31
|
+
protected
|
32
|
+
|
33
|
+
def self.define_skip_column_names command
|
34
|
+
command.define :skip_column_names, :description => "Don't print column names in output", :flag => :s, :type => :boolean
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.define_model command, models=%w[dataset collection source license]
|
38
|
+
models_string = models[0..-2].map { |m| "'#{m}'" }.join(', ') + ", or '#{models.last}'"
|
39
|
+
command.define :model, :description => "Model to search (one of #{models_string})", :flag => :m, :default => models.first, :type => String
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.define_data_file command
|
43
|
+
command.define :data_file, :description => "Path to a file containing YAML data.", :flag => :d
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Core REST actions
|
22
48
|
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
49
|
+
|
50
|
+
Chimps::Config.define_command :list, :description => "List resources" do |command|
|
51
|
+
define_skip_column_names(command)
|
52
|
+
define_model(command)
|
53
|
+
command.define :all, :description => "List all resources, not just those owned by you", :flag => :a
|
54
|
+
end
|
55
|
+
|
56
|
+
Chimps::Config.define_command :show, :description => "Show a resource in detail" do |command|
|
57
|
+
define_model(command, %w[dataset collection source license category tag])
|
27
58
|
end
|
28
59
|
|
60
|
+
Chimps::Config.define_command :create, :description => "Create a new resource" do |command|
|
61
|
+
define_model(command, %w[dataset source license])
|
62
|
+
define_data_file(command)
|
63
|
+
end
|
64
|
+
|
65
|
+
Chimps::Config.define_command :update, :description => "Update an existing resource" do |command|
|
66
|
+
define_model(command, %w[dataset source license])
|
67
|
+
define_data_file(command)
|
68
|
+
end
|
69
|
+
|
70
|
+
Chimps::Config.define_command :destroy, :description => "Destroy an existing resource" do |command|
|
71
|
+
define_model(command, %w[dataset package source license])
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Workflows
|
76
|
+
#
|
77
|
+
|
78
|
+
Chimps::Config.define_command :download, :description => "Download a dataset" do |command|
|
79
|
+
command.define :output, :description => "Path to output file (defaults to sensible path in current directory)", :flag => :o, :type => String
|
80
|
+
command.define :format, :description => "Preferred data-format (csv, tsv, xls, &c.)", :flag => :f, :type => String
|
81
|
+
command.define :pkg_fmt, :description => "Preferred package-format (zip, tar.bz2, &c.)", :flag => :p, :type => String
|
82
|
+
end
|
83
|
+
|
84
|
+
Chimps::Config.define_command :upload, :description => "Upload a dataset" do |command|
|
85
|
+
command.define :archive, :description => "Path to the local archive that will be created (defaults to a sensibly named ZIP file in the current directory)", :type => String, :flag => :a
|
86
|
+
command.define :format, :description => "Data format (tsv, csv, xls, &c.) of the uploaded data (will guess if not given)", :type => String, :flag => :f
|
87
|
+
end
|
88
|
+
|
89
|
+
Chimps::Config.define_command :batch, :description => "Perform a batch processing request" do |command|
|
90
|
+
command.define :output, :description => "Path to store the server's response", :type => String, :flag => :o
|
91
|
+
command.define :force, :description => "Force upload of data even if there were errors in the batch request.", :flag => :F
|
92
|
+
command.define :format, :description => "Data format to annotate each upload with (will guess if not given)", :type => String, :flag => :f
|
93
|
+
define_data_file(command)
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Miscellaneous
|
98
|
+
#
|
99
|
+
|
100
|
+
Chimps::Config.define_help_command!
|
101
|
+
|
102
|
+
Chimps::Config.define_command :search, :description => 'Search resources' do |command|
|
103
|
+
define_skip_column_names(command)
|
104
|
+
define_model(command)
|
105
|
+
end
|
106
|
+
|
107
|
+
Chimps::Config.define_command :query, :description => "Get a response from the Query API" do |command|
|
108
|
+
command.define :pretty_print, :description => "Pretty-print output", :flag => :p
|
109
|
+
define_data_file(command)
|
110
|
+
end
|
111
|
+
|
112
|
+
Chimps::Config.define_command :test, :description => "Test your authentication credentials with Infochimps"
|
113
|
+
|
114
|
+
|
29
115
|
# A list of all the commmand names defined by Chimps. Each name
|
30
116
|
# maps to a corresponding subclass of Chimps::Command living in
|
31
117
|
# the Chimps::Commands module.
|
32
|
-
|
118
|
+
#Configliere::COMMANDS += %w[search help test create show update destroy upload list download batch query]
|
33
119
|
|
34
|
-
|
35
|
-
autoload
|
120
|
+
Chimps::Config.commands.keys.each do |command|
|
121
|
+
autoload command.to_s.capitalize.to_sym, "chimps/commands/#{command}"
|
36
122
|
end
|
37
123
|
|
38
|
-
# Is +name+ a Chimps command name?
|
39
|
-
#
|
40
|
-
# @param [String] name
|
41
|
-
# @return [true, false]
|
42
|
-
def command_name? name
|
43
|
-
NAMES.include?(name)
|
44
|
-
end
|
45
124
|
end
|
46
125
|
end
|
data/lib/chimps/config.rb
CHANGED
@@ -1,91 +1,54 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# Load all configuration, load plugins, and resolve options.
|
4
|
-
def self.boot!
|
5
|
-
Chimps::Config.load
|
6
|
-
Chimps::Config.load_plugins
|
7
|
-
Chimps::Config.resolve_options!
|
8
|
-
end
|
1
|
+
require 'configliere'
|
9
2
|
|
10
|
-
|
11
|
-
COMMAND_LINE_OPTIONS = {
|
12
|
-
:identity_file => ENV["CHIMPS_RC"] || (ENV["HOME"] && File.expand_path("~/.chimps"))
|
13
|
-
# log_file -- will be specified on command line
|
14
|
-
# verbose -- will be specified on command line
|
15
|
-
}
|
3
|
+
module Chimps
|
16
4
|
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
:
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
5
|
+
# Chimps configuration. Managed by
|
6
|
+
# Configliere[http://github.com/infochimps/configliere]
|
7
|
+
Config = Configliere.new
|
8
|
+
|
9
|
+
Config.define :site_config, :description => "Path to site-wide configuration file", :env_var => "CHIMPS_ETC", :default => "/etc/chimps/chimpsrc.yaml", :type => String, :no_help => true
|
10
|
+
Config.define :config, :description => "Path to user configuration file", :env_var => "CHIMPS_RC", :default => (ENV["HOME"] && File.expand_path("~/.chimps")), :flag => :c, :type => String
|
11
|
+
Config.define :log, :description => "Path to log file", :flag => :l, :type => String
|
12
|
+
Config.define :timestamp_format, :description => "Format for timestamps", :type => String, :no_help => true, :default => "%Y%m%d-%H%M%S"
|
13
|
+
Config.define :plugin_dirs, :description => "List of directories from which to load plugins", :type => Array, :no_help => true, :default => ['/usr/share/chimps', '/usr/local/share/chimps']
|
14
|
+
Config.define :skip_plugins, :description => "Don't load any plugins", :flag => :q, :type => :boolean
|
15
|
+
Config.define :verbose, :description => "Be verbose", :flag => :v, :type => :boolean
|
16
|
+
|
17
|
+
Config.define 'query.host', :description => "Host to send Query API requests to", :type => String, :default => "http://api.infochimps.com", :no_help => true, :env_var => "CHIMPS_QUERY_HOST"
|
18
|
+
Config.define 'query.key', :description => "API key for the Query API", :type => String, :no_help => true
|
19
|
+
|
20
|
+
Config.define 'site.username', :description => "Your Infochimps username", :type => String
|
21
|
+
Config.define 'site.host', :description => "Host to send Dataset API requests to", :type => String, :default => "http://infochimps.org", :env_var => "CHIMPS_DATASET_HOST"
|
22
|
+
Config.define 'site.key', :description => "API key for the Dataset API", :type => String
|
23
|
+
Config.define 'site.secret', :description => "API secret for the Dataset API", :type => String
|
29
24
|
|
30
25
|
# Is Chimps in verbose mode?
|
31
26
|
#
|
32
27
|
# @return [true, false, nil]
|
33
28
|
def self.verbose?
|
34
|
-
|
29
|
+
Config[:verbose]
|
35
30
|
end
|
36
31
|
|
37
32
|
# The username Chimps will pass to Infochimps.
|
38
33
|
#
|
39
34
|
# @return [String]
|
40
35
|
def self.username
|
41
|
-
|
36
|
+
Config[:site][:username] or raise AuthenticationError.new("No Dataset API username set in #{Chimps::Config[:config]} or #{Chimps::Config[:site_config]}")
|
42
37
|
end
|
43
38
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
# passed on the command-line override those stored in a
|
49
|
-
# configuration file (if present).
|
50
|
-
def self.resolve_options!
|
51
|
-
Chimps::CONFIG.merge!(Chimps::COMMAND_LINE_OPTIONS) # overwrites from command line if necessary
|
52
|
-
end
|
53
|
-
|
54
|
-
# The root of the Chimps source base.
|
55
|
-
#
|
56
|
-
# @return [String]
|
57
|
-
def self.chimps_root
|
58
|
-
File.expand_path File.join(File.dirname(__FILE__), '../..')
|
59
|
-
end
|
60
|
-
|
61
|
-
# Require all ruby files in the directory
|
62
|
-
# Chimps::CONFIG[:plugins].
|
63
|
-
def self.load_plugins
|
64
|
-
return if Chimps::CONFIG[:skip_plugins]
|
65
|
-
plugin_dirs = Chimps::CONFIG[:plugins]
|
66
|
-
return if plugin_dirs.blank?
|
67
|
-
plugin_dirs.each do |dir|
|
68
|
-
Dir[File.expand_path(dir) + "/*.rb"].each { |plugin| require plugin }
|
69
|
-
end
|
70
|
-
end
|
39
|
+
def self.version
|
40
|
+
version_path = File.join(File.dirname(__FILE__), '../../VERSION')
|
41
|
+
@version ||= File.exist?(version_path) && File.new(version_path).read
|
42
|
+
end
|
71
43
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
case
|
80
|
-
when value.is_a?(Hash) && CONFIG.include?(key)
|
81
|
-
CONFIG[key].merge!(value)
|
82
|
-
when value.is_a?(Array) && CONFIG.include?(key)
|
83
|
-
CONFIG[key] += value
|
84
|
-
else
|
85
|
-
CONFIG[key] = value
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
44
|
+
# Require all Ruby files in the directory
|
45
|
+
# Chimps::Config[:plugin_dirs].
|
46
|
+
def self.load_plugins
|
47
|
+
return if Chimps::Config[:skip_plugins]
|
48
|
+
plugin_dirs = Chimps::Config[:plugin_dirs]
|
49
|
+
plugin_dirs.each do |dir|
|
50
|
+
Dir[File.expand_path(dir) + "/*.rb"].each { |plugin| require plugin }
|
89
51
|
end
|
90
52
|
end
|
53
|
+
|
91
54
|
end
|
data/lib/chimps/request.rb
CHANGED
@@ -10,7 +10,7 @@ module Chimps
|
|
10
10
|
class Request < RestClient::Resource
|
11
11
|
|
12
12
|
# Default headers to pass with every request.
|
13
|
-
DEFAULT_HEADERS = { :content_type => 'application/json', :accept => 'application/json' }
|
13
|
+
DEFAULT_HEADERS = { :content_type => 'application/json', :accept => 'application/json', :user_agent => "Chimps #{Chimps.version}" }
|
14
14
|
|
15
15
|
# Path of the URL to submit to. Must be a String.
|
16
16
|
attr_accessor :path
|
@@ -66,7 +66,7 @@ module Chimps
|
|
66
66
|
#
|
67
67
|
# @return [true, false]
|
68
68
|
def authenticable?
|
69
|
-
!Chimps::
|
69
|
+
!Chimps::Config[:site][:key].blank? && !Chimps::Config[:site][:secret].blank?
|
70
70
|
end
|
71
71
|
alias_method :signable?, :authenticable?
|
72
72
|
|
@@ -74,7 +74,7 @@ module Chimps
|
|
74
74
|
#
|
75
75
|
# @return [String]
|
76
76
|
def host
|
77
|
-
@host ||= Chimps::
|
77
|
+
@host ||= Chimps::Config[:site][:host]
|
78
78
|
end
|
79
79
|
|
80
80
|
# Return the URL for this request with the (signed, if necessary)
|
@@ -170,9 +170,9 @@ module Chimps
|
|
170
170
|
# false.
|
171
171
|
def authenticate_if_necessary!
|
172
172
|
return unless authenticate?
|
173
|
-
raise Chimps::AuthenticationError.new("API key or secret missing from #{
|
173
|
+
raise Chimps::AuthenticationError.new("API key or secret missing from #{Config[:config]} or #{Config[:site_config]}") unless (authenticable? || @forgive_authentication_error)
|
174
174
|
query_params[:requested_at] = Time.now.to_i.to_s
|
175
|
-
query_params[:apikey] = Chimps::
|
175
|
+
query_params[:apikey] = Chimps::Config[:site][:key]
|
176
176
|
end
|
177
177
|
|
178
178
|
# Return an unsigned query string for this request.
|
@@ -200,7 +200,7 @@ module Chimps
|
|
200
200
|
# @return [String]
|
201
201
|
def data_text
|
202
202
|
require 'json'
|
203
|
-
@data_text ||= data
|
203
|
+
@data_text ||= JSON.generate(data, {:max_nesting => false})
|
204
204
|
end
|
205
205
|
|
206
206
|
# Sign +string+ by concatenting it with the secret and computing
|
@@ -209,9 +209,9 @@ module Chimps
|
|
209
209
|
# @param [String]
|
210
210
|
# @return [String]
|
211
211
|
def sign string
|
212
|
-
raise Chimps::AuthenticationError.new("No API secret stored in #{
|
212
|
+
raise Chimps::AuthenticationError.new("No API secret stored in #{Config[:config]} or #{Config[:site_config]}.") unless (authenticable? || @forgive_authentication_error)
|
213
213
|
require 'digest/md5'
|
214
|
-
Digest::MD5.hexdigest(string +
|
214
|
+
Digest::MD5.hexdigest(string + Config[:site][:secret])
|
215
215
|
end
|
216
216
|
|
217
217
|
# Append the signature to the unsigned query string.
|
@@ -250,14 +250,14 @@ module Chimps
|
|
250
250
|
#
|
251
251
|
# @return [true, false]
|
252
252
|
def authenticable?
|
253
|
-
!Chimps::
|
253
|
+
!Chimps::Config[:query][:key].blank?
|
254
254
|
end
|
255
255
|
|
256
256
|
# The host to send requests to.
|
257
257
|
#
|
258
258
|
# @return [String]
|
259
259
|
def host
|
260
|
-
@host ||= Chimps::
|
260
|
+
@host ||= Chimps::Config[:query][:host]
|
261
261
|
end
|
262
262
|
|
263
263
|
# All Query API requests must be signed.
|
@@ -275,9 +275,9 @@ module Chimps
|
|
275
275
|
# false.
|
276
276
|
def authenticate_if_necessary!
|
277
277
|
return unless authenticate?
|
278
|
-
raise Chimps::AuthenticationError.new("API key or secret missing from #{
|
278
|
+
raise Chimps::AuthenticationError.new("API key or secret missing from #{Config[:config]} or #{Config[:site_config]}") unless (authenticable? || @forgive_authentication_error)
|
279
279
|
query_params[:requested_at] = Time.now.to_i.to_s
|
280
|
-
query_params[:apikey] = Chimps::
|
280
|
+
query_params[:apikey] = Chimps::Config[:query][:key]
|
281
281
|
end
|
282
282
|
|
283
283
|
# Sign +string+ by concatenting it with the secret and computing
|
@@ -286,9 +286,9 @@ module Chimps
|
|
286
286
|
# @param [String]
|
287
287
|
# @return [String]
|
288
288
|
def sign string
|
289
|
-
raise Chimps::AuthenticationError.new("No API secret stored in #{
|
289
|
+
raise Chimps::AuthenticationError.new("No API secret stored in #{Config[:config]} or #{Config[:site_config]}.") unless (authenticable? || @forgive_authentication_error)
|
290
290
|
require 'digest/md5'
|
291
|
-
Digest::MD5.hexdigest(string +
|
291
|
+
Digest::MD5.hexdigest(string + Config[:query][:secret])
|
292
292
|
end
|
293
293
|
|
294
294
|
# Append the signature to the unsigned query string.
|
data/lib/chimps/typewriter.rb
CHANGED
@@ -98,6 +98,10 @@ module Chimps
|
|
98
98
|
accumulate_resource(resource_name, resource_data)
|
99
99
|
when %w[errors batch search api_account message].include?(resource_name.to_s)
|
100
100
|
send("accumulate_#{resource_name}", resource_data)
|
101
|
+
when %w[message].include?(resource_name.to_s)
|
102
|
+
self << [resource_data]
|
103
|
+
when %w[error].include?(resource_name.to_s)
|
104
|
+
nil
|
101
105
|
when :array == resource_name # constructed by Chimps::Response
|
102
106
|
accumulate_listing(resource_data)
|
103
107
|
when :string == resource_name # constructed by Chimps::Response
|
data/lib/chimps/utils/log.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Chimps
|
2
2
|
|
3
|
-
# The Chimps logger. Set via Chimps::
|
3
|
+
# The Chimps logger. Set via Chimps::Config[:log] and defaults
|
4
4
|
# to $stdout.
|
5
5
|
#
|
6
6
|
# @return [Logger]
|
@@ -31,15 +31,13 @@ module Chimps
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
#
|
36
|
-
# Chimps::CONFIG[:log_file] or $stdout if the path is blank or
|
37
|
-
# equal to `-'.
|
34
|
+
# Return either the path to the log file in Chimps::Config[:log]
|
35
|
+
# or $stdout if the path is blank or equal to `-'.
|
38
36
|
#
|
39
37
|
# @return [String, $stdout] the path to the log or $stdout
|
40
38
|
def self.log_file
|
41
|
-
if Chimps::
|
42
|
-
Chimps::
|
39
|
+
if Chimps::Config[:log]
|
40
|
+
Chimps::Config[:log].strip == '-' ? $stdout : Chimps::Config[:log]
|
43
41
|
else
|
44
42
|
$stdout
|
45
43
|
end
|
@@ -3,7 +3,7 @@ module Chimps
|
|
3
3
|
module UsesModel
|
4
4
|
|
5
5
|
def model
|
6
|
-
|
6
|
+
config[:model]
|
7
7
|
end
|
8
8
|
|
9
9
|
def plural_model
|
@@ -15,8 +15,8 @@ module Chimps
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def model_identifier
|
18
|
-
raise CLIError.new("Must provide an ID or URL-escaped handle as the first argument") if argv.first.blank?
|
19
|
-
argv.first
|
18
|
+
raise CLIError.new("Must provide an ID or URL-escaped handle as the first argument") if config.argv.first.blank?
|
19
|
+
config.argv.first
|
20
20
|
end
|
21
21
|
|
22
22
|
def models_path
|
@@ -27,23 +27,6 @@ module Chimps
|
|
27
27
|
"#{plural_model}/#{model_identifier}.json"
|
28
28
|
end
|
29
29
|
|
30
|
-
def model= model
|
31
|
-
raise CLIError.new("Invalid model: #{model}. Must be one of #{models_string}") unless self.class::MODELS.include?(model)
|
32
|
-
@model = model
|
33
|
-
end
|
34
|
-
|
35
|
-
def models_string
|
36
|
-
returning(self.class::MODELS.dup) do |parts|
|
37
|
-
parts[0] = "#{parts.first} (default)"
|
38
|
-
parts[-1] = "or #{parts.last}"
|
39
|
-
end.join(', ')
|
40
|
-
end
|
41
|
-
|
42
|
-
def define_model_option
|
43
|
-
on_tail("-m", "--model MODEL", "Use a different resource, one of: #{models_string}") do |m|
|
44
|
-
self.model= m
|
45
|
-
end
|
46
|
-
end
|
47
30
|
end
|
48
31
|
end
|
49
32
|
end
|