lib/gitdocs/browser_app.rb
# -*- encoding : utf-8 -*-
require 'sinatra/base'
require 'cgi'
require 'haml'
require 'mimetype_fu'
require 'gitdocs/rendering_helper'
module Gitdocs
class BrowserApp < Sinatra::Base
set :haml, format: :html5
helpers RenderingHelper
helpers do
# @return [Integer]
def id
@id ||= params[:id].to_i
end
# @return [Gitdocs::Repository::Path]
def repository
@repository ||= Repository.new(Share.find(id))
end
# @return [Gitdocs::Repository::Path]
def path
halt(404) unless repository
@path ||= Repository::Path.new(
repository, CGI.unescape(params[:splat].first)
)
end
end
get('/') do
if Share.all.count == 1
redirect to("/#{Share.first.id}/")
else
haml(:home, locals: { nav_state: 'home' })
end
end
get('/search') do
haml(
:search,
locals: {
results: Search.search(params[:q]),
nav_state: nil
}
)
end
get('/:id*') do
default_locals = {
root: repository.root,
nav_state: nil
}
case params[:mode]
when 'meta'
begin
content_type :json
path.meta.to_json
rescue
halt(404)
end
when 'edit'
halt(404) unless path.text?
haml(
:edit,
locals: default_locals.merge(contents: path.content)
)
when 'revisions'
haml(
:revisions,
locals: default_locals.merge(revisions: path.revisions)
)
when 'raw'
send_file(path.absolute_path)
else
if path.directory?
haml(
:dir,
locals: default_locals.merge(
contents: path.file_listing,
rendered_readme: file_content_render(path.readme_path)
)
)
else
haml(
:file,
locals: default_locals.merge(
contents: file_content_render(
path.absolute_path(params[:revision])
)
)
)
end
end
end
post('/:id*') do
redirect_path =
if params[:file] # upload
path.join(params[:file][:filename])
path.mv(params[:file][:tempfile].path)
"/#{id}/#{path.relative_path}"
elsif params[:filename] # add file/directory
path.join(params[:filename])
if params[:new_file]
path.touch
"/#{id}/#{path.relative_path}?mode=edit"
elsif params[:new_directory]
path.mkdir
"/#{id}/#{path.relative_path}"
else
halt(400)
end
else
halt(400)
end
redirect to(redirect_path)
end
put('/:id*') do
commit_message =
if params[:revision] # revert
path.revert(params[:revision])
"Reverting '#{path.relative_path}' to #{params[:revision]}"
elsif params[:data] && params[:message] # save
path.write(params[:data])
params[:message]
end
repository.write_commit_message(commit_message)
redirect to("/#{id}/#{path.relative_path}")
end
delete('/:id*') do
path.remove
redirect to("/#{id}/#{path.relative_dirname}")
end
end
end