crowd_finder 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 70826c47d3675b7abbc6e1c0cf6ad55cba6c2d94
4
+ data.tar.gz: b6a01b53df7d5c1bebe4b85142da1f5c14d9b229
5
+ SHA512:
6
+ metadata.gz: bddb08a1602e106b7976aa20026ea098612af030c37fdd1cb29525a3a9435894a8efb976b1e7db5940219e8cabe5aff2cd8b3b636f40f881c888a370d3f28157
7
+ data.tar.gz: 4be035ccbd91d26a145d2128c488c54258b488c2140e71fcf42ad7395df2015911afe45dcb8fe006654c364a2a215385244247ca0c3de797ef583e2633855c7e
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "crowd_finder"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Daniel Ziv"]
9
+ spec.email = ["Daniel@shake.cards"]
10
+ spec.description = %q{Get all the data you need from crowdfunding campaigns}
11
+ spec.summary = %q{Crowd funding sites scraper}
12
+ spec.homepage = "https://github.com/DanielRasta/crowd_finder"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency 'json'
21
+ spec.add_development_dependency 'time'
22
+ spec.add_development_dependency 'open-uri'
23
+ spec.add_development_dependency 'open_uri_redirections'
24
+ spec.add_development_dependency 'nokogiri'
25
+ spec.add_development_dependency 'uri'
26
+
27
+ end
@@ -0,0 +1,26 @@
1
+ ###
2
+ # Influenced by this great tutorial
3
+ # http://metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/
4
+ ###
5
+
6
+ module AbstractInterface
7
+
8
+ class InterfaceNotImplementedError < NoMethodError
9
+ end
10
+
11
+ def self.included(klass)
12
+ klass.send(:include, AbstractInterface::Methods)
13
+ klass.send(:extend, AbstractInterface::Methods)
14
+ end
15
+
16
+ module Methods
17
+
18
+ def api_not_implemented(klass)
19
+ caller.first.match(/in \`(.+)\'/)
20
+ method_name = $1
21
+ raise AbstractInterface::InterfaceNotImplementedError.new("#{klass.class.name} needs to implement '#{method_name}' for interface #{self.name}!")
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,80 @@
1
+ require "abstract_interface"
2
+ require "sites_module"
3
+ require 'json'
4
+ require 'time'
5
+
6
+ class BaseFinder
7
+ include AbstractInterface
8
+
9
+ # Members
10
+
11
+ @url = ""
12
+ @body = ""
13
+
14
+ # Base
15
+
16
+ def set(new_value)
17
+ @url = new_value
18
+ @body = Sites::get_html(new_value)
19
+ end
20
+
21
+ def reload
22
+ @body = Sites::get_html(@url)
23
+ end
24
+
25
+ def to_json
26
+ my_hash = {:name => project_name,
27
+ :precentage => precentage,
28
+ :deadline => deadline,
29
+ :days_to_go => days_to_go,
30
+ :backers_count => num_of_backers,
31
+ :twitter_link => twitter_link,
32
+ :pledged => pledged,
33
+ :goal => goal}
34
+ return JSON.generate(my_hash)
35
+ rescue => e
36
+ ""
37
+ end
38
+
39
+ # Calculated
40
+
41
+ def precentage
42
+ p = pledged.gsub!(/[^0-9A-Za-z]/, '').to_f
43
+ g = goal.gsub!(/[^0-9A-Za-z]/, '').to_f
44
+ ((p/g)*100).round
45
+ rescue => e
46
+ ""
47
+ end
48
+
49
+ def days_to_go
50
+ ((deadline - Time.new)/(60*60*24)).floor
51
+ rescue => e
52
+ ""
53
+ end
54
+
55
+ # Implementation
56
+
57
+ def project_name
58
+ BaseFinder.api_not_implemented(self)
59
+ end
60
+
61
+ def num_of_backers
62
+ BaseFinder.api_not_implemented(self)
63
+ end
64
+
65
+ def twitter_link
66
+ BaseFinder.api_not_implemented(self)
67
+ end
68
+
69
+ def pledged
70
+ BaseFinder.api_not_implemented(self)
71
+ end
72
+
73
+ def test_print
74
+ BaseFinder.api_not_implemented(self)
75
+ end
76
+
77
+ def goal
78
+ BaseFinder.api_not_implemented(self)
79
+ end
80
+ end
@@ -0,0 +1,17 @@
1
+ # CrowdFinder.new('http://www.headstart.co.il/project.aspx?id=18568')
2
+
3
+
4
+ require "finders_factory"
5
+ require "sites_module"
6
+
7
+
8
+ module CrowdFinder
9
+ def self.new(url)
10
+ unless Sites::valid?(url)
11
+ raise "#{url} is invalid URL"
12
+ else
13
+ site_name = Sites::get_site_name(url)
14
+ findr = FindersFactory.build(site_name.to_sym,url)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require "kickstarter_finder"
2
+ require "headstart_finder"
3
+
4
+ class FindersFactory
5
+
6
+ def self.build(p_shape,p_url)
7
+ case p_shape
8
+ when :kickstarter
9
+ ret_class = KickstarterFinder.new
10
+ when :headstart
11
+ ret_class = HeadstartFinder.new
12
+ end
13
+
14
+ ret_class.set(p_url)
15
+ return ret_class
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ require 'base_finder'
2
+
3
+ class HeadstartFinder < BaseFinder
4
+
5
+ def test_print
6
+ "I'm #{self.class.name} and my url is #{@url}"
7
+ rescue => e
8
+ ""
9
+ end
10
+
11
+ def project_name
12
+ @body.css('.leftpanel')[0].css('h1').text.gsub("\n", ' ').squeeze(' ')
13
+ rescue => e
14
+ ""
15
+ end
16
+
17
+ def days_to_go
18
+ @body.css('.projectstatus').css('.bb').css('.l').css('div')[0].text.gsub("\n", ' ').gsub("\r", ' ').squeeze(' ')
19
+ rescue => e
20
+ ""
21
+ end
22
+
23
+ def deadline
24
+ "N/A"
25
+ end
26
+
27
+ def num_of_backers
28
+ @body.css('.projectstatus').css('.bb').css('.r').css('.t1').text.gsub("\n", ' ').gsub("\r", ' ').squeeze(' ')
29
+ rescue => e
30
+ ""
31
+ end
32
+
33
+ def twitter_link
34
+ ""
35
+ end
36
+
37
+ def pledged
38
+ @body.css('.projectstatus').css('.cu').text.gsub('\n', '').gsub("\n", ' ').gsub("\r", ' ').squeeze(' ')
39
+ rescue => e
40
+ ""
41
+ end
42
+
43
+ def goal
44
+ @body.css('.projectstatus').css('.pl').text.gsub('\n', '').gsub("\n", ' ').gsub("\r", ' ').squeeze(' ')
45
+ rescue => e
46
+ ""
47
+ end
48
+
49
+ end
@@ -0,0 +1,48 @@
1
+ require 'base_finder'
2
+
3
+ class KickstarterFinder < BaseFinder
4
+
5
+ def test_print
6
+ "I'm #{self.class.name} and my url is #{@url}"
7
+ rescue => e
8
+ ""
9
+ end
10
+
11
+ def project_name
12
+ @body.css('title')[0].text
13
+ rescue => e
14
+ ""
15
+ end
16
+
17
+ def num_of_backers
18
+ @body.css('div#backers_count').text.to_i
19
+ rescue => e
20
+ ""
21
+ end
22
+
23
+ def twitter_link
24
+ @body.css('.js-twitter-share')[0]['href']
25
+ rescue => e
26
+ ""
27
+ end
28
+
29
+ def pledged
30
+ @body.css('.stat-item')[1].css('data').text
31
+ rescue => e
32
+ ""
33
+ end
34
+
35
+ def goal
36
+ @body.css('.stat-item')[1].css('.money').text
37
+ rescue => e
38
+ ""
39
+ end
40
+
41
+ # Override
42
+
43
+ def deadline
44
+ Time.parse(@body.css('.ksr_page_timer')[0]["data-end_time"])
45
+ rescue => e
46
+ ""
47
+ end
48
+ end
@@ -0,0 +1,34 @@
1
+ ###
2
+ # Good guide
3
+ # http://ruby.bastardsbook.com/chapters/html-parsing/
4
+ ###
5
+
6
+ require 'open-uri'
7
+ require 'open_uri_redirections'
8
+ require 'nokogiri'
9
+ require 'uri'
10
+
11
+
12
+ module Sites
13
+ def self.get_html(p_url)
14
+ if valid?(p_url)
15
+ source = open(p_url, :allow_redirections => :safe){|f|f.read}
16
+ page = Nokogiri::HTML(source)
17
+ end
18
+ end
19
+
20
+ def self.valid?(url)
21
+ uri = URI.parse(url)
22
+ uri.kind_of?(URI::HTTP)
23
+ rescue URI::InvalidURIError
24
+ false
25
+ end
26
+
27
+ def self.get_site_name(url)
28
+ full_url = URI.parse(url).host.downcase
29
+ full_url.split(".")[1].downcase
30
+ rescue URI::InvalidURIError
31
+ ""
32
+ end
33
+
34
+ end
data/test/test.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "crowd_finder"
2
+ puts CrowdFinder.new('http://www.headstart.co.il/project.aspx?id=18568').to_json
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crowd_finder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Ziv
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: time
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: open-uri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: open_uri_redirections
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: uri
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Get all the data you need from crowdfunding campaigns
98
+ email:
99
+ - Daniel@shake.cards
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - crowd_finder..gemspec
105
+ - lib/abstract_interface.rb
106
+ - lib/base_finder.rb
107
+ - lib/crowd_finder.rb
108
+ - lib/finders_factory.rb
109
+ - lib/headstart_finder.rb
110
+ - lib/kickstarter_finder.rb
111
+ - lib/sites_module.rb
112
+ - test/test.rb
113
+ homepage: https://github.com/DanielRasta/crowd_finder
114
+ licenses:
115
+ - MIT
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubyforge_project:
133
+ rubygems_version: 2.0.14
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: Crowd funding sites scraper
137
+ test_files:
138
+ - test/test.rb