ditz-str 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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