How to store array in a variable in ruby - ruby

I need some help working and new with arrays. I am trying to store a value in an email in an instance variable to be used at a later stage of my test. The email body contains the following string
Finally, your Reference Number us 7712342 - please quote this number
So what my tests is going to do is
visit the email page
grab that string and store as str_array = my Array. And I only need the number: 7712342
The problem i have is the email body has a whole bunch of text so not sure how to grab that particular text i need.
Once i have it then im good to carry on with my tests. but im stuck for now.
Hope to find some help with this.
Here is something i quickly wrote.
element :email_form, '.form-control'
element :go_button, '.input-group-btn'
elements :subject, '.all_message-min_text'
def check_email_and_store_ref
email = "test-3#mailinator.com"
email_body = "Finally, your Web Order Reference Number is 7754468 - please quote this in any communication with us until you receive your Subscriber Number."
email_subject_line = find_element_by_text(self.subject.first, email_body, {:text_element => 'header', :partial_match => true})
ref_number = email_bidy.scan(/\d+/)
Capybara.visit 'https://www.mailinator.com/'
email_form.set email
go_button.click
email_subject_line.click
puts ref_number
#I can now use the above ref number in another method within my class
end

Use String#Scan
> email_body = "Finally, your Reference Number us 7712342 - please quote this number"
> reference_no = email_body.scan(/\d+/)
#=> ["7712342"]

Related

I am trying to retrieve data from a Ruby cdn of the Pokemon API but I am struggling

Below is my Pokemon TCG API key
I have read the documentation but I cannot find a way to retrieve the data I need which is the images of each card in a set. If anyone can help with or give me any pointers on how to retrieve this I would greatly appreciate it.
https://github.com/PokemonTCG/pokemon-tcg-sdk-ruby/blob/master/README.md
This above is the link to the documentation on Github.
Pokemon.configure do |config|
config.api_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
end
sets = Pokemon::Set.where(q: 'legalities.standard:legal').first
p sets
I am expecting to retrieve specific data from the Pokemon TCG API which from above should be within these Ruby classes.
p sets.images.symbol will print out the link to:
"https://images.pokemontcg.io/swshp/symbol.png"
p sets.images.logo will print out the link to:
"https://images.pokemontcg.io/swshp/logo.png"
When you are unsure what is contained within the class you're getting, in this case a Pokemon::Set class, you may see all the methods of this resulting variable with sets.methods.sort.each{|m| p m}, there you'll find the images method and can dig deeper to symbol and logo.
In your example you are searching for sets. In case of cards:
cards = Pokemon::Card.where(page: 5, pageSize: 100)
cards.each{|card| p card.images.large}
This will print out all the links to large cards.
Update
Clarification based on comments
How to print out methods and how to know which class you are referring to.
Let's start with you code snippet:
sets = Pokemon::Set.where(q: 'legalities.standard:legal').first
puts sets.class
Output:
Pokemon::Set
It would be more clear if you name your variable as set because you're selecting the .first element of an array.
Back to my cards example:
cards = Pokemon::Card.where(page: 5, pageSize: 100)
puts cards.class
Output:
Array
As I did not select any item from the array cards naming makes perfect sense, and this array will contain a card:
card = cards.first
puts card.class
Output
Pokemon::Card
Printing methods
So, given we are now well aware of class each variable contains and what we are referring to, we are ready to print out the methods for both:
sets.methods.sort.each{|method| p method}
cards[0].methods.sort.each{|method| p method}
Output:
…
:hash
:hp
:hp=
:id
:id=
:images <== Here!
:images=
:inspect
:instance_eval
:instance_exec
:instance_of?
…
Once again, mind the [0] selection of the first item. When we want to know methods, we want to know it either for Pokemon::Set or Pokemon::Card.

Cannot switch sender email when using ReplyAll via Outlook in Python Win32

I have multiple account associated to my outlook, i am trying to set the From field to this one specific email i own. Looking at https://learn.microsoft.com/en-gb/office/vba/api/outlook.mailitem I should be able to accomplish this by changing the SendUsingAccount property, however, i am running into ERROR:root:(-2147352571, 'Type mismatch.', None, 1). Does anyone know why?
pythoncom.CoInitialize()
outlook = win32.Dispatch("Outlook.Application")
selection = outlook.ActiveExplorer().Selection
count = selection.Count + 1
for i in range(1, count):
message = selection.Item(i)
reply = message.ReplyAll()
newBody = "test"
for myEmailAddress in outlook.Session.Accounts:
if "#test.com" in str(myEmailAddress):
From = myEmailAddress
break
print(From.DisplayName) #prints the email i want fine
reply.SendUsingAccount = From.DisplayName #this line is giving me the error. If I remove it , the email popups fine, but the From address is defaulting to one i dont want to use
reply.HTMLBody = newBody + reply.HTMLBody
reply.Display(False)
Application.Session.Accounts collection returns Account objects, not strings. And MailItem.SendUsingAccount property takes an Account object, not a string.
Replace the line
if "#test.com" in str(myEmailAddress):
with
if "#test.com" in str(myEmailAddress.SmtpAddress):
and
Reply.SendUsingAccount = From.DisplayName
with
Reply.SendUsingAccount = From

Concept for recipe-based parsing of webpages needed

I'm working on a web-scraping solution that grabs totally different webpages and lets the user define rules/scripts in order to extract information from the page.
I started scraping from a single domain and build a parser based on Nokogiri.
Basically everything works fine.
I could now add a ruby class each time somebody wants to add a webpage with a different layout/style.
Instead I thought about using an approach where the user specifies elements where content is stored using xpath and storing this as a sort of recipe for this webpage.
Example: The user wants to scrape a table-structure extracting the rows using a hash (column-name => cell-content)
I was thinking about writing a ruby function for extraction of this generic table information once:
# extracts a table's rows as an array of hashes (column_name => cell content)
# html - the html-file as a string
# xpath_table - specifies the html table as xpath which hold the data to be extracted
def basic_table(html, xpath_table)
xpath_headers = "#{xpath_table}/thead/tr/th"
html_doc = Nokogiri::HTML(html)
html_doc = Nokogiri::HTML(html)
row_headers = html_doc.xpath(xpath_headers)
row_headers = row_headers.map do |column|
column.inner_text
end
row_contents = Array.new
table_rows = html_doc.xpath('#{xpath_table}/tbody/tr')
table_rows.each do |table_row|
cells = table_row.xpath('td')
cells = cells.map do |cell|
cell.inner_text
end
row_content_hash = Hash.new
cells.each_with_index do |cell_string, column_index|
row_content_hash[row_headers[column_index]] = cell_string
end
row_contents << [row_content_hash]
end
return row_contents
end
The user could now specify a website-recipe-file like this:
<basic_table xpath='//div[#id="grid"]/table[#id="displayGrid"]'
The function basic_table is referenced here, so that by parsing the website-recipe-file I would know that I can use the function basic_table to extract the content from the table referenced by the xPath.
This way the user can specify simple recipe-scripts and only has to dive into writing actual code if he needs a new way of extracting information.
The code would not change every time a new webpage needs to be parsed.
Whenever the structure of a webpage changes only the recipe-script would need to be changed.
I was thinking that someone might be able to tell me how he would approach this. Rules/rule engines pop into my mind, but I'm not sure if that really is the solution to my problem.
Somehow I have the feeling that I don't want to "invent" my own solution to handle this problem.
Does anybody have a suggestion?
J.

get value from text_field without submitting?

What I need- some kind of way to grab the number entered into the form in order to check it against previous records PRIOR to updating, so that if a validation error occurs, the user can be prompted to confirm before the form is submitted. Params would work, but are only returned after the form is posted- so no help. Is there an ajax call that I can pass into a ruby variable? Or perhaps some kind of ruby code that will read the input in the text box without submitting or linking?
What I'm doing- I'm trying to set up a 'manual validation' because I don't want the validation to 'prevent' from saving. Instead, it should be more like a confirmation.
If you care for context, Here's the run-down- I have a client that pays monthly deposits. We confirm these deposits over the phone through a third party. Naturally, in order to get the most accurate data as possible, we have to account for human error and other factors. A deposit this month should never be less than a deposit last month- but deposits can be "moved" from one account to another, which would make it seem like it was less. I have a form that new data is input on, and I want it to check against previous records to see if the deposit is more or less than reported previously. If less, it should ask for confirmation- an "are you sure?" kind of thing.
The code is old & outdated, should be changed from the ground up, but would take months when I have days to do this. I'm just looking for a patch.
What I have so far- note that cur_deposit is this months and rec_deposit is last months.
<%
arr1 = []
arr2 = []
is_less = false
r = #recent_inquiries.last
r.inquiry_deposits.order(:id).each do |t|
arr1 << t.cur_deposit.to_f
arr1 << t.rec_deposit.to_f
end
#inquiry.inquiry_deposits.order(:id).each do |td|
#============THIS is the part that needs help
arr2 << params["cur_deposit_text_box"]
arr2 << params["rec_deposit_text_box"]
end
i = 0
while i < (arr1.size - 1)
comp_arr1 = []
comp_arr2 = []
comp_arr1 << arr1[i]
comp_arr1 << arr1[i + 1]
comp_arr2 << arr2[i]
comp_arr2 << arr2[i + 1]
if Inquiry.compare_deposits(comp_arr1, comp_arr2) != nil then is_less = true end
i = i + 2
end
if is_less
strConf = "A deposit from last month is greater than the same deposit this month, which should not happen. Are you sure?"
end
%>
<%= submit_tag "Save Inquiry", :onclick=>"$('#submit_form').val('Save Inquiry summary');", :class => 'tgButton3', :id => 'save_inquiry_button_bottom', :confirm => strConf %>
When I get this code working, I will stash all the functioning code into a model- I just have it in the view for testing. It is safe to assume that all the 'custom methods' this script calls to are functioning. If you need code from them, I'll happily share it.
Rails version 3.0.20
Can you use jQuery on your website? (if not it is doable in plain javascript)
$('#id-of-your-field').change(function(e){
//do here your client side logic if any needed
var yourfirstvalue = $(e.target).val();
//now take the value and send it to server (your ruby stuff)
$.ajax({
url: yourURL + "/" + yourfirstvalue,
success: function(data){
//this data can be sent as JSON in structure which suits the best to you
//so you can use it to populate your second dropdown
var values = JSON.parse(data);
//use your values
}
});
});
Google "combo box example" it might help you.
In order to close this question out, and in case anybody else is wondering, I will answer my own question. This is what I've found out.
Because of the nature of the relationship between client & server, there is really no way to get the value of the text input, store it in a ruby variable, and check it against another ruby variable. Ruby script only runs once and then is rendered, so while ajax may be able to continually run in the background and gather inputs, etc, the integration with ruby falls short when talking client-side only interaction. (Correct me if I'm wrong- after all, I posted the question to get everybody's input!)
The fix: I created a switch using hidden tags. When the form loads, the hidden tag is blank. After submitting the form, the update action checks the params of the newly entered data against the numbers from last month. If the conditions check out, it saves. If not, it re-loads the page with a message. If the message is confirmed, an ajax command changes the hidden tag to "true" which bypasses the comparison once it hits the update action again. Otherwise, the data is not saved. Problem solved!
I'm making this a community wiki answer in case anybody would like to add their two cents.

Sinatra can't convert Symbol into Integer when making MongoDB query

This is a sort of followup to my other MongoDB question about the torrent indexer.
I'm making an open source torrent indexer (like a mini TPB, in essence), and offer both SQLite and MongoDB for backend, currently.
However, I'm having trouble with the MongoDB part of it. In Sinatra, I get when trying to upload a torrent, or search for one.
In uploading, one needs to tag the torrent — and it fails here. The code for adding tags is as follows:
def add_tag(tag)
if $sqlite
unless tag_exists? tag
$db.execute("insert into #{$tag_table} values ( ? )", tag)
end
id = $db.execute("select oid from #{$tag_table} where tag = ?", tag)
return id[0]
elsif $mongo
unless tag_exists? tag
$tag.insert({:tag => tag})
end
return $tag.find({:tag => tag})[:_id] #this is the line it presumably crashes on
end
end
It reaches line 105 (noted above), and then fails. What's going on? Also, as an FYI this might turn into a few other questions as solutions come in.
Thanks!
EDIT
So instead of returning the tag result with [:_id], I changed the block inside the elsif to:
id = $tag.find({:tag => tag})
puts id.inspect
return id
and still get an error. You can see a demo at http://torrent.hypeno.de and the source at http://github.com/tekknolagi/indexer/
Given that you are doing an insert(), the easiest way to get the id is:
id = $tag.insert({:tag => tag})
id will be a BSON::ObjectId, so you can use appropriate methods depending on the return value you want:
return id # BSON::ObjectId('5017cace1d5710170b000001')
return id.to_s # "5017cace1d5710170b000001"
In your original question you are trying to use the Collection.find() method. This returns a Mongo::Cursor, but you are trying to reference the cursor as a document. You need to iterate over the cursor using each or next, eg:
cursor = $tag.find_one({:tag => tag})
return cursor.next['_id'];
If you want a single document, you should be using Collection.find_one().
For example, you can find and return the _id using:
return $tag.find_one({:tag => tag})['_id']
I think the problem here is [:_id]. I dont know much about Mongo but `$tag.find({:tag => tag}) is probably retutning an array and passing a symbol to the [] array operator is not defined.

Resources