Created
February 11, 2012 04:31
-
-
Save khy/1796178 to your computer and use it in GitHub Desktop.
A File System for useless.io
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Useless | |
# Useless::Base is the Rack endpoint for useless.io proper. It has two | |
# responsibilties: show documentation, and serve file from Useless::FS. | |
class Base | |
autoload :Files, 'useless/base/files' | |
def call(env) | |
# Show platform documentation at root | |
app = Rack::URLMap.new '/' => Doc.new('index'), | |
# serve files out of /files/* via the Files Rack endpoint. | |
'/files/' => Files.new | |
app.call(env) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Useless | |
class Base | |
# Useless::Base::Files simply retrieves files from Useless::FS and serves | |
# them up. | |
class Files | |
# Provide a helper method for file URLs to keep things consistent. | |
def self.url_for(id) | |
"http://useless.io/files/#{id}" | |
end | |
def call(env) | |
# The file ID is everything after the initial '/' in the path | |
id = env['PATH_INFO'][1..-1] | |
# Retrieve the file from FS | |
file = Useless::FS.get(BSON::ObjectId(id)) | |
# and serve it up with the associated content type | |
return [200, {'Content-Type' => file.content_type}, file.read] | |
# Two things can go wrong, and they'll both raise an error: | |
# * the specified ID is not a valid object ID | |
# * there is no file corresponding to the ID in the FS | |
rescue BSON::InvalidObjectId, Useless::FS::FileNotFound | |
[404, {'Content-Type' => 'text/plain'}, "File not found: #{id}"] | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe 'useless.io/files' do | |
include Rack::Test::Methods | |
def app | |
Useless | |
end | |
describe 'GET /files/:id' do | |
it 'should return a file if one exists for the specified ID' do | |
file = File.open(asset_path('muffin-milk.jpg')) | |
id = Useless::FS.put(file) | |
get Useless::FS.url_for(id) | |
last_response.should be_ok | |
# See spec/useless/fs_spec.rb | |
file.rewind | |
blob = file.read | |
blob.force_encoding('BINARY') | |
blob.should == last_response.body | |
end | |
it 'should return a 404 if the file does not exits' do | |
get Useless::FS.url_for(BSON::ObjectId.new) | |
last_response.should be_not_found | |
end | |
it 'should return a 404 if the specified ID is invalid' do | |
get Useless::FS.url_for('invalid-id') | |
last_response.should be_not_found | |
end | |
end | |
describe '.url_for' do | |
it 'should return the appropriate URL for the specified file ID' do | |
Useless::Base::Files.url_for('abc123').should == 'http://useless.io/files/abc123' | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Useless | |
# Useless::FS is a minimal wrapper around Mongo::Grid. | |
module FS | |
class FileNotFound < StandardError; end | |
def self.put(file, opts = {}) | |
Useless.mongo.grid.put(file, opts) | |
end | |
def self.get(id) | |
Useless.mongo.grid.get(id) | |
# To preserve the abstraction, raise our own exception when a file isn't | |
# found | |
rescue ::Mongo::GridFileNotFound => e | |
raise FileNotFound, e.message | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe Useless::FS do | |
it 'should allow for files to be added and retrieved via .put and .get' do | |
original_file = File.open(asset_path('muffin-milk.jpg')) | |
original_file_id = Useless::FS.put(original_file) | |
stored_file = Useless::FS.get(original_file_id) | |
# Useless::FS stores the file as an un-encoded binary blob, so in order to | |
# compare, we must strip the encoding, i.e. force a binary encoding. | |
original_file.rewind | |
original_blob = original_file.read | |
original_blob.force_encoding('BINARY') | |
original_blob.should == stored_file.read | |
end | |
describe '.get' do | |
it 'should raise Useless::FS::FileNotFound if the specified ID doesn\'t exist' do | |
-> { Useless::FS.get('nonexistant') }.should raise_error(Useless::FS::FileNotFound) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment