I'm trying to get an upload form working in Sinatra using Pony. Right now everything works fine, the file's getting read, the emails gets mailed successfully, I just can't seem to get the attachment to attach. I don't think I'm calling the file's path correctly? I'm not entirely sure, new to the whole Ruby/Sinatra/Pony scene. Any help? MUCH appreciated!
Here's what I have right now:
post '/upload' do
unless params[:file] &&
(tmpfile = params[:file][:tempfile]) &&
(name = params[:file][:filename])
#error = "No file selected"
return :success
end
STDERR.puts "Uploading file, original name #{name.inspect}"
while blk = tmpfile.read(65536)
# here you would write it to its final location
STDERR.puts blk.inspect
end
logger.info "some"
Pony.mail(
:from => params[:uname] + "<" + params[:email] + ">",
:to => 'example#example.com',
:subject => "Internship Prospect " + params[:uname] + " has contacted you",
:body => "Hello,\n\nYou have a new contact request\n\nName: "+params[:uname]+"\nEmail: "+params[:email]+"\n\nMessage:\n"+params[:message]+"\n\nThanks,\The Team",
:port => '587',
:via => :smtp,
:via_options => {
:address => 'smtp.gmail.com',
:port => '587',
:enable_starttls_auto => true,
:user_name => 'name#example.com',
:password => 'password',
:authentication => :plain,
:domain => 'localhost.localdomain',
:attachments => {params[:file][:filename] => File.read(params[:file][:tempfile])}
})
redirect "/success"
end
The :attachments key should be part of the first hash:
Pony.mail(
:from => params[:uname] + "<" + params[:email] + ">",
:to => 'example#example.com',
:subject => "Internship Prospect " + params[:uname] + " has contacted you",
:body => "Hello,\n\nYou have a new contact request\n\nName: "+params[:uname]+"\nEmail: "+params[:email]+"\n\nMessage:\n"+params[:message]+"\n\nThanks,\The Team",
:attachments => {params[:file][:filename] => File.read(params[:file][:tempfile])}
:port => '587',
:via => :smtp,
:via_options => {
:address => 'smtp.gmail.com',
:port => '587',
:enable_starttls_auto => true,
:user_name => 'name#example.com',
:password => 'password',
:authentication => :plain,
:domain => 'localhost.localdomain',
})
Related
I've got kind of a messy situation. I am in the process of migrating a bunch of data that was created in a now-defunct static site generator (webby), which has a lot of data stored in quasi-ERB template files.
I'm trying to write some Ruby to parse through these files, grab what I need, and then write them into my new applications data files.
The problem I am encountering is that I don't have a lot of normalization in the existing files, and matching against some of the patterns is tricky.
For example, each "event" (this is for a tech conference website) has a _sponsors.txt file that contains the information for the sponsors for that particular event, constructed of an array of hashes. These arrays aren't always named exactly the same thing, but they're generally similar.
This is a snippet of one of the files:
<% #psponsors = [
{ :image => 'ca_technologies.png', :name => 'CA Technologies', :link => 'http://www.ca.com/fr', :width => '100px', :height => '100px' },
{ :image => 'puppetlabs.png', :name => 'PuppetLabs', :link => 'https://puppetlabs.com', :width => '100px', :height => '100px' },
{ :image => 'microsoft_azure.png', :name => 'Microsoft Azure', :link => 'http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200618989', :width => '100px', :height => '100px' },
] %>
<% if #psponsors.empty? %>
<i> <a href='<%= File.join('/',#eventhome,'/sponsor') -%>'>Be the first to sponsor!</a></i>
<% end %>
<% #psponsors.each do |sponsor| %>
<img border="1" alt="<%= sponsor[:name] %>" title="<%= sponsor[:name] %>" width="<%= sponsor[:width] %>" height="<%= sponsor[:height] %>" src="<%= File.join('/',#eventhome,"logos/#{sponsor[:image]}") %>" />
<% end %>
<h1>Gold sponsors</h1>
<% #gsponsors = [
{ :image => 'normation.png', :name => 'Normation', :link => 'http://www.normation.com', :width => '100px', :height => '100px' },
{ :image => 'gandi.png', :name => 'Gandi.net', :link => 'https://www.gandi.net', :width => '100px', :height => '100px' },
{ :image => 'xebialabs.png', :name => 'XebiaLabs', :link => 'http://www.xebialabs.com', :width => '100px', :height => '100px' },
{ :image => 'redhat.png', :name => 'Red Hat', :link => 'https://www.redhat.com', :width => '100px', :height => '100px' },
{ :image => 'delphix.png', :name => 'Delphix', :link => 'http://delphix.com', :width => '100px', :height => '100px' },
{ :image => 'chef.png', :name => 'Chef', :link => 'http://chef.io', :width => '100px', :height => '100px' },
] %>
When I attempt to read in the whole file and match between the outside parameters I'm looking for, I end up getting a bunch of matches I don't want. My current workaround is to simply read each line, and set the state if the line matches the right start, then keep reading it in, and then break when I hit the end. This seems like it's completely non-delightful, and I'm sure I'm missing a much more elegant way to do this.
Instead of trying to parse these files, why don't you try executing them instead? Just append some code to dump these (or all: instance_variables.each { |varname| ...) instance variables as JSON to stdout or something similar, and try running that through ERB interpreter.
What about try nokogiri and xpath like this?
erb_template.erb
<% #psponsors = [
{:image => 'ca_technologies.png', :name => 'CA Technologies', :link => 'http://www.ca.com/fr', :width => '100px', :height => '100px'},
{:image => 'puppetlabs.png', :name => 'PuppetLabs', :link => 'https://puppetlabs.com', :width => '100px', :height => '100px'},
{:image => 'microsoft_azure.png', :name => 'Microsoft Azure', :link => 'http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200618989', :width => '100px', :height => '100px'},
] %>
<% if #psponsors.empty? %>
<i> <a href='http://localhost'>Be the first to sponsor!</a></i>
<% end %>
<% #psponsors.each do |sponsor| %>
<img border="1" alt="<%= sponsor[:name] %>" title="<%= sponsor[:name] %>" width="<%= sponsor[:width] %>" height="<%= sponsor[:height] %>" src="<%= File.join('/', #eventhome, "logos/#{sponsor[:image]}") %>"/>
<% end %>
<h1>Gold sponsors</h1>
<% #gsponsors = [
{:image => 'normation.png', :name => 'Normation', :link => 'http://www.normation.com', :width => '100px', :height => '100px'},
{:image => 'gandi.png', :name => 'Gandi.net', :link => 'https://www.gandi.net', :width => '100px', :height => '100px'},
{:image => 'xebialabs.png', :name => 'XebiaLabs', :link => 'http://www.xebialabs.com', :width => '100px', :height => '100px'},
{:image => 'redhat.png', :name => 'Red Hat', :link => 'https://www.redhat.com', :width => '100px', :height => '100px'},
{:image => 'delphix.png', :name => 'Delphix', :link => 'http://delphix.com', :width => '100px', :height => '100px'},
{:image => 'chef.png', :name => 'Chef', :link => 'http://chef.io', :width => '100px', :height => '100px'},
] %>
<% #gsponsors.each do |sponsor| %>
<img border="1" alt="<%= sponsor[:name] %>" title="<%= sponsor[:name] %>" width="<%= sponsor[:width] %>" height="<%= sponsor[:height] %>" src="<%= File.join('/', #eventhome, "logos/#{sponsor[:image]}") %>"/>
<% end %>
process
# encoding: utf-8
require 'nokogiri'
require 'erb'
#eventhome = ""
path = File.join("./erb_template.erb")
doc = Nokogiri::HTML(ERB.new(File.read(path)).result(binding))
links = doc.xpath("//a[./img]")
export = links.each_with_object({}) do |element, h|
h[element["href"]] = element.first_element_child["title"]
end
output
# {
# "http://www.ca.com/fr" => "CA Technologies",
# "https://puppetlabs.com" => "PuppetLabs",
# "http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200618989" => "Microsoft Azure",
# "http://www.normation.com" => "Normation",
# "https://www.gandi.net" => "Gandi.net",
# "http://www.xebialabs.com" => "XebiaLabs",
# "https://www.redhat.com" => "Red Hat",
# "http://delphix.com" => "Delphix",
# "http://chef.io" => "Chef"
# }
I am creating a form in Sinatra that will be sending data to an e-mail on submit using Pony gem. This is my code so far:
post '/pemco' do
Pony.mail(
:from => params[:name] + "<" + params[:email] + ">",
:to => '___#yandex.ru',
:subject => params[:name] + " has contacted you",
:body => params[:message],
:via => :smtp,
:via_options => {
:address => 'smtp.yandex.ru',
:port => '465',
:enable_starttls_auto => true,
:user_name => '___',
:password => '___',
:authentication => :plain
})
redirect '/'
end
I press submit, response pends for some time and then I get Net::ReadTimeout
file: protocol.rb location: rescue in rbuf_fill line: 158 error. What am I doing wrong?
This code works for yandex.ru (and you need to go here https://mail.yandex.ru/neo2/#setup/client and allow everything):
post '/sent' do
Pony.mail(
:to => "_yourEmail_#yandex.ru",
:from => "_sameYourEmail_#yandex.ru",
:via => :smtp,
:via_options => {
:address => 'smtp.yandex.ru',
:port => '25',
:enable_starttls_auto => true,
:user_name => '_yourUsername_',
:password => '_yourPassword_',
:authentication => :plain
})
end
And same code works for mail.ru (and generally you don't need to do anything else).
I am very new to this and I am trying to do something pretty simple but I am not sure where to begin. I simply need to increase the "vote" count of a newly posted link from 0 to 10 if a radio button is selected. Here is the complete code that I have so far, any help would be greatly appreciated:
require 'sinatra'
require 'data_mapper'
require 'haml'
require 'sinatra/reloader'
set :bind, '0.0.0.0'
DataMapper::setup(:default,"sqlite3://#{Dir.pwd}/example.db")
class Link
include DataMapper::Resource
property :id, Serial
property :title, String
property :url, Text
property :bullet, Boolean, :default => false
property :score, Integer
property :points, Integer, :default => 0
property :created_at, Time
attr_accessor :score
def calculate_score
time_elapsed = (Time.now - self.created_at) / 3600
self.score = ((self.points-1) / (time_elapsed+2)**1.8).real
end
def self.all_sorted_desc
self.all.each { |item| item.calculate_score }.sort { |a,b| a.score <=> b.score}.reverse
end
end
DataMapper.finalize.auto_upgrade!
get '/' do
#links = Link.all :order => :id.desc
haml :index
end
get '/hot' do
#links = Link.all_sorted_desc
haml :index
end
get '/:id' do
#link = Link.get params[:id]
haml :index
end
post '/' do
l = Link.new
l.title = params[:title]
l.url = params[:url]
l.bullet = params[:bullet]
l.created_at = Time.now
l.save
redirect back
end
put '/:id/vote/:type' do
l = Link.get params[:id]
l.points += params[:type].to_i
l.save
redirect back
end
delete '/:id' do
l = Link.get params[:id]
l.destroy
redirect '/'
end
__END__
## layout
%html
%head
%link(rel="stylesheet" href="/css/bootstrap.css")
%link(rel="stylesheet" href="/css/style.css")
%body
.container
#main
.title Learn Sinatra
.options
%a{:href => ('/')} New
|
%a{:href => ('/hot')} Hot
= yield
## index
#links-list
-#links.each do |l|
.row
.span3
%span.span
%form{:action => "#{l.id}/vote/1", :method => "post"}
%input{:type => "hidden", :name => "_method", :value => "put"}
%input{:type => "submit", :value => "U"}
%span.points
#{l.points}
%span.span
%form{:action => "#{l.id}/vote/-1", :method => "post"}
%input{:type => "hidden", :name => "_method", :value=> "put"}
%input{:type => "submit", :value => "D"}
.span6
%span.link-title
%h3
%a{:href => (l.url)} #{l.title}
%span.span
%form{:action => "#{l.id}", :method => "post"}
%input{:type => "hidden", :name => "_method", :value=> "delete"}
%input{:type => "submit", :value => "X"}
#add-link
%form{:action => "/", :method => "post"}
%input{:type => "text", :name => "title", :placeholder => "Title"}
%input{:type => "text", :name => "url", :placeholder => "Url"}
%input{:type => "radio", :name => "bullet", :value => "10"}
%input{:type => "submit", :value => "Submit"}
You basically have to define a route to a function the receives a GET/POST request it should trigger a column update which adds one to the vote count
I am trying to send an email from a contact form (built in HTML) with the Pony Gem within sinatra, I have followed the docs but something must be missing.
This is the Pony config
get '/contact' do
erb :contact, :layout => :layout
end
post '/contact' do
require 'pony'
Pony.mail({
:from => params[:name],
:to => 'myemailaddress',
:subject => params[:name] + "has contacted you via the Website",
:body => params[:comment],
:via => :smtp,
:via_options => {
:address => 'smtp.gmail.com',
:port => '587',
:enable_starttls_auto => true,
:user_name => 'myemailaddress',
:password => 'mypassword',
:authentication => :plain,
:domain => "localhost.localdomain"
}
})
redirect '/success'
end
get('/success') do
#notification = "Thanks for your email. I'll be in touch soon."
erb :index, :layout => :layout
end
So after clicking submit the contact page gets re rendered with no message
here is my submit button
<button type="submit" class="btn" value="send">Submit</button>
Am i missing a trigger here somewhere?
Are you sure you have the form setup to do a post? If it seems to be refreshing the page the form tag may not be setup properly. Also the button to submit should be an input tag of type submit. The HTML would need to look something like this:
<form action="/contact" method="post">
<!-- your form elements go here -->
<input type="submit" value="Sign in">
</form>
I'm new to all three, and I'm trying to write a simple contact form for a website. The code I have come up with is below, but I know there are some fundamental problems with it (due to my inexperience with sinatra). Any help at getting this working would be appreciated, I can't seem to figure out/find the documentation for this sort of thing.
haml code from the contact page:
%form{:name => "email", :id => "email", :action => "/contact", :method => "post", :enctype => "text/plain"}
%fieldset
%ol
%li
%label{:for => "message[name]"} Name:
%input{:type => "text", :name => "message[name]", :class => "text"}
%li
%label{:for => "message[mail]"} Mail:
%input{:type => "text", :name => "message[mail]", :class => "text"}
%li
%label{:for => "message[body]"} Message:
%textarea{:name => "message[body]"}
%input{:type => "submit", :value => "Send", :class => "button"}
And here is my code in sinatra's app.rb:
require 'rubygems'
require 'sinatra'
require 'haml'
require 'pony'
get '/' do
haml :index
end
get '/contact' do
haml :contact
end
post '/contact' do
name = #{params[:name]}
mail = #{params[:mail]}
body = #{params[:body]}
Pony.mail(:to => '*emailaddress*', :from => mail, :subject => 'art inquiry from' + name, :body => body)
end
I figured it out for any of you wondering:
haml:
%form{ :action => "", :method => "post"}
%fieldset
%ol
%li
%label{:for => "name"} Name:
%input{:type => "text", :name => "name", :class => "text"}
%li
%label{:for => "mail"} email:
%input{:type => "text", :name => "mail", :class => "text"}
%li
%label{:for => "body"} Message:
%textarea{:name => "body"}
%input{:type => "submit", :value => "Send", :class => "button"}
And the app.rb:
post '/contact' do
name = params[:name]
mail = params[:mail]
body = params[:body]
Pony.mail(:to => '*emailaddress*', :from => "#{mail}", :subject => "art inquiry from #{name}", :body => "#{body}")
haml :contact
end
In case anyone can use this, here is what you might need to use your gmail account to send mail.
post '/contact' do
require 'pony'
Pony.mail(
:name => params[:name],
:mail => params[:mail],
:body => params[:body],
:to => 'a_lumbee#gmail.com',
:subject => params[:name] + " has contacted you",
:body => params[:message],
:port => '587',
:via => :smtp,
:via_options => {
:address => 'smtp.gmail.com',
:port => '587',
:enable_starttls_auto => true,
:user_name => 'lumbee',
:password => 'p#55w0rd',
:authentication => :plain,
:domain => 'localhost.localdomain'
})
redirect '/success'
end
Note the redirect at the end, so you will need a success.haml to indicate to the user that their email was sent successfully.
Uhmm, i tried in irb the following:
foo = #{23}
Of course it wont work! the '#' is for comments in Ruby UNLESS it occurs in a string! Its even commented out in the syntax highlighting.
What you wanted was:
name = "#{params[:name]}"
as you did in your solution (which is not necessary, as it already is a string).
Btw, the reason why the code does not throw an error is the following:
a =
b =
42
will set a and b to 42. You can even do some strange things (as you accidentally did) and set the variables to the return value of a function which takes these variables as parameters:
def foo(a,b)
puts "#{a.nil?} #{b.nil?}" #outputs 'true true'
return 42
end
a =
b =
foo(a,b)
will set a and b to 42.
#{} is interpolation that is used inside "". Just using it outside for a variable assignment won't work.
It would be more likely to be used like this:
number_of_people = 15
Puts "There are #{number_of_people} scheduled tonight"
I've created an example of this in two parts that is available on github. The signup form app is here: signup-form-heroku and an example of the static website that interacts with this is here: static-website-to-s3-example.
The form app is built using Sinatra and is ready to deploy straight onto Heroku. The static site is ready to deploy straight to S3 and use amazon cloudfront.