scouter 0.0.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 (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +56 -0
  8. data/Rakefile +7 -0
  9. data/bin/scouter +26 -0
  10. data/lib/scouter/base/connection.rb +12 -0
  11. data/lib/scouter/base/object.rb +78 -0
  12. data/lib/scouter/base/version.rb +3 -0
  13. data/lib/scouter/buffer.rb +49 -0
  14. data/lib/scouter/facebook.rb +31 -0
  15. data/lib/scouter/feedly.rb +39 -0
  16. data/lib/scouter/google_plus.rb +83 -0
  17. data/lib/scouter/hatena_bookmark.rb +31 -0
  18. data/lib/scouter/linkedin.rb +38 -0
  19. data/lib/scouter/pinterest.rb +38 -0
  20. data/lib/scouter/pocket.rb +55 -0
  21. data/lib/scouter/twitter.rb +38 -0
  22. data/lib/scouter.rb +62 -0
  23. data/scouter.gemspec +29 -0
  24. data/spec/fixtures/scouter/buffer_google.json +2 -0
  25. data/spec/fixtures/scouter/buffer_yahoo.json +2 -0
  26. data/spec/fixtures/scouter/facebook_yahoo.json +15 -0
  27. data/spec/fixtures/scouter/facebook_yahoo_google.json +26 -0
  28. data/spec/fixtures/scouter/feedly_morizyun_feed.json +2 -0
  29. data/spec/fixtures/scouter/feedly_morizyun_hp.json +1 -0
  30. data/spec/fixtures/scouter/feedly_yahoo_news.json +2 -0
  31. data/spec/fixtures/scouter/hatenabookmark_yahoo.json +2 -0
  32. data/spec/fixtures/scouter/hatenabookmark_yahoo_google.json +2 -0
  33. data/spec/fixtures/scouter/linkedin_google.json +2 -0
  34. data/spec/fixtures/scouter/linkedin_yahoo.json +2 -0
  35. data/spec/fixtures/scouter/pinterest_google.json +2 -0
  36. data/spec/fixtures/scouter/pinterest_yahoo.json +2 -0
  37. data/spec/fixtures/scouter/pocket_google.html +30 -0
  38. data/spec/fixtures/scouter/pocket_morizyun_feed.html +30 -0
  39. data/spec/fixtures/scouter/pocket_morizyun_hp.html +30 -0
  40. data/spec/fixtures/scouter/pocket_yahoo.html +30 -0
  41. data/spec/fixtures/scouter/twitter_google.json +2 -0
  42. data/spec/fixtures/scouter/twitter_yahoo.json +2 -0
  43. data/spec/scouter/buffer_spec.rb +28 -0
  44. data/spec/scouter/facebook_spec.rb +36 -0
  45. data/spec/scouter/feedly_spec.rb +37 -0
  46. data/spec/scouter/google_plus_spec.rb +27 -0
  47. data/spec/scouter/hatena_bookmark_spec.rb +27 -0
  48. data/spec/scouter/linkedin_spec.rb +26 -0
  49. data/spec/scouter/pinterest_spec.rb +26 -0
  50. data/spec/scouter/pocket_spec.rb +26 -0
  51. data/spec/scouter/twitter_spec.rb +26 -0
  52. data/spec/scouter_spec.rb +82 -0
  53. data/spec/spec_helper.rb +72 -0
  54. metadata +225 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 416bbec5e85311a84f8efb202b6f90c634ff3d0c
4
+ data.tar.gz: be09b3a49c84bfe4c35a52ed4557ffa7f653a225
5
+ SHA512:
6
+ metadata.gz: 3d1b1812b31c5a94bb4b4c2dea8907a202da340f83d320c54696e63553fca78e900bbf4bcc033be2fe9397b93a88a6390059d4ef04e089694c75fd29d36876cb
7
+ data.tar.gz: 00f51fd971b0ee2ee5362c83f08c371de125ceb5870fa9fb9e57c8eaa1ba367e942dc511580d2fc108e860950e2f8035a6cbc94ab85c118d9af6cf162df1048c
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ *.iml
15
+ mkmf.log
16
+ /vendor/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in scouter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 morizyun
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,56 @@
1
+ # Scouter
2
+
3
+ Get share count in Buffer/Facebook/Feedly/GooglePlus/HatenaBookmark/Linkedin/Pinterest/Pocket/Twitter
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'scouter'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install scouter
20
+
21
+ ## Usage Command Line
22
+
23
+ scouter -u [page url]
24
+
25
+ ## Usage Ruby Program
26
+
27
+ require 'scouter'
28
+
29
+ results, errors = SocialCounter.new('http://google.com')
30
+ results.each do |url, service|
31
+ puts url #=> http://www.yahoo.co.jp
32
+ puts service.buffer #=> 129
33
+ puts service.facebook #=> 166458
34
+ puts service.googleplus #=> 139198
35
+ puts service.hatenabookmark #=> 13466
36
+ puts service.linkedin #=> 216
37
+ puts service.pinterest #=> 1
38
+ puts service.twitter #=> 1358112
39
+ end
40
+
41
+ if you want to get social count in facebook & twitter
42
+
43
+ results, errors = SocialCounter.new('http://google.com', [Scouter::Facebook, Scouter::Twitter])
44
+ results.each do |url, service|
45
+ puts url #=> http://www.yahoo.co.jp
46
+ puts service.facebook #=> 166458
47
+ puts service.twitter #=> 1358112
48
+ end
49
+
50
+ ## Contributing
51
+
52
+ 1. Fork it ( https://github.com/[my-github-username]/scouter/fork )
53
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
54
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
55
+ 4. Push to the branch (`git push origin my-new-feature`)
56
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
data/bin/scouter ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ #coding: utf-8
3
+
4
+ require 'thor'
5
+ require 'scouter'
6
+ require 'pry'
7
+
8
+ class Command < Thor
9
+ default_command :all
10
+
11
+ desc 'all', 'all social share count'
12
+ option :url, :type => :string, :aliases => :'-u', :desc => 'url'
13
+ def all
14
+ reulsts, errors = Scouter.get_count(options[:url])
15
+ puts errors unless errors.empty?
16
+
17
+ reulsts.each do |url, item|
18
+ puts "url: #{url}"
19
+ item.each do |name, count|
20
+ puts "#{name}: #{count}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ Command.start
@@ -0,0 +1,12 @@
1
+ module Scouter
2
+ module Base
3
+ module Connection
4
+ # get response by url
5
+ # @param [String] url url which returns json
6
+ # @return [Hash] json object
7
+ def get_response(url)
8
+ open(url).read
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,78 @@
1
+ require_relative 'connection'
2
+
3
+ module Scouter
4
+ module Base
5
+ class Object
6
+ extend Scouter::Base::Connection
7
+
8
+ # get Count By URL
9
+ # @param [String or Array] urls
10
+ def self.get_count(urls)
11
+ urls = check_and_trans_url(urls)
12
+ results, errors = {}, []
13
+ urls.each_slice(ONE_TIME_URL_MAX) do |u|
14
+ res, error = get_and_parse_response(u)
15
+ errors << error && next if error
16
+ results.merge!(res)
17
+ end
18
+ res_hash = Hashie::Mash.new(results)
19
+ return [res_hash, errors]
20
+ end
21
+
22
+ private
23
+
24
+ # Get service name
25
+ # @return [String] urls URL list
26
+ # @return [String] service name
27
+ def self.get_and_parse_response(urls)
28
+ url_str = api_url(urls)
29
+ json = get_response(url_str)
30
+ res = parse_response(json, urls)
31
+ return [res, nil]
32
+ rescue => e
33
+ message = "#{e.message}, urls: #{urls}"
34
+ return [nil, message]
35
+ end
36
+
37
+ # Get service name
38
+ # @return [String] service name
39
+ def self.service_name
40
+ self.name.to_s.downcase.gsub(/^(.*::)/, '')
41
+ end
42
+
43
+ # Check and transform urls to Array
44
+ # @return [String] service name
45
+ def self.check_and_trans_url(url)
46
+ url = to_array(url)
47
+ raise ArgumentError, "#{url} is not String and Array" unless url.class == Array
48
+ return url
49
+ end
50
+
51
+ # Transform Array or String to Array
52
+ # @param [Array or String] item
53
+ # @return [Array or nil]
54
+ def self.to_array(item)
55
+ case item.class.to_s
56
+ when 'Array'
57
+ item
58
+ when 'String'
59
+ [item]
60
+ else
61
+ nil
62
+ end
63
+ end
64
+
65
+ # Parse response data for response (For Override)
66
+ # @param [Hashie::Mash] response
67
+ # @return [Hash] urls & count
68
+ def self.parse_response(response, url = nil)
69
+ end
70
+
71
+ # build API URL (For Override)
72
+ # @param [String] url
73
+ # @return [String] API urls
74
+ def self.api_url(url)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ module Scouter
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,49 @@
1
+ module Scouter
2
+ class Buffer < Scouter::Base::Object
3
+ END_POINT = 'https://api.bufferapp.com/1'.freeze
4
+
5
+ # get Buffer Share Count
6
+ # @param [String or Array] urls
7
+ def self.get_count(urls)
8
+ urls = check_and_trans_url(urls)
9
+ results, errors = {}, []
10
+ urls.each_with_index do |u, idx|
11
+ sleep(WAIT_SEC) if idx != 0
12
+ res, error = get_and_parse_response(u)
13
+ errors << error && next if error
14
+ results.merge!(res)
15
+ end
16
+ res_hash = Hashie::Mash.new(results)
17
+ return [res_hash, errors]
18
+ end
19
+
20
+ private
21
+
22
+ # Get and parse response data
23
+ # @return [String] urls URL list
24
+ # @return [String] service name
25
+ def self.get_and_parse_response(url)
26
+ html = get_response(api_url(url))
27
+ res = parse_response(html, url)
28
+ return [res, nil]
29
+ rescue => e
30
+ message = "#{e.message}, url: #{url}"
31
+ return [nil, message]
32
+ end
33
+
34
+ # build Feedly API URL
35
+ # @param [String] url
36
+ # @return [String] API url
37
+ def self.api_url(url)
38
+ "#{END_POINT}/links/shares.json?url=#{url}"
39
+ end
40
+
41
+ # Parse json data for response
42
+ # @param [Hash] json
43
+ # @return [Hash] url & count
44
+ def self.parse_response(json, url)
45
+ res = JSON.parse(json)
46
+ { url => { self.service_name => res['shares'] } }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,31 @@
1
+ module Scouter
2
+ class Facebook < Scouter::Base::Object
3
+ END_POINT = 'https://graph.facebook.com'.freeze
4
+
5
+ private
6
+
7
+ # build Facebook Graph API url
8
+ # @param [Array] url
9
+ # @return [String] API url
10
+ def self.api_url(url)
11
+ str = url.map{ |u| "%27#{URI.escape(u)}%27" }.join(',')
12
+ "#{END_POINT}/fql?q=SELECT%20url,%20total_count%20FROM%20link_stat%20WHERE%20url%20in%20(#{str})"
13
+ end
14
+
15
+ # Parse json data of response
16
+ # @param [Hash] json
17
+ # @return [Hash] url & count
18
+ def self.parse_response(json, urls = nil)
19
+ parse_response_item(JSON.parse(json)['data'])
20
+ end
21
+
22
+ def self.parse_response_item(json_list)
23
+ results = {}
24
+ json_list.each do |json|
25
+ url = json['url']
26
+ results[url] = { self.service_name => json['total_count'] }
27
+ end
28
+ results
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,39 @@
1
+ module Scouter
2
+ class Feedly < Scouter::Base::Object
3
+ END_POINT = 'http://cloud.feedly.com/v3'.freeze
4
+
5
+ # get Feedly Count
6
+ # @param [String or Array] urls
7
+ def self.get_count(urls)
8
+ urls = check_and_trans_url(urls)
9
+ results, errors = {}, []
10
+ urls.each_with_index do |u, idx|
11
+ sleep(WAIT_SEC) if idx != 0
12
+ res, error = get_and_parse_response(u)
13
+ errors << error && next if error
14
+ results.merge!(res)
15
+ end
16
+ res_hash = Hashie::Mash.new(results)
17
+ return [res_hash, errors]
18
+ end
19
+
20
+ private
21
+
22
+ # build Feedly API URL
23
+ # @param [String] url
24
+ # @return [String] API url
25
+ def self.api_url(url)
26
+ escaped_url = CGI.escape(url)
27
+ "#{END_POINT}/feeds/feed%2F#{escaped_url}"
28
+ end
29
+
30
+ # Parse json data for response
31
+ # @param [Hash] json
32
+ # @return [Hash] url & count
33
+ def self.parse_response(json, url)
34
+ res = JSON.parse(json)
35
+ return {} if res.empty?
36
+ { url => { self.service_name => res['subscribers'] } }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,83 @@
1
+ module Scouter
2
+ class GooglePlus < Scouter::Base::Object
3
+ API_KEY = 'AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQ'.freeze
4
+
5
+ # get Google Plus Count
6
+ # @param [String or Array] urls
7
+ def self.get_count(urls)
8
+ urls = check_and_trans_url(urls)
9
+ results, errors = {}, []
10
+ urls.each_with_index do |u, idx|
11
+ sleep(WAIT_SEC) if idx != 0
12
+ res, error = get_and_parse_response(u)
13
+ errors << error && next if error
14
+ results.merge!(res)
15
+ end
16
+ res_hash = Hashie::Mash.new(results)
17
+ return [res_hash, errors]
18
+ end
19
+
20
+ private
21
+
22
+ # Get and parse response
23
+ # @return [String] urls URL list
24
+ # @return [String] service name
25
+ def self.get_and_parse_response(url)
26
+ json = get_response(url)
27
+ res = parse_response(json, url)
28
+ return [res, nil]
29
+ rescue => e
30
+ message = "#{e.message}, url: #{url}"
31
+ return [nil, message]
32
+ end
33
+
34
+ # get json data from API
35
+ # @param [String] url
36
+ # @return [Hash] response from API
37
+ def self.get_response(url)
38
+ option = {'Content-Type' => 'application/json'}
39
+ request = Net::HTTP::Post.new(api_uri.request_uri, option)
40
+ request.body = [{
41
+ jsonrpc: '2.0',
42
+ method: 'pos.plusones.get',
43
+ apiVersion: 'v1',
44
+ key: 'p',
45
+ id: 'p',
46
+ params: {
47
+ id: url,
48
+ userId: '@viewer',
49
+ groupId: '@self',
50
+ nolog: true,
51
+ }
52
+ }].to_json
53
+
54
+ Net::HTTP.start(api_uri.host, api_uri.port, :use_ssl => true) { |http|
55
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
56
+ http.request(request)
57
+ }.body
58
+ end
59
+
60
+ # Build url for api
61
+ # @param [Hash] json
62
+ # @return [String] API url
63
+ def self.api_uri
64
+ URI.parse("https://clients6.google.com/rpc?key=#{API_KEY}")
65
+ end
66
+
67
+ # Parse json data of response
68
+ # @param [Hash] response
69
+ # @return [Hash] url & count
70
+ def self.parse_response(json_list, url)
71
+ results = {}
72
+
73
+ json_list = JSON.parse(json_list)
74
+ json_list.map do |j|
75
+ count = j['result']['metadata']['globalCounts']['count'].to_i
76
+ results[url] = { self.service_name => count }
77
+ end
78
+
79
+ results
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,31 @@
1
+ module Scouter
2
+ class HatenaBookmark < Scouter::Base::Object
3
+ END_POINT = 'http://api.b.st-hatena.com'.freeze
4
+
5
+ private
6
+
7
+ # build Hatena Bookmark Count API URL
8
+ # @param [Array] url
9
+ # @return [String] API url
10
+ def self.api_url(url)
11
+ url_str = url.map{ |u| "url=#{URI.escape(u)}" }.join('&')
12
+ "#{END_POINT}/entry.counts?#{url_str}"
13
+ end
14
+
15
+ # Parse json data of response
16
+ # @param [Hash] response
17
+ # @return [Hash] url & count
18
+ def self.parse_response(response, urls = nil)
19
+ parse_response_item(JSON.parse(response))
20
+ end
21
+
22
+ def self.parse_response_item(json_list)
23
+ results = {}
24
+ json_list.each do |json|
25
+ url = json[0]
26
+ results[url] = { self.service_name => json[1] }
27
+ end
28
+ results
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ module Scouter
2
+ class Linkedin < Scouter::Base::Object
3
+ END_POINT = 'https://www.linkedin.com/countserv'.freeze
4
+
5
+ # get Linkedin Count
6
+ # @param [String or Array] urls
7
+ def self.get_count(urls)
8
+ urls = check_and_trans_url(urls)
9
+ results, errors = {}, []
10
+ urls.each_with_index do |u, idx|
11
+ sleep(WAIT_SEC) if idx != 0
12
+ res, error = get_and_parse_response(u)
13
+ errors << error && next if error
14
+ results.merge!(res)
15
+ end
16
+ res_hash = Hashie::Mash.new(results)
17
+ return [res_hash, errors]
18
+ end
19
+
20
+ private
21
+
22
+ # Build url for api
23
+ # @param [Hash] json
24
+ # @return [String] API url
25
+ def self.api_url(url)
26
+ "#{END_POINT}/count/share?url=#{url}&format=json"
27
+ end
28
+
29
+ # Parse json data for response
30
+ # @param [Hash] json
31
+ # @return [Hash] url & count
32
+ def self.parse_response(json, url)
33
+ res = JSON.parse(json)
34
+ { res['url'] => { self.service_name => res['count'] } }
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,38 @@
1
+ module Scouter
2
+ class Pinterest < Scouter::Base::Object
3
+ END_POINT = 'http://api.pinterest.com/v1'.freeze
4
+
5
+ # get Pinterest Count
6
+ # @param [String or Array] urls
7
+ def self.get_count(urls)
8
+ urls = check_and_trans_url(urls)
9
+ results, errors = {}, []
10
+ urls.each_with_index do |u, idx|
11
+ sleep(WAIT_SEC) if idx != 0
12
+ res, error = get_and_parse_response(u)
13
+ errors << error && next if error
14
+ results.merge!(res)
15
+ end
16
+ res_hash = Hashie::Mash.new(results)
17
+ return [res_hash, errors]
18
+ end
19
+
20
+ private
21
+
22
+ # Build url for api
23
+ # @param [Hash] json
24
+ # @return [String] API url
25
+ def self.api_url(url)
26
+ "#{END_POINT}/urls/count.json?url=#{url}"
27
+ end
28
+
29
+ # Parse json data for response
30
+ # @param [Hash] json
31
+ # @return [Hash] url & count
32
+ def self.parse_response(json, url)
33
+ res = JSON.parse(json.gsub(/(receiveCount\(|\))/, ''))
34
+ { url => { self.service_name => res['count'] } }
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,55 @@
1
+ module Scouter
2
+ class Pocket < Scouter::Base::Object
3
+ END_POINT = 'https://widgets.getpocket.com'.freeze
4
+
5
+ # get Pocket Count
6
+ # @param [String or Array] urls
7
+ def self.get_count(urls)
8
+ urls = check_and_trans_url(urls)
9
+ results, errors = {}, []
10
+ urls.each_with_index do |u, idx|
11
+ sleep(WAIT_SEC) if idx != 0
12
+ res, error = get_and_parse_response(u)
13
+ errors << error && next if error
14
+ results.merge!(res)
15
+ end
16
+ res_hash = Hashie::Mash.new(results)
17
+ return [res_hash, errors]
18
+ end
19
+
20
+ def self.set_api_random(num)
21
+ @@api_rand_num = num
22
+ end
23
+
24
+ private
25
+
26
+ # Get and parse response data
27
+ # @return [String] urls URL list
28
+ # @return [String] service name
29
+ def self.get_and_parse_response(url)
30
+ html = get_response(api_url(url))
31
+ res = parse_response(html, url)
32
+ return [res, nil]
33
+ rescue => e
34
+ message = "#{e.message}, url: #{url}"
35
+ return [nil, message]
36
+ end
37
+
38
+ # build Pocket API URL
39
+ # @param [String] url
40
+ # @return [String] API url
41
+ def self.api_url(url)
42
+ esc_url = URI.escape(url)
43
+ rand_num = @@api_rand_num || rand(100000000)
44
+ "#{END_POINT}/v1/button?label=pocket&count=vertical&align=left&v=1&url=#{esc_url}&title=&src=#{esc_url}&r=#{rand_num}"
45
+ end
46
+
47
+ # Parse html for response
48
+ # @param [Hash] html
49
+ # @return [Hash] url & count
50
+ def self.parse_response(html, url)
51
+ count = (html.to_s =~ /id="cnt"[^0-9]+([0-9]+)/) ? $1.to_i : 0
52
+ { url => { self.service_name => count } }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,38 @@
1
+ module Scouter
2
+ class Twitter < Scouter::Base::Object
3
+ END_POINT = 'http://urls.api.twitter.com'.freeze
4
+
5
+ # get Twitter Count
6
+ # @param [String or Array] urls
7
+ def self.get_count(urls)
8
+ urls = check_and_trans_url(urls)
9
+ results, errors = {}, []
10
+ urls.each_with_index do |u, idx|
11
+ sleep(WAIT_SEC) if idx != 0
12
+ res, error = get_and_parse_response(u)
13
+ errors << error && next if error
14
+ results.merge!(res)
15
+ end
16
+ res_hash = Hashie::Mash.new(results)
17
+ return [res_hash, errors]
18
+ end
19
+
20
+ private
21
+
22
+ # build Twitter API URL
23
+ # @param [String] url
24
+ # @return [String] API url
25
+ def self.api_url(url)
26
+ escaped_url = URI.escape(url)
27
+ "#{END_POINT}/1/urls/count.json?url=#{escaped_url}"
28
+ end
29
+
30
+ # Parse json data for response
31
+ # @param [Hash] json
32
+ # @return [Hash] url & count
33
+ def self.parse_response(json, url)
34
+ res = JSON.parse(json)
35
+ { url => { self.service_name => res['count'] } }
36
+ end
37
+ end
38
+ end