#!/usr/bin/env ruby
# starts a sinatra based web server that provides an interface to
# your ticgit tickets
#
# some of the sinatra code borrowed from sr's git-wiki
#
# author : Scott Chacon (schacon@gmail.com)
#
%w(rubygems sinatra git ticgit haml).each do |dependency|
begin
require dependency
rescue LoadError => e
puts "You need to install #{dependency} before we can proceed"
end
end
# !! TODO : if ARGV[1] is a path to a git repo, use that
# otherwise, look in ~/.ticgit
$ticgit = TicGit.open('.')
get('/_stylesheet.css') { Sass::Engine.new(File.read(__FILE__).gsub(/.*__END__/m, '')).render }
# ticket list view
get '/' do
@tickets = $ticgit.ticket_list(:order => 'date.desc')
haml(list('all'))
end
get '/fs/:state' do
@tickets = $ticgit.ticket_list(:state => params[:state], :order => 'date.desc')
haml(list(params[:state]))
end
get '/tag/:tag' do
@tickets = $ticgit.ticket_list(:tag => params[:tag], :order => 'date.desc')
haml(list(params[:tag]))
end
get '/sv/:saved_view' do
@tickets = $ticgit.ticket_list(:saved => params[:saved_view])
haml(list(params[:saved_view]))
end
# ticket single view
get '/ticket/:ticket' do
@ticket = $ticgit.ticket_show(params[:ticket])
haml(show)
end
# add ticket
get '/t/new' do
haml(new_ticket)
end
# add ticket finalize
post '/t/new' do
title = params[:title].to_s.strip
if title.size > 1
tags = params[:tags].split(',').map { |t| t.strip } rescue nil
t = $ticgit.ticket_new(title, {:comment => params[:comment].strip, :tags => tags})
redirect '/ticket/' + t.ticket_id.to_s
else
redirect '/t/new'
end
end
# add comment
post '/a/add_comment/:ticket' do
t = $ticgit.ticket_comment(params[:comment], params[:ticket])
redirect '/ticket/' + params[:ticket]
end
# add tag
post '/a/add_tags/:ticket' do
t = $ticgit.ticket_tag(params[:tags], params[:ticket])
redirect '/ticket/' + params[:ticket]
end
# change ticket state
get '/a/change_state/:ticket/:state' do
$ticgit.ticket_change(params[:state], params[:ticket])
redirect '/ticket/' + params[:ticket]
end
def layout(title, content)
@saved = $ticgit.config['list_options'].keys rescue []
%Q(
%html
%head
%title #{title}
%link{:rel => 'stylesheet', :href => '/_stylesheet.css', :type => 'text/css', :media => 'screen'}
%meta{'http-equiv' => 'Content-Type', :content => 'text/html; charset=utf-8'}
%body
#navigation
%a{:href => '/'} All
%a{:href => '/fs/open'} Open
%a{:href => '/fs/resolved'} Resolved
%a{:href => '/fs/hold'} Hold
%a{:href => '/fs/invalid'} Invalid
- if !@saved.empty?
| Saved:
- @saved.each do |s|
%a{:href => "/sv/\#{s}"}= s
#action
%a{:href => '/t/new'} New Ticket
#{content}
)
end
def new_ticket
layout('New Ticket', %q{
%h1 Create a New Ticket
%form{:action => '/t/new', :method => 'POST'}
%table
%tr
%th Title
%td
%input{:type => 'text', :name => 'title', :size => 30}
%tr
%th Tags
%td
%input{:name => 'tags', :size => 30}
%small (comma delimited)
%tr
%th Comment
%td
%textarea{:name => 'comment', :rows => 15, :cols => 30}
%tr
%td
%td
%input{:type => 'submit', :value => 'Create Ticket'}
})
end
def list(title = 'all')
@title = title
layout(title + ' tickets', %q{
%h1= "#{@title} tickets"
- if @tickets.empty?
%p No tickets found.
- else
%table.long
- c = 'even'
- @tickets.each do |t|
%tr{:class => (c == 'even' ? c = 'odd' : c = 'even') }
%td
%a{:href => "/ticket/#{t.ticket_id}" }
%code= t.ticket_id[0,6]
%td= t.title
%td{:class => t.state}= t.state
%td= t.opened.strftime("%m/%d")
%td= t.assigned_name
%td
- t.tags.each do |tag|
%a{:href => "/tag/#{tag}"}= tag
})
end
def show
layout('ticket', %q{
%center
%h1= @ticket.title
%form{:action => "/a/add_tags/#{@ticket.ticket_id}", :method => 'POST'}
%table
%tr
%th TicId
%td
%code= @ticket.ticket_id
%tr
%th Assigned
%td= @ticket.assigned
%tr
%th Opened
%td= @ticket.opened
%tr
%th State
%td{:class => @ticket.state}
%table{:width => '300'}
%tr
%td{:width=>'90%'}= @ticket.state
- $ticgit.tic_states.select { |s| s != @ticket.state}.each do |st|
%td{:class => st}
%a{:href => "/a/change_state/#{@ticket.ticket_id}/#{st}"}= st[0,2]
%tr
%th Tags
%td
- @ticket.tags.each do |t|
%a{:href => "/tag/#{t}"}= t
%div.addtag
%input{:name => 'tags'}
%input{:type => 'submit', :value => 'add tag'}
%h3 Comments
%form{:action => "/a/add_comment/#{@ticket.ticket_id}", :method => 'POST'}
%div
%textarea{:name => 'comment', :cols => 50}
%br
%input{:type => 'submit', :value => 'add comment'}
%div.comments
- @ticket.comments.reverse.each do |t|
%div.comment
%span.head
Added
= t.added.strftime("%m/%d %H:%M")
by
= t.user
%div.comment-text
= t.comment
%br
})
end
__END__
body
:font
family: Verdana, Arial, "Bitstream Vera Sans", Helvetica, sans-serif
color: black
line-height: 160%
background-color: white
margin: 2em
#navigation
a
background-color: #e0e0e0
color: black
text-decoration: none
padding: 2px
padding: 5px
border-bottom: 1px black solid
#action
text-align: right
.addtag
padding: 5px 0
h1
display: block
padding-bottom: 5px
a
color: black
a.exists
font-weight: bold
a.unknown
font-style: italic
.comments
margin: 10px 20px
.comment
.head
background: #eee
padding: 4px
.comment-text
padding: 10px
color: #333
table.long
width: 100%
table
tr.even
td
background: #eee
tr.odd
td
background: #fff
table
tr
th
text-align: left
padding: 3px
vertical-align: top
td.open
background: #ada
td.resolved
background: #abd
td.hold
background: #dda
td.invalid
background: #aaa
.submit
font-size: large
font-weight: bold
.page_title
font-size: xx-large
.edit_link
color: black
font-size: 14px
font-weight: bold
background-color: #e0e0e0
font-variant: small-caps
text-decoration: none