crunchbase-ruby-library 0.1.7 → 0.3.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.
- 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
|
+
[](https://badge.fury.io/rb/crunchbase-ruby-library)
|
|
6
|
+
[](https://travis-ci.org/encoreshao/crunchbase-ruby-library)
|
|
7
|
+
[](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
|