Parse Perl Data::Dumper output with ruby - ruby

I've a directory full of state files which were printed by Perl's Data::Dumper. The content looks like this:
$VAR1 = {
'localtime' => 'Tue Jun 6 11:48:20 2017',
'lookback_history' => {
'ifHCOutOctets' => {
'1496742350.42394' => '74365529910',
'1496742455.72943' => '74366309899',
'1496742446.38562' => '74366309114',
'1496742500.42388' => '74372744112'
},
'ifHCInOctets' => {
'1496742350.42394' => '13198364950',
'1496742455.72943' => '13198718163',
'1496742446.38562' => '13198705712',
'1496742500.42388' => '13199010183'
}
},
'timestamp' => '1496742500.42388',
'ifHCOutOctets' => '74372744112',
'ifHCInOctets' => '13199010183'
};
I've to analyze if the files contain unreproducible information.
Is there a way in ruby to parse those perl dumps?

If this data is yours and you are positive it contains no unexpected/harmful strings in it, the simplest way would be (assuming the content of the file is what you have posted):
eval(File.read(file))
my_local_var = $VAR1

Since you already have the files and can't change them, one way would be to use a utility that converts them to a format your Ruby understands, like JSON. If you have the JSON module in your Perl distribution (you probably have a system Perl), you also have the json_pp utility.
So you could shell out to that, and let it convert your Perl data structure (Data::Dumper is nothing else than that) to JSON:
$ cat data.pl | json_pp -f eval -t json > data.json
and then use Ruby to convert that JSON to a Ruby data structure:
require 'json'
JSON.parse(File.read('data.json'))
#=> {
# "localtime" => "Tue Jun 6 11:48:20 2017",
# "ifHCOutOctets" => "74372744112",
# "ifHCInOctets" => "13199010183",
# # ...
# }

Related

How to parse and send whole complicated XML from code in Rails

So I have this complicated XML and want it to parse it to array and send by Savon to the server. The question is how can I parse parameters?
<soapenv:Header>
<add:MessageID
xmlns:add="http://www.w3.org">sdhuf78dd67-8932
</add:MessageID>
<add:Action
xmlns:add="http://www.w3.org/2005">http://google/FMP
</add:Action>
<add:To
xmlns:add="http://www.w3.org/2005/08/addressing">https://no1.testbla.com/1HAD9ANA1
</add:To>
<link:TransactionFlowLink
xmlns:link="http://google/2010/06/"/>
<oas:Security
xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<oas:UsernameToken oas1:Id="UsernameToken-1"
xmlns:oas1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<oas:Username>AHOJHOLA</oas:Username>
<oas:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">Nonce</oas:Nonce>
<oas:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">HashedPassword</oas:Password>
<oas1:Created>CurrentGMTDateAndTime</oas1:Created>
</oas:UsernameToken>
</oas:Security>
<AMA_SecurityHostedUser
xmlns="http://xml.amfds.com/2010/06">
<UserID AgentDutyCode="DA" RequestorType="BO" PseudoCityCode="HIATRA67" POS_Type="5"/>
</AMA_SecurityHostedUser>
</soapenv:Header>
I know how to parse for example add:Action without parameter:
"add:Action" => "http://google/FMP"
And I know that parameter should be written with # prefix.
But I dont know how to write it together. Is this right?
"add:Action" => {
"#xmlns:add" => "http://www.w3.org/2005",
"http://google/FMP"
},etc.
To find out this information, you need to go and have a look at the Gyoku gem: the gem that Savon uses to translate Ruby hashes into XML. Specifically, the documentation on using explicit XML attributes. Looking at that, we can get the XML you're looking for with the following hash:
{
"add:Action" => {
"#xmlns:add" => "http://www.w3.org/2005",
:content! => "http://google/FMP"
}
}
We can test this in IRB directly with Gyoku:
irb> require 'gyoku'
# => true
irb> Gyoku.xml({"add:Action" => { "#xmlns:add" => "http://www.w3.org/2005", :content! => "http://google/FMP" } })
# => "<add:Action xmlns:add=\"http://www.w3.org/2005\">http://google/FMP</add:Action>"

In which version of ruby appeared ':' instead '=>'?

I mean
some: true
vs
:some => true
I have problem with compatibility my Rails version and Ruby version and I have to know in which version appeared only : instead =>.
I don't know how to find this kind of info by Google.
This is a feature introduced into Ruby 1.9:
{ example: 'key' }
# => { :example => 'key' }
This is similar to how JavaScript and other languages define their dictionary-type structures. The keys generated this way are always Symbol-type.
It's also possible to mix and match:
variable = :foo
{ example: 'key', 'string' => 'stored', variable => 'thing' }
# => {:example=>"key", "string"=>"stored", :foo=>"thing"}
This is a good thing because the x: approach is more limited. If you want dots in your keys, for example, you'll need to use the older style.

Conditionally add an extra parameter to an associative hash

I want to conditionally add an extra parameter to an associative hash.
The existing code looks like this:
:env => {
"ANSIBLE_FORCE_COLOR" => "true",
"ANSIBLE_HOST_KEY_CHECKING" => "#{config.host_key_checking}",
# Ensure Ansible output isn't buffered so that we receive ouput
# on a task-by-task basis.
"PYTHONUNBUFFERED" => 1
},
I want to conditionally add another variable "ANSIBLE_SSH_ARGS" => "-o ForwardAgent=yes" if config.ssh.forward_agent is true.
I could just copy paste, and create an if/else block but surely Ruby has something more elegant?
I solved it like so:
env = {
"ANSIBLE_FORCE_COLOR" => "true",
"ANSIBLE_HOST_KEY_CHECKING" => "#{config.host_key_checking}",
# Ensure Ansible output isn't buffered so that we receive ouput
# on a task-by-task basis.
"PYTHONUNBUFFERED" => 1
}
env["ANSIBLE_SSH_ARGS"] ="-o ForwardAgent=yes" if config.ssh.forward_agent
command << {
:env => env,
:notify => [:stdout, :stderr],
:workdir => #machine.env.root_path.to_s
}
Not sure this is idiomatic Ruby but it worked for me.

Rails 3.1 urllib2.quote(json.dumps(var)) Equivalent

In Python I can convert JSON into a useable encoded string eg:
cmd2 = [{'cmd': 'inlinepush',
'params': {'raw': 'score'
}
}]
url = urllib2.quote(json.dumps(cmd2))
print url
This produces:
%5B%7B%22cmd%22%3A%20%22inlinepush%22%2C%20%22params%22%3A%20%7B%22raw%22%3A%20%22score%22%7D%7D%5D
I have searched and searched but not found a Ruby or Rails equivalent, particularly in the NET::HTTP library.
I really have spent a lot of time thrashing to no end and would be grateful of any pointers.
Try this:
require 'cgi'
require 'json'
cmd2 = [{
'cmd' => 'inlinepush',
'params' => {
'raw' => 'score'
}
}]
puts CGI.escape(JSON.dump(cmd2))

Ruby: Generate a utf-8 character from code point as string

I need to write all utf-8 characters in file. I have all codes as string "5363" or "328E", but I can't add it to \u, to make structure, like "\u5363". Help me please.
(this will work if you have ruby 1.9 or newer)
#irb -E utf-8
irb(main):032:0> s=""
=> ""
irb(main):033:0> i=0x328e
=> 12942
irb(main):034:0> s<<i
=> "㊎"
irb(main):036:0> s<<0x5363
=> "㊎卣"
for your case:
my_char_codes = ["5363","328E"]
s = ""
my_char_codes.each{ |c| s << c.to_i(16) }
# now s contains "㊎卣"

Resources