Class: ScreenTracker
- Inherits:
-
Object
- Object
- ScreenTracker
- Defined in:
- lib/screen_tracker.rb
Constant Summary collapse
- DIGIT_TYPES =
[:hours, :minute_tens, :minute_ones, :second_tens, :second_ones]
Instance Attribute Summary collapse
-
#hwnd ⇒ Object
Returns the value of attribute hwnd.
Class Method Summary collapse
Instance Method Summary collapse
- #attempt_to_get_time_from_screen ⇒ Object
-
#dump_bmp(filename = 'dump.bmp') ⇒ Object
writes out all screen tracking info to various files in the current pwd.
- #dump_digits ⇒ Object
-
#get_bmp ⇒ Object
gets the snapshot of “all the digits together”.
-
#get_digits_as_bitmaps ⇒ Object
returns like {:hours => nil, :minutes_tens => raw_bmp, .…
-
#get_full_bmp ⇒ Object
gets snapshot of the full window.
- #get_hwnd ⇒ Object
- #get_relative_coords ⇒ Object
-
#identify_digit(bitmap) ⇒ Object
split out for unit testing purposes.
-
#initialize(name_or_regex, x, y, width, height, digits = nil, callback = nil) ⇒ ScreenTracker
constructor
digits are like => [100,5], :minute_tens, :minute_ones, :second_tens, :second_ones digits share the height start point, have their own x and width…
- #process_forever_in_thread ⇒ Object
- #wait_till_next_change ⇒ Object
Constructor Details
#initialize(name_or_regex, x, y, width, height, digits = nil, callback = nil) ⇒ ScreenTracker
digits are like => [100,5], :minute_tens, :minute_ones, :second_tens, :second_ones digits share the height start point, have their own x and width…
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/screen_tracker.rb', line 20 def initialize name_or_regex,x,y,width,height,digits=nil,callback=nil # cache to save us 0.00445136 per time LOL @name_or_regex = name_or_regex get_hwnd pps 'height', height, 'width', width if $VERBOSE raise 'poor dimentia' if width <= 0 || height <= 0 max_x, max_y = Win32::Screenshot::Util.dimensions_for(@hwnd) if(x < 0 || y < 0) if x < 0 x = max_x + x end if y < 0 y = max_y + y end end @height = height @x = x; @y = y; @x2 = x+width; @y2 = y+height; @callback = callback @max_x = max_x raise 'poor width or wrong window' if @x2 > max_x || @x2 == x raise 'poor height or wrong window' if @y2 > max_y || @y2 == y @digits = digits @displayed_warning = false pps 'using x',@x, 'from x', x, 'y', @y, 'from y', y,'x2',@x2,'y2',@y2,'digits', @digits if $VERBOSE end |
Instance Attribute Details
#hwnd ⇒ Object
Returns the value of attribute hwnd.
16 17 18 |
# File 'lib/screen_tracker.rb', line 16 def hwnd @hwnd end |
Class Method Details
.new_from_yaml(yaml, callback) ⇒ Object
8 9 10 11 12 13 14 |
# File 'lib/screen_tracker.rb', line 8 def self.new_from_yaml yaml, callback settings = YAML.load yaml # heigth is shared... height = settings["height"] digits = settings["digits"] return new(settings["name"], settings["x"], settings["y"], settings["width"], settings["height"], digits, callback) end |
Instance Method Details
#attempt_to_get_time_from_screen ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/screen_tracker.rb', line 151 def attempt_to_get_time_from_screen out = {} dump_digits if $DEBUG digits = get_digits_as_bitmaps # 0.08s [!] not too accurate...ltodo start = Time.now DIGIT_TYPES.each{|type| if digits[type] digit = identify_digit(digits[type]) unless digit if $DEBUG || $VERBOSE @a ||= 1 @a += 1 @already_wrote ||= {} unless @already_wrote[digits[type]] p 'unable to identify capture!' + type.to_s + @a.to_s File.binwrite("bad_digit#{@a}#{type}.bmp", digits[type]) unless type == :hours @already_wrote[digits[type]] = true end end if type == :hours digit = 0 # this one can fail in VLC else # early return p 'identity failure ' + type.to_s if $VERBOSE return end end out[type] = digit else # there isn't one specified as being on screen, so assume it is always zero (like youtube hour)... out[type] = 0 end } out = "%d:%d%d:%d%d" % DIGIT_TYPES.map{ |type| out[type] } puts '', 'got new screen time ' + out + " tracking delta:" + (Time.now - start).to_s if $VERBOSE return out, Time.now-start end |
#dump_bmp(filename = 'dump.bmp') ⇒ Object
writes out all screen tracking info to various files in the current pwd
77 78 79 80 81 |
# File 'lib/screen_tracker.rb', line 77 def dump_bmp filename = 'dump.bmp' File.binwrite filename, get_bmp File.binwrite 'all.' + filename, get_full_bmp dump_digits end |
#dump_digits ⇒ Object
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/screen_tracker.rb', line 83 def dump_digits if @digits @digit_count ||= 1 @digit_count += 1 for type, bitmap in get_digits_as_bitmaps File.binwrite type.to_s + '.' + @digit_count.to_s + '.bmp', bitmap end print 'wrote digits:', @digit_count, "\n" end end |
#get_bmp ⇒ Object
gets the snapshot of “all the digits together”
66 67 68 69 |
# File 'lib/screen_tracker.rb', line 66 def get_bmp # Note: we no longer bring the window to the front tho...which it needs to be in both XP and Vista to work...sigh. Win32::Screenshot::BitmapMaker.capture_area(@hwnd,@x,@y,@x2,@y2) {|h,w,bmp| return bmp} end |
#get_digits_as_bitmaps ⇒ Object
returns like {:hours => nil, :minutes_tens => raw_bmp, …
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/screen_tracker.rb', line 96 def get_digits_as_bitmaps # @digits are like {:hours => [100,5], :minute_tens => [x, width], :minute_ones, :second_tens, :second_ones} out = {} for type in DIGIT_TYPES assert @digits.key?(type) if @digits[type] x,w = @digits[type] if(x < 0) x = @max_x + x end out[type] = Win32::Screenshot::BitmapMaker.capture_area(@hwnd, x, @y, x+w, @y2) {|h,w,bmp| bmp} end end out end |
#get_full_bmp ⇒ Object
gets snapshot of the full window
72 73 74 |
# File 'lib/screen_tracker.rb', line 72 def get_full_bmp Win32::Screenshot::BitmapMaker.capture_all(@hwnd) {|h,w,bmp| return bmp} end |
#get_hwnd ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/screen_tracker.rb', line 45 def get_hwnd if @name_or_regex.to_s.downcase == 'desktop' # full screen option @hwnd = hwnd = Win32::Screenshot::BitmapMaker.desktop_window else @hwnd = Win32::Screenshot::BitmapMaker.hwnd(@name_or_regex) end unless @hwnd until @hwnd print 'perhaps not running yet? [%s]' % @name_or_regex sleep 1 STDOUT.flush @hwnd = Win32::Screenshot::BitmapMaker.hwnd(@name_or_regex) end puts 'found window' end end |
#get_relative_coords ⇒ Object
112 113 114 |
# File 'lib/screen_tracker.rb', line 112 def get_relative_coords [@x,@y,@x2,@y2] end |
#identify_digit(bitmap) ⇒ Object
split out for unit testing purposes
117 118 119 |
# File 'lib/screen_tracker.rb', line 117 def identify_digit bitmap OCR.identify_digit(bitmap, @digits) end |
#process_forever_in_thread ⇒ Object
189 190 191 192 193 194 195 196 |
# File 'lib/screen_tracker.rb', line 189 def process_forever_in_thread Thread.new { loop { out_time, delta = wait_till_next_change @callback. out_time, delta } } end |
#wait_till_next_change ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/screen_tracker.rb', line 121 def wait_till_next_change original = get_bmp time_since_last = Time.now loop { current = get_bmp if current != original if @digits got = attempt_to_get_time_from_screen if @displayed_warning && got # reassure user :) p 'tracking it successfully again' @displayed_warning = false end return got else puts 'screen time change only detected...' return end end sleep 0.02 if(Time.now - time_since_last > 5) p 'warning--unable to track screen time for some reason' unless @displayed_warning time_since_last = Time.now @displayed_warning = true # reget window, just in case that's the problem... get_hwnd end } end |