crowdflower 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ tags
data/HISTORY.md ADDED
@@ -0,0 +1,18 @@
1
+ ## 0.2.2 (2010-02-03)
2
+ * Simple Job#update addition
3
+
4
+ ## 0.2.1 (2010-01-24)
5
+ * Added latest attribute to judgments
6
+ * Fixed judgment class
7
+ * Added judgment for a unit
8
+
9
+ ## 0.2.0 (2009-10-13)
10
+
11
+ * Integration tests for CrowdFlower servers
12
+ * No more API redirects
13
+ * Webhook capability added
14
+
15
+ ## 0.1.0 (2009-09-14)
16
+
17
+ * First release
18
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Dolores Labs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,20 @@
1
+ = ruby-crowdflower
2
+
3
+ A toolkit for interacting with CrowdFlower via the REST API.
4
+
5
+ This is alpha software. Have fun!
6
+
7
+ == Note on Patches/Pull Requests
8
+
9
+ * Fork the project.
10
+ * Make your feature addition or bug fix.
11
+ * Add tests for it. This is important so I don't break it in a
12
+ future version unintentionally.
13
+ * Commit, do not mess with rakefile, version, or history.
14
+ (if you want to have your own version, that is fine but
15
+ bump version in a commit by itself I can ignore when I pull)
16
+ * Send me a pull request. Bonus points for topic branches.
17
+
18
+ == Copyright
19
+
20
+ Copyright (c) 2009 Dolores Labs. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "crowdflower"
8
+ gem.summary = %Q{a toolkit for the CrowdFlower API}
9
+ gem.description = <<-EOF
10
+ A toolkit for interacting with CrowdFlower via the REST API.
11
+
12
+ This is alpha software. Have fun!
13
+
14
+ EOF
15
+ gem.email = "brian@doloreslabs.com"
16
+ gem.homepage = "http://github.com/dolores/ruby-crowdflower"
17
+ gem.authors = ["Brian P O'Rourke", "Chris Van Pelt"]
18
+ gem.add_dependency 'httparty', '>= 0.4.3'
19
+ end
20
+
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
+ end
24
+
25
+ task :default => :build
26
+
27
+ task :refresh_builder => [:build] do
28
+ cp "pkg/crowdflower-#{File.read("VERSION").strip}.gem", "../builder/gems/cache/"
29
+ rm_rf "../builder/gems/gems/crowdflower-#{File.read("VERSION").strip}/"
30
+ `cd ../builder && bin/thor merb:gem:redeploy`
31
+ end
32
+
33
+ require 'rake/rdoctask'
34
+ Rake::RDocTask.new do |rdoc|
35
+ if File.exist?('VERSION.yml')
36
+ config = YAML.load(File.read('VERSION.yml'))
37
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
38
+ else
39
+ version = ""
40
+ end
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "crowdflower #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.3
data/bindev/cl_skel.rb ADDED
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # == Synopsis
4
+ # Use this command-line utility to create and update CrowdFlower jobs.
5
+ #
6
+ # == Examples
7
+ # Create a new job and populate it with data from a twitter feed.
8
+ # crowdflower -n -u 'http://search.twitter.com/search?q=milksteak'
9
+ #
10
+ # Other examples:
11
+ # crowdflower -q bar.doc
12
+ # crowdflower --verbose foo.html
13
+ #
14
+ # == Usage
15
+ # crowdflower [options] source_file
16
+ #
17
+ # For help use: crowdflower -h
18
+ #
19
+ # == Options
20
+ # -h, --help Displays help message
21
+ # -v, --version Display the version, then exit
22
+ # -q, --quiet Output as little as possible, overrides verbose
23
+ # -V, --verbose Verbose output
24
+ # -n, --new Create a new job
25
+ # -u, --uri Accepts an RSS, Atom, XML, or JSON data feed
26
+ # -f, --file Accepts .csv, .tsv, .xls, .xlsx, and .ods
27
+ # TO DO - add additional options
28
+ #
29
+ # == Author
30
+ # Mark Erdmann
31
+ #
32
+ # == Copyright
33
+ # Copyright (c) 2007 CrowdFlower. Licensed under the MIT License:
34
+ # http://www.opensource.org/licenses/mit-license.php
35
+
36
+
37
+ # TO DO - update Synopsis, Examples, etc
38
+ # TO DO - change license if necessary
39
+
40
+
41
+
42
+ require 'optparse'
43
+ require 'rdoc/usage'
44
+ require 'ostruct'
45
+ require 'date'
46
+
47
+
48
+ class App
49
+ VERSION = '0.0.1'
50
+
51
+ attr_reader :options
52
+
53
+ def initialize(arguments, stdin)
54
+ @arguments = arguments
55
+ @stdin = stdin
56
+
57
+ # Set defaults
58
+ @options = OpenStruct.new
59
+ @options.verbose = false
60
+ @options.quiet = false
61
+ # TO DO - add additional defaults
62
+ end
63
+
64
+ # Parse options, check arguments, then process the command
65
+ def run
66
+
67
+ if parsed_options? && arguments_valid?
68
+
69
+ puts "Start at #{DateTime.now}\n\n" if @options.verbose
70
+
71
+ output_options if @options.verbose # [Optional]
72
+
73
+ process_arguments
74
+ process_command
75
+
76
+ puts "\nFinished at #{DateTime.now}" if @options.verbose
77
+
78
+ else
79
+ output_usage
80
+ end
81
+
82
+ end
83
+
84
+ protected
85
+
86
+ def parsed_options?
87
+
88
+ # Specify options
89
+ opts = OptionParser.new
90
+ opts.on('-v', '--version') { output_version ; exit 0 }
91
+ opts.on('-h', '--help') { output_help }
92
+ opts.on('-V', '--verbose') { @options.verbose = true }
93
+ opts.on('-q', '--quiet') { @options.quiet = true }
94
+ opts.on('-n', '--new') { @options.newjob = true }
95
+ opts.on('-u', '--uri') { @options.uri = }
96
+ # TO DO - add additional options
97
+
98
+ opts.parse!(@arguments) rescue return false
99
+
100
+ process_options
101
+ true
102
+ end
103
+
104
+ # Performs post-parse processing on options
105
+ def process_options
106
+ @options.verbose = false if @options.quiet
107
+ end
108
+
109
+ def output_options
110
+ puts "Options:\n"
111
+
112
+ @options.marshal_dump.each do |name, val|
113
+ puts " #{name} = #{val}"
114
+ end
115
+ end
116
+
117
+ # True if required arguments were provided
118
+ def arguments_valid?
119
+ # TO DO - implement your real logic here
120
+ true if @arguments.length == 1
121
+ end
122
+
123
+ # Setup the arguments
124
+ def process_arguments
125
+ # TO DO - place in local vars, etc
126
+ end
127
+
128
+ def output_help
129
+ output_version
130
+ RDoc::usage() #exits app
131
+ end
132
+
133
+ def output_usage
134
+ RDoc::usage('usage') # gets usage from comments above
135
+ end
136
+
137
+ def output_version
138
+ puts "#{File.basename(__FILE__)} version #{VERSION}"
139
+ end
140
+
141
+ def process_command
142
+ # TO DO - do whatever this app does
143
+
144
+ #process_standard_input # [Optional]
145
+ end
146
+
147
+ def process_standard_input
148
+ input = @stdin.read
149
+ # TO DO - process input
150
+
151
+ # [Optional]
152
+ # @stdin.each do |line|
153
+ # # TO DO - process each line
154
+ #end
155
+ end
156
+ end
157
+
158
+
159
+ # TO DO - Add your Modules, Classes, etc
160
+
161
+
162
+ # Create and run the application
163
+ app = App.new(ARGV, STDIN)
164
+ app.run
File without changes
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{crowdflower}
8
+ s.version = "0.2.3"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Brian P O'Rourke", "Chris Van Pelt"]
12
+ s.date = %q{2010-02-22}
13
+ s.description = %q{A toolkit for interacting with CrowdFlower via the REST API.
14
+
15
+ This is alpha software. Have fun!
16
+
17
+ }
18
+ s.email = %q{brian@doloreslabs.com}
19
+ s.extra_rdoc_files = [
20
+ "LICENSE",
21
+ "README.rdoc"
22
+ ]
23
+ s.files = [
24
+ ".document",
25
+ ".gitignore",
26
+ "HISTORY.md",
27
+ "LICENSE",
28
+ "README.rdoc",
29
+ "Rakefile",
30
+ "VERSION",
31
+ "bindev/cl_skel.rb",
32
+ "bindev/crowdflower.rb",
33
+ "crowdflower.gemspec",
34
+ "lib/crowdflower.rb",
35
+ "lib/crowdflower/base.rb",
36
+ "lib/crowdflower/job.rb",
37
+ "lib/crowdflower/judgment.rb",
38
+ "lib/crowdflower/order.rb",
39
+ "lib/crowdflower/unit.rb",
40
+ "test/integration_tests.rb",
41
+ "test/sample.csv"
42
+ ]
43
+ s.homepage = %q{http://github.com/dolores/ruby-crowdflower}
44
+ s.rdoc_options = ["--charset=UTF-8"]
45
+ s.require_paths = ["lib"]
46
+ s.rubygems_version = %q{1.3.6}
47
+ s.summary = %q{a toolkit for the CrowdFlower API}
48
+ s.test_files = [
49
+ "test/integration_tests.rb"
50
+ ]
51
+
52
+ if s.respond_to? :specification_version then
53
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
+ s.specification_version = 3
55
+
56
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
57
+ s.add_runtime_dependency(%q<httparty>, [">= 0.4.3"])
58
+ else
59
+ s.add_dependency(%q<httparty>, [">= 0.4.3"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<httparty>, [">= 0.4.3"])
63
+ end
64
+ end
65
+
@@ -0,0 +1,47 @@
1
+ module CrowdFlower
2
+ @@key = nil
3
+ @@domain = nil
4
+
5
+ class UsageError < StandardError ; end
6
+
7
+ class APIError < StandardError
8
+ attr_reader :details
9
+
10
+ def initialize(hash)
11
+ @details = hash
12
+ super @details["message"]
13
+ end
14
+ end
15
+
16
+ module Defaults
17
+ def self.included(base)
18
+ base.send :include, HTTParty
19
+ base.send :headers, "accept" => "application/json"
20
+ base.send :format, :json
21
+ base.extend ClassMethods
22
+ end
23
+
24
+ module ClassMethods
25
+ def connect
26
+ unless CrowdFlower.key
27
+ raise UsageError, "Please establish a connection using 'CrowdFlower.connect!'"
28
+ end
29
+ self.base_uri CrowdFlower.domain
30
+ self.default_params :key => CrowdFlower.key
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.connect!(key, development = false)
36
+ @@domain = development ? "http://api.tsujigiri.local:4000/v1" : "https://api.crowdflower.com/v1"
37
+ @@key = key
38
+ end
39
+
40
+ def self.key
41
+ @@key
42
+ end
43
+
44
+ def self.domain
45
+ @@domain
46
+ end
47
+ end
@@ -0,0 +1,124 @@
1
+ module CrowdFlower
2
+ class Job
3
+ include Defaults
4
+ attr_reader :id
5
+
6
+ def initialize(job_id)
7
+ @id = job_id
8
+ Job.connect
9
+ end
10
+
11
+ def resource_uri
12
+ Job.resource_uri
13
+ end
14
+
15
+ def self.resource_uri
16
+ "/jobs"
17
+ end
18
+
19
+ def self.all
20
+ connect
21
+ get(resource_uri)
22
+ end
23
+
24
+ def self.upload(file, content_type, job_id = nil)
25
+ connect
26
+ job_uri = job_id ? "/#{job_id}" : ""
27
+ res = post("#{resource_uri}/#{job_uri}/upload",
28
+ :body => File.read(file),
29
+ :headers => custom_content_type(content_type))
30
+ if res["error"]
31
+ raise CrowdFlower::APIError.new(res["error"])
32
+ end
33
+ Job.new(res["id"])
34
+ end
35
+
36
+ # Creates a new empty Job in CrowdFlower.
37
+ def self.create
38
+ connect
39
+ res = post("#{resource_uri}/upload", :query => {:job => {:without_data => "true" } } )
40
+ if res["error"]
41
+ raise CrowdFlower::APIError.new(res["error"])
42
+ end
43
+ Job.new(res["id"])
44
+ end
45
+
46
+ def get(id = nil)
47
+ Job.get("#{resource_uri}/#{@id || id}")
48
+ end
49
+
50
+ # Returns an accessor for all the Units associated with this job.
51
+ # This enables you to do things like:
52
+ #
53
+ # * job.units.all
54
+ # * job.units.get [id]
55
+ # * job.units.create [data]
56
+ def units
57
+ Unit.new(self)
58
+ end
59
+
60
+ # Copies a job and optionally gold or all units.
61
+ # Parameters
62
+ # opts: Hash
63
+ # gold: when set to true copies gold units
64
+ # all_units: when set to true copies all units
65
+ def copy(opts = {})
66
+ res = Job.get("#{resource_uri}/#{@id}/copy", {:query => opts})
67
+ if res["error"]
68
+ raise CrowdFlower::APIError.new(res["error"])
69
+ end
70
+ Job.new(res["id"])
71
+ end
72
+
73
+ def status
74
+ Job.get("#{resource_uri}/#{@id}/ping")
75
+ end
76
+
77
+ def upload(file, content_type)
78
+ Job.upload(file, content_type, @id)
79
+ end
80
+
81
+ def legend
82
+ Job.get("#{resource_uri}/#{@id}/legend")
83
+ end
84
+
85
+ def download_csv(full = true, filename = nil)
86
+ filename ||= "#{full ? "f" : "a"}#{@id}.csv"
87
+ res = Job.get("#{resource_uri}/#{@id}.csv", {:format => :csv, :query => {:full => full}})
88
+ puts "Status... #{res.code.inspect}"
89
+ if res.code == 202
90
+ puts "CSV Generating... Trying again in 10 seconds."
91
+ Kernel.sleep 10
92
+ download_csv(full, filename)
93
+ else
94
+ puts "CSV written to: #{File.expand_path(filename)}"
95
+ File.open(filename, "w") {|f| f.puts res.body }
96
+ end
97
+ end
98
+
99
+ def pause
100
+ Job.get("#{resource_uri}/#{@id}/pause")
101
+ end
102
+
103
+ def resume
104
+ Job.get("#{resource_uri}/#{@id}/resume")
105
+ end
106
+
107
+ def cancel
108
+ Job.get("#{resource_uri}/#{@id}/cancel")
109
+ end
110
+
111
+ def update(data)
112
+ res = Job.put("#{resource_uri}/#{@id}.json", {:query => { :job => data }, :headers => { "Content-Length" => "0" } } )
113
+ if res["error"]
114
+ raise CrowdFlower::APIError.new(res["error"])
115
+ end
116
+ end
117
+
118
+ private
119
+ def self.custom_content_type(content_type)
120
+ #To preserve the accept header we are forced to merge the defaults back in...
121
+ Job.default_options[:headers].merge({"content-type" => content_type})
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,24 @@
1
+ module CrowdFlower
2
+ class Judgment
3
+ include Defaults
4
+ attr_reader :job
5
+
6
+ def initialize(job)
7
+ @job = job
8
+ Judgment.connect
9
+ end
10
+
11
+ def resource_uri
12
+ "/jobs/#{@job.id}/judgments"
13
+ end
14
+
15
+ #Pull every judgment
16
+ def all(page = 1, limit = 100, latest = true)#full = true
17
+ Judgment.get(resource_uri, {:query => {:limit => limit, :page => page, :latest => latest}})
18
+ end
19
+
20
+ def get(id)
21
+ Judgment.get("/#{id}")
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ module CrowdFlower
2
+ class Order
3
+ include Defaults
4
+ attr_reader :job
5
+
6
+ def initialize(job)
7
+ @job = job
8
+ Order.connect
9
+ end
10
+
11
+ def resource_uri
12
+ "/jobs/#{@job.id}/orders"
13
+ end
14
+
15
+ def debit(percentage = 100, channels = ["amt"])
16
+ Order.post(resource_uri, {:body => {:percentage => percentage, :channels => channels}})
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ module CrowdFlower
2
+ class Unit
3
+ include Defaults
4
+ attr_reader :job
5
+
6
+ def initialize(job)
7
+ @job = job
8
+ Unit.connect
9
+ end
10
+
11
+ def resource_uri
12
+ "/jobs/#{@job.id}/units"
13
+ end
14
+
15
+ def all(page = 1, limit = 1000)
16
+ Unit.get(resource_uri, {:query => {:limit => limit, :page => page}})
17
+ end
18
+
19
+ def get(id)
20
+ Unit.get("#{resource_uri}/#{id}")
21
+ end
22
+
23
+ def judgments(id)
24
+ Unit.get("#{resource_uri}/#{id}/judgments")
25
+ end
26
+
27
+ def create(data, gold = nil)
28
+ Unit.post(resource_uri, {:query => {:unit => {:data => data.to_json, :golden => gold}}})
29
+ end
30
+
31
+ def copy(unit_id, job_id, data = {})
32
+ Unit.get("#{resource_uri}/#{unit_id}/copy", {:query => {:unit => {:job_id => job_id, :data => data}}})
33
+ end
34
+
35
+ def split(on, with = " ")
36
+ Unit.get("#{resource_uri}/split", {:query => {:on => on, :with => with}})
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ require 'httparty'
2
+ require 'crowdflower/base'
3
+ require 'crowdflower/job'
4
+ require 'crowdflower/unit'
5
+ require 'crowdflower/judgment'
6
+ require 'crowdflower/order'
@@ -0,0 +1,94 @@
1
+ $: << File.dirname(__FILE__) + "/../lib"
2
+
3
+ require 'rubygems'
4
+ require 'ruby-crowdflower'
5
+ require 'json'
6
+
7
+ API_KEY = ENV["API_KEY"]
8
+
9
+ unless API_KEY && API_KEY.size > 5
10
+ puts <<EOF
11
+
12
+ These integration tests interact with api.crowdflower.com.
13
+ In order to run them, you will need to specify your API key.
14
+
15
+ This file is meant only as a reference - please understand
16
+ what you are doing before using the API - you are responsible
17
+ for your usage.
18
+
19
+ EOF
20
+
21
+ exit 1
22
+ end
23
+
24
+ # If you turn this on, tasks will be posted on CrowdFlower and your
25
+ # account will be charged. This is inadvisable for anyone other than
26
+ # CrowdFlower employees.
27
+ I_AM_RICH = ENV["CF_LIVE_TRANSACTIONS"] == "true"
28
+
29
+ if I_AM_RICH
30
+ puts "*** LIVE TRANSACTIONS ENABLED - THIS TEST RUN WILL BE CHARGED ***"
31
+ puts
32
+ end
33
+
34
+ def wait_until
35
+ 10.times do
36
+ if yield
37
+ return
38
+ end
39
+ sleep 1
40
+ end
41
+ raise "Condition not met in a reasonable time period"
42
+ end
43
+
44
+ def assert(truth)
45
+ unless truth
46
+ raise "Condition not met"
47
+ end
48
+ end
49
+
50
+ def say(msg)
51
+ $stdout.puts msg
52
+ end
53
+
54
+ say "Connecting to the API"
55
+ CrowdFlower.connect! API_KEY, true
56
+
57
+ say "Uploading a test CSV"
58
+ job = CrowdFlower::Job.upload(File.dirname(__FILE__) + "/sample.csv", "text/csv")
59
+
60
+ say "Trying to get all jobs"
61
+ assert CrowdFlower::Job.all.first["id"] == job.id
62
+
63
+ say "-- Waiting for CrowdFlower to process the data"
64
+ wait_until { job.get["units_count"] == 4 }
65
+
66
+ say "Adding some more data"
67
+ job.upload(File.dirname(__FILE__) + "/sample.csv", "text/csv")
68
+
69
+ say "-- Waiting for CrowdFlower to process the data"
70
+ # You could also register a webhook to have CrowdFlower notify your
71
+ # server.
72
+ wait_until { job.get["units_count"] == 8 }
73
+
74
+ say "Getting the units for this job."
75
+ assert job.units.all.size == 8
76
+
77
+ say "Copying the existing job to a new one."
78
+ job2 = job.copy :all_units => true
79
+
80
+ say "-- Waiting for CrowdFlower to finish copying the job."
81
+ # You could also register a webhook to have CrowdFlower notify your
82
+ # server.
83
+ wait_until { job2.get["units_count"] == 8 }
84
+
85
+ say "Checking the status of the job."
86
+ assert job.status["tainted_judgments"] == 0
87
+
88
+ say "Registering a webhook."
89
+ job.update :webhook_uri => "http://localhost:8080/crowdflower"
90
+
91
+ say "Webhook test needs to be written."
92
+ #job.test_webhook
93
+
94
+ say ">-< Tests complete. >-<"
data/test/sample.csv ADDED
@@ -0,0 +1,5 @@
1
+ "created_at","from_user","text"
2
+ "Sat, 10 Oct 2009 01:00:07 +0000","sogowave","CrowdFlower easily connects you with thousands of people online, around the clock. http://ow.ly/rpaT"
3
+ "Sat, 10 Oct 2009 01:00:05 +0000","SogoPR","CrowdFlower easily connects you with thousands of people online, around the clock. http://ow.ly/rpaS"
4
+ "Fri, 09 Oct 2009 15:00:07 +0000","SIIA_Software","...and don't forget: @CloudTrigger @businessobjects @longjump @CrowdFlower http://bit.ly/397y72"
5
+ "Fri, 02 Oct 2009 19:49:50 +0000","julzie","RT @rev2 CrowdFlower - Labor as a Service in a New Concept | Rev2.org http://retwt.me/v80H - GO LaaS!!"
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crowdflower
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 3
9
+ version: 0.2.3
10
+ platform: ruby
11
+ authors:
12
+ - Brian P O'Rourke
13
+ - Chris Van Pelt
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-02-22 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: httparty
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 4
31
+ - 3
32
+ version: 0.4.3
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: |+
36
+ A toolkit for interacting with CrowdFlower via the REST API.
37
+
38
+ This is alpha software. Have fun!
39
+
40
+ email: brian@doloreslabs.com
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files:
46
+ - LICENSE
47
+ - README.rdoc
48
+ files:
49
+ - .document
50
+ - .gitignore
51
+ - HISTORY.md
52
+ - LICENSE
53
+ - README.rdoc
54
+ - Rakefile
55
+ - VERSION
56
+ - bindev/cl_skel.rb
57
+ - bindev/crowdflower.rb
58
+ - crowdflower.gemspec
59
+ - lib/crowdflower.rb
60
+ - lib/crowdflower/base.rb
61
+ - lib/crowdflower/job.rb
62
+ - lib/crowdflower/judgment.rb
63
+ - lib/crowdflower/order.rb
64
+ - lib/crowdflower/unit.rb
65
+ - test/integration_tests.rb
66
+ - test/sample.csv
67
+ has_rdoc: true
68
+ homepage: http://github.com/dolores/ruby-crowdflower
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options:
73
+ - --charset=UTF-8
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project:
93
+ rubygems_version: 1.3.6
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: a toolkit for the CrowdFlower API
97
+ test_files:
98
+ - test/integration_tests.rb