How to bind a key sequence in Ruby Tk? - ruby

I am tring to bind the key sequence Control_L + Up in a Tk widget in Ruby. More explicitely, I want a proc to run when "Control_Left" and "Arrow-Up" are pressed together.
Untill now I have not been successful, I tried many combinations looking at TclTk, Python and Perl docs but I could not find the way out.
It should be something similar to
widget.bind("Control_L Up", proc {
puts "-----> sequence ok "
})
p.s. One by one the two events Control_L and Up are correcly catched.

I found it, to whoever may need it in future, this is the working snippet
require 'tk'
root = TkRoot.new()
root.minsize [400, 300]
root.geometry "+200+200"
root.bind('Control-Key-Up', proc { puts "presssed Control + Up"; } )
Tk.mainloop()
Observe that (1) it works even in form 'Control Key Up' as stated in TclTk docs. But it does not work if you write it as '<Control-Key-Up>', which is the default Tk syntax.

Related

Simplify Move and Maximise screen using Selenium (Ruby)

I am running my selenium tests using a ruby Framework having recently joined a new company. As I am working on 3 screens I have added in a browser step to move the browser window to my left most screen before maximising using
#driver.manage.window.move_to(-1800, 1500)
#driver.manage.window.maximize
My question very simply is, having never used Ruby before, is there a way to refactor these 2 lines into 1 I have tried various ways but always get an error.
It's not possible in this place because both are returning string object so you can't cascade the calling like
#driver.manage.window.move_to(-1800, 1500).maximize
But If it's very important for you, then I will tell you a way to do this, open the window.rb file where you can return the self from move_to function as shown below
def move_to(x, y)
#bridge.reposition_window Integer(x), Integer(y)
self
end
And then you can make a call like this
#driver.manage.window.move_to(-1800, 1500).maximize

What is the best way to get keyboard events (input without press 'enter') in a Ruby console application?

I've been looking for this answer in the internet for a while and have found other people asking the same thing, even here. So this post will be a presentation of my case and a response to the "solutions" that I have found.
I am such new in Ruby, but for learning purposes I decided to create a gem, here.
I am trying to implement a keyboard navigation to this program, that will allow the user use short-cuts to select what kind of request he want to see. And in the future, arrow navigations, etc.
My problem: I can't find a consistent way to get the keyboard events from the user's console with Ruby.
Solutions that I have tried:
Highline gem: Seems do not support this feature anymore. Anyway it uses the STDIN, keep reading.
STDIN.getch: I need to run it in a parallel loop, because at the same time that the user can use a short-cut, more data can be created and the program needs to show it. And well, I display formated text in the console, (Rails log). When this loop is running, my text lost the all the format.
Curses: Cool but I need to set position(x,y) to display my text every time? It will get confusing.
Here is where I am trying to do it.
You may note that I am using "stty -raw echo" (turns raw off) before show my text and "stty raw -echo" (turns raw on) after. That keeps my text formated.
But my key listener loop is not working. I mean, It works in sometimes but is not consistent. If a press a key twice it don't work anymore and sometimes it stops alone too.
Let me put one part of the code here:
def run
# Two loops run in parallel using Threads.
# stream_log loops like a normal stream in the file, but it also parser the text.
# break it into requests and store in #requests_queue.
# stream_parsed_log stream inside the #requests_queue and shows it in the screen.
#requests_queue = Queue.new
#all_requests = Array.new
# It's not working yet.
Thread.new { listen_keyboard }
Thread.new { stream_log }
stream_parsed_log
end
def listen_keyboard
# not finished
loop do
char = STDIN.getch
case char
when 'q'
puts "Exiting."
exit
when 'a'
#types_to_show = ['GET', 'POST', 'PUT', 'DELETE', 'ASSET']
requests_to_show = filter_to_show(#all_requests)
command = true
when 'p'
#types_to_show = ['POST']
requests_to_show = filter_to_show(#all_requests)
command = true
end
clear_screen if command
#requests_queue += requests_to_show if command
command = false
end
end
I need a light in my path, what should I do?
That one was my mistake.
It's just a logic error in another part of code that was running in another thread so the ruby don't shows the error by default. I used ruby -d and realized what was wrong. This mistake was messing my keyboard input.
So now it's fixed and I am using STDIN.getch with no problem.
I just turn the raw mode off before show any string. And everything is ok.
You can check here, or in the gem itself.
That's it.

Why does gets return zero in Ruby

I have a simple method
def save_logline
print "What's the name of the movie"
movie_name = gets.strip
print "And what is your precious logline?"
logline = gets.strip
File::open(movie_name + '.txt', 'w') do |f|
f.write(logline)
end
end
Anytime I run the code, I receive the first prompt where I insert the name of the movie, but once I press enter the second print is called, giving me this message.
And what is your precious logline?=> 0
The file is written but I'm prevented from inserting anything into the text file. What's wrong with my logic and how do I fix this? I am using irb in RubyMine with Ubuntu.
EDIT: It appears that due to other users response to my code working and my own test on a different development machine my code is just not working on that one machine. The only thing I could say is that I was using RubyMine's irb console. The question now must be is it a RubyMine issue or is there a bigger problem with my dev machine?
FINAL EDIT: I checked on my second comp that has RubyMine, it appears that it does not work in that RubyMine's irb console either. I'm going to issue the bug to RubyMine and give credit to Jeremy in a day or two unless someone knows why RubyMine's irb is acting funky.
Your code works. The 0 is the return value of f.write. It's saying it wrote zero bytes to your file, because you didn't give it any input.
Edit: Maybe you pressed enter twice by accident...

How to loop throgh all links in div and collect values from opened fields

Is it possible to open every link in certain div and collect values of opened fields alltogether in one file or at least terminal output?
I am trying to get list of coordinates from all markers visible on google map.
all_links = b.div(:id, "kmlfolders").links
all_links.each do |link|
b.link.click
b.link(:text, "Norādījumi").click
puts b.text_field(:title, "Galapunkta_adrese").value
end
Are there easier or more effective ways how to automatically collect coordinates from all markers?
Unless there is other data (alt tags? elements invoked via onhover?) in the HTML already that you could pick through, that does seem like the most practical way to iterate through the links, however from what I can see you are not actually making use of the 'link' object inside your loop. You'd need something more like this I think
all_links = b.div(:id, "kmlfolders").links
all_links.each do |thelink|
b.link(:href => thelink.href).click
b.link(:text, "Norādījumi").click
puts b.text_field(:title, "Galapunkta_adrese").value
end
Probably using their API is a lot more effective means to get what you want however, it's why folks make API's after all, and if one is available, then using it is almost always best. Using a test tool as a screen-scraper to gather the info is liable to be a lot harder in the long run than learning how to make some api calls and get the data that way.
for web based api's and Ruby I find the REST-CLIENT gem works great, other folks like HTTP-Party
As I'm not already familiar with Google API, I find it hard for me to dig into API for one particular need. Therefor I made short watir-webdriver script for collecting coordinates of markers on protected google map. Resulting file is used in python script that creates speedcam files for navigation devices.
In this case it's speedcam map maintained and updated by Latvian police, but this script can probably be used with any google map just by replacing url.
# encoding: utf-8
require "rubygems"
require "watir-webdriver"
#b = Watir::Browser.new :ff
#--------------------------------
#b.goto "http://maps.google.com/maps?source=s_q&f=q&hl=lv&geocode=&q=htt%2F%2Fmaps.google.com%2Fmaps%2Fms%3Fmsid%3D207561992958290099079.0004b731f1c645294488e%26msa%3D0%26output%3Dkml&aq=&sll=56.799934,24.5753&sspn=3.85093,8.64624&ie=UTF8&ll=56.799934,24.5753&spn=3.610137,9.887695&z=7&vpsrc=0&oi=map_misc&ct=api_logo"
#b.div(:id, "kmlfolders").wait_until_present
all_markers = #b.div(:id, "kmlfolders").divs(:class, "fdrlt")
#prev_coordinates = 1
puts "#{all_markers.length} speedcam markers detected"
File.open("list_of_coordinates.txt","w") do |outfile|
all_markers.each do |marker|
sleep 1
marker.click
sleep 1
description = #b.div(:id => "iw_kml").text
#b.span(:class, "actbar-text").click
sleep 2
coordinates = #b.text_field(:name, "daddr").value
redo if coordinates == #prev_coordinates
puts coordinates
outfile.puts coordinates
#prev_coordinates = coordinates
end
end
puts "Coordinates saved in file!"
#b.close
Works both on Mac OSX 10.7 and Windows7.

How can I programatically call the ruby debugger from within a ruby program in Ruby 1.9?

I am writing a web based debugger for Ruby, but in order to do this I need to be able to call the Ruby debugger from within a Ruby program on the server side. Has this ever been done? Is this even possible?
The end product being built will allow Ruby code to be edited, executed and stepped through using just a web browser. The ruby code that is to be debugged will be "eval"ed on the server side.
I have since been pointed in the right direction by one of the stackoverflow users who has suggested using popen or expect. I have tried both of these now but have encountered the following problems:
popen: When waiting for the console you have to use a timeout block to signal the end of the debug console's output (The command line terminal can detect this, so why can't ruby).
expect: In the program below the debugger inputs get out of sync with the debugger. Why is that?
require 'pty'
require 'expect'
$expect_verbose = true
PTY.spawn("rdebug deb.rb") do |from_debugger, to_debugger, pid|
a=nil
while ( a != "end" ) do
from_debugger.expect(/\(rdb:1\)/ ) do |input|
a = gets
to_debugger.puts( a + "\n" )
end
from_debugger.flush
end
end
I think you could make use of ruby-debug. I would imagine this as opening the same script on the server-side, and sending keystrokes to it. I think this is how I'd do it.
Think about it this way: the client pastes his code in your form. Optionally, he may click on some button that places a breakpoint on some line. Then he submits the whole thing. On server side, you process that form, and create a .rb file with the contents of the form. At the line where he put the breakpoint, you insert a debugger call. Then you run :
ruby client_script.rb
and this will stop the process once it reaches the debugger line. I would suggest you do all of this with Expect for Ruby or whatever. So, when the client presses step over on the page or inspect whatever variable, you send keystrokes to the process you spawned.
For example, if he wants to inspect the value of the variable x, you'd send this to the process:
p x
and you'd have to capture that output and send it back to the client's browser. Expect is kind of like popen , but a bit better.
I finally figured out how to do this using expect:
require 'pty'
require 'expect'
PTY.spawn("rdebug deb.rb") do |output,input,pid|
while true do
begin
buffer = ""
puts "-------"
puts output.readpartial(1024,buffer) until buffer =~ /\(rdb:1\)/
a = gets
input.puts a
rescue
break
end
end
end

Resources