StatsCollect 0.1.0.20101220 → 0.1.1.20101220
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.
- data/Credits +5 -0
 - data/ReleaseInfo +1 -1
 - data/TODO +2 -1
 - data/bin/StatsCollect.rb +0 -5
 - data/lib/StatsCollect/Backends/MySQL.rb +5 -2
 - data/lib/StatsCollect/Locations/Facebook.rb +3 -1
 - data/lib/StatsCollect/Locations/Youtube.rb +70 -2
 - data/lib/StatsCollect/Stats.rb +19 -3
 - metadata +2 -2
 
    
        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
    
    
    
        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 =  
     | 
| 
      
 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( 
     | 
| 
      
 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*) 
     | 
| 
      
 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 =  
     | 
| 
       27 
     | 
    
         
            -
                    lLoginForm.Passwd =  
     | 
| 
      
 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
         
     | 
    
        data/lib/StatsCollect/Stats.rb
    CHANGED
    
    | 
         @@ -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 
     | 
    
         
            -
                       
     | 
| 
      
 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
         
     |