how to amend a code to get query from external and save result to external - ruby

I have a code which looks like this
require 'net/http'
base = 'www.uniprot.org'
tool = 'mapping'
params = {
'from' => 'ACC+ID', 'to' => 'P_ENTREZGENEID', 'format' => 'tab',
'query' => 'A0A0K3AVS5 A0A0K3AVV4 A0A0K3AW32 A0A0K3AWP0'
}
http = Net::HTTP.new base
$stderr.puts "Submitting...\n";
response = http.request_post '/' + tool + '/',
params.keys.map {|key| key + '=' + params[key]}.join('&')
loc = nil
while response.code == '302'
loc = response['Location']
response = http.request_get loc
end
while loc
wait = response['Retry-After'] or break
$stderr.puts "Waiting (#{wait})...\n";
sleep wait.to_i
response = http.request_get loc
end
response.value # raises http error if not 2xx
puts response.body
which gives me what I need. however, I have two questions
1- How to load a query list instead I parse it into the code ? lets say I save a txt file with all the query i want to the desktop of a mac
2- How to export the output ?
If I have
B2D6P1
G5EC52
B2FDA8-2
B2MZB1
B3CJ34
B3CKG1
B3GWA1
what #tadman showed gives me the answer
however, I have the following
B2D6P1
G5EC52;B2D6P4
B2FDA8-2;B2FDA8
B2MZB1;P18834
B3CJ34
B3CKG1
B3GWA1;Q8I7K5
and the answer is like below
B2D6P1 rmd-2
G5EC52 tlf-1
B2D6P4 tlf-1
B2FDA8 smc-3
B2MZB1 col-14
P18834 col-14
B3CJ34 gcn-1
B3CKG1 urm-1
B3GWA1 nono-1
Q8I7K5 nono-1
what I want is that if I have two entries in each row (separated with ;) leading to the similar output , it gives me only one , otherwise give me as many as they have for example in above example , my desire output is
B2D6P1 rmd-2
G5EC52;B2D6P4 tlf-1
B2FDA8-2;B2FDA8 smc-3
B2MZB1;P18834 col-14
B3CJ34 gcn-1
B3CKG1 urm-1
B3GWA1;Q8I7K5 nono-1
is this possible ?

Reading query data:
query = File.readlines('ids.txt').map(&:chomp).join(' ')
That way you can have them on separate lines, easier to edit, and they're space separated when submitted.
That makes your params look like:
params = {
'query' => query,
...
}
Writing data:
File.open('output.txt', 'w') do |f|
f.write(response.body)
end
That's all there is to it. If it's a string, or can be converted to a string, you can write it to a file.

Related

Using a CSV file to insert values using Ruby

I have some sample code I can execute for our Nexpose server and I need to do some mass asset tagging. Here is an example of the code.
nsc = Nexpose::Connection.new('your_nexpose_instance', 'username', 'password', 3780)
nsc.login
criterion = Nexpose::Tag::Criterion.new('IP_RANGE', 'IN', ['ip1', 'ip2'])
criteria = Nexpose::Tag::Criteria.new(criterion)
tag = Nexpose::Tag.new("tagname", Nexpose::Tag::Type::Generic::CUSTOM)
tag.search_criteria = criteria
tag.save(nsc)
I have a file called with the following data.
ip1,ip2,tagname
192.168.1.1,192.168.1.255,Workstations
How would I go about running a for loop and using the CSV to quickly process the above code? I have no experiance with Ruby and tried to follow some example but I'm confused at this point.
There's a CSV library in Ruby's standard lib collection that you can use.
Basic example based on your code example and data, not tested:
require 'csv'
nsc = Nexpose::Connection.new('your_nexpose_instance', 'username', 'password', 3780)
nsc.login
CSV.foreach("path/to/file.csv", headers: true) do |row|
criterion = Nexpose::Tag::Criterion.new('IP_RANGE', 'IN', [row['ip1'], row['ip2'])
criteria = Nexpose::Tag::Criteria.new(criterion)
tag = Nexpose::Tag.new(row['tagname'], Nexpose::Tag::Type::Generic::CUSTOM)
tag.search_criteria = criteria
tag.save(nsc)
end
I made a directory with input.csv and main.rb
input.csv
ip1,ip2,tagname
192.168.1.1,192.168.1.255,Workstations
main.rb
require "csv"
CSV.foreach("input.csv", headers: true) do |row|
puts "ip1: #{row['ip1']}"
puts "ip2: #{row['ip2']}"
puts "tagname: #{row['tagname']}"
end
the output is
ip1: 192.168.1.1
ip2: 192.168.1.255
tagname: Workstations
I hope this can help. If you have questions I'm here :)
If you just need to loop through each line of the file and fire that chunk of code for each line, you could do something like this:
file = Net::HTTP.get(URI(<whatever_your_file_name_is>))
index = 0
file.each_line do |line|
next if index == 0
index += 1
split_line = line.split(',')
ip1 = split_line[0]
ip2 = split_line[1]
tagname = split_line[2]
nsc = Nexpose::Connection.new('your_nexpose_instance', 'username', 'password', 3780)
nsc.login
criterion = Nexpose::Tag::Criterion.new('IP_RANGE', 'IN', [ip1, ip2])
criteria = Nexpose::Tag::Criteria.new(criterion)
tag = Nexpose::Tag.new(tagname, Nexpose::Tag::Type::Generic::CUSTOM)
tag.search_criteria = criteria
tag.save(nsc)
end
NOTE: This code example is assuming that the CSV file is stored remotely, not locally.
ALSO: In case you're wondering, the next if index == 0 is there to skip your header record.
UPDATE
To use this approach for a local file, you can use File.open() instead of Net::HTTP.get(), like so:
file = File.open(<whatever_your_file_name_is>).read
Two things to note:
Make sure you use the fully-qualified name of the file - i.e. ~/folder/folder/filename.csv instead of just filename.csv.
If the files you're going to be loading are enormous, this might not be an ideal approach because it's actually reading the whole file into memory. But considering your file only has 3 columns, you'd have to have an extreme number of rows in the file for this to be an issue.

Building Data Structure out of JSON output

Hi Im working on writing a script that pulls data out of a ticketing system. Once it pulls the data it analyze the content of it and if it the content match a specific criteria then it needs to build a data structure file that will be dump in the same server.
I was able to parse the data in JSON format, listed below is the content:
[{"id"=>10423,
"type"=>"Ticket",
"lastUpdated"=>"2014-11-04T10:58:47Z",
"shortSubject"=>"FOO STATUS UPDATE",
"shortDetail"=>"Reply to this message if all systems are functional..",
"displayClient"=>"No Client",
"updateFlagType"=>0,
"prettyLastUpdated"=>"54 minutes ago",
"latestNote"=>
{"id"=>16850,
"type"=>"TechNote",
"mobileListText"=>"<b>t. trust: </b> All Systems are OK",
"noteColor"=>"clear",
"noteClass"=>"bubble right"}},
{"id"=>10422,
"type"=>"Ticket",
"lastUpdated"=>"2014-11-04T10:54:07Z",
"shortSubject"=>"FOO STATUS UPDATE",
"shortDetail"=>"Reply to this message if all systems are functional..",
"displayClient"=>"No Client",
"updateFlagType"=>0,
"prettyLastUpdated"=>"58 minutes ago",
"latestNote"=>nil},
{"id"=>10421,
"type"=>"Ticket",
"lastUpdated"=>"2014-11-04T10:53:17Z",
"shortSubject"=>"FOO STATUS UPDATE",
"shortDetail"=>"Reply to this message if all systems are functional..",
"displayClient"=>"No Client",
"updateFlagType"=>0,
"prettyLastUpdated"=>"59 minutes ago",
"latestNote"=>nil}]
In the data above you can see that each ticket has an id, lastupdate, short Subject, short Detail and lastest note the value of the latest note will be nill if no one reply to the ticket but if someone does reply then the value mobileListText will have something.
So what I need to do pretty much is once I get this data the script will look for the subject that complies with "FOO STATUS UPDATE" if that value matches then looks for the content of the shortDetail matches "Reply to this message if all systems are functional.." and if this complies then looks for its latestNote, if latestNote is nill then it will create a log file specifiying date and time when it run, the id of the ticket with this state and a message saying, ticket has not being reply, but if the latest note has the value "mobileListText"=>"t. trust: All Systems are OK", then creates the follwing data structure:
{"LastUpdate":1415130257,"Service":[{"time":"11-04-2014 10:58:47 GMT","region:":"","id":"","description":"All Systems are OK","service":""},{"time":"11-04-2014 10:54:07 GMT","region:":"","id":"","description":"All Systems are OK","service":""},{"time":"11-04-2014 10:53:17 GMT","region:":"","id":"","description":"All Systems are OK","service":""}]}
Im able to have part of this however, based on the data above, only one ticket has All Systems are OK, meaining that only one of the tickets has being reply, and it only should write something like this:
{"LastUpdate":1415130257,"Service":[{"time":"11-04-2014 10:58:47 GMT","region:":"","id":"","description":"All Systems are OK","service":""}]}
But Instead repeats this only ticket that has being replied serveral times.
this my code so far:
require 'rubygems'
require 'json'
require 'net/http'
require 'highline/import'
require 'pp'
require 'logger'
#usersol='foo'
#passol= 'foo123'
#urlsol= "http://dev-webhelpdesk.foo.corp:8081/helpdesk/WebObjects/Helpdesk.woa/ra/Tickets?list=group&page=1&limit=#{#limit}&username=#{#usersol}&password=#{#passol}"
#limit = '25'
#log = #log= Logger.new( 'message_solar.log')
def ticket_data #looks for ticket data in solarwinds
resp = Net::HTTP.get_response(URI.parse(#urlsol))
url_output = resp.body
JSON.parse(url_output)
end
#CRONJOB THAT START ALL
#echo "Reply to this message if all systems are functional.." | mail -r noc#foo.com -s "FOO STATUS UPDATE:" noc-team#FOO.com >> /dev/null
# Looking for all the tickets with the following content
# ticket id, ticket subject and content
def search_allok(allok)
description = []
allok.each do |systems|
output1 = systems.has_key?'id'
if output1
systems.values_at('shortSubject').each do | subject |
output2 = subject.match(%r(TRUST STATUS UPDATE))
if output2
latestnote = systems.values_at('latestNote')
latestnote.each do |content|
if content
final = content.values_at('mobileListText')
final_ok = final[0].sub!(/^\<b\>.*\<\/b\>\s/, "")
systems_ok = final_ok.match(%r(All Systems are OK))
if systems_ok
ids = systems['id']
notify = {"LastUpdate" => Time.now.to_i, "Service" => []}
allok.each do |lastup|
reference = lastup.has_key? 'id'
if reference
timeid = lastup.values_at('lastUpdated')
timeid.each do |lines|
final=lines.split(/[-, T, Z]/)
notify["Service"] << { "time" => "#{final[1]}-#{final[2]}-#{final[0]} #{final[3]} GMT", "region:" => "", "id" => "#{ids}", "description" => "#{systems_ok}" , "service" => ''}
end
end
end
File.open("notify.json", "w") do |fileformatted|
fileformatted.puts (JSON.dump(notify))
end
else
time = Time.now
#log.info("#{time} - Ticket ID #{systems['id']} has not being updated")
end
else
#log.info("#{time} - Ticket ID #{systems['id']} has not being reply")
end
end
end
end
end
end
end
# If the content is there then it need to create
# the data structure including the lastupdated
# (time when it run the script), and the lastupdate for the ticket
# and the description All Systems OK
#This method below I added to the one above, but I was thinking on doing it separate but I encouter issues passing the information needed from above to below
def datastructure(format_file) #creates JSON file lastupdated of each ticket in the queue
notify = {"LastUpdate" => Time.now.to_i, "Service" => []}
format_file.each do |lastup|
reference = lastup.has_key? 'id'
if reference
timeid = lastup.values_at('lastUpdated')
timeid.each do |lines|
final=lines.split(/[-, T, Z]/)
notify["Service"] << { "time" => "#{final[1]}-#{final[2]}-#{final[0]} #{final[3]} GMT", "region:" => "", "id" => "", "description" => region , "service" => ''}
end
end
end
File.open("notify.json", "w") do |fileformatted|
fileformatted.puts (JSON.dump(notify))
end
end
#ticket_data
#datastructure(ticket_data)
search_allok(ticket_data)
The code you've written is basically doing a roundabout version of what is achieved by using ruby's map and select methods. See this article: Ruby Explained: Map, Select, and Other Enumerable Methods

Generating KML files with Ruby

I'm using the ruby_kml gem right now to try to generate KML from some data in my model.
I also tried georuby.
Both of them, when they generate XML it seems to be coming back escaped like this:
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://earth.google.com/kml/2.1\">\n <Folder>\n <name>San Francisco</name>\n <LineStyle>\n <color>#0D7215</color>\n </LineStyle>\n <Placemark>\n <name>21 Google Bus</name>\n <description>\n <![CDATA[Click to add description.]]>\n </description>\n <LineString>\n <coordinates>37.784282779035216,-122.42228507995605 37.784144999999995,-122.42225699999999,37.784084,-122.42274499999999,37.785472,-122.423023,37.785391,-122.423564,37.785364,-122.423839,37.785418,-122.424714,37.785410999999996,-122.42497999999999,37.785391,-122.42522,37.784839,-122.42956,37.784631,-122.431297,37.782576,-122.43086799999999,37.776969,-122.42975399999999,37.776759999999996,-122.431384,37.776368,-122.431305 37.776368,-122.431305,37.777699999999996,-122.431575,37.778746999999996,-122.42335399999999,37.773609,-122.42231199999999,37.773013999999996,-122.42222799999999,37.772974999999995,-122.42222799999999,37.772915,-122.42226799999999,37.772774,-122.422446,37.772636999999996,-122.422585,37.772562,-122.42263399999999,37.772521999999995,-122.422643,37.771588,-122.42253799999999,37.771631,-122.421759</coordinates>\n </LineString>\n </Placemark>\n <LineStyle>\n <color>#0071CA</color>\n </LineStyle>\n <Placemark>\n <name>45 Inverter</name>\n <description>\n <![CDATA[Click to add description.]]>\n </description>\n <LineString>\n <coordinates>37.792490234462946,-122.40863800048828 37.792516,-122.408429,37.793068,-122.408541,37.792957,-122.409357,37.792051,-122.409189,37.788289999999996,-122.40841499999999,37.785495,-122.407866,37.785713,-122.406229,37.785713,-122.40591599999999,37.785699,-122.40576999999999,37.785658,-122.40568999999999,37.783249999999995,-122.40270699999999,37.778850999999996,-122.40827499999999,37.779104,-122.408577</coordinates>\n </LineString>\n </Placemark>\n <LineStyle>\n <color>#AD0101</color>\n </LineStyle>\n <Placemark>\n <name>82 X Wing</name>\n <description>\n <![CDATA[Click to add description.]]>\n </description>\n <LineString>\n <coordinates></coordinates>\n </LineString>\n </Placemark>\n <LineStyle>\n <color>#AD0101</color>\n </LineStyle>\n <Placemark>\n <name>93 X Wing</name>\n <description>\n <![CDATA[Click to add description.]]>\n </description>\n <LineString>\n <coordinates></coordinates>\n </LineString>\n </Placemark>\n </Folder>\n</kml>\n"
I'm not sure why it should be coming it escaped, since it definitely is not valid XML.
georuby does the same.
Does anyone know why it's coming out escaped and also how to unescape it?
Here's the code I'm using:
map = self;
kml = KMLFile.new
folder = KML::Folder.new(:name => map[:name])
map.lines.each do |line|
folder.features << KML::LineStyle.new(
color: line.color,
)
folder.features << KML::Placemark.new(
:name => line.name,
:geometry => KML::LineString.new(:coordinates => line.coordinates),
:description => line.description
)
end
kml.objects << folder
kml.render
Thanks!!!

modify active record relation in ruby

I have my #albums which are working fine; pickung data up with albums.json.
What I'd like to do is to split this #albums in three parts.
I was thinking of something like { "ownAlbums" : [ ... ], "friendSubscriptions" : [ ... ], "otherSubscriptions" : [ ... ] } But I got several errors like
syntax error, unexpected tASSOC, expecting kEND #albums["own"] => #albums
when I tried
#albums["own"] => #albums
or
TypeError (Symbol as array index):
when I tried:
#albums[:otherSubscriptions] = 'others'
and so on.
I never tried something like this before but this .json is just a simple array ?
How can I split it in three parts ?
Or do I have to modify the active record to do so ? Because if so, I'd find another way than splitting.
Second Edit
I tried something like this and it's actually working:
#albums = [*#albums]
own = []
cnt = 0
#albums.each do |ownAlbum|
cnt = cnt.to_int
own[cnt] = ownAlbum
cnt=cnt+1
end
subs = Subscription.where(:user_id => #user.user_id)
#albums[0] = own
#albums[1] = subs
But where I have [0] and [1] I'D prefer Strings.
But then I get the error: TypeError (can't convert String into Integer):
How to get around that ?

Working with nested hashes in Rails 3

I'm working with the Koala gem and the Facebook Graph API, and I want to break down the results I get for a users feed into separate variables for inserting into a mySQL database, probably using Active Record. Here is the code I have so far:
#token = Service.where(:provider => 'facebook', :user_id => session[:user_id]).first.token
#graph = Koala::Facebook::GraphAPI.new(#token)
#feeds = params[:page] ? #graph.get_page(params[:page]) : #graph.get_connections("me", "home")
And here is what #feeds looks like:
[{"id"=>"1519989351_1799856285747", "from"=>{"name"=>"April Daggett Swayne", "id"=>"1519989351"},
"picture"=>"http://photos-d.ak.fbcdn.net/hphotos-ak-ash4/270060_1799856805760_1519989351_31482916_3866652_s.jpg",
"link"=>"http://www.facebook.com/photo.php?fbid=1799856805760&set=a.1493877356465.2064294.1519989351&type=1", "name"=>"Mobile Uploads",
"icon"=>"http://static.ak.fbcdn.net/rsrc.php/v1/yx/r/og8V99JVf8G.gif", "type"=>"photo", "object_id"=>"1799856805760", "application"=>{"name"=>"Facebook for Android",
"id"=>"350685531728"}, "created_time"=>"2011-07-03T03:14:04+0000", "updated_time"=>"2011-07-03T03:14:04+0000"}, {"id"=>"2733058_10100271380562998", "from"=>{"name"=>"Joshua Ramirez",
"id"=>"2733058"}, "message"=>"Just posted a photo",
"picture"=>"http://platform.ak.fbcdn.net/www/app_full_proxy.php?app=124024574287414&v=1&size=z&cksum=228788edbab39cb34861aecd197ff458&src=http%3A%2F%2Fimages.instagram.com%2Fmedia%2F2011%2F07%2F02%2F2ad9768378cf405fad404b63bf5e2053_7.jpg",
"link"=>"http://instagr.am/p/G1tp8/", "name"=>"jtrainexpress's photo", "caption"=>"instagr.am",
"icon"=>"http://photos-e.ak.fbcdn.net/photos-ak-snc1/v27562/10/124024574287414/app_2_124024574287414_6936.gif", "actions"=>[{"name"=>"Comment",
"link"=>"http://www.facebook.com/2733058/posts/10100271380562998"}, {"name"=>"Like", "link"=>"http://www.facebook.com/2733058/posts/10100271380562998"}], "type"=>"link",
"application"=>{"name"=>"Instagram", "id"=>"124024574287414"}, "created_time"=>"2011-07-03T02:07:37+0000", "updated_time"=>"2011-07-03T02:07:37+0000"},
{"id"=>"588368718_10150230423643719", "from"=>{"name"=>"Eric Bailey", "id"=>"588368718"}, "link"=>"http://www.facebook.com/pages/Martis-Camp/105474549513998", "name"=>"Martis Camp",
"caption"=>"Eric checked in at Martis Camp.", "description"=>"Rockin the pool", "icon"=>"http://www.facebook.com/images/icons/place.png", "actions"=>[{"name"=>"Comment",
"link"=>"http://www.facebook.com/588368718/posts/10150230423643719"}, {"name"=>"Like", "link"=>"http://www.facebook.com/588368718/posts/10150230423643719"}],
"place"=>{"id"=>"105474549513998", "name"=>"Martis Camp", "location"=>{"city"=>"Truckee", "state"=>"CA", "country"=>"United States", "latitude"=>39.282813917575,
"longitude"=>-120.16736760768}}, "type"=>"checkin", "application"=>{"name"=>"Facebook for iPhone", "id"=>"6628568379"}, "created_time"=>"2011-07-03T01:58:32+0000",
"updated_time"=>"2011-07-03T01:58:32+0000", "likes"=>{"data"=>[{"name"=>"Mike Janes", "id"=>"725535294"}], "count"=>1}}]
I have looked around for clues on this, and haven't found it yet (but I'm still working on my stackoverflow-foo). Any help would be greatly appreciated.
That isn't a Ruby Hash, that's a fragment of a JSON string. First you need to decode into a Ruby data structure:
# If your JSON string is in json...
h = ActiveSupport::JSON.decode(json) # Or your favorite JSON decoder.
Now you'll have a Hash in h so you can access it like any other Hash:
array = h['data']
puts array[0]['id']
# prints out 1111111111_0000000000000
puts array[0]['from']['name']
# prints Jane Done

Resources