ditz-str 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +24 -0
- data/LICENSE +674 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/README.txt +143 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bin/ditz-str +189 -0
- data/bugs/issue-02615b8c3dd0382c92f350ce2158ecfe94d11ef8.yaml +22 -0
- data/bugs/issue-06a3bbf35a60c4da2d8ea0fdc86164263126d6b2.yaml +22 -0
- data/bugs/issue-0c00c1d7fdffaad304e62d79d9b3d5e92547055b.yaml +38 -0
- data/bugs/issue-20dad4b4533d6d76d496fe5970098f1eb8efd561.yaml +26 -0
- data/bugs/issue-360ae6529dbc66358fde6b532cbea79ece37a670.yaml +22 -0
- data/bugs/issue-5177d61bf3c2783f71ef63e6e2c5e720247ef699.yaml +18 -0
- data/bugs/issue-695b564c210da1965a2bb38eef782178aead6952.yaml +26 -0
- data/bugs/issue-7d0ce6429a9fb5fa09ce3376a8921a5ecb7ecfe5.yaml +34 -0
- data/bugs/issue-a04462fa22ab6e1b02cfdd052d1f6c6f491f08f5.yaml +22 -0
- data/bugs/issue-bca54ca5107eabc3b281701041cc36ea0641cbdd.yaml +26 -0
- data/bugs/issue-d0c7d04b014d705c5fd865e4d487b5e5b6983c33.yaml +26 -0
- data/bugs/issue-f94b879842aa0274aa74fc2833252d4a06ec65cc.yaml +22 -0
- data/bugs/project.yaml +18 -0
- data/data/ditz-str/blue-check.png +0 -0
- data/data/ditz-str/close.rhtml +39 -0
- data/data/ditz-str/component.rhtml +38 -0
- data/data/ditz-str/dropdown.css +11 -0
- data/data/ditz-str/dropdown.js +58 -0
- data/data/ditz-str/edit_issue.rhtml +53 -0
- data/data/ditz-str/green-bar.png +0 -0
- data/data/ditz-str/green-check.png +0 -0
- data/data/ditz-str/header.gif +0 -0
- data/data/ditz-str/header_over.gif +0 -0
- data/data/ditz-str/index.rhtml +148 -0
- data/data/ditz-str/issue.rhtml +152 -0
- data/data/ditz-str/issue_table.rhtml +28 -0
- data/data/ditz-str/new_component.rhtml +28 -0
- data/data/ditz-str/new_issue.rhtml +57 -0
- data/data/ditz-str/new_release.rhtml +29 -0
- data/data/ditz-str/plugins/git-sync.rb +83 -0
- data/data/ditz-str/plugins/git.rb +153 -0
- data/data/ditz-str/plugins/issue-claiming.rb +174 -0
- data/data/ditz-str/red-check.png +0 -0
- data/data/ditz-str/release.rhtml +111 -0
- data/data/ditz-str/style.css +236 -0
- data/data/ditz-str/unassigned.rhtml +37 -0
- data/data/ditz-str/yellow-bar.png +0 -0
- data/ditz-str.gemspec +121 -0
- data/lib/ditzstr/brick.rb +251 -0
- data/lib/ditzstr/file-storage.rb +54 -0
- data/lib/ditzstr/hook.rb +67 -0
- data/lib/ditzstr/html.rb +104 -0
- data/lib/ditzstr/lowline.rb +201 -0
- data/lib/ditzstr/model-objects.rb +346 -0
- data/lib/ditzstr/model.rb +265 -0
- data/lib/ditzstr/operator.rb +593 -0
- data/lib/ditzstr/trollop.rb +614 -0
- data/lib/ditzstr/util.rb +61 -0
- data/lib/ditzstr/view.rb +16 -0
- data/lib/ditzstr/views.rb +157 -0
- data/lib/ditzstr.rb +69 -0
- data/man/ditz.1 +38 -0
- data/test/helper.rb +18 -0
- data/test/test_ditz-str.rb +7 -0
- metadata +219 -0
@@ -0,0 +1,236 @@
|
|
1
|
+
body {
|
2
|
+
font-family: "lucida grande", "sans serif";
|
3
|
+
color: #333;
|
4
|
+
width: 60em;
|
5
|
+
margin: auto;
|
6
|
+
}
|
7
|
+
|
8
|
+
div.main {
|
9
|
+
padding: 20px;
|
10
|
+
margin: auto;
|
11
|
+
padding-top: 0;
|
12
|
+
margin-top: 1em;
|
13
|
+
background-color: #fcfcfc;
|
14
|
+
}
|
15
|
+
|
16
|
+
.person {
|
17
|
+
font-family: courier;
|
18
|
+
}
|
19
|
+
|
20
|
+
a, a:visited {
|
21
|
+
background: inherit;
|
22
|
+
text-decoration: none;
|
23
|
+
}
|
24
|
+
|
25
|
+
a {
|
26
|
+
color: #003d41;
|
27
|
+
}
|
28
|
+
|
29
|
+
a:visited {
|
30
|
+
color: #553d41;
|
31
|
+
}
|
32
|
+
|
33
|
+
ul {
|
34
|
+
list-style-type: none;
|
35
|
+
padding: 0;
|
36
|
+
}
|
37
|
+
|
38
|
+
p {
|
39
|
+
width: 40em;
|
40
|
+
}
|
41
|
+
|
42
|
+
.inline-status-image {
|
43
|
+
position: relative;
|
44
|
+
top: 0.2em;
|
45
|
+
}
|
46
|
+
|
47
|
+
.dimmed {
|
48
|
+
color: #bbb;
|
49
|
+
}
|
50
|
+
|
51
|
+
table {
|
52
|
+
border-style: none;
|
53
|
+
border-spacing: 0;
|
54
|
+
}
|
55
|
+
|
56
|
+
table.log {
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
td {
|
61
|
+
border-width: 0;
|
62
|
+
border-style: none;
|
63
|
+
padding-right: 0.5em;
|
64
|
+
padding-left: 0.5em;
|
65
|
+
}
|
66
|
+
|
67
|
+
tr {
|
68
|
+
vertical-align: top;
|
69
|
+
}
|
70
|
+
|
71
|
+
h1 {
|
72
|
+
padding: 0.5em;
|
73
|
+
margin-left: -20px;
|
74
|
+
margin-right: -20px;
|
75
|
+
background-color: #305275;
|
76
|
+
margin-top: 0;
|
77
|
+
margin-bottom: 0;
|
78
|
+
color: #fff;
|
79
|
+
}
|
80
|
+
|
81
|
+
h2 {
|
82
|
+
text-transform: uppercase;
|
83
|
+
font-size: smaller;
|
84
|
+
margin-top: 1em;
|
85
|
+
margin-left: -0.5em;
|
86
|
+
width: 100%;
|
87
|
+
/*background: #fffbce;*/
|
88
|
+
/*background: #628a0d;*/
|
89
|
+
padding: 5px;
|
90
|
+
color: #305275;
|
91
|
+
}
|
92
|
+
|
93
|
+
.attrname {
|
94
|
+
text-align: right;
|
95
|
+
font-size: smaller;
|
96
|
+
}
|
97
|
+
|
98
|
+
.attrval {
|
99
|
+
color: #222;
|
100
|
+
}
|
101
|
+
|
102
|
+
.issue-closed-fixed {
|
103
|
+
background-image: "green-check.png";
|
104
|
+
}
|
105
|
+
|
106
|
+
.issue-closed-wontfix {
|
107
|
+
background-image: "red-check.png";
|
108
|
+
}
|
109
|
+
|
110
|
+
.issue-closed-reorg {
|
111
|
+
background-image: "blue-check.png";
|
112
|
+
}
|
113
|
+
|
114
|
+
.inline-issue-link {
|
115
|
+
text-decoration: underline;
|
116
|
+
}
|
117
|
+
|
118
|
+
img {
|
119
|
+
border: 0;
|
120
|
+
}
|
121
|
+
|
122
|
+
/*
|
123
|
+
.issuestatus_closed {
|
124
|
+
background-color: #f2fff2;
|
125
|
+
text-align: center;
|
126
|
+
}
|
127
|
+
|
128
|
+
.issuestatus_in_progress {
|
129
|
+
background-color: #fffff2;
|
130
|
+
text-align: center;
|
131
|
+
}
|
132
|
+
|
133
|
+
.issuestatus_paused {
|
134
|
+
background-color: #fffff2;
|
135
|
+
text-align: center;
|
136
|
+
}
|
137
|
+
|
138
|
+
.issuestatus_unstarted {
|
139
|
+
background-color: #fff2f2;
|
140
|
+
text-align: center;
|
141
|
+
}
|
142
|
+
|
143
|
+
.issuestatus_closed a {
|
144
|
+
color: #202020;
|
145
|
+
}
|
146
|
+
|
147
|
+
.issuestatus_in_progress a {
|
148
|
+
color: #202020;
|
149
|
+
}
|
150
|
+
|
151
|
+
.issuestatus_paused a {
|
152
|
+
color: #202020;
|
153
|
+
}
|
154
|
+
|
155
|
+
.issuestatus_unstarted a {
|
156
|
+
color: #202020;
|
157
|
+
}
|
158
|
+
*/
|
159
|
+
|
160
|
+
div.footer {
|
161
|
+
font-size: small;
|
162
|
+
padding-left: 20px;
|
163
|
+
padding-right: 20px;
|
164
|
+
padding-top: 5px;
|
165
|
+
padding-bottom: 5px;
|
166
|
+
margin: auto;
|
167
|
+
background: #305275;
|
168
|
+
color: #fffee7;
|
169
|
+
}
|
170
|
+
|
171
|
+
.footer a {
|
172
|
+
color: #508d91;
|
173
|
+
}
|
174
|
+
|
175
|
+
.even-row {
|
176
|
+
font-size: smaller;
|
177
|
+
background-color: #f2f2f2;
|
178
|
+
}
|
179
|
+
|
180
|
+
.odd-row {
|
181
|
+
font-size: smaller;
|
182
|
+
background-color: #f2f2f2;
|
183
|
+
}
|
184
|
+
|
185
|
+
.menu {
|
186
|
+
padding: 0.5em;
|
187
|
+
margin-left: -20px;
|
188
|
+
margin-right: -20px;
|
189
|
+
background-color: #305275;
|
190
|
+
margin-top: 0;
|
191
|
+
margin-bottom: 0;
|
192
|
+
color: #fff;
|
193
|
+
}
|
194
|
+
|
195
|
+
.backptr {
|
196
|
+
font-size: smaller;
|
197
|
+
width: 100%;
|
198
|
+
text-align: left;
|
199
|
+
padding-bottom: 1em;
|
200
|
+
margin-top: 0;
|
201
|
+
}
|
202
|
+
|
203
|
+
.logcomment {
|
204
|
+
padding-left: 4em;
|
205
|
+
font-size: smaller;
|
206
|
+
}
|
207
|
+
|
208
|
+
.id {
|
209
|
+
font-family: courier;
|
210
|
+
}
|
211
|
+
|
212
|
+
.description {
|
213
|
+
background: #f2f2f2;
|
214
|
+
padding-left: 1em;
|
215
|
+
padding-right: 1em;
|
216
|
+
padding-top: 0.5em;
|
217
|
+
padding-bottom: 0.5em;
|
218
|
+
}
|
219
|
+
|
220
|
+
.message {
|
221
|
+
}
|
222
|
+
|
223
|
+
.littledate {
|
224
|
+
font-size: smaller;
|
225
|
+
}
|
226
|
+
|
227
|
+
.progress-meter-done {
|
228
|
+
background-color: #03af00;
|
229
|
+
}
|
230
|
+
|
231
|
+
.progress-meter-undone {
|
232
|
+
background-color: #ddd;
|
233
|
+
}
|
234
|
+
|
235
|
+
.progress-meter {
|
236
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
3
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
4
|
+
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
6
|
+
<head>
|
7
|
+
<title>Issues not assigned to any release</title>
|
8
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
9
|
+
<link rel="stylesheet" href="style.css" type="text/css" />
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
|
13
|
+
<div class="main">
|
14
|
+
<h1>Issues not assigned to any release</h1>
|
15
|
+
<div class="backptr"><%= link_to "index", "« #{project.name} project page" %></div>
|
16
|
+
|
17
|
+
<h2>All issues</h2>
|
18
|
+
<%= render "issue_table", :show_component => false, :show_release => true %>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<% if (not brickargs.empty?) && (not brickars[:actions].empty?) %>
|
22
|
+
<h2>Actions</h2><br>
|
23
|
+
<% firstitem = true %>
|
24
|
+
<% brickargs[:actions].each do |actionlink| %>
|
25
|
+
<% if firstitem %>
|
26
|
+
<%= "<a href=\"#{actionlink[1]}\">#{actionlink[0]}</a>" %>
|
27
|
+
<% firstitem = false %>
|
28
|
+
<% else %>
|
29
|
+
<%= " | <a href=\"#{actionlink[1]}\">#{actionlink[0]}</a>" %>
|
30
|
+
<% end %>
|
31
|
+
<% end %>
|
32
|
+
<% end %>
|
33
|
+
|
34
|
+
<div class="footer">Generated by <a href="http://ditz.rubyforge.org/">ditz</a>.</div>
|
35
|
+
|
36
|
+
</body>
|
37
|
+
</html>
|
Binary file
|
data/ditz-str.gemspec
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{ditz-str}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Nils F. Sandell"]
|
12
|
+
s.date = %q{2011-12-03}
|
13
|
+
s.description = %q{Modification of the ditz issue tracking originally created by William Morgan. First new feature is a portable web server for interacting with the issue system.}
|
14
|
+
s.email = %q{nils.sandell@systemstechnologyresearch.com}
|
15
|
+
s.executables = ["ditz-str"]
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE",
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.rdoc",
|
20
|
+
"README.txt"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
".document",
|
24
|
+
"Gemfile",
|
25
|
+
"Gemfile.lock",
|
26
|
+
"LICENSE",
|
27
|
+
"LICENSE.txt",
|
28
|
+
"README.rdoc",
|
29
|
+
"README.txt",
|
30
|
+
"Rakefile",
|
31
|
+
"VERSION",
|
32
|
+
"bin/ditz-str",
|
33
|
+
"bugs/issue-02615b8c3dd0382c92f350ce2158ecfe94d11ef8.yaml",
|
34
|
+
"bugs/issue-06a3bbf35a60c4da2d8ea0fdc86164263126d6b2.yaml",
|
35
|
+
"bugs/issue-0c00c1d7fdffaad304e62d79d9b3d5e92547055b.yaml",
|
36
|
+
"bugs/issue-20dad4b4533d6d76d496fe5970098f1eb8efd561.yaml",
|
37
|
+
"bugs/issue-360ae6529dbc66358fde6b532cbea79ece37a670.yaml",
|
38
|
+
"bugs/issue-5177d61bf3c2783f71ef63e6e2c5e720247ef699.yaml",
|
39
|
+
"bugs/issue-695b564c210da1965a2bb38eef782178aead6952.yaml",
|
40
|
+
"bugs/issue-7d0ce6429a9fb5fa09ce3376a8921a5ecb7ecfe5.yaml",
|
41
|
+
"bugs/issue-a04462fa22ab6e1b02cfdd052d1f6c6f491f08f5.yaml",
|
42
|
+
"bugs/issue-bca54ca5107eabc3b281701041cc36ea0641cbdd.yaml",
|
43
|
+
"bugs/issue-d0c7d04b014d705c5fd865e4d487b5e5b6983c33.yaml",
|
44
|
+
"bugs/issue-f94b879842aa0274aa74fc2833252d4a06ec65cc.yaml",
|
45
|
+
"bugs/project.yaml",
|
46
|
+
"data/ditz-str/blue-check.png",
|
47
|
+
"data/ditz-str/close.rhtml",
|
48
|
+
"data/ditz-str/component.rhtml",
|
49
|
+
"data/ditz-str/dropdown.css",
|
50
|
+
"data/ditz-str/dropdown.js",
|
51
|
+
"data/ditz-str/edit_issue.rhtml",
|
52
|
+
"data/ditz-str/green-bar.png",
|
53
|
+
"data/ditz-str/green-check.png",
|
54
|
+
"data/ditz-str/header.gif",
|
55
|
+
"data/ditz-str/header_over.gif",
|
56
|
+
"data/ditz-str/index.rhtml",
|
57
|
+
"data/ditz-str/issue.rhtml",
|
58
|
+
"data/ditz-str/issue_table.rhtml",
|
59
|
+
"data/ditz-str/new_component.rhtml",
|
60
|
+
"data/ditz-str/new_issue.rhtml",
|
61
|
+
"data/ditz-str/new_release.rhtml",
|
62
|
+
"data/ditz-str/plugins/git-sync.rb",
|
63
|
+
"data/ditz-str/plugins/git.rb",
|
64
|
+
"data/ditz-str/plugins/issue-claiming.rb",
|
65
|
+
"data/ditz-str/red-check.png",
|
66
|
+
"data/ditz-str/release.rhtml",
|
67
|
+
"data/ditz-str/style.css",
|
68
|
+
"data/ditz-str/unassigned.rhtml",
|
69
|
+
"data/ditz-str/yellow-bar.png",
|
70
|
+
"ditz-str.gemspec",
|
71
|
+
"lib/ditzstr.rb",
|
72
|
+
"lib/ditzstr/brick.rb",
|
73
|
+
"lib/ditzstr/file-storage.rb",
|
74
|
+
"lib/ditzstr/hook.rb",
|
75
|
+
"lib/ditzstr/html.rb",
|
76
|
+
"lib/ditzstr/lowline.rb",
|
77
|
+
"lib/ditzstr/model-objects.rb",
|
78
|
+
"lib/ditzstr/model.rb",
|
79
|
+
"lib/ditzstr/operator.rb",
|
80
|
+
"lib/ditzstr/trollop.rb",
|
81
|
+
"lib/ditzstr/util.rb",
|
82
|
+
"lib/ditzstr/view.rb",
|
83
|
+
"lib/ditzstr/views.rb",
|
84
|
+
"man/ditz.1",
|
85
|
+
"test/helper.rb",
|
86
|
+
"test/test_ditz-str.rb"
|
87
|
+
]
|
88
|
+
s.homepage = %q{http://github.com/nsandell/ditz-str}
|
89
|
+
s.licenses = ["GPL"]
|
90
|
+
s.require_paths = ["lib"]
|
91
|
+
s.rubygems_version = %q{1.7.2}
|
92
|
+
s.summary = %q{Customized STR version of ditz issue tracking system (original by William Morgan).}
|
93
|
+
|
94
|
+
if s.respond_to? :specification_version then
|
95
|
+
s.specification_version = 3
|
96
|
+
|
97
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
98
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
99
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
100
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
101
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
102
|
+
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
103
|
+
s.add_runtime_dependency(%q<trollop>, [">= 1.9"])
|
104
|
+
else
|
105
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
106
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
107
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
108
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
109
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
110
|
+
s.add_dependency(%q<trollop>, [">= 1.9"])
|
111
|
+
end
|
112
|
+
else
|
113
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
114
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
115
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
116
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
117
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
118
|
+
s.add_dependency(%q<trollop>, [">= 1.9"])
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
@@ -0,0 +1,251 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
require 'erb'
|
3
|
+
include WEBrick
|
4
|
+
|
5
|
+
module DitzStr
|
6
|
+
|
7
|
+
class BrickView < HtmlView
|
8
|
+
|
9
|
+
def initialize project, config, dir
|
10
|
+
super project, config, dir
|
11
|
+
end
|
12
|
+
|
13
|
+
def link_to name, text
|
14
|
+
links = generate_links
|
15
|
+
return "<a href=\"#{links[name]}\">#{text}</a>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def edit_issue issuename, changes
|
19
|
+
if changes[:description] != nil
|
20
|
+
end
|
21
|
+
if changes[:reporter] != nil
|
22
|
+
end
|
23
|
+
if changes[:title] != nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def comment_on_issue issuename, comment
|
28
|
+
|
29
|
+
issue_res = get_issue_by_name issuename
|
30
|
+
|
31
|
+
if issue_res[0]
|
32
|
+
iss = issue_res[1]
|
33
|
+
iss.log "commented", @config.user, comment
|
34
|
+
return "<html><head><meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=/issue-#{issuename}.html\"></head><body>Redirecting...</body></html>"
|
35
|
+
else
|
36
|
+
return issue_res[1]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def generate_edit_issue issue_id
|
41
|
+
end
|
42
|
+
|
43
|
+
def generate_close_issue issue_id, disposition
|
44
|
+
|
45
|
+
issue_res = get_issue_by_name issue_id
|
46
|
+
|
47
|
+
if issue_res[0]
|
48
|
+
issue = issue_res[1]
|
49
|
+
erb = ERB.new IO.read(File.join(@template_dir, "close.rhtml"))
|
50
|
+
return erb.result binding()
|
51
|
+
else
|
52
|
+
return issue_res[1]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_new_issue options
|
57
|
+
past_rels, upcoming_rels = @project.releases.partition { |r| r.released? }
|
58
|
+
erb = ERB.new IO.read(File.join(@template_dir, "new_issue.rhtml"))
|
59
|
+
return erb.result binding()
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_new_component
|
63
|
+
erb = ERB.new IO.read(File.join(@template_dir, "new_component.rhtml"))
|
64
|
+
return erb.result binding()
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_new_release
|
68
|
+
erb = ERB.new IO.read(File.join(@template_dir,"new_release.rhtml"))
|
69
|
+
return erb.result binding()
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_index
|
73
|
+
links = generate_links
|
74
|
+
generate_index_html_str links, {:brick=>true}
|
75
|
+
end
|
76
|
+
|
77
|
+
def generate_release relname
|
78
|
+
|
79
|
+
issue_link = "/new_issue.html?release=#{relname}"
|
80
|
+
#TODO Actions
|
81
|
+
|
82
|
+
links = generate_links
|
83
|
+
r = @project.release_for relname
|
84
|
+
generate_release_html_str links, r, {:brick=>true}
|
85
|
+
end
|
86
|
+
|
87
|
+
def generate_component comp_name
|
88
|
+
|
89
|
+
#TODO Actions
|
90
|
+
issue_link = "/new_issue.html?component=#{comp_name}"
|
91
|
+
|
92
|
+
links = generate_links
|
93
|
+
c = @project.component_for comp_name
|
94
|
+
generate_component_html_str links, c, {:brick=>true}
|
95
|
+
end
|
96
|
+
|
97
|
+
def generate_issue issuename
|
98
|
+
|
99
|
+
links = generate_links
|
100
|
+
|
101
|
+
issue_res = get_issue_by_name issuename
|
102
|
+
|
103
|
+
if issue_res[0]
|
104
|
+
return generate_issue_html_str links, issue_res[1], {:brick=>true}
|
105
|
+
else
|
106
|
+
return issue_res[1]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_issue_by_name issuename
|
111
|
+
issues_vec = @project.issues_for issuename
|
112
|
+
|
113
|
+
case issues_vec.size
|
114
|
+
when 0;
|
115
|
+
return [false,"<html><body>No such issue found...</body></html>"];
|
116
|
+
when 1;
|
117
|
+
return [true,issues_vec.first]
|
118
|
+
else
|
119
|
+
return [false,"<html><body>Multiple issues found...</body></html>"];
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class DitzStrServlet < HTTPServlet::AbstractServlet
|
125
|
+
|
126
|
+
def initialize(server, options)
|
127
|
+
super(server)
|
128
|
+
@project = options[:project]
|
129
|
+
@config = options[:config]
|
130
|
+
@brickview = options[:brickview]
|
131
|
+
@sharedir = options[:dir]
|
132
|
+
@user = options[:user]
|
133
|
+
end
|
134
|
+
|
135
|
+
def do_GET(req,resp)
|
136
|
+
if req.path=="/index.html" or req.path=="/"
|
137
|
+
#puts req.query['wee']
|
138
|
+
resp['content-type'] = 'text/html'
|
139
|
+
resp.body = @brickview.generate_index
|
140
|
+
elsif req.path.start_with? '/release-'
|
141
|
+
relname = req.path.sub('/release-','').sub('.html','')
|
142
|
+
resp['content-type'] = 'text/html'
|
143
|
+
resp.body = @brickview.generate_release relname
|
144
|
+
elsif req.path.start_with? '/component-'
|
145
|
+
compname = req.path.sub('/component-','').sub('.html','')
|
146
|
+
resp['content-type'] = 'text/html'
|
147
|
+
resp.body = @brickview.generate_component compname
|
148
|
+
elsif req.path.start_with? '/issue-'
|
149
|
+
issuename = req.path.sub('/issue-','').sub('.html','')
|
150
|
+
resp['content-type'] = 'text/html'
|
151
|
+
resp.body = @brickview.generate_issue issuename
|
152
|
+
elsif req.path=='/new_issue.html'
|
153
|
+
options = {}
|
154
|
+
if req.query['component']!=nil
|
155
|
+
options[:component] = req.query['component']
|
156
|
+
end
|
157
|
+
if req.query['release']!=nil
|
158
|
+
options[:release] = req.query['release']
|
159
|
+
end
|
160
|
+
options[:creator] = @user
|
161
|
+
resp['content-type'] = 'text/html'
|
162
|
+
resp.body = @brickview.generate_new_issue options
|
163
|
+
elsif req.path=='/new_component.html'
|
164
|
+
resp['content-type'] = 'text/html'
|
165
|
+
resp.body = @brickview.generate_new_component
|
166
|
+
elsif req.path=='/new_release.html'
|
167
|
+
resp['content-type'] = 'text/html'
|
168
|
+
resp.body = @brickview.generate_new_release
|
169
|
+
elsif req.path=='/close.html'
|
170
|
+
resp['content-type'] = 'text/html'
|
171
|
+
if req.query['issue']==nil
|
172
|
+
resp.body = 'Error, no such issue found.'
|
173
|
+
else
|
174
|
+
resp.body = @brickview.generate_close_issue req.query['issue'], req.query['disposition']
|
175
|
+
end
|
176
|
+
else
|
177
|
+
HTTPServlet::FileHandler.new(@server,@sharedir).do_GET(req,resp)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def do_POST(req,resp)
|
182
|
+
resp['content-type'] = 'text/html'
|
183
|
+
|
184
|
+
if req.path.start_with? '/new_issue.html'
|
185
|
+
issue = Issue.create({:project => @project, :config=> @config},{:title => req.query['title'], :desc => req.query['description'], :type => req.query['type'],
|
186
|
+
:component => req.query['component'], :release => req.query['release'], :reporter => 'poop', :comments => req.query['comments']});
|
187
|
+
issue.log "created", @config.user, req.query['comments']
|
188
|
+
resp.body = "<html><head><meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=/component-#{req.query['component']}.html\"></head><body>Redirecting...</body></html>"
|
189
|
+
@project.add_issue issue
|
190
|
+
@project.assign_issue_names!
|
191
|
+
elsif req.path.start_with? '/edit_issue.html'
|
192
|
+
|
193
|
+
elsif req.path.start_with? '/new_component.html'
|
194
|
+
component = Component.create({:project => @project, :config=>@config},{:name => req.query['name']});
|
195
|
+
@project.add_component component
|
196
|
+
resp.body = "<html><head><meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=/index.html\"></head><body>Redirecting...</body></html>"
|
197
|
+
elsif req.path.start_with? '/new_release.html'
|
198
|
+
release = Release.create({:project => @project, :config=>@config},{:name => req.query['name']})
|
199
|
+
release.log "created", @config.user, req.query['comments']
|
200
|
+
@project.add_release release
|
201
|
+
resp.body = "<html><head><meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=/index.html\"></head><body>Redirecting...</body></html>"
|
202
|
+
elsif req.path.start_with? '/issue-'
|
203
|
+
|
204
|
+
issue = "#{req.path}"
|
205
|
+
issue = issue.gsub('/issue-','')
|
206
|
+
issue = issue.gsub('.html','')
|
207
|
+
resp.body = @brickview.comment_on_issue issue, req.query['comment']
|
208
|
+
elsif req.path.start_with? '/close.html'
|
209
|
+
issue_id = req.query['issue']
|
210
|
+
comment = req.query['comment']
|
211
|
+
closer = req.query['closer']
|
212
|
+
disp = req.query['disposition']
|
213
|
+
|
214
|
+
issue_res = @brickview.get_issue_by_name issue_id
|
215
|
+
|
216
|
+
if issue_res[0]
|
217
|
+
iss = issue_res[1]
|
218
|
+
iss.close disp.to_sym, closer, comment
|
219
|
+
resp.body = "<html><head><meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=/issue-#{issue_id}.html\"></head><body>Redirecting...</body></html>"
|
220
|
+
else
|
221
|
+
return issue_res[1]
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
class Operator
|
228
|
+
|
229
|
+
def start_webrick(config = {})
|
230
|
+
config.update(:Port => 8080)
|
231
|
+
server = HTTPServer.new(config)
|
232
|
+
yield server if block_given?
|
233
|
+
['INT', 'TERM'].each {|signal|
|
234
|
+
trap(signal) {server.shutdown}
|
235
|
+
}
|
236
|
+
server.start
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
operation :brick, "Start brick web server for issue management.", :maybe_dir
|
241
|
+
def brick project, config, dir
|
242
|
+
brickview = BrickView.new(project,config, dir)
|
243
|
+
sharedir = File.dirname DitzStr::find_ditz_file("index.rhtml")
|
244
|
+
start_webrick { |server|
|
245
|
+
imgdir = File.dirname DitzStr::find_ditz_file("index.rhtml")
|
246
|
+
server.mount('/', DitzStrServlet, {:brickview => brickview, :dir =>sharedir, :user=>config.user, :project=>project, :config=>config })
|
247
|
+
}
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module DitzStr
|
2
|
+
|
3
|
+
## stores ditz database on disk
|
4
|
+
class FileStorage
|
5
|
+
PROJECT_FN = "project.yaml"
|
6
|
+
ISSUE_FN_GLOB = "issue-*.yaml"
|
7
|
+
|
8
|
+
def ISSUE_TO_FN i; "issue-#{i.id}.yaml" end
|
9
|
+
|
10
|
+
def initialize base_dir
|
11
|
+
@base_dir = base_dir
|
12
|
+
@project_fn = File.join @base_dir, PROJECT_FN
|
13
|
+
end
|
14
|
+
|
15
|
+
def load
|
16
|
+
DitzStr::debug "loading project from #{@project_fn}"
|
17
|
+
project = Project.from @project_fn
|
18
|
+
|
19
|
+
fn = File.join @base_dir, ISSUE_FN_GLOB
|
20
|
+
DitzStr::debug "loading issues from #{fn}"
|
21
|
+
project.issues = Dir[fn].map { |fn| Issue.from fn }
|
22
|
+
DitzStr::debug "found #{project.issues.size} issues"
|
23
|
+
|
24
|
+
project.issues.each { |i| i.project = project }
|
25
|
+
project
|
26
|
+
end
|
27
|
+
|
28
|
+
def save project
|
29
|
+
dirty = false
|
30
|
+
dirty = project.each_modelobject { |o| break true if o.changed? }
|
31
|
+
if dirty
|
32
|
+
DitzStr::debug "project is dirty, saving #{@project_fn}"
|
33
|
+
project.save! @project_fn
|
34
|
+
end
|
35
|
+
|
36
|
+
changed_issues = project.issues.select { |i| i.changed? }
|
37
|
+
changed_issues.each do |i|
|
38
|
+
fn = filename_for_issue i
|
39
|
+
DitzStr::debug "issue #{i.name} is dirty, saving #{fn}"
|
40
|
+
i.save! fn
|
41
|
+
end
|
42
|
+
|
43
|
+
project.deleted_issues.each do |i|
|
44
|
+
fn = filename_for_issue i
|
45
|
+
DitzStr::debug "issue #{i.name} has been deleted, deleting #{fn}"
|
46
|
+
FileUtils.rm fn
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def filename_for_issue i; File.join @base_dir, ISSUE_TO_FN(i) end
|
51
|
+
def filename_for_project; @project_fn end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|