Skip to content

Instantly share code, notes, and snippets.

@jamiehodge
Created April 10, 2012 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamiehodge/2354879 to your computer and use it in GitHub Desktop.
Save jamiehodge/2354879 to your computer and use it in GitHub Desktop.
application/vnd.amundsen.maze+xml
require 'sinatra'
require 'sequel'
require 'sqlite3'
require 'nokogiri'
DB = Sequel.sqlite
DB.instance_eval do
create_table :mazes do
primary_key :id
String :name
end
create_table :cells do
primary_key :id
foreign_key :maze_id, :mazes
Integer :position
FalseClass :north
FalseClass :south
FalseClass :east
FalseClass :west
end
end
class Maze < Sequel::Model
one_to_many :cells
end
class Cell < Sequel::Model
many_to_one :maze
plugin :list, scope: :maze_id
plugin :boolean_readers
end
maze = Maze.create name: 'five-by-five'
[
[1,1,1,0],
[1,1,1,0],
[1,1,0,0],
[0,1,0,1],
[0,1,1,0],
[1,0,1,0],
[1,0,0,1],
[0,0,1,0],
[1,1,0,0],
[0,0,1,1],
[1,0,0,1],
[0,1,1,0],
[1,0,1,1],
[1,0,0,1],
[0,1,1,0],
[1,1,1,0],
[1,0,1,0],
[1,1,0,0],
[0,1,0,1],
[0,0,1,0],
[1,0,0,1],
[0,0,0,1],
[0,0,1,1],
[1,1,0,1],
[0,0,1,1]
].each_with_index do |cell,i|
maze.add_cell(
position: i,
north: cell[0] == 0,
west: cell[1] == 0,
south: cell[2] == 0,
east: cell[3] == 0
)
end
before do
content_type 'application/vnd.amundsen.maze+xml'
end
get '/' do
nokogiri :collection, locals: { mazes: Maze }
end
before %r{^/(?<maze>[^/]+)} do
@maze = Maze.first(name: params[:maze]) || not_found
end
get '/:maze' do
nokogiri :item, locals: { maze: @maze }
end
before %r{^/[^/]+/(?<cell>\d+)} do
pass if params[:cell].to_i == 999
@cell = @maze.cells_dataset.first(position: params[:cell]) || not_found
end
get '/:maze/999' do
nokogiri :exit, locals: {
maze: @maze,
total: 0,
side: 0,
exit: 0
}
end
get '/:maze/:cell' do
total = @maze.cells.count
side = Math.sqrt(total).to_i
nokogiri :cell, locals: {
maze: @maze,
cell: @cell,
total: total,
side: side,
north: @cell.position - 1,
west: @cell.position - side,
south: @cell.position + 1,
east: @cell.position + side,
exit: @cell.position == @cell.last_position
}
end
__END__
@@collection
xml.collection href: url('/') do
mazes.each do |maze|
xml.link rel: 'maze', href: url("/#{maze.name}")
end
end
@@item
xml.item href: url("/#{maze.name}") do
xml.link rel: 'start', href: url("/#{maze.name}/0")
xml.link rel: 'collection', href: url('/')
end
@@cell
xml.cell href: url("/#{maze.name}/#{cell.position}"), rel: 'current', total: total, side: side do
xml.link href: url("/#{maze.name}/#{north}"), rel: 'north' if cell.north?
xml.link href: url("/#{maze.name}/#{west}"), rel: 'west' if cell.west?
xml.link href: url("/#{maze.name}/#{south}"), rel: 'south' if cell.south?
xml.link href: url("/#{maze.name}/#{east}"), rel: 'east' if cell.east?
if exit
xml.link href: url("/#{maze.name}/999"), rel: 'exit'
else
end
xml.link href: url('/'), rel: 'collection'
xml.link href: url("/#{maze.name}"), rel: 'maze'
end
@@exit
xml.cell href: url("/#{maze.name}/999"), rel: 'current', total: total, side: side do
xml.link href: url("/#{maze.name}/0"), rel: 'start'
xml.link href: url('/'), rel: 'collection'
xml.link href: url("/#{maze.name}"), rel: 'maze'
end
@@error
xml.error do
xml.title title
xml.code code
xml.message message
end
@@layout
xml.maze version: '1.0' do
xml << yield
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment