.PHONY: install
-install: Component/* Tool/* Utility/* koakuma.cgi.in apache.conf.in
+install: Component/* Tool/* Utility/* Static/* koakuma.cgi.in apache.conf.in
mkdir -p $(PREFIX)/lib/koakuma/component/
mkdir -p $(PREFIX)/lib/koakuma/utility/
mkdir -p $(PREFIX)/lib/koakuma/htdocs/static/
cp -rf Utility/* $(PREFIX)/lib/koakuma/utility/
$(REPLACE) Tool/create-project.in > $(PREFIX)/bin/create-project
$(REPLACE) Tool/launch-job.in > $(PREFIX)/bin/launch-job
- cp -rf koakuma.png $(PREFIX)/lib/koakuma/htdocs/static/
- cp style.css $(PREFIX)/lib/koakuma/htdocs/static/
+ cp -rf Static/* $(PREFIX)/lib/koakuma/htdocs/static/
$(REPLACE) koakuma.cgi.in > $(PREFIX)/lib/koakuma/cgi-bin/koakuma.cgi
$(REPLACE) apache.conf.in > $(PREFIX)/etc/koakuma/apache.conf
chmod +x $(PREFIX)/lib/koakuma/cgi-bin/koakuma.cgi
#!/usr/bin/env tclsh
# $Id$
+package require tdom
+foreach path [glob "@@PREFIX@@/lib/koakuma/utility/*.tcl"] {
+ source $path
+}
+set name ""
+set description ""
+set dothis ""
+foreach arg $argv {
+ if { [string range "$arg" 0 0] == "-" } {
+ if { "$arg" == "-h" || "$arg" == "--help" } {
+ puts "Usage: $argv0 \[-u username\] \[-p password\] \[-R rpc_url\] name description"
+ puts "You can set the environment variable `KOAKUMA_RPC' to override default RPC URL."
+ puts "Default: http://127.0.0.1/koakuma/rpc"
+ exit 0
+ } elseif { "$arg" == "-u" } {
+ set dothis "set-username"
+ } elseif { "$arg" == "-p" } {
+ set dothis "set-password"
+ } elseif { "$arg" == "-R" } {
+ set dothis "set-rpc"
+ }
+ } else {
+ if { "$dothis" == "set-username" } {
+ set ::rpc::useranme "$arg"
+ } elseif { "$dothis" == "set-password" } {
+ set ::rpc::password "$arg"
+ } elseif { "$dothis" == "set-rpc" } {
+ set RPC_URL "$arg"
+ } elseif { "$name" == "" } {
+ set name "$arg"
+ } elseif { "$description" == "" } {
+ set description "$arg"
+ }
+ set dothis ""
+ }
+}
+
+if { "$name" == "" || "$description" == "" } {
+ puts "See --help."
+ exit 1
+}
+
+dom createNodeCmd -tagName "name" -jsonType NONE elementNode keyName
+dom createNodeCmd -tagName "description" -jsonType NONE elementNode keyDescription
+
+dom createNodeCmd -jsonType STRING textNode valueString
+
+set doc [dom createDocumentNode]
+
+$doc appendFromScript {
+ keyName {valueString "$name"}
+ keyDescription {valueString "$description"}
+}
+
+set result [::rpc::send "/launch-job" "[$doc asJSON]"]
+if { [lindex $result 0] == 200 } {
+} else {
+ set doc [dom parse -json "[lindex $result 1]"]
+ puts "Error: [$doc selectNodes "string(/error)"]"
+}
}
proc start_html {title has_toc} {
- global toc
+ global toc env
rputs "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
rputs "<html>"
rputs " <head>"
rputs " <div id=\"title\">"
rputs " Koakuma"
rputs " </div>"
+ rputs " <a href=\"$env(SCRIPT_NAME)\">Root</a>"
rputs " <div id=\"clearfix\"></div>"
if { "$has_toc" == "1" } {
rputs " <div id=\"toc\">"
if { [regexp {^/rpc(/.*)?$} "$path"] } {
rputs "Content-Type: application/json"
} else {
+ if { ![regexp {/$} "$env(PATH_INFO)"] } {
+ puts "Status: 301 Moved Permanently"
+ puts "Location: $env(SCRIPT_NAME)$env(PATH_INFO)/"
+ puts ""
+ exiting 0
+ }
rputs "Content-Type: text/html"
}
if { "$path" == "/" } {
if { "$api" == "" || "$api" == "/" } {
rputs ""
rputs "[$doc asJSON]"
+ } elseif { "$api" == "/launch-job" } {
+ if { [catch {dom parse -json "$data" clidoc}] } {
+ rputs "Status: 400 Bad Request"
+ $doc appendFromScript {
+ keyError {valueString "Bad JSON"}
+ }
+ } else {
+ set projname "[$clidoc selectNodes "string(/name)"]"
+ set builddesc "[$clidoc selectNodes "string(/description)"]"
+ if { "$projname" == "" || "$builddesc" == "" } {
+ rputs "Status: 400 Bad Request"
+ $doc appendFromScript {
+ keyError {valueString "Required field missing"}
+ }
+ } else {
+ set has_name 0
+ open_projects
+ scan_projects {
+ upvar 1 has_name has_name
+ upvar 1 projname projname
+ if { "$name" == "$projname" } {
+ set has_name 1
+ break
+ }
+ }
+ close_projects
+ if { $has_name == 0 } {
+ rputs "Status: 400 Bad Request"
+ $doc appendFromScript {
+ keyError {valueString "Project does not exist"}
+ }
+ } else {
+ }
+ }
+ }
+ rputs ""
+ rputs "[$doc asJSON]"
} elseif { "$api" == "/create-project" } {
if { [catch {dom parse -json "$data" clidoc}] } {
rputs "Status: 400 Bad Request"
rputs "[$doc asJSON]"
}
} elseif { [regexp {^/project/[^/]+.*$} "$path"] } {
- regexp {^/project/([^/]+).*$} "$path" -> projname
+ regexp {^/project/([^/]+)(.*)$} "$path" -> projname projpath
open_projects
set has_project [project_exists "$projname"]
close_projects
if { "$has_project" != "" } {
- add_toc "Description"
- tputs "[html_escape "$has_project"]"
- add_toc "Details"
- tputs "<table border=\"0\">"
- tputs " <tr>"
- tputs " <th>"
- tputs " Last run"
- tputs " </th>"
- tputs " <td>"
- if { [file exists "@@PREFIX@@/lib/koakuma/db/data/$projname/lastrun"] } {
+ if { "$projpath" == "" || "$projpath" == "/" } {
+ add_toc "Description"
+ tputs "[html_escape "$has_project"]"
+ add_toc "Details"
+ tputs "<table border=\"0\">"
+ tputs " <tr>"
+ tputs " <th>"
+ tputs " Last run"
+ tputs " </th>"
+ tputs " <td>"
+ if { [file exists "@@PREFIX@@/lib/koakuma/db/data/$projname/lastrun"] } {
+ set fid [open "@@PREFIX@@/lib/koakuma/db/data/$projname/lastrun" "r"]
+ set date "[clock format "[gets $fid]" -format "%a %b %d %H:%M:%S %Z %Y"]"
+ close $fid
+ tputs "$date"
+ } else {
+ tputs "No builds yet"
+ }
+ tputs " "
+ tputs " </td>"
+ tputs " </tr>"
+ tputs " <tr>"
+ tputs " <th>"
+ tputs " Last successful run"
+ tputs " </th>"
+ tputs " <td>"
+ if { [file exists "@@PREFIX@@/lib/koakuma/db/data/$projname/lastsuccessfulrun"] } {
+ set fid [open "@@PREFIX@@/lib/koakuma/db/data/$projname/lastsuccessfulrun" "r"]
+ set date "[clock format "[gets $fid]" -format "%a %b %d %H:%M:%S %Z %Y"]"
+ close $fid
+ tputs "$date"
+ } else {
+ tputs "No successful builds yet"
+ }
+ tputs " "
+ tputs " </td>"
+ tputs " </tr>"
+ tputs "</table>"
+ add_toc "Build details"
+
+ rputs ""
+ start_html "Project: $projname" 1
+ rputs "$content"
+ end_html 1
} else {
- tputs "Was never ran"
- }
- tputs " "
- tputs " </td>"
- tputs " </tr>"
- tputs "</table>"
+ tputs "I could not find the endpoint you were finding."
- rputs ""
- start_html "Project: $projname" 1
- rputs "$content"
- end_html 1
+ rputs "Status: 404 Not Found"
+ rputs ""
+ start_html "Project: $projname" 1
+ rputs "$content"
+ end_html 1
+ }
} else {
tputs "I could not find the project you were finding."