how to set command line parameter to BSON::Timestamp - ruby

Pls advice how to set command line parametertail_from which will be accepted by below code:
def optail
tail_from = options[:tail_from]
if tail_from.is_a? Time
tail_from = tailer.most_recent_position(tail_from)
end
tailer.tail(:from => tail_from, :filter => options[:oplog_filter])
...
end
It suggested to be Unix Timestamp
but task fails with error:
For mongo databases, tail :from must be a BSON::Timestamp Mongoriver::Assertions::AssertionFailure)

You can create a BSON::Timestamp from a Unix timestamp using its constructor, setting the increment to 0.
Also, the change streams' functionality has been expanded in recent releases and instead of using an oplog tailer you should consider database or cluster level change streams.

Related

How to deal with shell commands that never stops

Here is the case;
There is this app called "termux" on android which allows me to use a terminal on android, and one of the addons are androids API's like sensors, tts engines, etc.
I wanted to make a script in ruby using this app, specifically this api, but there is a catch:
The script:
require('json')
JSON.parse(%x'termux-sensor -s "BMI160 Gyro" -n 1')
-s = Name or partially the name of the sensor
-n = Count of times the command will run
returns me:
{
"BMI160 Gyroscope" => {
"values" => [
-0.03...,
0.00...,
1.54...
]
}
}
I didn't copied and pasted the values, but that's not the point, the point is that this command takes almost a full second the load, but there is a way to "make it faster"
If I use the argument "-d" and not use "-n", I can specify the time in milliseconds to delay between data being sent in STDOUT, it also takes a full second to load, but when it loads, the delay works like charm
And since I didn't specify a 'n' number of times, it never stops, and there is the problem
How can I retrieve the data continuously in ruby??
I thought about using another thread so it won't stop my program, but how can I tell ruby to return the last X lines of the STDOUT from a command that hasn't and will not ever stop since "%x'command'" in ruby waits for a return?
If I understood you need to connect to stdout from a long running process.
see if this works for your scenario using IO.popen:
# by running this program
# and open another terminal
# and start writing some data into data.txt
# you will see it appearing in this program output
# $ date >> data.txt
io_obj = IO.popen('tail -f ./data.txt')
while !io_obj.eof?
puts io_obj.readline
end
I found out a built in module that saved me called PTY and the spawn#method plus thread management helped me to keep a variable updated with the command values each time the command outputted new bytes

How to fetch schema version using regex?

I have the following text:
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160405090205) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
I need to get 20160405090205 number. How can I get it?
I've tried /version.*[0-9]/, but this captures only version: 20160405090205.
schema = File.read(Rails.root.join('db', 'schema.rb'))
version, *_ = schema.match(/version: (\d+)/m).captures
version # => "20160405090205"
version, *_ = ... is needed here because captures returns an array even when there is a single capture.
You could get it a capture group
string = "ActiveRecord::Schema.define(version: 20160405090205) do"
version = string.match(/version: (\d+)/m).captures.first

Ruby net-ssh-multi: passing a password as a parameter at runtime

I am trying to use net-ssh-multi to run a command on a group of servers. For this taks, ssh-key authentication is not an option; a password has to be passed to each server defined in the session.use lines. Here's the problem, 'net/ssh' can take a password parameter, but 'net/ssh/multi' cannot. What I would like to do is somehting like this:
require 'net/ssh'
require 'net/ssh/multi'
#The necessary data is contained in a Ticket object
my_ticket = Ticket.new
Net::SSH::Multi.start (:password => 'xxxx') do |session|
# define the servers we want to use
my_ticket.servers.each do |serv_id|
session.use "#{my_ticket.user_name}##{serv_id}"
end
# execute commands on all servers
session.exec "uptime"
# run the aggregated event loop
session.loop
end
However, this get me:
file.rb:35:in `start': wrong number of arguments (1 for 2) (ArgumentError) from file.rb:35
I know this is a bit of a n00b question, but I would really appreciate some help.
(http://rubydoc.info/gems/net-ssh-multi/1.1/Net/SSH/Multi)
Turns out the answer is far simpler than I thought it would be. Poring over the documentation, I noticed this in the Class: Net::SSH::Multi::Server docs:
Class: Net::SSH::Multi::Server
Overview:
Encapsulates the connection
information for a single remote
server, as well as the Net::SSH
session corresponding to that
information. You'll rarely need to
instantiate one of these directly:
instead, you should use
Net::SSH::Multi::Session#use.'
So, no class extending or calls to super-classes are necessary. The above can be accomplished with:
require 'net/ssh'
require 'net/ssh/multi'
#The necessary data is contained in a Ticket object
my_ticket = Ticket.new
Net::SSH::Multi.start do |session|
# define the servers we want to use
my_ticket.servers.each do |session_server|
session.use session_server , :user => my_ticket.user_name , \
:password => my_ticket.user_pass
end
# execute commands on all servers
session.exec my_ticket.command_to_do
# run the aggregated event loop
session.loop
end

System call in Ruby

I'm a beginner in ruby and in programming as well and need help with system call for moving a file from source to destination like this:
system(mv "#{#SOURCE_DIR}/#{my_file} #{#DEST_DIR}/#{file}")
Is it possible to do this in Ruby? If so, what is the correct syntax?
system("mv #{#SOURCE_DIR}/#{my_file} #{#DEST_DIR}/#{file})
can be replaced with
system("mv", "#{#SOURCE_DIR}/#{my_file}", "#{#DEST_DIR}/#{file}")
which reduces the chances of a command line injection attack.
Two ways
Recommended way
You can use the functions in the File Utils libary see here to move your files e.g
mv(src, dest, options = {})
Options: force noop verbose
Moves file(s) src to dest. If file and dest exist on the different disk
partition, the file is copied instead.
FileUtils.mv 'badname.rb', 'goodname.rb'
FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true # no error
FileUtils.mv %w(junk.txt dust.txt), '/home/aamine/.trash/'
FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
Naughty way
Use the backticks approach (run any string as a command)
result = `mv "#{#SOURCE_DIR}/#{my_file} #{#DEST_DIR}/#{file}"`
Ok, that's just a variation of calling the system command but looks much naughtier!
system("mv #{#SOURCE_DIR}/#{my_file} #{#DEST_DIR}/#{file})
should be the correct call
I recommend you to use Tanaka akira's escape library
Here is example from one my app:
cmd = Escape.shell_command(['python', Rails::Configuration.new.root_path + '/script/grab.py']).to_s
system cmd

Source code problem of ZenTest

Here is one method that monkey patched the Dir[] method from autotest
class Dir
class << self
alias :old_index :[]
def [](*args)
$-w, old_warn = false, $-w
old_index(*args)
ensure
$-w = old_warn
end
end
end
Could you please help by explain this line $-w, old_warn = false, $-w ?
Thanks in advance.
You can assign multiple variables to multiple values on one line in Ruby.
That line is equivalent to the following:
old_warn = $-w
$-w = false
If you were asking what the purpose was; $-w is a global variable in Ruby that points to a boolean that indicates whether or not the user passed the -w flag to the ruby executable when they ran the script. In other words, the variable indicates whether or not the script/program is currently supposed to be printing "warnings".
Essentially, the purpose of that entire block of code is to ensure that warnings are turned off before executing it's core. The old value of the warn flag is saved into a new variable; the warn flag is turned off; and then when the execution is done, the warn flag is re-set back to whatever it used to be.

Resources