biblesearch-api 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ spec/cassettes
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *~
20
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in biblesearch-api.gemspec
4
+ gemspec
data/HISTORY.md ADDED
@@ -0,0 +1,3 @@
1
+ 1.0.1 - Client now uses version 2 of the API, all calls now mostly uniform.
2
+ 0.0.2 - #versions and #verses now always respond in the plural, tested
3
+ 0.0.1 - Basic functionality, no tests
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Bryce Allison
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # BibleSearch::API
2
+
3
+ Ruby wrapper for BibleSearch API (bibles.org)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'biblesearch-api'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install biblesearch-api
18
+
19
+ ## Usage
20
+
21
+ ```ruby
22
+ biblesearch = BibleSearch.new('YOUR_API_KEY')
23
+
24
+ # Let's get some versions
25
+ versions = biblesearch.versions
26
+ spanish_versions = biblesearch.versions(:language => 'spa')
27
+ version = biblesearch.version('GNT')
28
+ # You can also add a language to a singular version
29
+ spanish_version = biblesearch.version('spa-GNT')
30
+
31
+ # Let's get some books
32
+ books = biblesearch.books('GNT')
33
+ # You can also provide a testament
34
+ old_testament_books = biblsearch.books('GNT', 'OT')
35
+ # A single book can be specified as a hash ...
36
+ book = biblesearch.book(:version_id => 'GNT', :book_id => '2Tim')
37
+ # ... or as a string
38
+ book = biblesearch.book('GNT:2Tim')
39
+
40
+ # Let's get some chapters for the book, either via hash ...
41
+ chapters = biblesearch.chapters(:version_id => 'GNT', :book_id => '2Tim')
42
+ # ... or string
43
+ chapters = biblesearch.chapters('GNT:2Tim')
44
+ # A single chapter can be specified as a hash ...
45
+ chapter = biblesearch.chapter(:version_id => 'GNT', :book_id => '2Tim', :chapter => 1)
46
+ # ... or as a string
47
+ chatper = biblesearch.chapter('GNT:2Tim.1')
48
+
49
+ # Let's get some verses
50
+ verses = biblesearch.verses("CEV:John.1","16","17")
51
+ # A single verse can be specified as a hash ...
52
+ verse = biblesearch.verse(:version_id => 'GNT', :book_id => 'Acts', :chapter => '8', :verse => '34')
53
+ # ... or as a string
54
+ verse = biblesearch.verse('GNT:Acts.8.34')
55
+
56
+ # Let's do a search
57
+ results = biblesearch.search('john 3:16') #passage search
58
+ results = biblesearch.search('mary') #keyword search
59
+
60
+ # Let's get some passages for a single version ...
61
+ passages = biblesearch.passages('john 3:16', :version => 'KJV')
62
+ # ... or for multiple versions
63
+ passages = biblesearch.passages('john 3:16', :versions => ['KJV', 'CEV'])
64
+ ```
65
+
66
+ ### Return values
67
+
68
+ All methods return a Hashie::Mash, and all of these mashes respond to #fums, which contains a string describing the FUMS for the call that was made.
69
+
70
+ Plural calls (#passages, #versions, #search, etc) respond to #collection with an array of mashes.
71
+
72
+ Singular calls (#version, #verse, etc) respond to #value with a mash.
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork it
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Test against all supported rubies (`rake overtest` (see below))
79
+ 4. Commit your changes (`git commit -am 'Added some feature'`)
80
+ 5. Push to the branch (`git push origin my-new-feature`)
81
+ 6. Create new Pull Request
82
+
83
+ ### Supported Rubies
84
+
85
+ As of this release, the following MRI versions are verified as supported:
86
+
87
+ * 1.8.7
88
+ * 1.9.2-p180
89
+ * 1.9.3
90
+
91
+ In order to test against all of them, an "overtest" rake task is supplied that uses RVM to test against each of the supported versions. You will, however, have to bundle against each of them independently.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+ require "bundler/gem_tasks"
5
+ require 'rake/testtask'
6
+
7
+ RUBY_TEST_VERSIONS = [
8
+ '1.8.7',
9
+ '1.9.2-p180',
10
+ '1.9.3'
11
+ ]
12
+
13
+ Rake::TestTask.new do |t|
14
+ t.libs.push "spec"
15
+ t.pattern = 'spec/**/*_spec.rb'
16
+ t.verbose = true
17
+ end
18
+
19
+ task :default => :test
20
+
21
+ desc 'Tests the library against several rubies'
22
+ task :overtest do
23
+ system "rvm #{RUBY_TEST_VERSIONS.map{|x| "#{x}@biblesearch-api"}.join(',')} do bundle exec rake test"
24
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/biblesearch-api/client_version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Bryce Allison"]
6
+ gem.email = ["bryceallison@gmail.com"]
7
+ gem.description = %q{Wrapper for the American Bible Society Bible Search API}
8
+ gem.summary = %q{Wrapper for the American Bible Society Bible Search API}
9
+ gem.homepage = "http://bibles.org"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "biblesearch-api"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = BibleSearch::VERSION
17
+
18
+ gem.add_dependency "oj"
19
+ gem.add_dependency "hashie"
20
+ gem.add_dependency "httparty"
21
+ gem.add_development_dependency 'vcr'
22
+ gem.add_development_dependency 'webmock'
23
+ gem.add_development_dependency 'minitest', '= 3.3.0'
24
+ gem.add_development_dependency 'rake', '= 0.9.2.2'
25
+ end
@@ -0,0 +1,87 @@
1
+ require 'biblesearch-api/client_version'
2
+
3
+ require 'biblesearch-api/endpoints/books'
4
+ require 'biblesearch-api/endpoints/chapters'
5
+ require 'biblesearch-api/endpoints/passages'
6
+ require 'biblesearch-api/endpoints/search'
7
+ require 'biblesearch-api/endpoints/verses'
8
+ require 'biblesearch-api/endpoints/versions'
9
+
10
+ require 'hashie'
11
+ require 'httparty'
12
+
13
+ directory = File.expand_path(File.dirname(__FILE__))
14
+
15
+ Hash.send :include, Hashie::HashExtensions
16
+
17
+ class BibleSearchError < StandardError
18
+ attr_reader :data
19
+
20
+ def initialize(data)
21
+ @data = data
22
+ super
23
+ end
24
+ end
25
+
26
+ class BibleSearch
27
+ include HTTParty
28
+
29
+ include Books
30
+ include Chapters
31
+ include Passages
32
+ include Search
33
+ include Verses
34
+ include Versions
35
+
36
+ no_follow = true
37
+ format :json
38
+
39
+ attr_accessor :api_key
40
+ def initialize(api_key, base_uri = 'bibles.org/v2')
41
+ self.class.base_uri base_uri
42
+ self.class.basic_auth(@api_key = api_key, 'X')
43
+ end
44
+
45
+ private
46
+ def mashup(response)
47
+ response = Hashie::Mash.new(response)
48
+ # => raise BibleSearchError.new("Code #{response.code} -- #{response.desc}") unless response.stat == "ok"
49
+ response
50
+ end
51
+
52
+ def required_keys_present?(hash, required)
53
+ hash.keys.sort_by {|key| key.to_s} == required.sort_by {|key| key.to_s}
54
+ end
55
+
56
+ def get_mash(*args)
57
+ api_response = self.class.get(*args)
58
+ result = {}
59
+ result['meta'] = {}
60
+ begin
61
+ result['meta'] = api_response['response'].delete('meta')
62
+ result['response'] = api_response['response']
63
+ rescue MultiJson::LoadError
64
+ result['meta']['message'] = api_response.body
65
+ ensure
66
+ result['meta']['http_code'] = api_response.code
67
+ return mashup(result)
68
+ end
69
+ end
70
+
71
+ def pluralize_result(result)
72
+ result.kind_of?(Array) ? result : [result]
73
+ end
74
+
75
+ def fumsify(api_result, value)
76
+ fumsified = Hashie::Mash.new
77
+ fumsified.fums = api_result.meta.fums
78
+
79
+ if value.kind_of?(Array)
80
+ fumsified.collection = value
81
+ else
82
+ fumsified.value = value
83
+ end
84
+
85
+ fumsified
86
+ end
87
+ end
@@ -0,0 +1,58 @@
1
+ require 'httparty'
2
+
3
+ module BibleSearch
4
+ class APIInterface
5
+ include HTTParty
6
+ include Singleton
7
+
8
+ no_follow = true
9
+ format :json
10
+
11
+ attr_accessor :api_key
12
+ def initialize(api_key, base_uri = 'bibles.org/v2')
13
+ self.class.base_uri base_uri
14
+ self.class.basic_auth(@api_key = api_key, 'X')
15
+ end
16
+
17
+ private
18
+ def mashup(response)
19
+ Hashie::Mash.new(response)
20
+ end
21
+
22
+ def required_keys_present?(hash, required)
23
+ hash.keys.sort_by {|key| key.to_s} == required.sort_by {|key| key.to_s}
24
+ end
25
+
26
+ def api_get(*args)
27
+ api_response = self.class.get(*args)
28
+ result = {}
29
+ result['meta'] = {}
30
+ begin
31
+ result['meta'] = api_response['response'].delete('meta')
32
+ result['response'] = api_response['response']
33
+ rescue MultiJson::LoadError
34
+ result['meta']['message'] = api_response.body
35
+ ensure
36
+ result['meta']['http_code'] = api_response.code
37
+ return mashup(result)
38
+ end
39
+ end
40
+
41
+ def pluralize_result(result)
42
+ result.kind_of?(Array) ? result : [result]
43
+ end
44
+
45
+ def fumsify(api_result, value)
46
+ fumsified = Hashie::Mash.new
47
+ fumsified.fums = api_result.meta.fums
48
+
49
+ if value.kind_of?(Array)
50
+ fumsified.collection = value
51
+ else
52
+ fumsified.value = value
53
+ end
54
+
55
+ fumsified
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ class BibleSearch
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,38 @@
1
+ class BibleSearch
2
+ module Books
3
+ def books(version_id, testament_id = nil)
4
+ api_endpoint = "/versions/#{version_id}/books.js"
5
+ api_endpoint += "?testament=#{testament_id}" unless testament_id.nil?
6
+
7
+ api_result = get_mash(api_endpoint)
8
+
9
+ books = []
10
+ if api_result.meta.http_code == 200
11
+ books = pluralize_result(api_result.response.books)
12
+ end
13
+
14
+ fumsify(api_result, books)
15
+ end
16
+
17
+ def book(book_sig)
18
+ if book_sig.is_a?(Hash)
19
+ unless required_keys_present?(book_sig, [:version_id, :book_id])
20
+ raise ArgumentError.new('Book signature hash must include :version_id and :book_id')
21
+ end
22
+ return book("#{book_sig[:version_id]}:#{book_sig[:book_id]}")
23
+ end
24
+
25
+ unless book_sig.match(/([A-Za-z0-9]+-)?[A-Za-z0-9]+:[A-Za-z0-9]+/)
26
+ raise ArgumentError.new('Book signature must be in the form "VERSION_ID:BOOK_ID"')
27
+ end
28
+
29
+ book = nil
30
+ api_result = get_mash("/books/#{book_sig}.js")
31
+ if api_result.meta.http_code == 200
32
+ book = api_result.response.books.first
33
+ end
34
+
35
+ fumsify(api_result, book)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,47 @@
1
+ class BibleSearch
2
+ module Chapters
3
+ def chapters(book_sig)
4
+ if book_sig.is_a?(Hash)
5
+ unless required_keys_present?(book_sig, [:version_id, :book_id])
6
+ raise ArgumentError.new('Book signature hash must include :version_id and :book_id')
7
+ end
8
+
9
+ return chapters("#{book_sig[:version_id]}:#{book_sig[:book_id]}")
10
+ end
11
+
12
+ unless book_sig.match(/([A-Za-z0-9]+-)?[A-Za-z0-9]+:[A-Za-z0-9]+/)
13
+ raise ArgumentError.new('Book signature must be in the form "VERSION_ID:BOOK_ID"')
14
+ end
15
+
16
+ chapters = []
17
+ api_result = get_mash("/books/#{book_sig}/chapters.js")
18
+ if api_result.meta.http_code == 200
19
+ chapters = pluralize_result(api_result.response.chapters)
20
+ end
21
+
22
+ fumsify(api_result, chapters)
23
+ end
24
+
25
+ def chapter(chapter_sig)
26
+ if chapter_sig.is_a?(Hash)
27
+ unless required_keys_present?(chapter_sig, [:version_id, :book_id, :chapter])
28
+ raise ArgumentError.new('Chapter signature hash must include :version_id, :book_id, and :chapter')
29
+ end
30
+
31
+ return chapter("#{chapter_sig[:version_id]}:#{chapter_sig[:book_id]}.#{chapter_sig[:chapter]}")
32
+ end
33
+
34
+ unless chapter_sig.match(/([A-Za-z0-9]+-)?[A-Za-z0-9]+:[A-Za-z0-9]+\.[0-9]+/)
35
+ raise ArgumentError.new('Chapter signature must be in the form "VERSION_ID:BOOK_ID.CHAPTER_NUMBER"')
36
+ end
37
+
38
+ chapter = nil
39
+ api_result = get_mash("/chapters/#{chapter_sig}.js")
40
+ if api_result.meta.http_code == 200
41
+ chapter = api_result.response.chapters.first
42
+ end
43
+
44
+ fumsify(api_result, chapter)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ class BibleSearch
2
+ module Passages
3
+ def passages(passage, options = {})
4
+ versions = options.delete(:versions)
5
+ unless versions.nil?
6
+ if versions.is_a?(Array)
7
+ versions = versions.join(',')
8
+ end
9
+ options[:version] = versions
10
+ end
11
+ options = options.merge({"q[]" => passage})
12
+
13
+ passages = []
14
+ api_result = get_mash("/passages.js", :query => options)
15
+ if api_result.meta.http_code == 200
16
+ passages = pluralize_result(api_result.response.search.result.passages)
17
+ end
18
+
19
+ fumsify(api_result, passages)
20
+ end
21
+ end
22
+ end