crunchbase-ruby-library 0.1.7 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +47 -0
- data/.travis.yml +12 -0
- data/Gemfile +4 -0
- data/README.md +44 -54
- data/Rakefile +4 -1
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/crunchbase-ruby-library.gemspec +15 -12
- data/lib/crunchbase.rb +12 -3
- data/lib/crunchbase/api.rb +110 -102
- data/lib/crunchbase/client.rb +50 -0
- data/lib/crunchbase/exception.rb +13 -11
- data/lib/crunchbase/model.rb +50 -48
- data/lib/crunchbase/model/acquired_by.rb +23 -20
- data/lib/crunchbase/model/acquiree.rb +2 -1
- data/lib/crunchbase/model/acquirer.rb +2 -1
- data/lib/crunchbase/model/acquisition.rb +16 -19
- data/lib/crunchbase/model/address.rb +4 -6
- data/lib/crunchbase/model/advisory_role.rb +2 -2
- data/lib/crunchbase/model/board_members_and_advisor.rb +10 -9
- data/lib/crunchbase/model/category.rb +6 -7
- data/lib/crunchbase/model/competitor.rb +3 -2
- data/lib/crunchbase/model/current_team.rb +7 -11
- data/lib/crunchbase/model/customer.rb +3 -2
- data/lib/crunchbase/model/degree.rb +4 -5
- data/lib/crunchbase/model/entity.rb +98 -108
- data/lib/crunchbase/model/error.rb +3 -4
- data/lib/crunchbase/model/featured_team.rb +19 -0
- data/lib/crunchbase/model/founded_company.rb +2 -3
- data/lib/crunchbase/model/founder.rb +3 -4
- data/lib/crunchbase/model/fund.rb +8 -11
- data/lib/crunchbase/model/fund_raise.rb +7 -8
- data/lib/crunchbase/model/funding_round.rb +29 -24
- data/lib/crunchbase/model/headquarter.rb +2 -1
- data/lib/crunchbase/model/image.rb +6 -7
- data/lib/crunchbase/model/investment.rb +20 -27
- data/lib/crunchbase/model/investor.rb +6 -7
- data/lib/crunchbase/model/ipo.rb +12 -12
- data/lib/crunchbase/model/job.rb +11 -10
- data/lib/crunchbase/model/location.rb +20 -11
- data/lib/crunchbase/model/member.rb +3 -4
- data/lib/crunchbase/model/membership.rb +7 -8
- data/lib/crunchbase/model/new.rb +5 -6
- data/lib/crunchbase/model/office.rb +3 -4
- data/lib/crunchbase/model/organization.rb +39 -38
- data/lib/crunchbase/model/organization_summary.rb +7 -8
- data/lib/crunchbase/model/owned_by.rb +4 -5
- data/lib/crunchbase/model/parent_location.rb +3 -3
- data/lib/crunchbase/model/past_team.rb +7 -11
- data/lib/crunchbase/model/person.rb +53 -46
- data/lib/crunchbase/model/person_summary.rb +13 -14
- data/lib/crunchbase/model/primary_affiliation.rb +6 -6
- data/lib/crunchbase/model/primary_image.rb +3 -3
- data/lib/crunchbase/model/primary_location.rb +8 -7
- data/lib/crunchbase/model/product.rb +14 -13
- data/lib/crunchbase/model/product_summary.rb +4 -5
- data/lib/crunchbase/model/school.rb +3 -2
- data/lib/crunchbase/model/search.rb +39 -40
- data/lib/crunchbase/model/search_result.rb +7 -6
- data/lib/crunchbase/model/simple_organization.rb +9 -10
- data/lib/crunchbase/model/sub_organization.rb +3 -4
- data/lib/crunchbase/model/video.rb +4 -5
- data/lib/crunchbase/model/website.rb +7 -11
- data/lib/crunchbase/request.rb +8 -0
- data/lib/crunchbase/request/client.rb +69 -0
- data/lib/crunchbase/version.rb +2 -1
- data/spec/crunchbase.yml.example +2 -2
- data/spec/crunchbase/client_spec.rb +25 -0
- data/spec/crunchbase/data/board_members_and_advisors/facebook.json +462 -0
- data/spec/crunchbase/data/categories/facebook.json +67 -0
- data/spec/crunchbase/data/current_team/facebook.json +4335 -0
- data/spec/crunchbase/data/featured_team/facebook.json +286 -0
- data/spec/crunchbase/data/funding_rounds/37bd05f961af726ba3c1b279da842805.json +484 -0
- data/spec/crunchbase/data/funding_rounds/facebook.json +2049 -0
- data/spec/crunchbase/data/headquarters/facebook.json +50 -0
- data/spec/crunchbase/data/investors/facebook.json +776 -0
- data/spec/crunchbase/data/news/facebook.json +1426 -0
- data/spec/crunchbase/data/news/facebook_2.json +1426 -0
- data/spec/crunchbase/data/offices/facebook.json +50 -0
- data/spec/crunchbase/data/organizations/crunchbase.json +2845 -0
- data/spec/crunchbase/data/organizations/ekohe.json +654 -0
- data/spec/crunchbase/data/organizations/facebook-without-relationships.json +45 -0
- data/spec/crunchbase/data/organizations/facebook.json +6723 -0
- data/spec/crunchbase/data/organizations/mx-media-llc.json +7 -0
- data/spec/crunchbase/data/past_team/facebook.json +4336 -0
- data/spec/crunchbase/data/people/facebook_founders.json +148 -0
- data/spec/crunchbase/data/people/mark-zuckerberg.json +2602 -0
- data/spec/crunchbase/data/websites/facebook.json +74 -0
- data/spec/crunchbase/model/board_members_and_advisor_spec.rb +39 -11
- data/spec/crunchbase/model/category_spec.rb +47 -0
- data/spec/crunchbase/model/current_team_spec.rb +50 -0
- data/spec/crunchbase/model/featured_team_spec.rb +40 -0
- data/spec/crunchbase/model/founders_spec.rb +49 -0
- data/spec/crunchbase/model/fund_raise_spec.rb +4 -24
- data/spec/crunchbase/model/funding_round_spec.rb +75 -32
- data/spec/crunchbase/model/headquarter_spec.rb +37 -0
- data/spec/crunchbase/model/investment_spec.rb +4 -15
- data/spec/crunchbase/model/investor_spec.rb +37 -0
- data/spec/crunchbase/model/new_spec.rb +86 -0
- data/spec/crunchbase/model/office_spec.rb +29 -9
- data/spec/crunchbase/model/organization_spec.rb +160 -34
- data/spec/crunchbase/model/past_team_spec.rb +36 -14
- data/spec/crunchbase/model/person_spec.rb +21 -19
- data/spec/crunchbase/model/product_spec.rb +4 -31
- data/spec/crunchbase/model/search_spec.rb +25 -49
- data/spec/crunchbase/model/website_spec.rb +36 -9
- data/spec/crunchbase/support/api_helper.rb +19 -0
- data/spec/spec_helper.rb +14 -4
- metadata +103 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59dae45ccc627c105545d3862e2978249476c664
|
4
|
+
data.tar.gz: 201f6b5b6e96b6ceb7c43f860f1479dc5bd39ba7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fa95c9721d6a6b73f2d952992198897b59da4d2f7e68f8bfa8b081b25fb8796a889015a87cceebeaaa175ec2ca7fb49f23a45be778f5e87239d6614325e5550
|
7
|
+
data.tar.gz: e20fa1269b918d8fe6466a62c7539c9b81a919007ab60490c305277723252cfebdbe946a4a9e6223d51ea8cb063f8fc50be1cab54ad4a2cef5d89a6b8756d37c
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# This is the configuration used to check the rubocop source code.
|
2
|
+
|
3
|
+
inherit_from: .rubocop_todo.yml
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
DisplayCopNames: true
|
7
|
+
TargetRubyVersion: 2.3
|
8
|
+
Exclude:
|
9
|
+
- '**/*.yml'
|
10
|
+
- 'tmp/**/*'
|
11
|
+
|
12
|
+
Style/StringLiterals:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Documentation:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
Style/RegexpLiteral:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
Style/SpaceInsideHashLiteralBraces:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Style/DotPosition:
|
25
|
+
EnforcedStyle: trailing
|
26
|
+
|
27
|
+
Style/FormatString:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
Lint/AssignmentInCondition:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Style/EmptyLinesAroundAccessModifier:
|
34
|
+
Enabled: false
|
35
|
+
|
36
|
+
Style/SingleLineBlockParams:
|
37
|
+
Enabled: false
|
38
|
+
|
39
|
+
Style/NumericLiterals:
|
40
|
+
Exclude:
|
41
|
+
- 'spec/**/*'
|
42
|
+
|
43
|
+
Style/StringLiteralsInInterpolation:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Style/CaseIndentation:
|
47
|
+
# Valid values are: case, end
|
48
|
+
IndentWhenRelativeTo: end
|
49
|
+
IndentOneStep: false
|
50
|
+
|
51
|
+
Lint/EndAlignment:
|
52
|
+
AlignWith: variable
|
53
|
+
|
54
|
+
Lint/UselessAssignment:
|
55
|
+
Enabled: false
|
56
|
+
|
57
|
+
Style/NumericLiterals:
|
58
|
+
Enabled: false
|
59
|
+
|
60
|
+
Metrics/BlockLength:
|
61
|
+
Exclude:
|
62
|
+
- "**/*_spec.rb"
|
63
|
+
|
64
|
+
Metrics/ModuleLength:
|
65
|
+
Exclude:
|
66
|
+
- "**/*_spec.rb"
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-08-28 16:18:43 +0800 using RuboCop version 0.45.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 7
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 53
|
12
|
+
|
13
|
+
# Offense count: 1
|
14
|
+
# Configuration parameters: CountComments.
|
15
|
+
Metrics/ClassLength:
|
16
|
+
Max: 250
|
17
|
+
|
18
|
+
# Offense count: 1
|
19
|
+
Metrics/CyclomaticComplexity:
|
20
|
+
Max: 7
|
21
|
+
|
22
|
+
# Offense count: 181
|
23
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives.
|
24
|
+
# URISchemes: http, https
|
25
|
+
Metrics/LineLength:
|
26
|
+
Max: 267
|
27
|
+
|
28
|
+
# Offense count: 7
|
29
|
+
# Configuration parameters: CountComments.
|
30
|
+
Metrics/MethodLength:
|
31
|
+
Max: 28
|
32
|
+
|
33
|
+
# Offense count: 49
|
34
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
35
|
+
# SupportedStyles: nested, compact
|
36
|
+
Style/ClassAndModuleChildren:
|
37
|
+
Enabled: false
|
38
|
+
|
39
|
+
# Offense count: 38
|
40
|
+
Style/Documentation:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
# Offense count: 16
|
44
|
+
# Configuration parameters: MinBodyLength.
|
45
|
+
Style/GuardClause:
|
46
|
+
Enabled: false
|
47
|
+
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# Crunchbase
|
2
2
|
|
3
|
-
Crunchbase API
|
3
|
+
Crunchbase API v3.1 - Ruby Library [CrunchBase Data Hub](https://data.crunchbase.com/v3.1/docs/using-the-api).
|
4
4
|
|
5
|
-
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/crunchbase-ruby-library.svg)](https://badge.fury.io/rb/crunchbase-ruby-library)
|
6
|
+
[![Build Status](https://travis-ci.org/encoreshao/crunchbase-ruby-library.svg?branch=master)](https://travis-ci.org/encoreshao/crunchbase-ruby-library)
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/github/encoreshao/crunchbase-ruby-library/badge.svg)](https://coveralls.io/github/encoreshao/crunchbase-ruby-library)
|
8
|
+
|
9
|
+
### How to installation
|
6
10
|
|
7
11
|
Add this line to your application's Gemfile:
|
8
12
|
|
@@ -16,82 +20,68 @@ Or install it yourself as:
|
|
16
20
|
|
17
21
|
$ gem install crunchbase-ruby-library
|
18
22
|
|
19
|
-
|
23
|
+
### Certificate (User Key)
|
20
24
|
|
21
|
-
|
25
|
+
cCeate the file `config/initializers/crunchbase.rb` in your rails project and add user_key.
|
22
26
|
|
23
27
|
require 'crunchbase'
|
24
28
|
|
25
|
-
Crunchbase::API.key
|
29
|
+
Crunchbase::API.key = 'user_key'
|
26
30
|
Crunchbase::API.debug = false
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
Retrieve the way, Please use Search Class. The Search Will Return a list consisting of objects of the OrganizationSummary | PersonSummary | ProductSummary type. Example:
|
31
|
-
|
32
|
-
Query Orgnization
|
33
|
-
|
34
|
-
Method 1
|
35
|
-
response = Crunchbase::Model::Search.search({query: "Google"}, 'organizations')
|
36
|
-
|
37
|
-
Method 2
|
38
|
-
response = Crunchbase::Model::Search.search({name: "Google"}, 'organizations')
|
39
|
-
|
40
|
-
Method 3
|
41
|
-
response = Crunchbase::Model::Search.search({domain_name: "google.com"}, 'organizations')
|
42
|
-
|
43
|
-
response.total_items || response.per_page || response.pages || response.current_page
|
44
|
-
response.results.each { |r| puts r.name }
|
45
|
-
|
32
|
+
### Creating request client
|
46
33
|
|
47
|
-
|
34
|
+
client = Crunchbase::Client.new
|
48
35
|
|
49
|
-
|
36
|
+
### Searchable items
|
50
37
|
|
51
|
-
|
38
|
+
- Organization
|
39
|
+
- Person
|
40
|
+
- Product
|
41
|
+
- IPO
|
42
|
+
- Acquisitions
|
43
|
+
- Funding Rounds
|
52
44
|
|
53
|
-
|
45
|
+
#### Searching...
|
54
46
|
|
55
|
-
|
47
|
+
* client.search({query: "Google"}, 'organizations') # Full text search of an Organization's name, aliases
|
48
|
+
* client.search({name: "Google"}, 'organizations') # Full text search limited to name and aliases
|
49
|
+
* client.search({domain_name: "google.com"}, 'organizations') # Text search of an Organization's domain_name
|
50
|
+
* client.search({name: "encore"}, 'people') # A full-text query of name only
|
51
|
+
* client.search({query: "encore"}, 'people') # A full-text query of name, title, and company
|
52
|
+
* client.search({types: "investor"}, 'people') # Filter by type (currently, either this is empty, or is simply "investor")
|
53
|
+
* client.search({}, 'products')
|
54
|
+
* client.search({}, 'ipos')
|
55
|
+
* client.search({}, 'acquisitions')
|
56
|
+
* client.search({}, 'funding-rounds')
|
56
57
|
|
57
|
-
response
|
58
|
+
returned response included data on below:
|
59
|
+
* results
|
60
|
+
* total_items
|
61
|
+
* per_page
|
62
|
+
* pages
|
63
|
+
* current_page
|
58
64
|
|
59
|
-
|
65
|
+
### Get Organization && RelationShips by the permalink
|
60
66
|
|
61
|
-
response =
|
62
|
-
|
63
|
-
response.results.each { |i| i.name }
|
64
|
-
|
65
|
-
## Get Organization && RelationShips
|
66
|
-
|
67
|
-
Get information by the permalink, Example:
|
68
|
-
|
69
|
-
response = Crunchbase::Model::Organization.get("facebook")
|
67
|
+
response = client.get('Organization', 'facebook')
|
70
68
|
|
71
69
|
Relationship objects [ primary_image founders current_team investors owned_by sub_organizations headquarters offices products categories customers competitors members memberships funding_rounds investments acquisitions acquired_by ipo funds websites images videos news ]
|
72
70
|
|
73
|
-
|
74
|
-
response.competitors_total_items
|
75
|
-
response.websites
|
71
|
+
# Methods - Get Organization with one relationship data
|
76
72
|
|
77
|
-
|
78
|
-
|
79
|
-
# Methods
|
80
|
-
|
81
|
-
past_team = Crunchbase::Model::PastTeam.organization_lists("facebook")
|
73
|
+
1. response = client.get('Organization', 'facebook', 'PastTeam')
|
82
74
|
past_team.results.collect { |p| [p.title, p.person.first_name] }
|
83
75
|
|
84
76
|
....
|
85
77
|
|
86
|
-
|
87
|
-
|
88
|
-
Get information by the permalink, Example:
|
78
|
+
### Get Person by the permalink
|
89
79
|
|
90
|
-
person =
|
80
|
+
person = client.get('Person', permalink)
|
91
81
|
|
92
82
|
#<Crunchbase::Model::Person:0x007fc185215f68 @type_name="Person", @uuid="a578dcf9859ec8b52182e3aa3c383b13", ...>
|
93
83
|
|
94
|
-
people =
|
84
|
+
people = client.list('Person', page)
|
95
85
|
|
96
86
|
people.results
|
97
87
|
|
@@ -101,7 +91,7 @@ Get information by the permalink, Example:
|
|
101
91
|
#<Crunchbase::Model::PersonSummary: ...>
|
102
92
|
...... ]
|
103
93
|
|
104
|
-
|
94
|
+
### Contributing
|
105
95
|
|
106
96
|
1. Fork it ( https://github.com/encoreshao/crunchbase-ruby-library/fork )
|
107
97
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
@@ -109,6 +99,6 @@ Get information by the permalink, Example:
|
|
109
99
|
4. Push to the branch (`git push origin my-new-feature`)
|
110
100
|
5. Create a new Pull Request
|
111
101
|
|
112
|
-
|
102
|
+
### Copyright
|
113
103
|
|
114
104
|
Copyright © 2015-05 Encore Shao. See LICENSE for details.
|
data/Rakefile
CHANGED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'crunchbase'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
require "pry"
|
12
|
+
Pry.start
|
13
|
+
|
14
|
+
# require 'irb'
|
15
|
+
# IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -1,25 +1,28 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'crunchbase/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'crunchbase-ruby-library'
|
8
9
|
spec.version = Crunchbase::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
10
|
+
spec.authors = ['Encore Shao']
|
11
|
+
spec.email = ['encore.shao@gmail.com']
|
12
|
+
spec.summary = 'A Ruby wrapper for Crunchbase API v3.1'
|
13
|
+
spec.description = 'A Ruby wrapper for Crunchbase API version 3.1'
|
14
|
+
spec.homepage = 'https://github.com/encoreshao/crunchbase-ruby-library'
|
15
|
+
spec.license = 'MIT'
|
15
16
|
|
16
17
|
spec.files = `git ls-files -z`.split("\x0")
|
17
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
20
|
+
spec.require_paths = ['lib']
|
20
21
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
23
|
+
spec.add_development_dependency 'rake'
|
24
|
+
spec.add_development_dependency 'pry'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
|
+
spec.add_development_dependency 'rspec-its'
|
27
|
+
spec.add_development_dependency 'rubocop'
|
25
28
|
end
|
data/lib/crunchbase.rb
CHANGED
@@ -1,12 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'singleton'
|
2
3
|
require 'time'
|
3
4
|
|
4
|
-
require
|
5
|
-
require 'crunchbase/
|
5
|
+
require 'json'
|
6
|
+
require 'crunchbase/version'
|
6
7
|
require 'crunchbase/model'
|
7
|
-
require
|
8
|
+
require 'crunchbase/request'
|
9
|
+
require 'crunchbase/client'
|
10
|
+
require 'crunchbase/api'
|
11
|
+
require 'crunchbase/exception'
|
8
12
|
|
9
13
|
module Crunchbase
|
14
|
+
API_VERSION = '3.1'
|
15
|
+
API_BASE_URL = 'https://api.crunchbase.com'
|
16
|
+
WEB_SITE_URL = 'https://www.crunchbase.com'
|
17
|
+
IMAGE_URL = 'https://res.cloudinary.com/crunchbase-production/'
|
18
|
+
|
10
19
|
class << self
|
11
20
|
end
|
12
21
|
end
|
data/lib/crunchbase/api.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'net/http'
|
4
5
|
|
@@ -12,157 +13,164 @@ require 'timeout'
|
|
12
13
|
|
13
14
|
module Crunchbase
|
14
15
|
class API
|
15
|
-
|
16
|
-
|
16
|
+
SUPPORTED_ENTITIES = {
|
17
|
+
'categories' => Model::Category,
|
18
|
+
'organizations' => Model::OrganizationSummary,
|
19
|
+
'people' => Model::PersonSummary,
|
20
|
+
'products' => Model::ProductSummary,
|
21
|
+
'ipos' => Model::Ipo,
|
22
|
+
'funding_rounds' => Model::FundingRound,
|
23
|
+
'funding-rounds' => Model::FundingRound,
|
24
|
+
'acquisitions' => Model::Acquisition,
|
25
|
+
'locations' => Model::Location,
|
26
|
+
'offices' => Model::Office,
|
27
|
+
'customers' => Model::Customer,
|
28
|
+
'degrees' => Model::Degree,
|
29
|
+
# 'experience' => nil,
|
30
|
+
'primary_affiliation' => Model::PrimaryAffiliation,
|
31
|
+
'videos' => Model::Video,
|
32
|
+
'founded_companies' => Model::FoundedCompany,
|
33
|
+
'primary_location' => Model::PrimaryLocation,
|
34
|
+
'advisor_at' => Model::AdvisoryRole,
|
35
|
+
'investors' => Model::Organization
|
36
|
+
}.freeze
|
17
37
|
|
18
38
|
@timeout_limit = 60
|
19
39
|
@redirect_limit = 2
|
20
|
-
@
|
21
|
-
@base_url = 'https://api.crunchbase.com'
|
22
|
-
@site_url = "https://www.crunchbase.com"
|
23
|
-
@image_url = "https://res.cloudinary.com/crunchbase-production/"
|
24
|
-
@debug = false
|
40
|
+
@debug = false
|
25
41
|
|
26
42
|
# Must be overridden in subclasses
|
27
|
-
RESOURCE_NAME =
|
28
|
-
RESOURCE_LIST =
|
43
|
+
RESOURCE_NAME = 'undefined'
|
44
|
+
RESOURCE_LIST = 'undefineds'
|
29
45
|
|
30
|
-
ORDER_CREATED_AT_ASC = 'created_at
|
31
|
-
ORDER_CREATED_AT_DESC = 'created_at
|
32
|
-
ORDER_UPDATED_AT_ASC = 'updated_at
|
33
|
-
ORDER_UPDATED_AT_DESC = 'updated_at
|
46
|
+
ORDER_CREATED_AT_ASC = 'created_at ASC'
|
47
|
+
ORDER_CREATED_AT_DESC = 'created_at DESC'
|
48
|
+
ORDER_UPDATED_AT_ASC = 'updated_at ASC'
|
49
|
+
ORDER_UPDATED_AT_DESC = 'updated_at DESC'
|
34
50
|
|
35
51
|
class << self
|
36
|
-
attr_accessor :timeout_limit, :redirect_limit, :key, :
|
52
|
+
attr_accessor :timeout_limit, :redirect_limit, :key, :debug
|
37
53
|
|
38
54
|
def api_url
|
39
|
-
|
55
|
+
API_BASE_URL.gsub(/\/$/, '') + '/v' + API_VERSION + '/'
|
40
56
|
end
|
41
|
-
end
|
42
57
|
|
43
|
-
|
44
|
-
|
58
|
+
def single_entity(permalink, entity_name)
|
59
|
+
raise CrunchException, 'Unsupported Entity Type' unless SUPPORTED_ENTITIES.keys.include?(entity_name)
|
45
60
|
|
46
|
-
|
47
|
-
|
61
|
+
fetch(permalink, entity_name)
|
62
|
+
end
|
48
63
|
|
49
|
-
|
64
|
+
# Returns the JSON parser, whether that's an instance of Yajl or JSON
|
65
|
+
def parser
|
66
|
+
return Yajl::Parser if defined?(Yajl)
|
50
67
|
|
51
|
-
# Returns the JSON parser, whether that's an instance of Yajl or JSON
|
52
|
-
def self.parser
|
53
|
-
if defined?(Yajl)
|
54
|
-
Yajl::Parser
|
55
|
-
else
|
56
68
|
JSON
|
57
69
|
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Fetches URI for the permalink interface.
|
61
|
-
def self.fetch(permalink, object_name)
|
62
|
-
get_json_response( api_url + "#{object_name}/#{permalink}" )
|
63
|
-
end
|
64
|
-
|
65
|
-
# Fetches URI for the search interface.
|
66
|
-
def self.search(options, resource_list)
|
67
|
-
options[:page] = 1 if options[:page].nil?
|
68
|
-
options[:order] = ORDER_CREATED_AT_ASC if options[:order].nil?
|
69
70
|
|
70
|
-
|
71
|
+
# Fetches URI for the permalink interface.
|
72
|
+
def fetch(permalink, kclass_name)
|
73
|
+
get_json_response(api_url + "#{kclass_name}/#{permalink}")
|
74
|
+
end
|
71
75
|
|
72
|
-
|
73
|
-
|
76
|
+
# Fetches URI for the search interface.
|
77
|
+
def search(options, resource_list)
|
78
|
+
options[:page] = 1 if options[:page].nil?
|
79
|
+
options[:order] = ORDER_CREATED_AT_ASC if options[:order].nil?
|
74
80
|
|
81
|
+
uri = api_url + "#{resource_list}?" + collect_parameters(options)
|
75
82
|
|
76
|
-
|
77
|
-
|
78
|
-
options[:page] = 1 if options[:page].nil?
|
79
|
-
model_name = options.delete(:model_name)
|
83
|
+
get_json_response(uri)
|
84
|
+
end
|
80
85
|
|
81
|
-
|
86
|
+
# Fetches URI for the search interface.
|
87
|
+
def list(options, resource_list)
|
88
|
+
options[:page] = 1 if options[:page].nil?
|
89
|
+
model_name = options.delete(:model_name) || SUPPORTED_ENTITIES[resource_list]
|
82
90
|
|
83
|
-
|
84
|
-
end
|
91
|
+
uri = api_url + "#{resource_list}?" + collect_parameters(options)
|
85
92
|
|
86
|
-
|
87
|
-
|
93
|
+
Model::Search.new options, get_json_response(uri), model_name
|
94
|
+
end
|
88
95
|
|
89
|
-
|
90
|
-
|
96
|
+
def collect_parameters(options)
|
97
|
+
require 'cgi'
|
91
98
|
|
92
|
-
|
93
|
-
|
94
|
-
end
|
99
|
+
options.map { |k, v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" }.join('&')
|
100
|
+
end
|
95
101
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
102
|
+
def organization_lists(permalink, category, options)
|
103
|
+
lists_for_category('organizations', permalink, category, options)
|
104
|
+
end
|
100
105
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
106
|
+
def person_lists(permalink, category, options)
|
107
|
+
lists_for_category('people', permalink, category, options)
|
108
|
+
end
|
105
109
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
model_name = options.delete(:model_name)
|
110
|
+
def funding_rounds_lists(permalink, category, options)
|
111
|
+
lists_for_category('funding-rounds', permalink, category, options)
|
112
|
+
end
|
110
113
|
|
111
|
-
|
114
|
+
def lists_for_category(classify_name, permalink, category, options)
|
115
|
+
options[:page] = 1 if options[:page].nil?
|
116
|
+
options[:order] = ORDER_CREATED_AT_ASC if options[:order].nil?
|
117
|
+
model_name = options.delete(:model_name)
|
112
118
|
|
113
|
-
|
114
|
-
end
|
119
|
+
uri = api_url + "#{classify_name}/#{permalink}/#{category}?#{collect_parameters(options)}"
|
115
120
|
|
116
|
-
|
117
|
-
|
118
|
-
# JSON contains an error.
|
119
|
-
def self.get_json_response(uri)
|
120
|
-
raise Crunchbase::Exception, "User key required, visit http://data.crunchbase.com" unless @key
|
121
|
-
uri = uri + "#{uri.match('\?') ? "&" : "?"}user_key=#{@key}"
|
121
|
+
Model::Search.new options, get_json_response(uri), model_name
|
122
|
+
end
|
122
123
|
|
123
|
-
|
124
|
-
|
125
|
-
|
124
|
+
# Gets specified URI, then parses the returned JSON. Raises Timeout error
|
125
|
+
# if request time exceeds set limit. Raises Exception if returned
|
126
|
+
# JSON contains an error.
|
127
|
+
def get_json_response(uri)
|
128
|
+
raise Exception, 'User key required, visit https://data.crunchbase.com/v3.1/docs' unless @key
|
129
|
+
uri += "#{uri =~ /\?/ ? '&' : '?'}user_key=#{@key}"
|
126
130
|
|
127
|
-
|
128
|
-
|
131
|
+
resp = Timeout.timeout(@timeout_limit) do
|
132
|
+
get_url_following_redirects(uri, @redirect_limit)
|
133
|
+
end
|
129
134
|
|
130
|
-
|
131
|
-
|
135
|
+
response = parser.parse(resp)
|
136
|
+
response = response[0] if response.is_a?(Array)
|
137
|
+
raise Exception, message: response['message'], status: response['status'] unless response['message'].nil?
|
132
138
|
|
133
|
-
|
134
|
-
|
139
|
+
response['data']
|
140
|
+
end
|
135
141
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
142
|
+
# Performs actual HTTP requests, recursively if a redirect response is
|
143
|
+
# encountered. Will raise HTTP error if response is not 200, 404, or 3xx.
|
144
|
+
def get_url_following_redirects(uri_str, limit = 10)
|
145
|
+
raise Exception, 'HTTP redirect too deep' if limit.zero?
|
140
146
|
|
141
|
-
|
147
|
+
uri = URI.parse(URI.encode(uri_str))
|
142
148
|
|
143
|
-
|
149
|
+
debugging(uri)
|
144
150
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
151
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
152
|
+
http.use_ssl = true if uri.scheme == 'https'
|
153
|
+
response = http.start do |h|
|
154
|
+
h.request Net::HTTP::Get.new(uri.request_uri)
|
155
|
+
end
|
150
156
|
|
151
|
-
|
157
|
+
case response
|
152
158
|
when Net::HTTPSuccess, Net::HTTPNotFound, Net::HTTPInternalServerError
|
153
159
|
response.body
|
154
160
|
when Net::HTTPRedirection
|
155
161
|
get_url_following_redirects(response['location'], limit - 1)
|
156
162
|
else
|
157
163
|
response.error!
|
164
|
+
end
|
158
165
|
end
|
159
|
-
end
|
160
166
|
|
161
|
-
|
162
|
-
|
163
|
-
puts "*** #{uri} ***"
|
164
|
-
puts "*"*120
|
165
|
-
end
|
167
|
+
def debugging(uri)
|
168
|
+
return unless debug
|
166
169
|
|
170
|
+
puts '*' * 140
|
171
|
+
puts "*** #{uri} ***"
|
172
|
+
puts '*' * 140
|
173
|
+
end
|
174
|
+
end
|
167
175
|
end
|
168
176
|
end
|