1 Unstar Star 0 Fork 0

Lax / MatrixJavaScriptGPL-3.0

Create your Gitee Account
Explore and code with more than 5 million developers,Free private repositories !:)
Sign up
个人项目进度追踪工具 spread retract

Clone or download
app.rb 12.14 KB
Copy Edit Web IDE Raw Blame History
Lax authored 2012-11-01 14:45 . adjust order in kanban
# encoding: utf-8
require 'yaml'
require 'json'
require 'time'
require 'stalker'
# status workflow
SW = {
:new => [:acknowledged, :rejected, :assigned],
:rejected => [:closed, :new],
:acknowledged => [:assigned, :resolved],
:assigned => [:resolved],
:resolved => [:assigned, :closed],
:closed => [:reopen]
}
# AppController
class AppController < Sinatra::Base
include MatrixHelpers::APP
set :server, %w[thin mongrel webrick]
set :port, 9090
set :static, true
set :method_override, true
enable :sessions
@@websites = File.exists?('config/websites.yml') ? YAML.load_file('config/websites.yml') : YAML.load_file('config/websites.yml.default')
# Settings
ConfigDB.first_or_create({:name => 'environment'}, {:value => ENV['RACK_ENV'] || 'production'})
ConfigDB.first_or_create({:name => 'auth_method'}, {:value => ENV['AUTH'] || 'passport'})
ConfigDB.first_or_create({:name => 'message_queue'}, {:value => ENV['MQ'] || ''})
# Authentication
@@auth = ConfigDB.first :name => 'auth_method'
auth_method = @@auth.value
auth_mod = File.expand_path("./lib/auth_#{auth_method}", File.dirname(__FILE__))
require auth_mod
include Auth
# message_queue
@@mq = ConfigDB.first :name => 'message_queue'
# system user: root, guest
UserGroup.first_or_create({:id => 1}, {:name => 'Administrators', :description => '管理员'})
UserGroup.first_or_create({:id => 2}, {:name => 'User', :description => '用户'})
UserGroup.first_or_create({:id => 3}, {:name => 'Anonymous', :description => '匿名用户'})
User.first_or_create({:name => 'root'}, {:user_group_id => 1})
User.first_or_create({:name => 'guest'}, {:user_group_id => 3})
Project.first_or_create({:id => 1}, {:name => '未分类'})
Project.first_or_create({:id => 2}, {:name => 'Matrix优化'})
Project.first_or_create({:id => 3}, {:name => '新技术评测'})
Tasklet.first_or_create({:name => 'Welcome'}, { :description => '-', :user_id => 1, :project_id => 1, :due => Time.now + 86400})
Tasklet.first_or_create({:name => 'Feedback'}, { :description => 'write feedback on https://github.com/Lax/matrix', :user_id => 1, :project_id => 1, :due => Time.now + 86400})
Trace.first_or_create({:tasklet_id => Tasklet.first.id, :name => '任务执行记录1'})
Trace.first_or_create({:tasklet_id => Tasklet.first.id, :name => '预设检查点1', :check_point => true}, {:created_at => Time.now - 86400, :due => Time.now + 86400})
Trace.first_or_create({:tasklet_id => Tasklet.first.id, :name => '预设检查点2', :check_point => true}, {:created_at => Time.now - 86400, :due => Time.now - 86400/2, :finished_at => Time.now - 86400/4})
Trace.first_or_create({:tasklet_id => Tasklet.first.id, :name => '任务执行记录2'})
Trace.first_or_create({:tasklet_id => Tasklet.first.id, :name => '预设检查点3', :check_point => true}, {:created_at => Time.now - 86400, :due => Time.now - 86400/2})
before do
@current_user = auth_login if @@auth
@projects = Project.all
@users = User.all
@matrix_root = ENV['MATRIX_ROOT'] || 'https://uimatrix.herokuapp.com'
@tasklet_status = "new/rejected/acknowledged/assigned/resolved/closed".split('/')
@current_panel = "Index"
end
["/tasks", "/tasklets", "/project/:project_id"].each do |loc|
get loc do
#selector = { :order => [:finished_at.desc, :urgent.desc, :important.desc, :created_at.desc, :id.desc] }
selector = { :order => [:id.desc] }
if params[:project_id] and @current_project = Project.get(params[:project_id])
selector[:project_id] = @current_project.id
@current_panel = "project_#{@current_project.id}"
end
@tasks = Tasklet.all(selector)
if params[:fmt] && params[:fmt] == "yaml"
content_type 'text/plain'
@tasks.reverse.to_yaml
elsif params[:fmt] && params[:fmt] == 'json'
@tasks.map do |task|
{ "name" => task.name,
"desc" => task.status,
"values" => [{'from' => "/Date(#{Time.parse(task.created_at.asctime).to_i * 1000})/",
'to' => "/Date(#{Time.parse(task.finished? ? task.updated_at.asctime : task.due.asctime).to_i * 1000})/",
'desc' => "[#{task.name}] #{task.description}"
}]
}
end.to_json
else
if params[:gantt] and params[:gantt] == 'true'
erb :tasklet_gantt, :layout => !request.xhr?
else
erb :tasklet_list
end
end
end
end
["/", "/myview", "/myview/:status"].each do |loc|
get loc do
@current_panel = "MyView"
@current_point = params[:status] ? "MyView_#{params[:status]}" : "MyView_all"
order = [:finished_at.desc, :urgent.desc, :important.desc, :created_at.desc, :id.desc]
# myviews: unassigned, :assign_to_me, :created_by_me, :monitor_by_me, :recent_update => []
@myviews = {}
# init __selector
__selector = {
:assign_to_me => {:assignment => {:user => @current_user}},
:unassigned => {:assignment => nil},
:created_by_me => {:user => @current_user},
:monitor_by_me => {:monitors => {:user => @current_user}}
}
__selector.keys.each do |list|
__selector[list][:order] = [:created_at.desc]
__selector[list][:limit] = 30 unless params[:status]
__selector[list][:status] = :closed if status = params[:status] and status.to_sym == :closed
__selector[list][:status.not] = :closed if status = params[:status] and status.to_sym == :open
end
# get tasklets
__selector.keys.each do |list|
@myviews[list] = Tasklet.all(__selector[list])
end
erb :myview
end
end
["/kanban"].each do |loc|
get loc do
@current_panel = "Kanban"
@kanban = {}
@kanban[:new] = Tasklet.all(:status => :new, :order => [:created_at.desc]) + Tasklet.all(:status => :reopen, :order => [:created_at.desc]) + Tasklet.all(:status => :acknowledged, :order => [:created_at.desc])
@kanban[:doing] = Tasklet.all(:status => :assigned, :order => [:created_at.desc])
@kanban[:review] = Tasklet.all(:status => :resolved, :order => [:created_at.desc]) + Tasklet.all(:status => :rejected, :order => [:created_at.desc])
erb :kanban
end
end
["/task/create", "/tasklet/create"].each do |loc|
post loc do
task = Tasklet.new(params)
if task.name != "" and task.save
Monitor.first_or_create(:tasklet_id => task.id, :user_id => task.user_id)
project = Project.get(task.project_id)
redirect task.link
else
redirect "#{project.link}?msg=creation_failed_of_tasklet"
end
end
end
["/task/import", "/tasklet/import"].each do |loc|
get loc do
erb :tasklet_import
end
post loc do
if params[:format] == 'yaml' and params[:content]
entries = YAML.load(params[:content])
entries.each do |entry|
entry['id'] = nil
Tasklet.new(entry).save
end
redirect '/'
end
redirect '/task/import?msg=import_failed_of_tasklet'
end
end
["/task/:id", "/tasklet/:id"].each do |loc|
get loc do
@task = Tasklet.get(params[:id])
@tasklet_next_status = SW[@task.status.to_sym] || @tasklet_status
@traces = Trace.all(:tasklet_id => @task.id, :order => [:id.desc])
@current_panel = "project_#{@task.project_id}"
erb :tasklet_show, :layout => !request.xhr?
end
put loc do
exec_result = nil
msg = nil
task = Tasklet.get(params[:id])
if params[:status] and task.status != params[:status]
status_before = task.status
status_after = params[:status]
msg = "状态更新: #{status_before} => #{status_after}"
task.status = params[:status]
exec_result = true if task.save
elsif params[:monitor_add] and params[:user_id]
user = User.get(params[:user_id])
if ! Monitor.first(:tasklet_id => task.id, :user_id => user.id) and Monitor.create(:tasklet_id => task.id, :user_id => user.id)
msg = "关注者添加 #{user.name}"
exec_result = true
end
elsif params[:monitor_del] and params[:user_id]
user = User.get(params[:user_id])
if m = Monitor.get(:tasklet_id => task.id, :user_id => user.id)
m.destroy
msg = "关注者删除 #{user.name}"
end
exec_result = true
elsif params[:assign_to]
if !task.assign_to or task.assign_to.id != User.get(params[:assign_to]).id
assignment = Assignment.first_or_create(:tasklet_id => task.id)
user_before = assignment.user ? assignment.user.name : '-'
user_after = User.get(params[:assign_to]).name
assignment.user_id = params[:assign_to]
if assignment.save
exec_result = true
task.update(:status => 'assigned') if task.status == 'new' or task.status == 'reopen'
Monitor.first_or_create(:tasklet_id => task.id, :user_id => assignment.user_id)
msg = "分配: #{user_before} => #{user_after}"
end
end
end
if exec_result
Trace.create(:tasklet_id => task.id, :user_id => @current_user.id, :name => msg) if msg
task.monitors.user.each do |u|
Stalker.enqueue('email.send',
:from => @current_user.name,
:to => u.name,
:ref => "tasklet_#{task.id}@todo.som",
:subject => "[TODO #{task.id}] #{task.name}",
:body => %|[UPDATE][#{Time.now.ctime}] #{msg}
--------------------
标题: #{task.name}
描述: #{task.description}
创建日期: #{task.created_at.ctime} 任务创建者: #{task.user.name}
期望日期: #{task.due.ctime} 当前执行者: #{task.assign_to ? task.assign_to.name : '-'}
--------------------
#{ Trace.all(:tasklet_id => task.id).map {|tt| "[#{tt.created_at.ctime}] #{tt.user.name} - #{tt.name}\n#{tt.description}\n"}.join("\n") }
--------------------
查看详情: #{@matrix_root}#{task.link}?from=send.mail
|
) if @@mq.value == 'stalker'
end
status 201
redirect task.link
else
status 412
redirect "#{task.link}?update_failed_of_tasklet"
end
end
#delete loc do
# Task.get(params[:id]).destroy
# redirect '/'
#end
end
['/trace/import'].each do |loc|
get loc do
erb :trace_import
end
post loc do
if params[:format] == 'yaml' and params[:content]
entries = YAML.load(params[:content])
entries.each do |entry|
entry['id'] = nil
Trace.new(entry).save
end
redirect '/'
end
redirect '/?import_failed_of_trace'
end
end
get '/traces' do
traces = Trace.all
content_type 'text/plain'
traces.to_yaml
end
post '/trace/create' do
trace = Trace.new(params)
msg = trace.name
if trace.save
task = trace.tasklet
task.monitors.user.each do |u|
Stalker.enqueue('email.send',
:from => @current_user.name,
:to => u.name,
:ref => "tasklet_#{task.id}@todo.som",
:subject => "[TODO #{task.id}] #{task.name}",
:body => %|[UPDATE][#{Time.now.ctime}] #{msg}
--------------------
标题: #{task.name}
描述: #{task.description}
创建日期: #{task.created_at.ctime} 任务创建者: #{task.user.name}
期望日期: #{task.due.ctime} 当前执行者: #{task.assign_to ? task.assign_to.name : '-'}
--------------------
#{ Trace.all(:tasklet_id => task.id).map {|tt| "[#{tt.created_at.ctime}] #{tt.user.name} - #{tt.name}\n#{tt.description}\n"}.join("\n") }
--------------------
查看详情: #{@matrix_root}#{task.link}?from=send.mail
|
) if @@mq.value == 'stalker'
end
redirect Tasklet.get(trace.tasklet_id).link
else
redirect '/?creation_failed_of_trace'
end
end
put '/trace/:id' do
trace = Trace.get(params[:id])
trace.finished_at = params[:finished] ? Time.now : nil
trace.user_id = params[:user_id] ? params[:user_id] : trace.user_id
if trace.save
status 201
redirect Tasklet.get(trace.tasklet_id).link
else
status 412
redirect '/?update failed_of_trace'
end
end
get '/user/logout' do
session[:username] = nil
redirect '/'
end
get '/user/:id' do
@user = User.get(params[:id])
@tasklets = Tasklet.all({:status.not => :closed, :assignment => {:user => @user}})
erb :user_show
end
get '/matrix/config' do
@settings = ConfigDB.all
@user_groups = UserGroup.all
erb :matrix_config
end
["/websites"].each do |loc|
get loc do
@current_panel = "websites"
@websites = @@websites
erb :websites
end
end
register Sinatra::Async
@@pool = Hash.new []
get '/events' do
@current_panel = "events"
@channel = params[:channel] || 'default'
erb :events
end
aget '/events/sub/:channel' do
@@pool[params[:channel]].push self
end
aget '/events/pub/:channel' do
msg = params[:msg] ? params[:msg] : '-'
@@pool[params[:channel]].each {|observer| observer.body { msg } }
@@pool[params[:channel]] = []
body "sent!"
end
end

Comment ( 0 )

Sign in for post a comment

JavaScript
1
https://gitee.com/liulantao/matrix.git
git@gitee.com:liulantao/matrix.git
liulantao
matrix
Matrix
master

Search