class Tor::StatsObj

This class can be used to obtain a variety of statistics or data from Tor::Router. The same user have multiple IP addresses on different days, but the fingerprint might not change, especially not withing a month. Use uniq stats when available.

Public Instance Methods

continent_count(code,*platform) click to toggle source

This returns the number of OR IP addresses from the continent with the code used as input (and optionally platform parameter).

@example Get number of OR IP addr from continents

Tor::StatsObj.continent_count("EU")
Tor::StatsObj.continent_count("NA","UNIX")
Tor::StatsObj.continent_count( ["EU","NA","SA"] ,[ "UNIX", "LINUX" ] )
# File lib/tstats.rb, line 67
def continent_count(code,*platform)
    rslt = (platform.empty? or platform == ["ALL"] ) ? Router.where(:continent=>code) : Router.where(:continent=>code, :platform=>platform) 
    rslt.count                        # continent code   "AF","EU","AS","NA","SA","OC"
end
continent_count_uniq(code,*platform) click to toggle source

This returns the number of OR IP addresses from the continent with the code used as input (and optionally platform parameter).

@example Get number of OR IP addr from continents

Tor::StatsObj.continent_count("EU")
Tor::StatsObj.continent_count("NA","UNIX")
Tor::StatsObj.continent_count( ["EU","NA","SA"] ,[ "UNIX", "LINUX" ] )
# File lib/tstats.rb, line 79
def continent_count_uniq(code,*platform)
    rslt = (platform.empty? or platform == ["ALL"] ) ?
            Router.where(:id=> get_uniqid(country_list, *platform), :continent=>code) :
            Router.where(:id=> get_uniqid(country_list, *platform), :continent=>code, :platform=>platform) 
    rslt.count                        # continent code   "AF","EU","AS","NA","SA","OC"
end
continent_getfingerprint(continent_filter,*platform) click to toggle source

This retuns an array of all OR fingerprints from Tor::Router using a filter of continents and optional platform parameter.

@example Get all OR IP fingerprints from France

Tor::StatsObj.continent_getfingerprint("EU")
Tor::StatsObj.continent_getfingerprint(["AF",EU"], "WINDOWS")
Tor::StatsObj.continent_getfingerprint(["NA","SA"], ["WINDOWS", "LINUX"] )
# File lib/tstats.rb, line 147
def continent_getfingerprint(continent_filter,*platform) 
    if platform.empty? or platform == ["ALL"] 
        onionr = Router.where(:continent=>continent_filter,:id=>get_uniqid(countryfilter,*platform))
    else
        onionr=Router.where(:continent=>continent_filter,:platform=>platform ,:id=>get_uniqid(countryfilter,*platform))
    end         
    onion_ipaddr = onionr.collect{|each_country| each_country.fingerprint}
end
continent_list(*platform) click to toggle source

This returns a list of all continents that have contributed to the OR IP addresses in Tor::Router It can return only the those that have contributed to a particular platform

@example Get Countries the that use Unix

Tor::StatsObj.continent_list
Tor::StatsObj.continent_list("UNIX")
Tor::StatsObj.continent_list( ["UNIX", "LINUX"] )
# File lib/tstats.rb, line 29
def continent_list(*platform)
    tmpresult = (platform.empty? or platform == ["ALL"]) ? Router.all : Router.where(:platform=>platform)
    tmpresult.group_by{|c| c.continent}.keys
end
continent_stat(allcontinents,*platform) click to toggle source

It takes an array of continent codes as input, and produces a hash with the continent codes as keys and the total number of ors from the country as value

@example Get continents statistics

Tor::StatsObj.continent_stat(["EU","NA","SA"])             => {"EU" => total, .... "SA" => total }
Tor::StatsObj.continent_stat(["EU","NA","SA"], "LINUX")
Tor::StatsObj.continent_stat( Tor::StatsObj.country_list )

Note: Results of #continent_list can be used as argument for this #continent_stat.

# File lib/tstats.rb, line 188
def continent_stat(allcontinents,*platform)
    continent_count_hash={}
    if allcontinents.class==String
        continent_count_hash[allcontinents] = continent_count(allcontinents,*platform)
    else
        allcontinents.each{|each_continent|
            continent_count_hash[each_continent] = continent_count(each_continent,*platform)
        }
    end
    continent_count_hash
end
continent_stat_uniq(allcontinents,*platform) click to toggle source

It takes an array of continent codes as input, and produces a hash with the continent codes as keys and the total number of ors from the country as value

@example Get continents statistics

Tor::StatsObj.continent_stat_uniq(["EU","NA","SA"])             => {"EU" => total, .... "SA" => total }
Tor::StatsObj.continent_stat_uniq(["EU","NA","SA"], "LINUX")
Tor::StatsObj.continent_stat_uniq( Tor::StatsObj.country_list )

Note: Results of #continent_list can be used as argument for this #continent_stat_uniq.

# File lib/tstats.rb, line 209
def continent_stat_uniq(allcontinents,*platform)
    continent_count_hash={}
    if allcontinents.class==String
        continent_count_hash[allcontinents] = continent_count_uniq(allcontinents,*platform)
    else
        allcontinents.each{|each_continent|
            continent_count_hash[each_continent] = continent_count_uniq(each_continent,*platform)
        }
    end
    continent_count_hash
end
country_count(code,*platform) click to toggle source

This returns the number of OR IP addresses from the country with the code used as input (and optionally platform parameter).

@example Get number of OR IP addr from continents

Tor::StatsObj.country_count("FR")
Tor::StatsObj.country_count("FR","UNIX")
Tor::StatsObj.country_count( ["FR","DE"] ,[ "UNIX", "LINUX" ] )
# File lib/tstats.rb, line 41
def country_count(code,*platform)
    rslt = (platform.empty? or platform == ["ALL"] ) ?
              Router.where(:country_code=>code) :
              Router.where(:country_code=>code,:platform=>platform)
    rslt.count
end
country_count_uniq(countryfilter,*platform) click to toggle source

This returns the total number of uniq identities found in the database.

<b>Get total number of routers in countries<b>. #country_count_uniq) #country_count_uniq("FR","WINDOWS") #country_count_uniq,["UNIX",LINUX"] )

# File lib/tstats.rb, line 55
def country_count_uniq(countryfilter,*platform)
    get_uniqid(countryfilter,*platform).count
end
country_getfingerprint(country_filter,*platform) click to toggle source

This retuns an array of all OR fingerprints from the Tor::Router using a filter of countries and optional platform parameter.

@example Get all OR IP fingerprints from France

Tor::StatsObj.country_getingerprint("FR")
Tor::StatsObj.country_getingerprint(["FR",GB"], "WINDOWS")
Tor::StatsObj.country_getingerprint(["FR",GB"], ["WINDOWS", "LINUX"] )
# File lib/tstats.rb, line 131
def country_getfingerprint(country_filter,*platform) 
    if platform.empty? or platform == ["ALL"] 
        onionr = Router.where(:country_code=>country_filter)
    else
        onionr=Router.where(:country_code=>country_filter,:platform=>platform )
    end         
    onion_ipaddr = onionr.collect{|each_country| each_country.fingerprint}
end
country_getip(country_filter,*platform) click to toggle source

This retuns an array of all OR IP addresses from the Tor::Router using a filter of countries and optional platform parameter.

@example Get all OR IP addresses from France

Tor::StatsObj.country_getip("FR")
Tor::StatsObj.country_getip(["FR",GB"], "WINDOWS")
Tor::StatsObj.country_getip(["FR",GB"], ["WINDOWS", "LINUX"] )
# File lib/tstats.rb, line 115
def country_getip(country_filter,*platform) 
    if platform.empty? or platform == ["ALL"] 
        onionr = Router.where(:country_code=>country_filter)
    else
        onionr=Router.where(:country_code=>country_filter,:platform=>platform )
    end         
    onion_ipaddr=onionr.collect{|each_country| each_country.ipaddr}
end
country_list(*platform) click to toggle source

This returns a list of all countries that have contributed to the OR IP addresses in Tor::Router It can return only the those that have contributed to a particular platform

@example Get Countries the that use Unix

Tor::StatsObj.country_list
Tor::StatsObj.country_list("UNIX")
Tor::StatsObj.country_list( ["UNIX", "LINUX"] )
# File lib/tstats.rb, line 16
def country_list(*platform)
    tmpresult = (platform.empty? or platform == ["ALL"]) ? Router.all : Router.where(:platform=>platform)
    tmpresult.group_by{|c| c.country_code}.keys
end
country_stat(countrycodes,*platform) click to toggle source

It takes an array of country codes as input, and produces a hash with the country codes as keys and the total number of ors from the country as value. An optional platform can also be set.

@example Get country statistics

Tor::StatsObj.country_stat(["EU","NA","SA"])             => {"EU" => country,total, .... "SA" => country,total }
Tor::StatsObj.country_stat(["EU","NA","SA"], "LINUX")
Tor::StatsObj.country_stat( Tor::StatsObj.country_list )
Tor::StatsObj.country_stat( Tor::StatsObj.country_list(platform) )

Note: Results of #country_list can be used as argument for this #country_stat.

# File lib/tstats.rb, line 98
def country_stat(countrycodes,*platform)
    country_count_hash={}
    if countrycodes.class==String
        country_count_hash[countrycodes] = country_count(countrycodes,*platform)
    else
        countrycodes.each{|each_country| country_count_hash[each_country] = country_count(each_country,*platform)}
    end
    country_count_hash
end
country_stat_uniq(countrycodes,*platform) click to toggle source

It takes an array of country codes as input, and produces a hash with the country codes as keys and the total number of unique ors from the country as value. An optional platform can also be set.

@example Get country statistics

Tor::StatsObj.country_stat_uniq(["FR","GB","US"])             => {"FR" => total, .... "US" => total }
Tor::StatsObj.country_stat_uniq([DE","FR"], "LINUX")
Tor::StatsObj.country_stat_uniq( Tor::StatsObj.country_list )
Tor::StatsObj.country_stat_uniq( Tor::StatsObj.country_list(platform) )

Note: Results of #country_list can be used as argument for this #country_stat_uniq.

# File lib/tstats.rb, line 167
def country_stat_uniq(countrycodes,*platform)
    #   get_uniqid can be used for this, but this that will involve more calls to Tor::Router than necessary
    country_count_hash={}
    if countrycodes.class==String
        country_count_hash[countrycodes] = country_count_uniq(countrycodes,*platform)
    else
    countrycodes.each{|each_country| 
        country_count_hash[each_country] = country_count_uniq(each_country,*platform) }
    end
    country_count_hash
end
genkml(mapname,*platform) click to toggle source

This method generates a KML using the locations in Tor::Router database. It takes a name for the KML document as input, and an optional platform parameter.

@example Generate KML file

Tor::StatsObj.genkml("KML doc name")
Tor::StatsObj.genkml("KML platform name", ["WINDOWS","UNIX","LINUX", "OTHER"] )
Tor::StatsObj.genkml("KML platform name", "LINUX" )
# File lib/tstats.rb, line 310
def genkml(mapname,*platform)
    tour_hash= (defined? WORLDTOUR) ? WORLDTOUR : Constants::WORLDTOUR
    attack_tour = (defined? ATTACK_TOUR) ? ATTACK_TOUR: Constants::ATTACK_TOUR

    torcountry= topcountries_uniq(0,*platform)                       # collect{|country,count| country}                
    xml = Builder::XmlMarkup.new(:indent=>2)
    xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
    xml.kml("xmlns" => "http://www.opengis.net/kml/2.2",
                 "xmlns:gx"=>"http://www.google.com/kml/ext/2.2") do
        y=1


        xml.Document do
            xml.name mapname
            
            # define styles to use for placemarks and tour
            xml.Style("id"=>"redplaces") do
                xml.IconStyle do
                    xml.color "ff0000ff"
                end
            end
            xml.Style("id"=>"greenplaces") do
                xml.IconStyle do
                    xml.color "ff00ff00"
                end
            end
            xml.Style("id"=>"blackplaces") do
                xml.IconStyle do
                    xml.color "ff000000"
                end
            end
            xml.Style("id"=>"blueplaces") do
                xml.IconStyle do
                    xml.color "0000ff00"
                end
            end

            xml.Folder("id"=>"torbridges") do
                xml.name "Tor Bridges - #{Bridge.count}"
                allbridges = Bridge.all
                allbridges.each{|eachbridge|
                    brindex = 1 + allbridges.index(eachbridge)
                    placeid = "bridge#{brindex }"
                    xml.Placemark("id"=> placeid) do
                        xml.name "BR#{brindex.to_s}"
                        xml.description "#{eachbridge.ipaddr}:#{eachbridge.port}"
                        xml.styleUrl "#blueplaces"
                        xml.Point do
                            xml.extrude 1
                            xml.coordinates "#{eachbridge.lng},#{eachbridge.lat}"
                        end
                    end
                }
            end

            # Google earth tour
            xml.gx :Tour do
              xml.name "Tor World"
              xml.gx :Playlist do
                tour_hash.keys.each{|each_centre|
                  xml.gx :FlyTo do
                    xml.gx :duration,1.0
                    xml.LookAt do
                      country_lat,country_lng= get_latlng(each_centre)
                      xml.longitude country_lng
                      xml.latitude country_lat
                      xml.range 4900000
                    end   #end LookAt
                  end     # end FlyTo
                  

                  tour_hash[each_centre].each{|eachzone|
                    # toggle on
                    xml.gx :AnimatedUpdate do
                        xml.gx :duration,0.0
                        xml.Update do
                            xml.targetHref
                            xml.Change do
                                xml.Placemark("targetId"=> eachzone) do
                                    xml.gx :balloonVisibility,1
                                end        # end Placemark
                            end            # end Change
                        end                # end Update
                    end                    #end AnimatedUpdate
                    xml.gx :Wait do
                      xml.gx :duration,2.0
                    end

                    # toggle off
                    xml.gx :AnimatedUpdate do
                      xml.gx :duration,0.0
                      xml.Update do
                        xml.targetHref
                        xml.Change do
                            xml.Placemark("id"=> eachzone) do
                                xml.gx :balloonVisibility,0
                            end       # end placemark
                        end          # end Change
                      end           # end Update
                    end            # end AnimatedUpdate
                    xml.gx :Wait do
                        xml.gx :duration,2.0
                    end
                  } # eachzone
                }  #each_centre
              end    # end of gx:Playlist
            end      # end of gx:Tour


            # Google earth attack tour
            xml.gx :Tour do
              xml.name "Tor - Attack"
              xml.gx :Playlist do
                  xml.gx :FlyTo do
                    xml.gx :duration,1.0
                    xml.LookAt do
                      xml.longitude attack_tour[:lng]
                      xml.latitude attack_tour[:lat]
                      xml.range 2000000
                    end   #end LookAt
                  end     # end FlyTo


                  attack_tour["red"].each{|eachzone|
                    # toggle on
                    xml.gx :AnimatedUpdate do
                        xml.gx :duration,0.0
                        xml.Update do
                            xml.targetHref
                            xml.Change do
                                xml.Placemark("targetId"=> eachzone) do
                                    xml.styleUrl "#redplaces"
                                end        # end Placemark
                            end            # end Change
                        end                # end Update
                    end                    #end AnimatedUpdate
                  } # eachzone

                  attack_tour["black"].each{|eachzone|
                    # toggle on
                    xml.gx :AnimatedUpdate do
                        xml.gx :duration,2.0
                        xml.Update do
                            xml.targetHref
                            xml.Change do
                                xml.Placemark("targetId"=> eachzone) do
                                    xml.styleUrl "#blackplaces"
                                end        # end Placemark
                            end            # end Change
                        end                # end Update
                    end                    #end AnimatedUpdate
                    xml.gx :Wait do
                        xml.gx :duration,2.0
                    end
                  } # eachzone

              end    # end of gx:Playlist
            end      # end of gx:Tour

            torcountry.each { |country_code,countrytotal|
                countryname = get_countryname(country_code)
                xml.Folder("id"=>country_code) do
                    xml.name "#{countryname}-#{countrytotal}"
                    xml.LookAt do
                      country_lat,country_lng = get_latlng(country_code)
                      xml.longitude country_lng
                      xml.latitude country_lat
                      xml.range 4500000
                    end
                    idarray = get_uniqid(country_code,*platform)
                    if platform.empty? or  platform==["ALL"] or platform==["All"]
                        torlocations = Router.where(:id=>idarray,:country_code=>country_code)
                    else
                        torlocations = Router.where(:id=>idarray,:country_code=>country_code,:platform=>platform)
                    end
                    torplaces_sorted = torlocations.group_by{|c| [ c.lat, c.lng, c.country, c.city ] }.sort_by{|a,b| b.count}.reverse
                    torplaces_sorted.each{|lat_lng_country_city|
                        # Group by fingerprint here and get the size of the hash, and get the number of elements in the hash instead of get_uniqid
                        # but what if user is mobile? different isps, latitude-longitude, or lives the city or country
                        lat, lng, country, city = lat_lng_country_city[0]
                        pointtotal = lat_lng_country_city[1].count
                        placeid = "#{country_code}#{ 1 + torplaces_sorted.index(lat_lng_country_city)}"
                        xml.Placemark("id"=> placeid) do
                            strcount = (pointtotal == 1) ? 'OR' : 'ORs'
                            #xml.name "#{y}"
                            y += 1
                            kmlcity= (city.empty?) ? "#{country}" : "#{city}"
                            xml.description "#{pointtotal} #{strcount} in #{kmlcity} of #{countrytotal}(country total)"
                            xml.styleUrl "#greenplaces"
                            xml.Point do
                                xml.extrude 1
                                xml.coordinates "#{lng},#{lat}"
                            end
                        end
                    }
                end
            }
        end
    end
    xml.target! #Return the xml file
end
get_countryname(ccode) click to toggle source

This returns the country name from the country code.

@example Get country name from country code

Tor::StatsObj.get_countryname("FR")
# File lib/tstats.rb, line 254
def get_countryname(ccode)
    x=Router.where(:country_code=>ccode).first
    (x.nil?) ? nil : x.country
end
get_latlng(country_code) click to toggle source

This returns the [latitude,longitude] from the country code. Using the constant Tor::Constants::COUNLATLNG,

or alternatively if Tor::COUNLATLNG has been defined in a program.
# File lib/tstats.rb, line 262
def get_latlng(country_code)
    countrylatlng = Constants::COUNLATLNG
    if (defined? COUNLATLNG)
      if (COUNLATLNG.keys.include? country_code)
        lat= COUNLATLNG[country_code][:lat]
        lng= COUNLATLNG[country_code][:lng]
      end
    elsif countrylatlng.keys.include? country_code
      lat=countrylatlng[country_code][:lat]
      lng=countrylatlng[country_code][:lng]
    else
      puts "#{country_code}, #{get_countryname(country_code)} - not in the country-latitude file, using cordinates(0,0)"
      lat=0.0
      lng=0.0
    end
    [lat,lng]
end
get_uniqid(countryfilter,*platform) click to toggle source

This returns the id of uniq identities in the database

@example Get Uniq id of ORs in the UK

Tor::Stats.Obj.get_uniqid("GB")
Tor::Stats.Obj.get_uniqid("GB","WINDOWS")
Tor::Stats.Obj.get_uniqid(["GB","FR",DE"] , ["UNIX","LINUX"])
# File lib/tstats.rb, line 289
def get_uniqid(countryfilter,*platform)
    if platform.empty? or  platform==["ALL"] or platform==["All"]
        torlocations = Router.where(:country_code=>countryfilter)
    else
        torlocations = Router.where(:platform=>platform,:country_code=>countryfilter)
    end
    identitygroup = torlocations.group_by{|c| c.fingerprint}
    idarray = identitygroup.keys.collect{|eachidentitykey|
        #Collect just the id of the most recent location of the fingerprint
        identitygroup[eachidentitykey].max{|a,b| a.published_at <=> b.published_at}.id
    }
end
topcountries(num,*platform) click to toggle source

This returns the top n-countries. An optional platform parameter can be passed to this and returns an array of countries and total

@example Top n-countries #topcountries => [[country,total].…] #topcountries(n, “UNIX”) #topcountries(n, [“UNIX”,“LINUX”])

# File lib/tstats.rb, line 229
def topcountries(num,*platform)
    countryarray  = country_list(*platform)
    top_countries = country_stat(countryarray,*platform).sort_by{|k,v| v}
    result = (num==0) ? top_countries.reverse : top_countries.last(num).reverse
end
topcountries_uniq(num,*platform) click to toggle source

This returns the top n-countries. An optional platform parameter can be passed to this and returns an array of countries and total

@example Top n-countries #topcountries_uniq => [[country,total].…] #topcountries_uniq(n, “UNIX”) #topcountries_uniq(n, [“UNIX”,“LINUX”])

# File lib/tstats.rb, line 243
def topcountries_uniq(num,*platform)
    countryarray  = country_list(*platform)
    top_countries = country_stat_uniq(countryarray,*platform).sort_by{|k,v| v}
    result = (num==0) ? top_countries.reverse : top_countries.last(num).reverse
end