sinatra -- unknown media type - ruby

I am writing a blog for games, loading files with extension *.sgf Sinatra doesn't recognize this.
Unknown media type: ".sgf" file: base.rb location: content_type line: 132
The backtrace mentions webrick
/usr/lib/ruby/1.9.1/webrick/httpserver.rb in service
si.service(req, res) /usr/lib/ruby/1.9.1/webrick/httpserver.rb in run
server.service(req, res) /usr/lib/ruby/1.9.1/webrick/server.rb in block in start_thread
block ? block.call(sock) : run(sock)
I caught this since although my Sinatra app works when I do ruby myApp.rb it doesn't work when I do foreman start for Heroku (and it didn't work when I deployed).

You should configure Sinatra to understand your MIME-type:
configure do
mime_type :sgf, 'application/octet-stream'
end
or inplace:
get '/upload' do
content_type :sgf
# Do what you want with the file
end
More info.

Related

Sinatra Routing - Separate Files

I'm going through a recently released book on Sinatra that demonstrates this way of setting up routes in different files:
# app.rb
require "sinatra"
require "slim"
class Todo < Sinatra::Base
# ...
Dir[File.join(File.dirname(__FILE__), "lib", "*.rb")].each { |lib| require lib }
end
# lib/routes.rb
get "/test" do
"The application is running"
end
# config.ru
require "sinatra"
require "bundler/setup"
Bundler.require
ENV["RACK_ENV"] = "development"
require File.join(File.dirname(__FILE__), "app.rb")
Todo.start!
However, it fails to find the route at http://localhost:4567/test. It would make sense to me that this should work when I run ruby config.ru or bundle exec rackup -p 4567. But coming from Rails development where all this configuration is built-in, I don't have a complete understanding of how everything gets wired together. The server is running on that port and I get the Sinatra doesn't know this ditty 404 page. If I reopen the class as suggested by this SO answer, the /test route is found.
# lib/routes.rb
class Todo < Sinatra::Base
get "/test" do
"The application is running"
end
end
Is there something I'm missing about this suggested way to include routes without reopening the class?
Try ruby app.rb, it should work.
You'll need to restart the webserver to load routes that were added while it was running. Routes are loaded into memory when app.rb is invoked and Sinatra is launched. The route itself looks fine and it appears routes.rb is being imported successfully via Dir[File.join(File.dirname(__FILE__), "lib", "*.rb")].each { |lib| require lib }.
If you're running the server directly through terminal Ctrl+X, Ctrl+C should shut it down, then restart it via rackup config.ru* or ruby app.rb. You may confirm the route is recognized by making a get request through your browser to: http://127.0.0.1:4567/test.
For the rackup config.ru command to work, you can change config.ru to something like:
# config.ru
require './app'
run Sinatra::Application
This is just a deployment convenience.
Edit: #shaun, because Todo extends Sinatra::Base it's fine to use run Todo in your case.
The book suggested Todo.start! to run the application from the config.ru file, but the Sinatra documentation example uses run Sinatra::Application. So I just changed the line from Todo.start! to
run Todo
That seems to work, but I'll have to look into the consequences.

Sinatra - Error Handling

I'm trying to make my sinatra app show a custom error page when an error is raised on the server (e.g. an IOError or ArgumentError).
Currently I'm using AJAX to load the results into a certain #results div, but if and when an error arises on the server, I would like an error page to open up on a new page.
Currently, the IOError is shown on the server and a error is seen in the console (the server responded with a status of 500 (Internal Server Error)). Other than that, nothing happens.
I think that I have to play about with the Javascript (as well as the Sinatra::Base class) but I've spent the whole of yesterday and this morning not getting anywhere.
I would be very grateful for any help. I've created an oversimplified version of my app which I have shown below...
Sinatra_app.rb
require 'sinatra/base'
require9 'sinatra'
require 'slim'
# A helper module
module GVhelpers
def create_results(name)
# raise IOError, "There's a problem..."
return "<p>The Server Says 'Hey #{name}'</p>"
end
end
class GVapp < Sinatra::Base
helpers GVhelpers
set :root, File.dirname(__FILE__)
error do
#error = env['sinatra.error']
slim :"500", :locals => {:error => error}
end
get '/' do
slim :index
end
post '/form' do
name = params[:personName]
create_results(name)
end
end
GVapp.run!
index.slim (in views folder)
script src="/jquery.min.js"
script src="/Gvapp.js"
form#sayHey action="/form" method="post"
| Name:
input type="text" name="personName"
br
input type="submit"
#output
500.slim (in views folder)
h1 Oops! Something went Wonky!
p Apologies, there was an error with your request:
strong request.env['sinatra.error'].message
p If the error persists, please contact the administrator.
Gvapp.js (in public folder)
$(document).ready(function() {
$('#sayHey').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '/form',
data: $('#sayHey').serialize(),
success: function(response){
$('#output').html(response);
}
})
})
})
Sinatra swallows exceptions when run in the development environment by default and shows its debugging error page instead. So, to trigger your custom error handlers, you have to either run the application inside a Rack environment other than development (probably production), or preferably, tell Sinatra to not use its default error handlers in development mode.
Consider the following, standalone Sinatra application example:
require "sinatra"
#disable :show_exceptions
get "/" do
raise RuntimeError.new("boom")
end
error RuntimeError do
"A RuntimeError occured"
end
If you run this application using the default development environment like this:
$ ruby foo.rb
Then you will get Sinatra’s default error page. If you uncomment the disable line in the example, the error handler will be triggered instead, displaying a page containing "A RuntimeError occured". Alternatively, you can, as explained, run the application in an environment other than development as only that one pre-sets the show_exception setting. You can do that by setting the RACK_ENV environment variable:
$ RACK_ENV=production ruby foo.rb
For development purposes, setting RACK_ENV to production is not the correct way of course. Use disable :show_exceptions instead. You can use a configure block as outlined in the Sinatra README to conditionally disable the setting for the development environment.
configure :development do
disable :show_exceptions
end
That behaviour is documented in Sinatra’s documentation on configuration, along with several other useful settings.

How to start a minimal ruby app using Puma or Unicorn?

I have a very basic ruby example running on Thin, but I would like to know how to translate this example to use Unicorn or Puma as the HTTP server instead. Here is the code I have now:
require 'rack'
class HelloWorld
def talk()
return "Hello World!"
end
end
class SomeServer
def start(server_object, port)
app = proc do |env|
[ 200, {"Content-Type" => "text/html"}, [server_object.talk()] ]
end
Rack::Handler::Thin::run(app, :Port => port)
end
end
SomeServer.new.start(HelloWorld.new, 3000)
This runs fine and well, but I cannot figure out how to make it run using Puma or Unicorn instead. Most online documentation I find for the two is for Rails apps. How can I utilize the multi-threading capabilities of these servers with this simple program?
use sinatra.
So to take it step by step first install sinatra and puma gems
gem install sinatra
gem install puma
then create a file myapp.rb
require 'sinatra'
configure { set :server, :puma }
get '/' do
"Hello World!"
end
then run the file
ruby myapp.rb
by default sinatra listens on 4567 so go to localhost:4567
you can configure puma to listen on a specific port or do a lot of other things using a config file read the documentation
A minimal example that doesn't require additional gems looks like this.
Using a single file
Create a puma config file config.rb with the following content:
app do |env|
body = 'Hello, World!'
[200, { 'Content-Type' => 'text/plain', 'Content-Length' => body.length.to_s }, [body]]
end
bind 'tcp://127.0.0.1:3000'
and run puma with
puma -C /path/to/config.rb
That's it.
Using a configuration and a rackup file
In the example above, the config file contains the application itself. It makes sense to move the application to a rackup file: Create a rackup file app.ru with the following content:
class HelloWorld
def call(env)
body = 'Hello, World!'
[200, { 'Content-Type' => 'text/plain', 'Content-Length' => body.length.to_s }, [body]]
end
end
run HelloWorld.new
Then update your config.rb, removing the app and linking the rackup file instead:
rackup '/path/to/app.ru'
bind 'tcp://127.0.0.1:3000'
and run puma as before with
puma -C /path/to/config.rb
The example configuration file for puma is helpful. (Update: This example configuration file is no longer maintained. The authors refer to dsl.rb instead.)
Instead of starting your app with Rack::Handler::Thin, you should be able to use the Puma Rack handler instead, like this:
Rack::Handler::Puma.run(app, :Port =>port)
You'd need to also require 'rack/handler/puma' after installing the Puma gem.

Sinatra, modular style. What did I do wrong?

I use Sinatra modular style, i don't know what going bad. I serach google but didn't find anything
require 'sinatra/base'
class App < Sinatra::Base
get '/' do
haml '%h1 Test'
end
end
run App
And a see test.rb:12:in <main>': undefined methodrun' for main:Object (NoMethodError)
What going wrong?
did you run it via ruby -rubygems hi.rb (assuming this code is in hi.rb). If so, you don't need run App. Unless you are running it through another framework built on/with Sinatra.
Also might want to include haml...
You have a config.ru:
# config.ru
require 'my_app'
run MyApp
and a my_app.rb:
# my_app.rb
require 'sinatra/base'
require 'haml'
class MyApp < Sinatra::Base
get('/') { haml '%h1 Test' }
# start the server if ruby file executed directly
run! if app_file == $0
end
then in the folder where the my_app.rb is run this to start the app on localhost:4657:
rackup -p 4567
Regarding the comment above where the error below is displayed:
`start_tcp_server': no acceptor (RuntimeError)
This appears when you are trying to bind to an already bound port. Trying a different port number should resolve.

Trying to Workout how-to run a Ruby (Sinatra) app on the Ebb webserver

I need to write a super fast Ruby application to process web requests on Sinatra - and want to run it on the Ebb webserver. But I cannot work out how to do this. Could someone please help me?
sinatra has a -s option to specify a handler. try running your app with -s ebb.
You need to look at Rack: http://rack.rubyforge.org/
It's pretty easy really, you have a .ru file which instructs Rack how to start your application, and in your application you have a 'call' method which is called on each request, and sends the response back to Rack.
In my_app.ru
require 'my_app'
require 'ebb'
# Rack config
use Rack::Static, urls: ['/js', '/public', '/index.html']
use Rack::ShowExceptions
# Run application
run MyApp.new
In my_app.rb
class MyApp
def call env
request = Rack::Request.new env
response = Rack::Response.new
params = request.params
response.body = "Hello World"
response['Content-Length'] = response.body.size.to_s
response.finish
end
end
Then you specify the .ru file in your sinatra config, like:
rackup: my_app.ru

Resources