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.
Files changed (65) hide show
  1. data/.document +5 -0
  2. data/Gemfile +14 -0
  3. data/Gemfile.lock +24 -0
  4. data/LICENSE +674 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/README.txt +143 -0
  8. data/Rakefile +55 -0
  9. data/VERSION +1 -0
  10. data/bin/ditz-str +189 -0
  11. data/bugs/issue-02615b8c3dd0382c92f350ce2158ecfe94d11ef8.yaml +22 -0
  12. data/bugs/issue-06a3bbf35a60c4da2d8ea0fdc86164263126d6b2.yaml +22 -0
  13. data/bugs/issue-0c00c1d7fdffaad304e62d79d9b3d5e92547055b.yaml +38 -0
  14. data/bugs/issue-20dad4b4533d6d76d496fe5970098f1eb8efd561.yaml +26 -0
  15. data/bugs/issue-360ae6529dbc66358fde6b532cbea79ece37a670.yaml +22 -0
  16. data/bugs/issue-5177d61bf3c2783f71ef63e6e2c5e720247ef699.yaml +18 -0
  17. data/bugs/issue-695b564c210da1965a2bb38eef782178aead6952.yaml +26 -0
  18. data/bugs/issue-7d0ce6429a9fb5fa09ce3376a8921a5ecb7ecfe5.yaml +34 -0
  19. data/bugs/issue-a04462fa22ab6e1b02cfdd052d1f6c6f491f08f5.yaml +22 -0
  20. data/bugs/issue-bca54ca5107eabc3b281701041cc36ea0641cbdd.yaml +26 -0
  21. data/bugs/issue-d0c7d04b014d705c5fd865e4d487b5e5b6983c33.yaml +26 -0
  22. data/bugs/issue-f94b879842aa0274aa74fc2833252d4a06ec65cc.yaml +22 -0
  23. data/bugs/project.yaml +18 -0
  24. data/data/ditz-str/blue-check.png +0 -0
  25. data/data/ditz-str/close.rhtml +39 -0
  26. data/data/ditz-str/component.rhtml +38 -0
  27. data/data/ditz-str/dropdown.css +11 -0
  28. data/data/ditz-str/dropdown.js +58 -0
  29. data/data/ditz-str/edit_issue.rhtml +53 -0
  30. data/data/ditz-str/green-bar.png +0 -0
  31. data/data/ditz-str/green-check.png +0 -0
  32. data/data/ditz-str/header.gif +0 -0
  33. data/data/ditz-str/header_over.gif +0 -0
  34. data/data/ditz-str/index.rhtml +148 -0
  35. data/data/ditz-str/issue.rhtml +152 -0
  36. data/data/ditz-str/issue_table.rhtml +28 -0
  37. data/data/ditz-str/new_component.rhtml +28 -0
  38. data/data/ditz-str/new_issue.rhtml +57 -0
  39. data/data/ditz-str/new_release.rhtml +29 -0
  40. data/data/ditz-str/plugins/git-sync.rb +83 -0
  41. data/data/ditz-str/plugins/git.rb +153 -0
  42. data/data/ditz-str/plugins/issue-claiming.rb +174 -0
  43. data/data/ditz-str/red-check.png +0 -0
  44. data/data/ditz-str/release.rhtml +111 -0
  45. data/data/ditz-str/style.css +236 -0
  46. data/data/ditz-str/unassigned.rhtml +37 -0
  47. data/data/ditz-str/yellow-bar.png +0 -0
  48. data/ditz-str.gemspec +121 -0
  49. data/lib/ditzstr/brick.rb +251 -0
  50. data/lib/ditzstr/file-storage.rb +54 -0
  51. data/lib/ditzstr/hook.rb +67 -0
  52. data/lib/ditzstr/html.rb +104 -0
  53. data/lib/ditzstr/lowline.rb +201 -0
  54. data/lib/ditzstr/model-objects.rb +346 -0
  55. data/lib/ditzstr/model.rb +265 -0
  56. data/lib/ditzstr/operator.rb +593 -0
  57. data/lib/ditzstr/trollop.rb +614 -0
  58. data/lib/ditzstr/util.rb +61 -0
  59. data/lib/ditzstr/view.rb +16 -0
  60. data/lib/ditzstr/views.rb +157 -0
  61. data/lib/ditzstr.rb +69 -0
  62. data/man/ditz.1 +38 -0
  63. data/test/helper.rb +18 -0
  64. data/test/test_ditz-str.rb +7 -0
  65. 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", "&laquo; #{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