Run Ruby file from html form submit - ruby

I have a Ruby program that reads a file and returns a certain output. I have to now create a web app of this program using Sinatra. I created a form with all the file options and I want to now run that Ruby code with that selected file from the form after the submit button is pressed.
Basically, I’m not sure how to get this external Ruby program to run with the the filename that was selected by the user from the HTML form.
The Ruby program (example.rb) starts with the definition def read_grammar_defs(filename).
// sinatra_main.rb
require 'sinatra'
require 'sinatra/reloader' if development? #gem install sinatra-contrib
require './rsg.rb'
get '/' do
erb :home
end
post '/p' do
//call program to read file with the parameter from form
end
// layout.erb
<!doctype html>
<html lang="en">
<head>
<title><%= #title || "RSG" %></title>
<meta charset="UTF8">
</head>
<body>
<h1>RubyRSG Demo</h1>
<p>Select grammar file to create randomly generated sentence</p>
<form action="/p" method="post">
<select name="grammar_file">
<option value="Select" hidden>Select</option>
<option value="Poem">Poem</option>
<option value="Insult">Insult</option>
<option value="Extension-request">Extension-request</option>
<option value="Bond-movie">Bond-movie</option>
</select>
<br><br>
</form>
<button type="submit">submit</button>
<section>
<%= yield %>
</section>
</body>
</html>

The easiest way is as follows:
Package the example.rb code into a class or module like so:
class FileReader
def self.read_grammar_defs(filename)
# ...
end
end
require the file from your sinatra server
Inside the post action, read the params and call the method:
post '/p' do
#result = FileReader.read_grammar_defs(params[:grammar_file])
erb :home
end
With this code, after submitting the form, it would populate the #result variable and render the :home template. Instance variables are accessible from ERB and so you could access it from therer if you wanted to display the result.
This is one potential issue with this, though - when the page is rendered the url will still say "your_host.com/p" and if the user reloads the page, they will get a 404 / "route not found" error because there is no get "/p" defined.
As a workaround, you can redirect '/' and use session as described in this StackOverflow answer or Sinatra' official FAQ to pass the result value.

Related

Wicked-PDF not showing images, 'wicked_pdf_image_tag' undefined

I want to generate a PDF with our department logo in it. When I try to use the WickedPdf class in my controller (using the method described at https://github.com/mileszs/wicked_pdf):
def some_action
image_tag_string = image_tag('logo.jpg')
pdf = WickedPdf.new.pdf_from_string(image_tag_string)
save_path = Rails.root.join('testpdfs','logotest.pdf')
File.open(save_path, 'wb') do |file|
file << pdf
end
end
...the application saves the PDF to the target directory, but it has a blue-and-white '?' mark where the image should be.
If I do this instead:
image_tag_string = wicked_pdf_image_tag('logo.jpg')
pdf = WickedPdf.new.pdf_from_string(image_tag_string)
I get the following error:
NoMethodError:
undefined method `wicked_pdf_image_tag' for #<...
It would appear that my Rails app is also missing / not linking to a helper file belonging to the wicked-pdf gem.
Answers to similar questions on StackOverflow recommend writing a custom "image-tag" helper to locate the image or installing wkhtmltopdf. For me, image-tag shows the logo just fine when placed in a View (whatever.html.erb). "logo.jpg" is already located in both the asset pipeline and #{RailsRoot}/public/images. Finally, I am using wkhtmltopdf 0.9.9, wicked-pdf 0.11.0, and rails 4 on Ubuntu 14.04.
In a nutshell - what am I doing wrong that causes WickedPDF to fail to render the image?
First thing create a pdf template to render and use your wicked_pdf tags in that template..
for example-
app/views/layout/application.pdf.erb-
<!doctype html>
<html>
<head>
<meta charset='utf-8' />
</head>
<body onload='number_pages'>
<div id="content">
<%= yield %>
</div>
</body>
</html>
app/views/pdf/pdf_view.pdf.erb-
<div>
<%= wicked_pdf_image_tag 'logo.jpg' %>
</div>
use this template instead
def save
pdf = WickedPdf.new.pdf_from_string(
render_to_string(
template: 'example/pdf_view.pdf.erb',
layout: 'layouts/application.pdf.erb'))
send_data(pdf,
filename: 'file_name.pdf',
type: 'application/pdf',
disposition: 'attachment')
end
This might help you..
Use the wicked_pdf_image_tag helper in your view and reference the image with asset_url if your image is in public/images or use asset_pack_url if the image is in public/packs/media/images
<%= wicked_pdf_image_tag asset_url('/images/footer_logo.png') %>
or
<%= wicked_pdf_image_tag asset_pack_url('media/images/footer_logo.png') %>
I converted image url that 'http' from 'https'. Than worked.
Heroku-18
Rails 4.2
wicked_pdf (1.1.0)
wkhtmltopdf-binary (0.12.4)
In my case, I am using carrierwave, the solution was taken from this post
<img src="<%= root_url + "/" +file.service_url %>">
This worked on rails 5.

Undefined Method Join-error when running CarrierWave and Sinatra.

I'm trying the Gentle Introduction to CarrierWave-tutorial by using the web-framework Sinatra. When I run my app it starts just fine and the app asks me to upload a file and it does so without any problems. However, while uploading the file, the app throws me an "undefined method `join' for # String:0x3480d50 "-error.
I've looked around a little bit on the internet and I found this issue at github where they say that the error may be due to incompatibilities between Rack and Sinatra or for having installed duplicate versions of Sinatra.
Does anybody know what's happening?
My uploader_app:
require 'carrierwave'
require 'sinatra'
require 'sqlite3'
require 'sequel'
require 'carrierwave/sequel'
DB = Sequel.sqlite
DB.create_table :uploads do
String :file
end
# uploader
class MyUploader < CarrierWave::Uploader::Base
storage :file
end
# model
class Upload < Sequel::Model
mount_uploader :file, MyUploader
end
# sinatra app
get '/' do
#uploads = Upload.all
erb :index
end
post '/' do
upload = Upload.new
upload.file = params[:image]
upload.save
redirect to('/')
end
__END__
## index
<!DOCTYPE html>
<html>
<body>
<div>
<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="image" />
<input type="submit" name="submit" value="Upload" />
</form>
<% #uploads.each do |upload| %>
<img src="<%= upload.file.url %>" />
<% end %>
</div>
</body>
</html>
The error is occurring on this line in the Carrierwave Library:
path = encode_path(file.path.gsub(File.expand_path(root), ''))
It fails because root is nil, so File.expand_path(root) raises an error. I don't know why root isn't set, but the following code (that I modified from this answer) worked for me:
CarrierWave.configure do |config|
config.root = settings.root
end
I just added it to the code after declaring the Sequel class and before defining the route. Probably best to stick it in a configure block too. Note that settings.root in the code above is Sinatra's root setting.
This doesn't seem to be caused by the current problems between Rack 1.6.0 and Sinatra 1.4.5 as that's what I was running, although I'm on Ruby v2.1.2 as I mentioned in the comments above.
Depending on what you want, Sinatra's root might not be the best place to put things, as I ended up with a directory inside the project root called "uploads" which had the files in, but config.root obviously needs to be set to something.
Hope that helps.

ruby code to search and get a string from a html content

Am new to ruby.
am trying to get the webpage contents and search and return a string from that response
following code retunrs the webpage as html
require 'rubygems'
require 'uri'
require 'net/http'
AppArgs = Array.new
def get()
content = Net::HTTP.get('integration.twosmiles.com', '/status')
puts content
end
get()
html content
<!-- PAGE CONTENT -->
<div class="container-fluid page-content">
<div class="row-fluid">
<h1>Status</h1>
<p>The rails app is up. Nothing to see here, move on.</p>
<br>
<p>uptime:</p>
22:09:18 up 66 days, 22:37, 0 users, load average: 0.00, 0.01, 0.05
<br>
<br><br>
<p>other</p>
# On branch deploy
<br>
commit bc1407b29697bab36bc2f5e35aa197228181e225
<br>
</div>
</div>
<!-- END PAGE CONTENT -->
Above is the part of the web page content . From this content i want to get the commit bc1407b29697bab36bc2f5e35aa197228181e225
and ony want to return the key value bc1407b29697bab36bc2f5e35aa197228181e225.how it is possbile using ruby code
key = get()[/commit\s+([a-f0-9]{10,})/i, 1]
puts key
Regex explanation here.

Watir Webdriver : Entering text in <p> tag within an iframe

I am really stuck now. I have an iframe in which there is a < p> tag where I want to send some text, but I am just not able to do it.
HTML:
<iframe id="edit-field-verdict-0-value_ifr" frameborder="0" src="javascript:""" style="width: 100%; height: 100px;">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head xmlns="http://www.w3.org/1999/xhtml">
<body id="tinymce" class="mceContentBody " spellcheck="false" dir="ltr">
<p>
<br mce_bogus="1">
</p>
</body>
</html>
</iframe>
The code that i have tried is :
#browser.elements(:xpath => '//*[#id="tinymce"]').p.send_keys [:control, 'a']
The error that I am getting is:
undefined method `elements' for #<String:0x24ba570> (NoMethodError)
I also tried
$browser.frame(:id,'edit-field-verdict-0-value_ifr').html.body(:id,'tinymce').p.send_keys [:control, 'a']
But as the body is not recognized by Watir, I tried elements_by_xpath as well. It didn't work.
How can I make this thing work?
For the first attempt, the error message is saying that #browser is a string rather than a Watir::Browser object. You should verify that #browser is correctly set. Based on your second example, perhaps it is meant to be the global variable $browser.
For the second attempt, body is supported in Watir. However, html will return the page's html rather than the html element. Given that there should only be one body element, the html element can be omitted.
$browser.frame(:id,'edit-field-verdict-0-value_ifr').body(:id,'tinymce').p.send_keys [:control, 'a']
But also keep in mind that you only need to include the frame method (to tell watir to look inside the frame) and as little as needed to reliably find the element you are interacting with. Anything extra is just making the code more verbose, and also perhaps making things more brittle and easy to break. So the above could be shortened down to just
$browser.frame(:id,'edit-field-verdict-0-value_ifr').p.send_keys [:control, 'a']
Based on the id of the element you are testing, I assume it is a WYSIMYG Editor. You should look at the Watir-Webdriver page for an example - http://watirwebdriver.com/wysiwyg-editors/. The TinyMCE Editor example from the webpage:
require 'watir-webdriver'
b = Watir::Browser.new
b.goto 'http://tinymce.moxiecode.com/tryit/full.php'
b.execute_script("tinyMCE.get('content').execCommand('mceSetContent',false, 'hello world' );")
b.frame(:id => "content_ifr").send_keys 'hello world again'

writing strings inside head-element in rails

I'm working with a site using client-side templates through knockout.js.
The backend api, and login, is written in rails.
What I want to do is have each client-side html template in a separate file, and then have those templates lifted into the page using the templates. Similar to how javascript files are lifted in.
So I have a directory in my app/assets called templates
Each template in the directory should be added to the page in a script tag with the type="text/html"
I've gotten so far as to product the actual templates content now I just want to put it in the html.erb file in the head property.
However it always lands in the Body as normal text, not as HTML.
I've defined the following method in my controller:
def html_templates
output = ''
templates = Dir.glob 'app/assets/templates/*'
templates.each { |template|
file = File.open(template, "rb")
output += '<script type="text/html" id="'+(File.basename template, '.html')+'">'
output += file.read
output += '</script>'
}
return output
end
I try to add it to the .erb layout file like so:
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<%= html_templates %>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
Yet the output is always put in the body, with all my html escaped.
Also, if anyone has better solutions to have to solve this. Please, recommend.
Thanks :) so basically you should use raw method whenever you don't want output to be escaped

Resources