SocialShareFeature 0.1.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
+ SHA256:
3
+ metadata.gz: '09b9451bdd5df3cd6c3ab161174144ec9198ca5a2716744a57ecbfd9b4174d0c'
4
+ data.tar.gz: 4d7a4b7df4c86886921ce6ce419f0d735b2251c0921bca9c58044d3eca7e1c8b
5
+ SHA512:
6
+ metadata.gz: ecb0e00e59424541526772cc7e5d1951e478e98d074eb3947f269b5356e66f6c4c8c974c50adc8cf2163c560809d72e7c32bdf1ecd06e3579ee42f928040e81b
7
+ data.tar.gz: 5304c905a04e24b504cea582452218a42f07d21930468fc9cfed9d135213cc467ae7c7aea847dccbb580028499c730a32208f36071f3461c8f33526cfec4b890
@@ -0,0 +1,3 @@
1
+ module SocialShareFeature
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,20 @@
1
+ require "SocialShareFeature/version"
2
+ require 'share_count'
3
+ require 'share_button'
4
+
5
+ module SocialShareFeature
6
+ class Error < StandardError; end
7
+ # Your code goes here...
8
+ module Count
9
+ extend ShareCount
10
+ end
11
+ module Button
12
+ extend ShareButton
13
+ end
14
+ class << self
15
+ attr_accessor :facebook_token_for_count,:allow_sites_for_share_button
16
+ def configure
17
+ yield self.config
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ module ShareButton
2
+ module Generators
3
+ class InstallGenerator < ::Rails::Generators::Base
4
+ desc "Copy ShareButton default files"
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ # def copy_config
8
+ # directory 'config'
9
+ # end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ ShareButton.configure do |config|
2
+ config.allow_sites = %w(twitter facebook google_plus weibo qq douban google_bookmark
3
+ delicious tumblr pinterest email linkedin wechat vkontakte
4
+ xing reddit hacker_news telegram odnoklassniki whatsapp_app whatsapp_web)
5
+ end
@@ -0,0 +1,6 @@
1
+ module ShareButton
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,44 @@
1
+ module ShareButton
2
+ module Helper
3
+
4
+ def social_share_button_tag(title, opts = {})
5
+ @opts = opts
6
+ @opts[:allow_sites] ||= SocialShareFeature.allow_sites_for_share_button
7
+ @html = []
8
+ @html << "<div class='share-button' data-title='#{h title}' data-img='#{opts[:image]}'"
9
+ @html << "data-url='#{opts[:url]}' data-desc='#{opts[:desc]}' data-via='#{opts[:via]}'>"
10
+ generate_link
11
+ @html << "</div>"
12
+ raw @html.join("\n")
13
+ end
14
+
15
+ def generate_link
16
+ @extra_data = {}
17
+ @rel = @opts[:rel]
18
+ if @opts[:allow_sites].class == Array
19
+ @opts[:allow_sites].each do |name|
20
+ links name
21
+ end
22
+ else
23
+ links @opts[:allow_sites]
24
+ end
25
+ end
26
+
27
+ def links name
28
+ @extra_data = @opts.select { |k, _| k.to_s.start_with?('data') } if name.eql?('tumblr')
29
+ special_data = @opts.select { |k, _| k.to_s.start_with?('data-' + name) }
30
+ special_data["data-wechat-footer"] = t "social_share_button.wechat_footer" if name == "wechat"
31
+ link_title = "#{name.capitalize}"
32
+ # "<img src='images/social-icon1.png' class='w-100'>"
33
+ # link_title = t "social_share_button.share_to", :name => t("social_share_button.#{name.downcase}")
34
+ @html << link_to("#", { :rel => ["nofollow", @rel],
35
+ "data-site" => name,
36
+ :class => @opts[:class],
37
+ :onclick => "return ShareButton.share(this);",
38
+ :title => h(link_title) }.merge(@extra_data).merge(special_data)) do
39
+ @opts[:img].present? ? "<img src='#{@opts[:img][:src]}' class='#{@opts[:img][:class]}'>".html_safe : name.capitalize
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,6 @@
1
+ module ShareButton
2
+ module Rails
3
+ class Railtie < ::Rails::Railtie
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,28 @@
1
+ require "share_button/helper"
2
+ # I18n.load_path += Dir.glob( File.dirname(__FILE__) + "lib/locales/*.{rb,yml}" )
3
+
4
+ module ShareButton
5
+ NETWORK_LIST = [
6
+ :facebook,
7
+ :google,
8
+ :linkedin,
9
+ :pinterest,
10
+ :reddit,
11
+ :twitter,
12
+ :weibo
13
+ ]
14
+ def supported_networks
15
+ NETWORK_LIST
16
+ end
17
+ module Rails
18
+ if ::Rails.version < "3.1"
19
+ require "share_button/railtie"
20
+ else
21
+ require "share_button/engine"
22
+ end
23
+ end
24
+ end
25
+
26
+ ActiveSupport.on_load(:action_view) do
27
+ include ShareButton::Helper
28
+ end
@@ -0,0 +1,55 @@
1
+ module ShareCount
2
+ class Base
3
+ include ShareCount::StringHelper
4
+ DEFAULT_TIMEOUT = 3
5
+ DEFAULT_OPEN_TIMEOUT = 3
6
+
7
+ @@config = {}
8
+
9
+ class << self
10
+ def config=(val)
11
+ @@config = val
12
+ end
13
+ end
14
+
15
+ attr_accessor :checked_url
16
+
17
+ def initialize(checked_url)
18
+ # remove URI fragment
19
+ @checked_url = checked_url.gsub(/#.+$/, '')
20
+ end
21
+
22
+ def shares
23
+ shares!
24
+ rescue => e
25
+ puts "[#{self.class.name}] Error during requesting sharings of '#{checked_url}': #{e}"
26
+ nil
27
+ end
28
+
29
+ def shares!
30
+ raise NotImplementedError
31
+ end
32
+
33
+ protected
34
+
35
+ def config_name
36
+ to_underscore(self.class.name.split('::').last).to_sym
37
+ end
38
+
39
+ def timeout
40
+ (@@config[config_name] || {})[:timeout] || DEFAULT_TIMEOUT
41
+ end
42
+
43
+ def open_timeout
44
+ (@@config[config_name] || {})[:open_timeout] || DEFAULT_OPEN_TIMEOUT
45
+ end
46
+
47
+ def get(url, params)
48
+ RestClient::Resource.new(url, timeout: timeout, open_timeout: open_timeout).get(params)
49
+ end
50
+
51
+ def post(url, params, headers = {})
52
+ RestClient::Resource.new(url, timeout: timeout, open_timeout: open_timeout).post(params, headers)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,23 @@
1
+ module ShareCount
2
+ class Facebook < Base
3
+ # URL = 'http://graph.facebook.com/v2.7/'
4
+ URL = 'https://graph.facebook.com/v3.0/'
5
+
6
+ def shares!
7
+ return raise "It's Seems that you have not initilized ' SocialShareFeature.facebook_token_for_count = Your App ID|Your App Secret' in intilizer to use facebook count you need to do this please see usages in README." unless SocialShareFeature.facebook_token_for_count.present?
8
+ token = SocialShareFeature.facebook_token_for_count
9
+ response = get(URL, params: {
10
+ id: checked_url,
11
+ fields: 'engagement',
12
+ access_token: token
13
+ })
14
+ json_response = JSON.parse(response)
15
+
16
+ if json_response['engagement']
17
+ json_response['engagement']['share_count'] || 0
18
+ else
19
+ 0
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ module ShareCount
2
+ class Google < Base
3
+ URL = 'https://clients6.google.com/rpc?key=AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQ'
4
+
5
+ def shares!
6
+ response = post(URL, JSON.dump(params), { content_type: :json, accept: :json })
7
+
8
+ JSON.parse(response)[0]['result']['metadata']['globalCounts']['count'].to_i
9
+ end
10
+
11
+ private
12
+
13
+ def params
14
+ [{
15
+ 'method' => 'pos.plusones.get',
16
+ 'id' => 'p',
17
+ 'jsonrpc' => '2.0',
18
+ 'key' => 'p',
19
+ 'apiVersion' => 'v1',
20
+ 'params' => {
21
+ 'nolog' => true,
22
+ 'id' => checked_url,
23
+ 'source' => 'widget',
24
+ 'userId' => '@viewer',
25
+ 'groupId' => '@self'
26
+ }
27
+ }]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ module ShareCount
2
+ class Linkedin < Base
3
+ URL = 'http://www.linkedin.com/countserv/count/share'
4
+
5
+ def shares!
6
+ response = get(URL, {
7
+ params: {
8
+ url: checked_url,
9
+ format: 'json'
10
+ }
11
+ })
12
+
13
+ JSON.parse(response)['count']
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module ShareCount
2
+ class Pinterest < Base
3
+ URL = 'http://api.pinterest.com/v1/urls/count.json'
4
+
5
+ def shares!
6
+ response = get(URL, params: { url: checked_url })
7
+
8
+ /count":(\d+)/.match(response.body)[-1].to_i
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module ShareCount
2
+ class Reddit < Base
3
+ URL = 'http://www.reddit.com/api/info.json'
4
+
5
+ def shares!
6
+ response = get(URL, params: { url: checked_url })
7
+
8
+ children_data = JSON.parse(response)['data']['children']
9
+ children_data.map { |c| c['data']['score'] }.reduce(:+) || 0
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module ShareCount
2
+ module StringHelper
3
+ def to_underscore(str)
4
+ str.dup.tap { |s| (s.gsub!(/(.)([A-Z])/,'\1_\2') || s).downcase! }
5
+ end
6
+
7
+ def to_camel_case(str)
8
+ str.split('_').map(&:capitalize).join
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,13 @@
1
+ module ShareCount
2
+ class Twitter < Base
3
+ URL = 'http://cdn.api.twitter.com/1/urls/count.json'
4
+
5
+ def shares!
6
+ response = get(URL, params: { url: checked_url })
7
+
8
+ JSON.parse(response)['count']
9
+ end
10
+ end
11
+ end
12
+
13
+
@@ -0,0 +1,35 @@
1
+ module ShareCount
2
+ class Weibo < Base
3
+ URL_FOR_SHORT = 'https://api.weibo.com/2/short_url/shorten.json'
4
+ URL_FOR_SHARE = 'https://api.weibo.com/2/short_url/share/counts.json'
5
+
6
+ def shares!
7
+ response = get(URL_FOR_SHARE, {
8
+ params: {
9
+ _: '1414437609900',
10
+ source: '8003029170',
11
+ url_short: short_url
12
+ }
13
+ })
14
+
15
+ JSON.parse(response)['urls'].first['share_counts'].to_i
16
+ end
17
+
18
+ private
19
+
20
+ def short_url
21
+ response = get(URL_FOR_SHORT, {
22
+ :params => {
23
+ :_ => '1414437609673',
24
+ :source => '8003029170',
25
+ :url_long => checked_url
26
+ }
27
+ })
28
+ JSON.parse(response)['urls'].first['url_short']
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+
35
+
@@ -0,0 +1,98 @@
1
+ require 'rest-client'
2
+ require 'json'
3
+ require 'share_count/string_helper'
4
+ require 'share_count/base'
5
+ require 'share_count/facebook'
6
+ require 'share_count/google'
7
+ require 'share_count/linkedin'
8
+ require 'share_count/pinterest'
9
+ require 'share_count/reddit'
10
+ require 'share_count/twitter'
11
+ require 'share_count/weibo'
12
+ module ShareCount
13
+ # class << self
14
+ include ShareCount::StringHelper
15
+ def config=(val)
16
+ ShareCount::Base.config = val
17
+ end
18
+ NETWORK_LIST = [
19
+ :facebook,
20
+ :google,
21
+ # :linkedin,
22
+ # :pinterest,
23
+ :reddit,
24
+ # :twitter,
25
+ :weibo
26
+ ]
27
+ def supported_networks
28
+ NETWORK_LIST
29
+ end
30
+ NETWORK_LIST.each do |network_name|
31
+ define_method(network_name) do |url|
32
+ class_name = to_camel_case(network_name.to_s)
33
+ ShareCount.const_get(class_name).new(url).shares
34
+ end
35
+ define_method("#{network_name}!") do |url|
36
+ class_name = to_camel_case(network_name.to_s)
37
+ ShareCount.const_get(class_name).new(url).shares!
38
+ end
39
+ end
40
+ def omit(url, excluded_networks = [])
41
+ selected_base(url, NETWORK_LIST.map(&:to_s) - excluded_networks.map(&:to_s), false)
42
+ end
43
+ def omit!(url, excluded_networks = [])
44
+ selected_base(url, NETWORK_LIST.map(&:to_s) - excluded_networks.map(&:to_s), true)
45
+ end
46
+ def selected(url, selected_networks)
47
+ selected_base(url, selected_networks, false)
48
+ end
49
+ def selected!(url, selected_networks)
50
+ selected_base(url, selected_networks, true)
51
+ end
52
+ def all(url)
53
+ selected(url, NETWORK_LIST)
54
+ end
55
+ def all!(url)
56
+ selected!(url, NETWORK_LIST)
57
+ end
58
+ def total(url, selected_networks = NETWORK_LIST)
59
+ selected!(url, selected_networks).values.reduce(:+)
60
+ end
61
+ def has_any?(url, selected_networks = NETWORK_LIST)
62
+ lambdas = filtered_networks(selected_networks).map do |network_name|
63
+ -> {self.send("#{network_name}!", url)}
64
+ end
65
+ pool = thread_pool(lambdas)
66
+ found = false
67
+ while !pool.empty? && !found
68
+ sleep 0.05
69
+ if thread = pool.find(&:stop?)
70
+ if thread.value > 0
71
+ pool.each(&:kill)
72
+ found = true
73
+ else
74
+ pool.delete(thread)
75
+ end
76
+ end
77
+ end
78
+ found
79
+ end
80
+ private
81
+ def filtered_networks(selected_networks)
82
+ selected_networks.map(&:to_s) & NETWORK_LIST.map(&:to_s)
83
+ end
84
+ def thread_pool(lambdas)
85
+ lambdas.map { |l| Thread.new { l.call } }
86
+ end
87
+ def selected_base(url, selected_networks, with_exception)
88
+ lambdas = filtered_networks(selected_networks).map do |network_name|
89
+ method_name = with_exception ? "#{network_name}!" : network_name
90
+ -> {{network_name => self.send(method_name, url)}}
91
+ end
92
+ thread_pool(lambdas).reduce({}) do |result, thread|
93
+ thread.join
94
+ result.merge(thread.value)
95
+ end
96
+ end
97
+ # end
98
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: SocialShareFeature
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Avdhesh
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-04-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
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: coffee-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
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: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
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: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ description: Share on social media platform and check how many times url was shared
98
+ in social networks, e.g. share counts.
99
+ email:
100
+ - avdhesh51000@gmail.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - lib/SocialShareFeature.rb
106
+ - lib/SocialShareFeature/version.rb
107
+ - lib/generators/share_button/install_generator.rb
108
+ - lib/generators/share_button/templates/config/initializers/share_button.rb
109
+ - lib/share_button.rb
110
+ - lib/share_button/engine.rb
111
+ - lib/share_button/helper.rb
112
+ - lib/share_button/railtie.rb
113
+ - lib/share_count.rb
114
+ - lib/share_count/base.rb
115
+ - lib/share_count/facebook.rb
116
+ - lib/share_count/google.rb
117
+ - lib/share_count/linkedin.rb
118
+ - lib/share_count/pinterest.rb
119
+ - lib/share_count/reddit.rb
120
+ - lib/share_count/string_helper.rb
121
+ - lib/share_count/twitter.rb
122
+ - lib/share_count/weibo.rb
123
+ homepage: https://github.com/Avdhesh51000/SocialShareFeature
124
+ licenses:
125
+ - MIT
126
+ metadata:
127
+ allowed_push_host: https://rubygems.org/
128
+ homepage_uri: https://github.com/Avdhesh51000/SocialShareFeature
129
+ source_code_uri: https://github.com/Avdhesh51000/SocialShareFeature
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ requirements: []
145
+ rubygems_version: 3.0.3
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Social Share on networks and shared count.
149
+ test_files: []