clarify 1.1.1 → 2.0.0.alpha.1

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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -16
  3. data/.rspec +2 -0
  4. data/.simplecov +3 -0
  5. data/.travis.yml +7 -0
  6. data/CHANGELOG.md +4 -0
  7. data/Dockerfile +11 -0
  8. data/Gemfile +2 -2
  9. data/LICENSE +1 -1
  10. data/README.md +202 -47
  11. data/Rakefile +62 -4
  12. data/clarify.gemspec +10 -7
  13. data/cucumber.yml +1 -0
  14. data/features/create-bundles.feature +10 -0
  15. data/features/delete-bundle.feature +7 -0
  16. data/features/identity-steps.feature +6 -0
  17. data/features/list-bundles.feature +13 -0
  18. data/features/search-bundles.feature +10 -0
  19. data/features/step_definitions/curied_url_steps.rb +6 -0
  20. data/features/step_definitions/error_steps.rb +4 -0
  21. data/features/step_definitions/http_verification_step.rb +4 -0
  22. data/features/step_definitions/identity_steps.rb +12 -0
  23. data/features/step_definitions/list_steps.rb +76 -0
  24. data/features/support/env.rb +36 -0
  25. data/features/support/lib/curies.rb +19 -0
  26. data/features/support/lib/customer.rb +41 -0
  27. data/features/support/lib/exceptions.rb +27 -0
  28. data/features/support/lib/names.rb +16 -0
  29. data/lib/clarify.rb +16 -14
  30. data/lib/clarify/bundle_repository.rb +26 -0
  31. data/lib/clarify/client.rb +51 -0
  32. data/lib/clarify/collection_iterator.rb +27 -0
  33. data/lib/clarify/configuration.rb +29 -7
  34. data/lib/clarify/errors.rb +22 -0
  35. data/lib/clarify/response.rb +29 -0
  36. data/lib/clarify/response_factory.rb +34 -0
  37. data/lib/clarify/responses/bundle.rb +11 -0
  38. data/lib/clarify/responses/collection.rb +31 -0
  39. data/lib/clarify/responses/no_body.rb +13 -0
  40. data/lib/clarify/responses/search_collection.rb +18 -0
  41. data/lib/clarify/responses/tracks.rb +15 -0
  42. data/lib/clarify/rest_client.rb +129 -0
  43. data/lib/clarify/version.rb +3 -1
  44. data/spec/clarify/bundle_repository_spec.rb +37 -0
  45. data/spec/clarify/client_spec.rb +93 -0
  46. data/spec/clarify/collection_iterator_spec.rb +86 -0
  47. data/spec/clarify/configuration_spec.rb +77 -0
  48. data/spec/clarify/errors_spec.rb +15 -0
  49. data/spec/clarify/response_factory_spec.rb +51 -0
  50. data/spec/clarify/response_spec.rb +69 -0
  51. data/spec/clarify/responses/bundle_spec.rb +8 -0
  52. data/spec/clarify/responses/collection_spec.rb +58 -0
  53. data/spec/clarify/responses/search_collection_spec.rb +40 -0
  54. data/spec/clarify/responses/tracks_spec.rb +18 -0
  55. data/spec/clarify/rest_client_spec.rb +222 -0
  56. data/spec/spec_helper.rb +4 -9
  57. data/src_readme/README_no_output.md +186 -0
  58. data/src_readme/examples/bundle_create.rb +11 -0
  59. data/src_readme/examples/bundle_fetch.rb +9 -0
  60. data/src_readme/examples/bundles_list_fetch.rb +11 -0
  61. data/src_readme/examples/bundles_paged_over.rb +8 -0
  62. data/src_readme/examples/bundles_search.rb +20 -0
  63. data/src_readme/examples/list_bundles.rb +6 -0
  64. data/src_readme/examples/searches_paged_over.rb +10 -0
  65. data/src_readme/examples/setup.rb +5 -0
  66. data/src_readme/make.rb +56 -0
  67. data/src_readme/readme.md.erb +55 -0
  68. metadata +127 -62
  69. data/LICENSE.txt +0 -24
  70. data/examples/create.rb +0 -14
  71. data/examples/delete.rb +0 -12
  72. data/examples/list.rb +0 -14
  73. data/examples/search.rb +0 -26
  74. data/examples/test.rb +0 -15
  75. data/lib/clarify/bundle.rb +0 -40
  76. data/lib/clarify/metadata.rb +0 -26
  77. data/lib/clarify/request.rb +0 -37
  78. data/lib/clarify/search.rb +0 -10
  79. data/lib/clarify/track.rb +0 -40
  80. data/spec/lib/clarify/bundle_spec.rb +0 -43
  81. data/spec/lib/clarify/configuration_spec.rb +0 -19
  82. data/spec/lib/clarify/metadata_spec.rb +0 -36
  83. data/spec/lib/clarify/search_spec.rb +0 -22
  84. data/spec/lib/clarify/track_spec.rb +0 -81
@@ -6,8 +6,8 @@ require 'clarify/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'clarify'
8
8
  spec.version = Clarify::VERSION
9
- spec.authors = ['rubygeek']
10
- spec.email = ['nola@rubygeek.com']
9
+ spec.authors = ['Clarify Inc.']
10
+ spec.email = ['support@clarify.io']
11
11
  spec.summary = 'Search audio and video in a few lines of code'
12
12
  spec.description = 'Use the Clarify API to make your audio and video files searchable in just a few lines of code.'
13
13
  spec.homepage = 'http://www.clarify.io'
@@ -18,9 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'httparty', '~> 0.13', '>= 0.13.1'
22
- spec.add_development_dependency 'bundler', '~> 1.5'
23
- spec.add_development_dependency 'rake', '~> 10.0', '>= 10.0.0'
24
- spec.add_development_dependency 'rspec', '~> 3.0', '>= 3.0.0'
25
- spec.add_development_dependency 'debugger', '~> 1.6', '>= 1.6.8'
21
+ spec.add_development_dependency 'bundler', '~> 1.5'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'cucumber', '~> 1.3.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+ spec.add_development_dependency 'rspec-expectations', '~> 3.2.0'
26
+ spec.add_development_dependency 'rubocop', '~> 0.29.0'
27
+ spec.add_development_dependency 'simplecov', '~> 0.9.0'
26
28
  end
29
+
@@ -0,0 +1 @@
1
+ default: --color
@@ -0,0 +1,10 @@
1
+ Feature: As a user of the API, I am able to create a bundle.
2
+ Scenario: A user has added a new media file for processing.
3
+ Given I am using the environment's API key
4
+ And I know the following urls referenced as:
5
+ | name | URL |
6
+ | media:dorothy | http://media.clarify.io/audio/books/dorothyandthewizardinoz_01_baum_64kb.mp3 |
7
+ When I create a bundle named "Wizard of Oz" with the media url "[media:dorothy]"
8
+ When I request a list of bundles
9
+ Then I should get the HTTP status code 200
10
+ And my results should incude a bundle named "Wizard of Oz"
@@ -0,0 +1,7 @@
1
+ Feature: As a user of the API, I am able to delete a bundle.
2
+ Scenario: A user has added a new media file for processing.
3
+ Given I am using the environment's API key
4
+ And I have a bundle named "K.C."
5
+ When I delete my bundle
6
+ Then the server should not list my bundle
7
+
@@ -0,0 +1,6 @@
1
+ Feature: As an unauthenticated user, I get an exception that I can handle.
2
+ Scenario: I have not entered an API key, but attempt to connect anyway.
3
+ Given I am not using an API key
4
+ When I request a list of bundles without authentication
5
+ Then the response should be rejected with a 401 Unauthorized status code
6
+
@@ -0,0 +1,13 @@
1
+ Feature: As a user of the API, I am able to list my submitted bundles.
2
+ Scenario: I am building an index page to my bundle collection.
3
+ Given I am using the documentation API key
4
+ And I know the following urls referenced as:
5
+ | name | URL |
6
+ | media:future-of-women-flying | http://archive.org/download/Greatest_Speeches_of_the_20th_Century/TheFutureofWomeninFlying_64kb.mp3 |
7
+ | media:watergate-tapes | http://ia700200.us.archive.org/18/items/Greatest_Speeches_of_the_20th_Century/OnReleasingtheWatergateTapes_64kb.mp3 |
8
+ | media:resignation-address | http://ia600200.us.archive.org/18/items/Greatest_Speeches_of_the_20th_Century/ResignationAddress-1974_64kb.mp3 |
9
+ When I request a list of bundles
10
+ Then I should get the HTTP status code 200
11
+ And my results should include a track with the URL "[media:future-of-women-flying]"
12
+ And my results should include a track with the URL "[media:watergate-tapes]"
13
+ And my results should include a track with the URL "[media:resignation-address]"
@@ -0,0 +1,10 @@
1
+
2
+ Feature: As a user of the API, I am able to search for bundles based on the content.
3
+ Scenario: I am building a search functionality into my application.
4
+ Given I am using the documentation API key
5
+ And I know the following urls referenced as:
6
+ | name | URL |
7
+ | media:future-of-women-flying | http://archive.org/download/Greatest_Speeches_of_the_20th_Century/TheFutureofWomeninFlying_64kb.mp3 |
8
+ When I search my bundles for the text "women"
9
+ Then I should get the HTTP status code 200
10
+ And my results should include a track with the URL "[media:future-of-women-flying]"
@@ -0,0 +1,6 @@
1
+ Given(/^I know the following urls referenced as:$/) do |table|
2
+ table.map_headers! { |header| header.downcase.to_sym }
3
+ table.hashes.each do |row|
4
+ curies[row[:name]] = row[:url]
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+
2
+ Then(/^the response should be rejected with a 401 Unauthorized status code$/) do
3
+ expect(exceptions.caught.class.to_s).to eq('Clarify::UnauthenticatedError')
4
+ end
@@ -0,0 +1,4 @@
1
+
2
+ Then(/^I should get the HTTP status code (\d+)$/) do |code|
3
+ expect(@result.http_status_code).to eq code.to_i
4
+ end
@@ -0,0 +1,12 @@
1
+
2
+ Given(/^I am using the documentation API key$/) do
3
+ customer.log_in_as_docs
4
+ end
5
+
6
+ Given(/^I am not using an API key$/) do
7
+ customer.clear_api_key
8
+ end
9
+
10
+ Given(/^I am using the environment's API key$/) do
11
+ customer.log_in_via_environment
12
+ end
@@ -0,0 +1,76 @@
1
+
2
+ When(/^I request a list of bundles without authentication$/) do
3
+ begin
4
+ @result = customer.bundle_repository.fetch
5
+ rescue Clarify::StandardError => err
6
+ exceptions.caught = err
7
+ end
8
+ end
9
+
10
+ When(/^I request a list of bundles$/) do
11
+ @result = customer.bundle_repository.fetch
12
+ end
13
+
14
+ When(/^I search my bundles for the text "(.*?)"$/) do |query_string|
15
+ @result = customer.bundle_repository.search(query_string)
16
+ end
17
+
18
+ Then(/^my results should include a track with the URL "(.*?)"$/) do |url|
19
+ if @result.is_a? Clarify::Responses::SearchCollection
20
+ urls = @result.map { |_, bundle_url| bundle_url }
21
+ else
22
+ urls = @result.to_a
23
+ end
24
+
25
+ bundles = urls.map { |bundle_url| customer.restclient.get(bundle_url) }
26
+
27
+ tracks = bundles.map do |bundle|
28
+ customer.restclient.get(bundle.relation('clarify:tracks'))
29
+ end
30
+ media_urls = tracks.map do |tracks_resource|
31
+ tracks_resource.map { |track| track['media_url'] }
32
+ end.flatten
33
+
34
+ expect(media_urls).to include(curies.resolve(url))
35
+ end
36
+
37
+ # rubocop:disable Metrics/LineLength
38
+ When(/^I create a bundle named "(.*?)" with the media url "(.*?)"$/) do |name, url|
39
+ # rubocop:enable Metrics/LineLength
40
+ bundle = {
41
+ name: names.translate(name),
42
+ media_url: curies.resolve(url)
43
+ }
44
+ customer.bundle_repository.create!(bundle)
45
+ end
46
+
47
+ Then(/^my results should incude a bundle named "(.*?)"$/) do |name|
48
+ all_results = Clarify::CollectionIterator.new(customer.restclient, @result)
49
+ bundles = all_results.map do |item|
50
+ customer.restclient.get(item)
51
+ end
52
+ bundle_names = bundles.map(&:name)
53
+
54
+ expect(bundle_names).to include(names.translate(name))
55
+ end
56
+
57
+ Given(/^I have a bundle named "(.*?)"$/) do |name|
58
+ bundle = {
59
+ name: names.translate(name)
60
+ }
61
+ @my_bundle = customer.bundle_repository.create!(bundle)
62
+ end
63
+
64
+ When(/^I delete my bundle$/) do
65
+ customer.bundle_repository.delete!(@my_bundle)
66
+ end
67
+
68
+ Then(/^the server should not list my bundle$/) do
69
+ result = customer.bundle_repository.fetch
70
+ all_results = Clarify::CollectionIterator.new(customer.restclient, result)
71
+ bundle_urls = all_results.map do |item|
72
+ item['href']
73
+ end
74
+
75
+ expect(bundle_urls).to_not include(@my_bundle.relation('self'))
76
+ end
@@ -0,0 +1,36 @@
1
+
2
+ $LOAD_PATH << File.dirname(__FILE__) + '/lib/'
3
+ $LOAD_PATH << File.dirname(__FILE__) + '/../../lib/'
4
+
5
+ require 'simplecov'
6
+ require 'clarify'
7
+ require 'customer'
8
+ require 'exceptions'
9
+ require 'curies'
10
+
11
+ # EnvHelpers is
12
+ class EnvHelpers
13
+ def customer
14
+ @customer ||= ClarifyTests::Customer.new
15
+ end
16
+
17
+ def exceptions
18
+ @exceptions ||= ClarifyTests::Exceptions.new
19
+ end
20
+
21
+ def curies
22
+ @curies ||= ClarifyTests::Curies.new
23
+ end
24
+
25
+ def names
26
+ @names ||= ClarifyTests::Names.new
27
+ end
28
+ end
29
+
30
+ World do
31
+ EnvHelpers.new
32
+ end
33
+
34
+ After do
35
+ exceptions.raise_pending!
36
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module ClarifyTests
3
+ # The Curies class helps improve readability in URL-based tests by
4
+ # introducing a replacable reference.
5
+ class Curies
6
+ def initialize
7
+ @curies = {}
8
+ end
9
+
10
+ def []=(name, value)
11
+ @curies["[#{name}]"] = value
12
+ end
13
+
14
+ def resolve(url)
15
+ return url unless url[0] == '['
16
+ @curies.fetch(url)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+
2
+ module ClarifyTests
3
+ # The Customer represents a user of the API. The Customer might do things like
4
+ # log in with particular keys, or create RestClients, Configurations, etc.
5
+ class Customer
6
+ attr_reader :api_key
7
+
8
+ def initialize
9
+ end
10
+
11
+ def log_in_as_docs
12
+ self.api_key = 'docs-api-key'
13
+ end
14
+
15
+ def log_in_via_environment
16
+ self.api_key = ENV.fetch('CLARIFY_API_KEY')
17
+ end
18
+
19
+ def clear_api_key
20
+ self.api_key = ''
21
+ end
22
+
23
+ def api_key=(val)
24
+ @api_key = val
25
+
26
+ @client = nil
27
+ end
28
+
29
+ def bundle_repository
30
+ client.bundle_repository
31
+ end
32
+
33
+ def restclient
34
+ client.restclient
35
+ end
36
+
37
+ def client
38
+ @client ||= Clarify::Client.new(api_key: api_key)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+
2
+ module ClarifyTests
3
+ # Used for catching and re-throwing exceptions used in tests. Guarantees that
4
+ # an exception won't be swalloawed when integrated with After commands.
5
+ class Exceptions
6
+ attr_writer :caught
7
+
8
+ def initialize
9
+ @caught = nil
10
+ end
11
+
12
+ def caught
13
+ exception = @caught
14
+ @caught = nil
15
+
16
+ exception
17
+ end
18
+
19
+ def raise_pending!
20
+ fail @caught if exception?
21
+ end
22
+
23
+ def exception?
24
+ !@caught.nil?
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+
2
+ require 'securerandom'
3
+
4
+ module ClarifyTests
5
+ # Take names you use in a test and make them unique, guaranteeing two tests
6
+ # can't trample on the same account.
7
+ class Names
8
+ def translate(name)
9
+ "#{uuid}{#{name}}"
10
+ end
11
+
12
+ def uuid
13
+ @uuid ||= SecureRandom.uuid
14
+ end
15
+ end
16
+ end
@@ -1,17 +1,19 @@
1
- require "clarify/version"
2
- require "clarify/configuration"
3
- require "clarify/bundle"
4
- require "clarify/request"
5
- require "clarify/metadata"
6
- require "clarify/track"
7
- require "clarify/search"
8
1
 
2
+ # The Clarify API SDK
9
3
  module Clarify
10
- class << self
11
- attr_accessor :configuration
12
- end
13
- def self.configure
14
- self.configuration ||= Configuration.new
15
- yield(configuration)
16
- end
17
4
  end
5
+
6
+ require 'clarify/bundle_repository'
7
+ require 'clarify/rest_client'
8
+ require 'clarify/configuration'
9
+ require 'clarify/errors'
10
+ require 'clarify/client'
11
+ require 'clarify/response'
12
+ require 'clarify/response_factory'
13
+ require 'clarify/responses/bundle'
14
+ require 'clarify/responses/collection'
15
+ require 'clarify/responses/search_collection'
16
+ require 'clarify/responses/no_body'
17
+ require 'clarify/collection_iterator'
18
+ require 'clarify/responses/tracks'
19
+ require 'clarify/version'
@@ -0,0 +1,26 @@
1
+
2
+ module Clarify
3
+ # A simple entrypoint to the API. Exposes access to search and CRUD
4
+ # operations on Bundles.
5
+ class BundleRepository
6
+ def initialize(restclient)
7
+ @restclient = restclient
8
+ end
9
+
10
+ def fetch
11
+ @restclient.get('/v1/bundles')
12
+ end
13
+
14
+ def search(query_string)
15
+ @restclient.get('/v1/search', query: query_string)
16
+ end
17
+
18
+ def create!(about)
19
+ @restclient.post('/v1/bundles', about)
20
+ end
21
+
22
+ def delete!(bundle)
23
+ @restclient.delete(bundle.relation!('self'))
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+
2
+ module Clarify
3
+ # The Client simplifies the configuration and bootstrapping of the restclient
4
+ # and bundle repository.
5
+ class Client
6
+ def initialize(config, opts = {})
7
+ @config = config
8
+ @klass_restclient = opts.fetch(:rest_client, Clarify::RestClient)
9
+ @klass_configuration = opts.fetch(:configuration, Clarify::Configuration)
10
+ @klass_bundle_repository = opts.fetch(:bundle_repository,
11
+ Clarify::BundleRepository)
12
+ @klass_iterator = opts.fetch(:iterator, Clarify::CollectionIterator)
13
+ end
14
+
15
+ def get(url, params = {})
16
+ restclient.get(url, params)
17
+ end
18
+
19
+ def put(url, params = {})
20
+ restclient.put(url, params)
21
+ end
22
+
23
+ def post(url, params = {})
24
+ restclient.post(url, params)
25
+ end
26
+
27
+ def delete(url, params = {})
28
+ restclient.delete(url, params)
29
+ end
30
+
31
+ def pager(collection)
32
+ @klass_iterator.new(restclient, collection)
33
+ end
34
+
35
+ def bundles
36
+ bundle_repository
37
+ end
38
+
39
+ def bundle_repository
40
+ @bundle_repository ||= @klass_bundle_repository.new(restclient)
41
+ end
42
+
43
+ def restclient
44
+ @restclient ||= @klass_restclient.new(configuration)
45
+ end
46
+
47
+ def configuration
48
+ @configuration ||= @klass_configuration.new(@config)
49
+ end
50
+ end
51
+ end