scouter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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