#!/usr/bin/ruby require "getoptlong" require "rubygems" require "active_support" require "open-uri" # ENV['RAILS_ENV'] = ENV['RAILS_ENV'] || 'development' # require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require File.expand_path(File.dirname(__FILE__) + "/../lib/pokerstats/pokerstars_file") require File.expand_path(File.dirname(__FILE__) + '/../lib/pokerstats/player_statistics') # require 'pokerstats/pokerstars_file' # require 'pokerstats/player_statistics' def search_poker_edge(playername, players_shown = {}) return if players_shown[playername] escaped_playername = URI.escape(playername).gsub(/["'\[\]]/,'\\\\\&').gsub(/[\[\]]/,'\\\\\\\\\&') result = `curl -s http://www.poker-edge.com/whoami.php?site=Stars\\&name=#{escaped_playername}` if result =~ /(Pre-Flop Tend.*\n)/ verbose = $1.gsub(/<\/?[^>]*>/, "") if verbose =~ /Pre-Flop Tendency: ([^-]*) -/ preflop = $1 else preflop = "N/A" end else preflop = "N/A (data error)" end if result =~ /(Player Type.*\n)/ verbose = $1.gsub(/<\/?[^>]*>/, "") if verbose =~ /[Yy]ou are a ([^(]* \(.*\))/ player_type = $1 else player_type = "" end else player_type = "" end players_shown[playername] = preflop players_shown[playername] += " " + player_type unless player_type.empty? end def display_ratio numerator, denominator if numerator.nil? or denominator.nil? return "***" elsif denominator < 9 return "#{numerator}/#{denominator}" else return "#{(100.0 * numerator / denominator).to_i}%" end end def dopsfile(file, players_shown) return if File.directory?(file) players = {} last = nil statistics = Pokerstats::PlayerStatistics.new Pokerstats::PokerstarsFile.open(file) do |pokerstarsfile| pokerstarsfile.each do |handrecord| begin handrecord.parse statistics.record(handrecord) last = handrecord rescue Exception => e puts e.message end end end return if last.nil? players = last.stats.players puts puts "=" * file.size puts file puts "=" * file.size STDOUT.sync = true printf("Searching Poker-Edge: ") players.collect {|each| Thread.new{printf("%s ", each); search_poker_edge(each, players_shown) }}.collect{|each| printf("."); each.value} printf("\n") STDOUT.sync = false puts "=" * file.size reports = statistics.reports printf "%-20s|%3s %4s %4s %5s %5s %5s|%5s %5s %5s|%5s %5s %5s | %s\n", "Screen Name", "Num", "VP$%", "PFR%", "Pre/Pos", "BAtt%", "BDef%", "CBet%", "Call", "Fold", "3Bet%", "Call", "Fold", "Poker-Edge Description" puts "--------------------|---------------------------------|-----------------|------------------|--------------------------------------------" players.each do |each| report = reports[each] # puts report.to_yaml t_hands = report[:t_hands] vpi_p = display_ratio report[:t_vpip], report[:t_hands] pfr_p = display_ratio report[:t_pfr_opportunity_taken], report[:t_pfr_opportunity] prefa = report[:t_preflop_passive].zero? ? 0.0 : [1.0 * report[:t_preflop_aggressive] / report[:t_preflop_passive],9.9].min posfa = report[:t_postflop_passive].zero? ? 0.0 : [1.0 * report[:t_postflop_aggressive] / report[:t_postflop_passive],9.9].min batt_p = display_ratio report[:t_blind_attack_opportunity_taken], report[:t_blind_attack_opportunity] bdef_p = display_ratio report[:t_blind_defense_opportunity_taken], report[:t_blind_defense_opportunity] cbet_flop_p = display_ratio report[:t_f_cbet], report[:t_f_cbet_o] call_cbet_flop_p = display_ratio report[:t_c_f_cbet], report[:t_c_f_cbet_o] fold_to_cbet_flop_p = display_ratio report[:t_f2_f_cbet], report[:t_f2_f_cbet_o] preflop_3bet_p = display_ratio report[:t_p_3bet], report[:t_p_3bet_o] call_preflop_3bet_p = display_ratio report[:t_c_p_3bet], report[:t_p_4bet_o] fold_to_preflop_3bet_p = display_ratio report[:t_f2_p_3bet], report[:t_p_4bet_o] description = players_shown[each][/\(.*\)/] description ||= "" description.gsub!("Passive", "P") description.gsub!("Aggressive", "A") description.gsub!("Tight", "T") description.gsub!("Loose", "L") players_shown[each].gsub!(/\(.*\)/, description) printf "%-20s|%3d %4s %4s %2.1f/%2.1f %5s %5s|%5s %5s %5s|%5s %5s %5s | %s\n", each, t_hands, vpi_p, pfr_p, prefa, posfa, batt_p, bdef_p, cbet_flop_p, call_cbet_flop_p, fold_to_cbet_flop_p, preflop_3bet_p, call_preflop_3bet_p,fold_to_preflop_3bet_p, players_shown[each] # puts report.to_yaml end puts "=" * file.size GC.start end def newpsfiles(user, time) Dir["/Users/#{user}/Library/Application Support/PokerStars/HandHistory/**/*"].select{|each| File.mtime(each) > time} end def getpsdata(user, time, players_shown) puts "Loading PokerStars HandHistories that have changed since #{time}" while (files = newpsfiles(user, time)).empty? sleep 1 end puts files.inspect files.each {|each| dopsfile(each, players_shown)} end def display_recent_pokerstars_results user players_shown = {} getpsdata(user, Time.now - 3000, players_shown) loop {getpsdata(user, Time.now, players_shown)} end def display_poker_edge_results players_shown = {} $*.each do |playername| puts "Poker Edge Search for #{playername}" search_poker_edge(playername, players_shown) puts "="*80 printf "%-20s %s\n", playername, players_shown[playername] puts "="*80 end end opts = GetoptLong.new( [ "--help", "-h", GetoptLong::NO_ARGUMENT], [ "--version", "-v", GetoptLong::NO_ARGUMENT], [ "--user", "-u", GetoptLong::OPTIONAL_ARGUMENT] ) version_file = File.expand_path(File.dirname(__FILE__) + "/../VERSION") print "Pokerstars HandHistory Statistics, v#{File.read(version_file).chop}\n" print "Copyright (c) 2009 Andrew C. Greenberg All Rights Reserved\n" user = `whoami`.chop opts.each do |opt, arg| case opt when "--help", "--usage" print "#{$0} playername {--user username} {--player playername} {--help } {--version}\n" when "--version" print "Pokerstars version #{File.read(version_file).chop}\n" when "--user" user = arg unless arg.empty? end end if $*.empty? display_recent_pokerstars_results user else display_poker_edge_results end