StatsCollect 0.1.0.20101220 → 0.1.1.20101220

Sign up to get free protection for your applications and to get access to all the features.
data/Credits CHANGED
@@ -5,6 +5,11 @@
5
5
  * http://www.ruby-lang.org/
6
6
  * Thanks a lot Matz for this truly wonderful language !
7
7
 
8
+ == rUtilAnts
9
+ * Muriel Salvan (http://murielsalvan.users.sourceforge.net)
10
+ * http://rutilants.sourceforge.net
11
+ * Used for plugins and logging handling.
12
+
8
13
  = Projects used by StatsCollect plugins
9
14
 
10
15
  == Plugin Backends/MySQL
data/ReleaseInfo CHANGED
@@ -2,7 +2,7 @@
2
2
  # This file has been generated by RubyPackager during a delivery.
3
3
  # More info about RubyPackager: http://rubypackager.sourceforge.net
4
4
  {
5
- :Version => '0.1.0.20101220',
5
+ :Version => '0.1.1.20101220',
6
6
  :Tags => [ 'Beta' ],
7
7
  :DevStatus => 'Beta'
8
8
  }
data/TODO CHANGED
@@ -1 +1,2 @@
1
- * MySpace: Get the user ID by parsing the Profile URL and remove :MySpaceName configuration option.
1
+ * MySpace: Get the user ID by parsing the Profile URL and remove :MySpaceName configuration option.
2
+ * Get all the orders at once, and merge them to call Locations just once per execution.
data/bin/StatsCollect.rb CHANGED
@@ -4,11 +4,6 @@
4
4
  # Licensed under the terms specified in LICENSE file. No warranty is provided.
5
5
  #++
6
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
7
  require 'rUtilAnts/Logging'
13
8
  RUtilAnts::Logging::initializeLogging('','')
14
9
  require 'tmpdir'
@@ -36,7 +36,10 @@ module StatsCollect
36
36
  rStatus = nil
37
37
 
38
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')
39
+ @LstStatsOrders = []
40
+ @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').each do |iRow|
41
+ @LstStatsOrders << iRow.clone
42
+ end
40
43
  end
41
44
  if (!@LstStatsOrders.empty?)
42
45
  lID, rTimeStamp, lStrLocations, lStrObjects, lStrCategories, rStatus = @LstStatsOrders.pop
@@ -115,7 +118,7 @@ module StatsCollect
115
118
  # Return:
116
119
  # * _Integer_: Its resulting ID
117
120
  def addCategory(iCategory, iValueType)
118
- @MySQLConnection.query("INSERT INTO stats_categories (name, value_type) VALUES ('#{@MySQLConnection.escape_string(iLocation)}', #{iValueType})")
121
+ @MySQLConnection.query("INSERT INTO stats_categories (name, value_type) VALUES ('#{@MySQLConnection.escape_string(iCategory)}', #{iValueType})")
119
122
 
120
123
  return @MySQLConnection.insert_id
121
124
  end
@@ -42,7 +42,9 @@ module StatsCollect
42
42
  lProfilePage = iMechanizeAgent.get('http://www.facebook.com/profile.php')
43
43
  lNbrFriends = nil
44
44
  lProfilePage.root.css('script').each do |iScriptNode|
45
- lMatch = iScriptNode.content.match(/>(\d*) friends<\\\/a><\\\/span>/)
45
+ lMatch = iScriptNode.content.match(/>Friends \((\d*)\)<\\\/a><\\\/span>/)
46
+ # The following line is valid for old profiles only
47
+ #lMatch = iScriptNode.content.match(/>(\d*) friends<\\\/a><\\\/span>/)
46
48
  if (lMatch != nil)
47
49
  lNbrFriends = Integer(lMatch[1])
48
50
  break
@@ -23,8 +23,8 @@ module StatsCollect
23
23
  require 'mechanize'
24
24
  lMechanizeAgent = Mechanize.new
25
25
  lLoginForm = lMechanizeAgent.get('http://www.youtube.com').link_with(:text => 'Sign In').click.forms[1]
26
- lLoginForm.Email = 'Muriel.Esteban@GMail.com'
27
- lLoginForm.Passwd = 'M[K2LBVu0}xT|b<[<Q")'
26
+ lLoginForm.Email = iConf[:LoginEMail]
27
+ lLoginForm.Passwd = iConf[:LoginPassword]
28
28
  lMechanizeAgent.submit(lLoginForm, lLoginForm.buttons.first).meta.first.click
29
29
  if ((oStatsProxy.isCategoryIncluded?('Video plays')) or
30
30
  (oStatsProxy.isCategoryIncluded?('Video likes')) or
@@ -33,6 +33,19 @@ module StatsCollect
33
33
  (oStatsProxy.isCategoryIncluded?('Video responses')))
34
34
  getVideos(oStatsProxy, lMechanizeAgent)
35
35
  end
36
+ if ((oStatsProxy.isObjectIncluded?('Global')) and
37
+ ((oStatsProxy.isCategoryIncluded?('Visits')) or
38
+ (oStatsProxy.isCategoryIncluded?('Followers'))))
39
+ getOverview(oStatsProxy, lMechanizeAgent)
40
+ end
41
+ if ((oStatsProxy.isObjectIncluded?('Global')) and
42
+ (oStatsProxy.isCategoryIncluded?('Friends')))
43
+ getFriends(oStatsProxy, lMechanizeAgent)
44
+ end
45
+ if ((oStatsProxy.isObjectIncluded?('Global')) and
46
+ (oStatsProxy.isCategoryIncluded?('Following')))
47
+ getSubscriptions(oStatsProxy, lMechanizeAgent)
48
+ end
36
49
  end
37
50
 
38
51
  # Get the videos statistics
@@ -62,6 +75,61 @@ module StatsCollect
62
75
  logDebug "#{lLstVideosRead.size} videos read: #{lLstVideosRead.join(', ')}"
63
76
  end
64
77
 
78
+ # Get the overview statistics
79
+ #
80
+ # Parameters:
81
+ # * *oStatsProxy* (_StatsProxy_): The stats proxy to be used to populate stats
82
+ # * *iMechanizeAgent* (_Mechanize_): The agent reading pages
83
+ def getOverview(oStatsProxy, iMechanizeAgent)
84
+ lOverviewPage = iMechanizeAgent.get('http://www.youtube.com/account_overview')
85
+ lNbrVisits = nil
86
+ lNbrFollowers = nil
87
+ lOverviewPage.root.css('div.statBlock').each do |iStatsSectionNode|
88
+ lChildrenNodes = iStatsSectionNode.children
89
+ lChildrenNodes.each_with_index do |iNode, iIdx|
90
+ if (iNode.content == 'Channel Views:')
91
+ lNbrVisits = Integer(lChildrenNodes[iIdx+1].content.strip)
92
+ elsif (iNode.content == 'Subscribers:')
93
+ lNbrFollowers = Integer(lChildrenNodes[iIdx+1].content.strip)
94
+ end
95
+ end
96
+ if ((lNbrVisits != nil) and
97
+ (lNbrFollowers != nil))
98
+ break
99
+ end
100
+ end
101
+ if (lNbrVisits == nil)
102
+ logErr "Unable to get number of visits: #{lOverviewPage}"
103
+ elsif (lNbrFollowers == nil)
104
+ logErr "Unable to get number of followers: #{lOverviewPage}"
105
+ else
106
+ oStatsProxy.addStat('Global', 'Visits', lNbrVisits)
107
+ oStatsProxy.addStat('Global', 'Followers', lNbrFollowers)
108
+ end
109
+ end
110
+
111
+ # Get the friends statistics
112
+ #
113
+ # Parameters:
114
+ # * *oStatsProxy* (_StatsProxy_): The stats proxy to be used to populate stats
115
+ # * *iMechanizeAgent* (_Mechanize_): The agent reading pages
116
+ def getFriends(oStatsProxy, iMechanizeAgent)
117
+ lOverviewPage = iMechanizeAgent.get('http://www.youtube.com/profile?view=friends')
118
+ lNbrFriends = Integer(lOverviewPage.root.xpath('//span[@name="channel-box-item-count"]').first.content)
119
+ oStatsProxy.addStat('Global', 'Friends', lNbrFriends)
120
+ end
121
+
122
+ # Get the friends statistics
123
+ #
124
+ # Parameters:
125
+ # * *oStatsProxy* (_StatsProxy_): The stats proxy to be used to populate stats
126
+ # * *iMechanizeAgent* (_Mechanize_): The agent reading pages
127
+ def getSubscriptions(oStatsProxy, iMechanizeAgent)
128
+ lOverviewPage = iMechanizeAgent.get('http://www.youtube.com/profile?view=subscriptions')
129
+ lNbrFollowing = Integer(lOverviewPage.root.xpath('//span[@name="channel-box-item-count"]').first.content)
130
+ oStatsProxy.addStat('Global', 'Following', lNbrFollowing)
131
+ end
132
+
65
133
  end
66
134
 
67
135
  end
@@ -10,12 +10,10 @@ require 'StatsCollect/StatsProxy'
10
10
  module StatsCollect
11
11
 
12
12
  # Stats orders statuses
13
- # !!! Those constants are also defined in the RoR website.
14
13
  STATS_ORDER_STATUS_TOBEPROCESSED = 0
15
14
  STATS_ORDER_STATUS_RECOVERABLE_ERROR = 1
16
15
  STATS_ORDER_STATUS_UNRECOVERABLE_ERROR = 2
17
16
  # Value types
18
- # !!! Those constants are also defined in the RoR website.
19
17
  STATS_VALUE_TYPE_INTEGER = 0
20
18
  STATS_VALUE_TYPE_FLOAT = 1
21
19
  STATS_VALUE_TYPE_PERCENTAGE = 2
@@ -33,6 +31,7 @@ module StatsCollect
33
31
  parsePluginsFromDir('Notifiers', "#{File.expand_path(File.dirname(__FILE__))}/Notifiers", 'StatsCollect::Notifiers')
34
32
 
35
33
  @Backend = nil
34
+ @BackendInit = false
36
35
  @Notifier = nil
37
36
  @ConfigFile = nil
38
37
  @DisplayHelp = false
@@ -183,7 +182,10 @@ module StatsCollect
183
182
  begin
184
183
  # Collect statistics
185
184
  logInfo "[#{DateTime.now.strftime('%Y-%m-%d %H:%M:%S')}] - Begin collecting stats..."
186
- @BackendInstance.initSession(@Conf[:Backends][@Backend])
185
+ if (!@BackendInit)
186
+ @BackendInstance.initSession(@Conf[:Backends][@Backend])
187
+ @BackendInit = true
188
+ end
187
189
  # Get the stats orders to process
188
190
  lFoundOrder = false
189
191
  lTimeStamp, lLstLocations, lLstObjects, lLstCategories, lStatus = @BackendInstance.getNextStatsOrder
@@ -245,6 +247,20 @@ module StatsCollect
245
247
  end
246
248
  end
247
249
 
250
+ # Enqueue a new stats order
251
+ #
252
+ # Parameters:
253
+ # * *iLstLocations* (<em>list<String></em>): Locations list (can be empty for all locations)
254
+ # * *iLstObjects* (<em>list<String></em>): Objects list (can be empty for all objects)
255
+ # * *iLstCategories* (<em>list<String></em>): Categories list (can be empty for all categories)
256
+ def pushStatsOrder(iLstLocations, iLstObjects, iLstCategories)
257
+ if (!@BackendInit)
258
+ @BackendInstance.initSession(@Conf[:Backends][@Backend])
259
+ @BackendInit = true
260
+ end
261
+ @BackendInstance.putNewStatsOrder(DateTime.now, iLstLocations, iLstObjects, iLstCategories, STATS_ORDER_STATUS_TOBEPROCESSED)
262
+ end
263
+
248
264
  private
249
265
 
250
266
  # Process an order
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
8
+ - 1
9
9
  - 20101220
10
- version: 0.1.0.20101220
10
+ version: 0.1.1.20101220
11
11
  platform: ruby
12
12
  authors:
13
13
  - Muriel Salvan