StatsCollect 0.1.0.20101220

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS ADDED
@@ -0,0 +1,2 @@
1
+ = Muriel Salvan (murielsalvan@users.sourceforge.net)
2
+ * 0.1.0.20101220
data/ChangeLog ADDED
@@ -0,0 +1,5 @@
1
+ = StatsCollect Release History
2
+
3
+ == 0.1.0.20101220 (Beta)
4
+
5
+ * Initial version
data/Credits ADDED
@@ -0,0 +1,31 @@
1
+ = Projects used by StatsCollect
2
+
3
+ == Ruby
4
+ * Yukihiro « matz » Matsumoto (http://www.rubyist.net/~matz/)
5
+ * http://www.ruby-lang.org/
6
+ * Thanks a lot Matz for this truly wonderful language !
7
+
8
+ = Projects used by StatsCollect plugins
9
+
10
+ == Plugin Backends/MySQL
11
+
12
+ === ruby-mysql
13
+ * TOMITA Masahiro (http://www.tmtm.org/)
14
+ * http://www.tmtm.org/en/ruby/mysql/
15
+ * Used to access MySQL databases.
16
+
17
+ == Plugin Notifiers/SendMail
18
+
19
+ === Mail
20
+ * Mikel Lindsaar (http://lindsaar.net/)
21
+ * http://github.com/mikel/mail
22
+ * Used to send notification mails.
23
+
24
+ == Most Locations plugins
25
+
26
+ === Mechanize
27
+ * Mike Dalessio (http://github.com/flavorjones)
28
+ * http://mechanize.rubyforge.org
29
+ * Used to scrap web pages to get statistics.
30
+
31
+ = People that helped a lot in developing StatsCollect
data/LICENSE ADDED
@@ -0,0 +1,31 @@
1
+
2
+ The license stated herein is a copy of the BSD License (modified on July 1999).
3
+ The AUTHOR mentionned below refers to the list of people involved in the
4
+ creation and modification of any file included in the delivered package.
5
+ This list is found in the file named AUTHORS.
6
+ The AUTHORS and LICENSE files have to be included in any release of software
7
+ embedding source code of this package, or using it as a derivative software.
8
+
9
+ Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright notice,
15
+ this list of conditions and the following disclaimer.
16
+ 2. Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+ 3. The name of the author may not be used to endorse or promote products
20
+ derived from this software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
25
+ EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31
+ OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,18 @@
1
+ -- This file is best viewed when processed by rdoc.
2
+ ++
3
+
4
+ = StatsCollect
5
+
6
+ StatsCollect is a little framework gathering statistics from external sources (social networks, web sites...), stored in pluggable backends. It can be very easily extended thanks to its plugins (currently include Facebook, Myspace, Youtube, Google).
7
+
8
+ == Where is the documentation ?
9
+
10
+ Check the website at http://statscollect.sourceforge.net
11
+
12
+ == Who wrote it ?
13
+
14
+ Check the AUTHORS[link:files/AUTHORS.html] file.
15
+
16
+ == What is the license ?
17
+
18
+ You can find out in the LICENSE[link:files/LICENSE.html] file.
data/ReleaseInfo ADDED
@@ -0,0 +1,8 @@
1
+
2
+ # This file has been generated by RubyPackager during a delivery.
3
+ # More info about RubyPackager: http://rubypackager.sourceforge.net
4
+ {
5
+ :Version => '0.1.0.20101220',
6
+ :Tags => [ 'Beta' ],
7
+ :DevStatus => 'Beta'
8
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ # Configuration for Backends
3
+ :Backends => {
4
+ 'MySQL' => {
5
+ :DBHost => 'localhost',
6
+ :DBUser => 'mydbuser',
7
+ :DBPassword => '*****',
8
+ :DBName => 'mydb',
9
+ },
10
+ 'Terminal' => {}
11
+ },
12
+
13
+ # Configuration for Notifiers
14
+ :Notifiers => {
15
+ 'SendMail' => {
16
+ :SMTP => {
17
+ :address => "mail.myhost.com",
18
+ :port => 25,
19
+ :domain => 'mail.myhost.com',
20
+ :user_name => 'smtpuser',
21
+ :password => '*****',
22
+ :authentication => nil,
23
+ :enable_starttls_auto => false
24
+ },
25
+ # The From field
26
+ :From => 'MailOriginator@myhost.com',
27
+ # To who the notifications are sent
28
+ :To => 'mail@host.com'
29
+ },
30
+ 'None' => {}
31
+ },
32
+
33
+ # Configuration for Locations
34
+ :Locations => {
35
+ 'MySpace' => {
36
+ :LoginEMail => 'MySpaceLogin',
37
+ :LoginPassword => '****',
38
+ # This is the last part of profile URL
39
+ :MySpaceName => 'myspace_user',
40
+ # List the blogs IDs. They can be taken from their respective URL.
41
+ :BlogsID => [
42
+ 123456789,
43
+ 234567891,
44
+ 345678912
45
+ ]
46
+ },
47
+ 'Facebook' => {
48
+ :LoginEMail => 'FacebookLogin',
49
+ :LoginPassword => '*****'
50
+ },
51
+ 'FacebookArtist' => {
52
+ :LoginEMail => 'FacebookLogin',
53
+ :LoginPassword => '*****',
54
+ # URL of the page (after the /pages sub-directory) to fetch stats from
55
+ :PageID => 'ArtistName/123456789012345'
56
+ },
57
+ 'ReverbNation' => {
58
+ :LoginEMail => 'ReverbNationLogin',
59
+ :LoginPassword => '*****'
60
+ },
61
+ 'AddThis' => {
62
+ :Login => 'AddThisLogin',
63
+ :Password => '*****',
64
+ # List of objects for which we retrieve the AddThis stats
65
+ :Objects => [
66
+ 'www.myhost.com'
67
+ ]
68
+ },
69
+ 'FacebookLike' => {
70
+ # List of objects for which we retrieve the Facebook likes
71
+ :Objects => [
72
+ 'www.myhost.com'
73
+ ]
74
+ },
75
+ 'Tweets' => {
76
+ # List of objects for which we retrieve the tweets
77
+ :Objects => [
78
+ 'www.myhost.com'
79
+ ]
80
+ },
81
+ 'Twitter' => {
82
+ :Name => 'TwitterID'
83
+ },
84
+ 'GoogleSearch' => {
85
+ # List of objects for which we will query Google search
86
+ :Objects => [
87
+ 'GoogleSearchString'
88
+ ]
89
+ },
90
+ }
91
+ }
data/TODO ADDED
@@ -0,0 +1 @@
1
+ * MySpace: Get the user ID by parsing the Profile URL and remove :MySpaceName configuration option.
@@ -0,0 +1,30 @@
1
+ #!/bin/env ruby
2
+ #--
3
+ # Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
4
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
5
+ #++
6
+
7
+ # Uncomment for PlanetHoster
8
+ #require 'rubygems'
9
+ #ENV['GEM_PATH'] = "/home/murieles/ruby/gems:/home/murieles/.gem/ruby/1.8:/usr/lib/ruby/gems/1.8"
10
+ #Gem.clear_paths
11
+
12
+ require 'rUtilAnts/Logging'
13
+ RUtilAnts::Logging::initializeLogging('','')
14
+ require 'tmpdir'
15
+ lLogFile = "#{Dir.tmpdir}/StatsCollect_#{Process.pid}.log"
16
+ setLogFile(lLogFile)
17
+ require 'StatsCollect/Stats'
18
+
19
+ rErrorCode = 0
20
+
21
+ lStatsCollect = StatsCollect::Stats.new
22
+ rErrorCode = lStatsCollect.setup(ARGV)
23
+ if (rErrorCode == 0)
24
+ rErrorCode = lStatsCollect.collect
25
+ lStatsCollect.notify(lLogFile)
26
+ end
27
+
28
+ File.unlink(lLogFile)
29
+
30
+ exit rErrorCode
@@ -0,0 +1,190 @@
1
+ #--
2
+ # Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ module StatsCollect
7
+
8
+ module Backends
9
+
10
+ class MySQL
11
+
12
+ # Initialize a session of this backend
13
+ #
14
+ # Parameters:
15
+ # * *iConf* (<em>map<Symbol,Object></em>): Configuration of this backend
16
+ def initSession(iConf)
17
+ require 'mysql'
18
+ @MySQLConnection = Mysql.new(iConf[:DBHost], iConf[:DBUser], iConf[:DBPassword], iConf[:DBName])
19
+ # TODO: Use bound variables everywhere !
20
+ end
21
+
22
+ # Get the next stats order.
23
+ # Code to begin a new transaction can be set in this method too.
24
+ #
25
+ # Return:
26
+ # * _DateTime_: The time stamp, or nil if no new stats order
27
+ # * <em>list<String></em>: List of locations
28
+ # * <em>list<String></em>: List of objects
29
+ # * <em>list<String></em>: List of categories
30
+ # * _Integer_: The order status
31
+ def getNextStatsOrder
32
+ rTimeStamp = nil
33
+ rLstLocations = nil
34
+ rLstObjects = nil
35
+ rLstCategories = nil
36
+ rStatus = nil
37
+
38
+ if (defined?(@LstStatsOrders) == nil)
39
+ @LstStatsOrders = @MySQLConnection.query('SELECT id, timestamp, objects_list, categories_list, locations_list, status FROM stats_orders WHERE status=0 OR status=1 ORDER BY timestamp DESC')
40
+ end
41
+ if (!@LstStatsOrders.empty?)
42
+ lID, rTimeStamp, lStrLocations, lStrObjects, lStrCategories, rStatus = @LstStatsOrders.pop
43
+ rLstLocations = lStrLocations.split('|')
44
+ rLstObjects = lStrObjects.split('|')
45
+ rLstCategories = lStrCategories.split('|')
46
+ @MySQLConnection.query('start transaction')
47
+ @MySQLConnection.query("DELETE FROM stats_orders WHERE id=#{lID}")
48
+ end
49
+
50
+ return rTimeStamp, rLstLocations, rLstObjects, rLstCategories, rStatus
51
+ end
52
+
53
+ # Get the list of known locations
54
+ #
55
+ # Return:
56
+ # * <em>map<String,Integer></em>: Each location with its associated ID
57
+ def getKnownLocations
58
+ rKnownLocations = {}
59
+
60
+ @MySQLConnection.query('SELECT name, id FROM stats_locations').each do |iRow|
61
+ iLocationName, iLocationID = iRow
62
+ rKnownLocations[iLocationName] = iLocationID.to_i
63
+ end
64
+
65
+ return rKnownLocations
66
+ end
67
+
68
+ # Get the list of known categories
69
+ #
70
+ # Return:
71
+ # * <em>map<String,[Integer,Integer]></em>: Each category with its associated ID and value type
72
+ def getKnownCategories
73
+ rKnownCategories = {}
74
+
75
+ @MySQLConnection.query('SELECT name, id, value_type FROM stats_categories').each do |iRow|
76
+ iCategoryName, iCategoryID, iValueType = iRow
77
+ rKnownCategories[iCategoryName] = [ iCategoryID.to_i, iValueType.to_i ]
78
+ end
79
+
80
+ return rKnownCategories
81
+ end
82
+
83
+ # Get the list of known objects
84
+ #
85
+ # Return:
86
+ # * <em>map<String,Integer></em>: Each object with its associated ID
87
+ def getKnownObjects
88
+ rKnownObjects = {}
89
+
90
+ @MySQLConnection.query('SELECT name, id FROM stats_objects').each do |iRow|
91
+ iObjectName, iObjectID = iRow
92
+ rKnownObjects[iObjectName] = iObjectID.to_i
93
+ end
94
+
95
+ return rKnownObjects
96
+ end
97
+
98
+ # Add a new location
99
+ #
100
+ # Parameters:
101
+ # * *iLocation* (_String_): The location
102
+ # Return:
103
+ # * _Integer_: Its resulting ID
104
+ def addLocation(iLocation)
105
+ @MySQLConnection.query("INSERT INTO stats_locations (name) VALUES ('#{@MySQLConnection.escape_string(iLocation)}')")
106
+
107
+ return @MySQLConnection.insert_id
108
+ end
109
+
110
+ # Add a new category
111
+ #
112
+ # Parameters:
113
+ # * *iCategory* (_String_): The category
114
+ # * *iValueType* (_Integer_): Its value type
115
+ # Return:
116
+ # * _Integer_: Its resulting ID
117
+ def addCategory(iCategory, iValueType)
118
+ @MySQLConnection.query("INSERT INTO stats_categories (name, value_type) VALUES ('#{@MySQLConnection.escape_string(iLocation)}', #{iValueType})")
119
+
120
+ return @MySQLConnection.insert_id
121
+ end
122
+
123
+ # Add a new object
124
+ #
125
+ # Parameters:
126
+ # * *iObject* (_String_): The object
127
+ # Return:
128
+ # * _Integer_: Its resulting ID
129
+ def addObject(iObject)
130
+ @MySQLConnection.query("INSERT INTO stats_objects (name) VALUES ('#{@MySQLConnection.escape_string(iObject)}')")
131
+
132
+ return @MySQLConnection.insert_id
133
+ end
134
+
135
+ # Add a new stat
136
+ #
137
+ # Parameters:
138
+ # * *iTimeStamp* (_DateTime_): The time stamp
139
+ # * *iLocationID* (_Integer_): Location ID
140
+ # * *iObjectID* (_Integer_): Object ID
141
+ # * *iCategoryID* (_Integer_): Category ID
142
+ # * *iValue* (_Object_): The value to store
143
+ # * *iValueType* (_Integer_): The value type
144
+ def addStat(iTimeStamp, iLocationID, iObjectID, iCategoryID, iValue, iValueType)
145
+ # Convert the value to its internal representation
146
+ lStrValue = nil
147
+ case iValueType
148
+ when STATS_VALUE_TYPE_INTEGER
149
+ lStrValue = iValue.to_s
150
+ when STATS_VALUE_TYPE_FLOAT
151
+ lStrValue = iValue.to_s
152
+ when STATS_VALUE_TYPE_PERCENTAGE
153
+ lStrValue = iValue.to_s
154
+ when STATS_VALUE_TYPE_UNKNOWN
155
+ lStrValue = iValue.to_s
156
+ else
157
+ logErr "Unknown category value type: #{iValueType}. It will be treated as Unknown."
158
+ lStrValue = iValue.to_s
159
+ end
160
+ # Add the new stat in the DB for real
161
+ @MySQLConnection.query("INSERT INTO stats_values (timestamp, stats_object_id, stats_category_id, stats_location_id, value) VALUES ('#{iTimeStamp.strftime('%Y-%m-%d %H:%M:%S')}', #{iObjectID}, #{iCategoryID}, #{iLocationID}, '#{lStrValue}')")
162
+ end
163
+
164
+ # Add a new stats order
165
+ #
166
+ # Parameters:
167
+ # * *iTimeStamp* (_DateTime_): The time stamp
168
+ # * *iLstLocations* (<em>list<String></em>): List of locations
169
+ # * *iLstObjects* (<em>list<String></em>): List of objects
170
+ # * *iLstCategories* (<em>list<String></em>): List of categories
171
+ # * *iStatus* (_Integer_): The order status
172
+ def putNewStatsOrder(iTimeStamp, iLstLocations, iLstObjects, iLstCategories, iStatus)
173
+ @MySQLConnection.query("INSERT INTO stats_orders (timestamp, locations_list, objects_list, categories_list, status) VALUES ('#{iTimeStamp.strftime('%Y-%m-%d %H:%M:%S')}', '#{@MySQLConnection.escape_string(iLstLocations.join('|'))}', '#{@MySQLConnection.escape_string(iLstObjects.join('|'))}', '#{@MySQLConnection.escape_string(iLstCategories.join('|'))}', #{iStatus})")
174
+ end
175
+
176
+ # Commit the current stats order transaction
177
+ def commit
178
+ @MySQLConnection.query('commit')
179
+ end
180
+
181
+ # Rollback the current stats order transaction
182
+ def rollback
183
+ @MySQLConnection.query('rollback')
184
+ end
185
+
186
+ end
187
+
188
+ end
189
+
190
+ end
@@ -0,0 +1,157 @@
1
+ #--
2
+ # Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ module StatsCollect
7
+
8
+ module Backends
9
+
10
+ class Terminal
11
+
12
+ # Initialize a session of this backend
13
+ #
14
+ # Parameters:
15
+ # * *iConf* (<em>map<Symbol,Object></em>): Configuration of this backend
16
+ def initSession(iConf)
17
+ @IdxID = 0
18
+ end
19
+
20
+ # Get the next stats order.
21
+ # Code to begin a new transaction can be set in this method too.
22
+ #
23
+ # Return:
24
+ # * _DateTime_: The time stamp, or nil if no new stats order
25
+ # * <em>list<String></em>: List of locations
26
+ # * <em>list<String></em>: List of objects
27
+ # * <em>list<String></em>: List of categories
28
+ # * _Integer_: The order status
29
+ def getNextStatsOrder
30
+ rTimeStamp = nil
31
+ rLstLocations = nil
32
+ rLstObjects = nil
33
+ rLstCategories = nil
34
+ rStatus = nil
35
+
36
+ if (defined?(@LstStatsOrders) == nil)
37
+ @LstStatsOrders = [
38
+ [ DateTime.now, [], [], [], STATS_ORDER_STATUS_TOBEPROCESSED ]
39
+ ]
40
+ end
41
+ if (!@LstStatsOrders.empty?)
42
+ rTimeStamp, rLstLocations, rLstObjects, rLstCategories, rStatus = @LstStatsOrders.pop
43
+ end
44
+
45
+ return rTimeStamp, rLstLocations, rLstObjects, rLstCategories, rStatus
46
+ end
47
+
48
+ # Get the list of known locations
49
+ #
50
+ # Return:
51
+ # * <em>map<String,Integer></em>: Each location with its associated ID
52
+ def getKnownLocations
53
+ rKnownLocations = {}
54
+
55
+ return rKnownLocations
56
+ end
57
+
58
+ # Get the list of known categories
59
+ #
60
+ # Return:
61
+ # * <em>map<String,[Integer,Integer]></em>: Each category with its associated ID and value type
62
+ def getKnownCategories
63
+ rKnownCategories = {}
64
+
65
+ return rKnownCategories
66
+ end
67
+
68
+ # Get the list of known objects
69
+ #
70
+ # Return:
71
+ # * <em>map<String,Integer></em>: Each object with its associated ID
72
+ def getKnownObjects
73
+ rKnownObjects = {}
74
+
75
+ return rKnownObjects
76
+ end
77
+
78
+ # Add a new location
79
+ #
80
+ # Parameters:
81
+ # * *iLocation* (_String_): The location
82
+ # Return:
83
+ # * _Integer_: Its resulting ID
84
+ def addLocation(iLocation)
85
+ logMsg "Added location: #{iLocation} (#{@IdxID})"
86
+ @IdxID += 1
87
+
88
+ return @IdxID-1
89
+ end
90
+
91
+ # Add a new category
92
+ #
93
+ # Parameters:
94
+ # * *iCategory* (_String_): The category
95
+ # * *iValueType* (_Integer_): Its value type
96
+ # Return:
97
+ # * _Integer_: Its resulting ID
98
+ def addCategory(iCategory, iValueType)
99
+ logMsg "Added category: #{iCategory}, #{iValueType} (#{@IdxID})"
100
+ @IdxID += 1
101
+
102
+ return @IdxID-1
103
+ end
104
+
105
+ # Add a new object
106
+ #
107
+ # Parameters:
108
+ # * *iObject* (_String_): The object
109
+ # Return:
110
+ # * _Integer_: Its resulting ID
111
+ def addObject(iObject)
112
+ logMsg "Added object: #{iObject} (#{@IdxID})"
113
+ @IdxID += 1
114
+
115
+ return @IdxID-1
116
+ end
117
+
118
+ # Add a new stat
119
+ #
120
+ # Parameters:
121
+ # * *iTimeStamp* (_DateTime_): The time stamp
122
+ # * *iLocationID* (_Integer_): Location ID
123
+ # * *iObjectID* (_Integer_): Object ID
124
+ # * *iCategoryID* (_Integer_): Category ID
125
+ # * *iValue* (_Object_): The value to store
126
+ # * *iValueType* (_Integer_): The value type
127
+ def addStat(iTimeStamp, iLocationID, iObjectID, iCategoryID, iValue, iValueType)
128
+ logMsg "Added stat: #{iTimeStamp} | Location: #{iLocationID} | Object: #{iObjectID} | Category: #{iCategoryID} | Value: #{iValue}"
129
+ end
130
+
131
+ # Add a new stats order
132
+ #
133
+ # Parameters:
134
+ # * *iTimeStamp* (_DateTime_): The time stamp
135
+ # * *iLstLocations* (<em>list<String></em>): List of locations
136
+ # * *iLstObjects* (<em>list<String></em>): List of objects
137
+ # * *iLstCategories* (<em>list<String></em>): List of categories
138
+ # * *iStatus* (_Integer_): The order status
139
+ def putNewStatsOrder(iTimeStamp, iLstLocations, iLstObjects, iLstCategories, iStatus)
140
+ logMsg "Added new stats order: #{iTimeStamp} | Locations: #{iLstLocations.join(', ')} | Objects: #{iLstObjects.join(', ')} | Categories: #{iLstCategories.join(', ')} | Status: #{iStatus}"
141
+ end
142
+
143
+ # Commit the current stats order transaction
144
+ def commit
145
+ logMsg 'Transaction committed'
146
+ end
147
+
148
+ # Rollback the current stats order transaction
149
+ def rollback
150
+ logMsg 'Transaction rollbacked'
151
+ end
152
+
153
+ end
154
+
155
+ end
156
+
157
+ end
@@ -0,0 +1,65 @@
1
+ #--
2
+ # Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ module StatsCollect
7
+
8
+ module Locations
9
+
10
+ class AddThis
11
+
12
+ # Execute the plugin.
13
+ # This method has to add the stats and errors to the proxy.
14
+ # It can filter only objects and categories given.
15
+ # It has access to its configuration.
16
+ #
17
+ # Parameters:
18
+ # * *oStatsProxy* (_StatsProxy_): The stats proxy to be used to populate stats
19
+ # * *iConf* (<em>map<Symbol,Object></em>): The configuration associated to this plugin
20
+ # * *iLstObjects* (<em>list<String></em>): List of objects to filter (can be empty for all)
21
+ # * *iLstCategories* (<em>list<String></em>): List of categories to filter (can be empty for all)
22
+ def execute(oStatsProxy, iConf, iLstObjects, iLstCategories)
23
+ require 'mechanize'
24
+ lMechanizeAgent = Mechanize.new
25
+ # Get the number of likes from Facebook
26
+ if (oStatsProxy.isCategoryIncluded?('Monthly shares'))
27
+ getDomains(oStatsProxy, lMechanizeAgent, iConf, 'month', 'Monthly shares')
28
+ end
29
+ if (oStatsProxy.isCategoryIncluded?('Weekly shares'))
30
+ getDomains(oStatsProxy, lMechanizeAgent, iConf, 'week', 'Weekly shares')
31
+ end
32
+ if (oStatsProxy.isCategoryIncluded?('Daily shares'))
33
+ getDomains(oStatsProxy, lMechanizeAgent, iConf, 'day', 'Daily shares')
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ # Get domains stats for a given period
40
+ #
41
+ # Parameters:
42
+ # * *oStatsProxy* (_StatsProxy_): The stats proxy to be used to populate stats
43
+ # * *iMechanizeAgent* (_Mechanize_): The mechanize agent
44
+ # * *iConf* (<em>map<Symbol,Object></em>): The configuration associated to this plugin
45
+ # * *iAddThisPeriod* (_String_): The period given to AddThis API
46
+ # * *iCategory* (_String_): Corresponding category
47
+ def getDomains(oStatsProxy, iMechanizeAgent, iConf, iAddThisPeriod, iCategory)
48
+ iMechanizeAgent.auth(iConf[:Login], iConf[:Password])
49
+ lData = eval(iMechanizeAgent.get_file("http://api.addthis.com/analytics/1.0/pub/shares/domain.json?period=#{iAddThisPeriod}").gsub(/:/,'=>'))
50
+ iConf[:Objects].each do |iObject|
51
+ lNbrShares = 0
52
+ lData.each do |iDataInfo|
53
+ if (iDataInfo['domain'] == iObject)
54
+ lNbrShares = iDataInfo['shares']
55
+ end
56
+ end
57
+ oStatsProxy.addStat(iObject, iCategory, lNbrShares)
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ end