meta_project 0.4.11 → 0.4.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/CHANGES +277 -269
  2. data/MIT-LICENSE +21 -21
  3. data/README +126 -126
  4. data/Rakefile +152 -152
  5. data/doc/base_attrs.rdoc +2 -2
  6. data/lib/meta_project.rb +11 -10
  7. data/lib/meta_project/core_ext/open_uri.rb +22 -22
  8. data/lib/meta_project/core_ext/pathname.rb +36 -36
  9. data/lib/meta_project/core_ext/string.rb +4 -4
  10. data/lib/meta_project/http/multipart.rb +32 -0
  11. data/lib/meta_project/patois/parser.rb +98 -98
  12. data/lib/meta_project/project.rb +4 -4
  13. data/lib/meta_project/project/base.rb +8 -8
  14. data/lib/meta_project/project/codehaus.rb +1 -1
  15. data/lib/meta_project/project/codehaus/codehaus_project_svn.rb +30 -30
  16. data/lib/meta_project/project/trac.rb +1 -1
  17. data/lib/meta_project/project/trac/trac_project.rb +53 -53
  18. data/lib/meta_project/project/xforge.rb +5 -5
  19. data/lib/meta_project/project/xforge/ruby_forge.rb +46 -48
  20. data/lib/meta_project/project/xforge/session.rb +177 -191
  21. data/lib/meta_project/project/xforge/source_forge.rb +49 -49
  22. data/lib/meta_project/project/xforge/xfile.rb +44 -44
  23. data/lib/meta_project/project/xforge/xforge_base.rb +81 -79
  24. data/lib/meta_project/project_analyzer.rb +35 -35
  25. data/lib/meta_project/release/freshmeat.rb +267 -267
  26. data/lib/meta_project/release/raa.rb +572 -572
  27. data/lib/meta_project/scm_web.rb +1 -1
  28. data/lib/meta_project/scm_web/browser.rb +111 -111
  29. data/lib/meta_project/scm_web/pathname.rb +88 -88
  30. data/lib/meta_project/tracker.rb +6 -6
  31. data/lib/meta_project/tracker/base.rb +23 -23
  32. data/lib/meta_project/tracker/digit_issues.rb +33 -32
  33. data/lib/meta_project/tracker/issue.rb +56 -52
  34. data/lib/meta_project/tracker/jira.rb +2 -2
  35. data/lib/meta_project/tracker/jira/jira_issues.rb +34 -33
  36. data/lib/meta_project/tracker/jira/jira_tracker.rb +123 -123
  37. data/lib/meta_project/tracker/trac.rb +1 -1
  38. data/lib/meta_project/tracker/trac/trac_tracker.rb +32 -32
  39. data/lib/meta_project/tracker/xforge.rb +3 -3
  40. data/lib/meta_project/tracker/xforge/ruby_forge_tracker.rb +17 -17
  41. data/lib/meta_project/tracker/xforge/source_forge_tracker.rb +17 -17
  42. data/lib/meta_project/tracker/xforge/xforge_tracker.rb +190 -105
  43. data/lib/meta_project/version_parser.rb +52 -52
  44. data/lib/rake/contrib/xforge.rb +3 -3
  45. data/lib/rake/contrib/xforge/base.rb +64 -64
  46. data/lib/rake/contrib/xforge/news_publisher.rb +97 -97
  47. data/lib/rake/contrib/xforge/release.rb +134 -134
  48. metadata +3 -3
  49. data/TODO +0 -9
@@ -1 +1 @@
1
- require 'meta_project/project/trac/trac_project'
1
+ require 'meta_project/project/trac/trac_project'
@@ -1,54 +1,54 @@
1
- module MetaProject
2
- module Project
3
- module Trac
4
- class TracProject < Base
5
-
6
- def initialize(trac_base_url, svn_root_url, svn_path)
7
- @trac_base_url = trac_base_url
8
- @svn_path = svn_path
9
- @scm = RSCM::Subversion.new("#{svn_root_url}#{svn_path}", svn_path)
10
- @tracker = ::MetaProject::Tracker::Trac::TracTracker.new(@trac_base_url)
11
- end
12
-
13
- TRAC_VERSION_PATTERN = /<strong>Trac ([\d\.]+)[^<]*<\/strong>/
14
-
15
- def scm_web
16
- unless @scm_web
17
-
18
- front_page = better_open(@trac_base_url).read
19
- if(front_page =~ TRAC_VERSION_PATTERN)
20
- version = $1
21
- # If there is no minor version part, add 0
22
- version = "#{version}.0" if version =~ /^[\d]+\.[\d]+$/
23
- version = version.gsub(/\./, "").to_i
24
- if(version >= 90)
25
- html = "#{@trac_base_url}/browser/#{@svn_path}/\#{path}?rev=\#{revision}"
26
- raw = "#{@trac_base_url}/browser/#{@svn_path}/\#{path}?rev=\#{revision}&format=txt"
27
- else
28
- html = "#{@trac_base_url}/file/#{@svn_path}/\#{path}?rev=\#{revision}"
29
- raw = "#{@trac_base_url}/file/#{@svn_path}/\#{path}?rev=\#{revision}&format=txt"
30
- end
31
-
32
- dir = "#{@trac_base_url}/browser/#{@svn_path}/\#{path}"
33
- history = "#{@trac_base_url}/log/#{@svn_path}/\#{path}"
34
- diff = "#{@trac_base_url}/changeset/\#{revision}"
35
- child_dirs_pattern = /title="Browse Directory" href="[^"]+">([^<]+)<\/a>/
36
- child_files_pattern = /title="View File" href="[^"]+">([^<]+)<\/a>/
37
-
38
- @scm_web = ScmWeb::Browser.new(dir, history, raw, html, diff, child_dirs_pattern, child_files_pattern)
39
- else
40
- raise ProjectException.new("Couldn't determine the Trac version. Is the URL '#{@trac_base_url}' correct? I was looking for the regexp /#{TRAC_VERSION_PATTERN.source}/ on the page, but couldn't find it.")
41
- end
42
- end
43
-
44
- @scm_web
45
- end
46
-
47
- def home_page
48
- "#{@trac_base_url}/wiki"
49
- end
50
-
51
- end
52
- end
53
- end
1
+ module MetaProject
2
+ module Project
3
+ module Trac
4
+ class TracProject < Base
5
+
6
+ def initialize(trac_base_url, svn_root_url, svn_path)
7
+ @trac_base_url = trac_base_url
8
+ @svn_path = svn_path
9
+ @scm = RSCM::Subversion.new("#{svn_root_url}#{svn_path}", svn_path)
10
+ @tracker = ::MetaProject::Tracker::Trac::TracTracker.new(@trac_base_url)
11
+ end
12
+
13
+ TRAC_VERSION_PATTERN = /<strong>Trac ([\d\.]+)[^<]*<\/strong>/
14
+
15
+ def scm_web
16
+ unless @scm_web
17
+
18
+ front_page = better_open(@trac_base_url).read
19
+ if(front_page =~ TRAC_VERSION_PATTERN)
20
+ version = $1
21
+ # If there is no minor version part, add 0
22
+ version = "#{version}.0" if version =~ /^[\d]+\.[\d]+$/
23
+ version = version.gsub(/\./, "").to_i
24
+ if(version >= 90)
25
+ html = "#{@trac_base_url}/browser/#{@svn_path}/\#{path}?rev=\#{revision}"
26
+ raw = "#{@trac_base_url}/browser/#{@svn_path}/\#{path}?rev=\#{revision}&format=txt"
27
+ else
28
+ html = "#{@trac_base_url}/file/#{@svn_path}/\#{path}?rev=\#{revision}"
29
+ raw = "#{@trac_base_url}/file/#{@svn_path}/\#{path}?rev=\#{revision}&format=txt"
30
+ end
31
+
32
+ dir = "#{@trac_base_url}/browser/#{@svn_path}/\#{path}"
33
+ history = "#{@trac_base_url}/log/#{@svn_path}/\#{path}"
34
+ diff = "#{@trac_base_url}/changeset/\#{revision}"
35
+ child_dirs_pattern = /title="Browse Directory" href="[^"]+">([^<]+)<\/a>/
36
+ child_files_pattern = /title="View File" href="[^"]+">([^<]+)<\/a>/
37
+
38
+ @scm_web = ScmWeb::Browser.new(dir, history, raw, html, diff, child_dirs_pattern, child_files_pattern)
39
+ else
40
+ raise ProjectException.new("Couldn't determine the Trac version. Is the URL '#{@trac_base_url}' correct? I was looking for the regexp /#{TRAC_VERSION_PATTERN.source}/ on the page, but couldn't find it.")
41
+ end
42
+ end
43
+
44
+ @scm_web
45
+ end
46
+
47
+ def home_page
48
+ "#{@trac_base_url}/wiki"
49
+ end
50
+
51
+ end
52
+ end
53
+ end
54
54
  end
@@ -1,5 +1,5 @@
1
- require 'meta_project/project/xforge/xforge_base'
2
- require 'meta_project/project/xforge/session'
3
- require 'meta_project/project/xforge/xfile'
4
- require 'meta_project/project/xforge/ruby_forge'
5
- require 'meta_project/project/xforge/source_forge'
1
+ require 'meta_project/project/xforge/xforge_base'
2
+ require 'meta_project/project/xforge/session'
3
+ require 'meta_project/project/xforge/xfile'
4
+ require 'meta_project/project/xforge/ruby_forge'
5
+ require 'meta_project/project/xforge/source_forge'
@@ -1,49 +1,47 @@
1
- require 'meta_project/tracker/xforge'
2
-
3
- module MetaProject
4
- module Project
5
- module XForge
6
- class RubyForge < XForgeBase
7
-
8
- def initialize(unix_name, cvs_mod=nil)
9
- super("rubyforge.org", unix_name, cvs_mod)
10
- end
11
-
12
- def tracker_class
13
- ::MetaProject::Tracker::XForge::RubyForgeTracker
14
- end
15
-
16
- protected
17
-
18
- def create_cvs(unix_name, mod)
19
- RSCM::Cvs.new(":pserver:anonymous@rubyforge.org:/var/cvs/#{unix_name}", mod)
20
- end
21
-
22
- def create_view_cvs(unix_name, mod)
23
- view_cvs = "http://rubyforge.org/cgi-bin/viewcvs.cgi/"
24
- cvsroot = "?cvsroot=#{unix_name}"
25
- path_cvs_root = "#{mod}/\#{path}#{cvsroot}"
26
- path_cvs_root_rev = "#{path_cvs_root}&rev=\#{revision}"
27
-
28
- dir = "#{view_cvs}#{path_cvs_root}"
29
- history = "#{view_cvs}#{path_cvs_root}"
30
- raw = "#{view_cvs}*checkout*/#{path_cvs_root_rev}"
31
- html = "#{view_cvs}#{path_cvs_root_rev}&content-type=text/vnd.viewcvs-markup"
32
- diff = "#{view_cvs}#{mod}/\#{path}.diff#{cvsroot}&r1=\#{previous_revision}&r2=\#{revision}"
33
-
34
- child_dirs_pattern = /href="([^\?]*)\/\?cvsroot=#{unix_name}">/
35
- child_files_pattern = /href="([^\?^\/]*)\?cvsroot=#{unix_name}">/
36
-
37
- ScmWeb::Browser.new(dir, history, raw, html, diff, child_dirs_pattern, child_files_pattern)
38
- end
39
-
40
- # Regexp used to find projects' home page
41
- def home_page_regexp
42
- # This seems a little volatile
43
- /<a href=\"(\w*:\/\/[^\"]*)\"><img src=\"\/themes\/osx\/images\/ic\/home/
44
- end
45
-
46
- end
47
- end
48
- end
1
+ module MetaProject
2
+ module Project
3
+ module XForge
4
+ class RubyForge < XForgeBase
5
+
6
+ def initialize(unix_name, cvs_mod=nil)
7
+ super("rubyforge.org", unix_name, cvs_mod)
8
+ end
9
+
10
+ def tracker_class
11
+ ::MetaProject::Tracker::XForge::RubyForgeTracker
12
+ end
13
+
14
+ protected
15
+
16
+ def create_cvs(unix_name, mod)
17
+ RSCM::Cvs.new(":pserver:anonymous@rubyforge.org:/var/cvs/#{unix_name}", mod)
18
+ end
19
+
20
+ def create_view_cvs(unix_name, mod)
21
+ view_cvs = "http://rubyforge.org/cgi-bin/viewcvs.cgi/"
22
+ cvsroot = "?cvsroot=#{unix_name}"
23
+ path_cvs_root = "#{mod}/\#{path}#{cvsroot}"
24
+ path_cvs_root_rev = "#{path_cvs_root}&rev=\#{revision}"
25
+
26
+ dir = "#{view_cvs}#{path_cvs_root}"
27
+ history = "#{view_cvs}#{path_cvs_root}"
28
+ raw = "#{view_cvs}*checkout*/#{path_cvs_root_rev}"
29
+ html = "#{view_cvs}#{path_cvs_root_rev}&content-type=text/vnd.viewcvs-markup"
30
+ diff = "#{view_cvs}#{mod}/\#{path}.diff#{cvsroot}&r1=\#{previous_revision}&r2=\#{revision}"
31
+
32
+ child_dirs_pattern = /href="([^\?]*)\/\?cvsroot=#{unix_name}">/
33
+ child_files_pattern = /href="([^\?^\/]*)\?cvsroot=#{unix_name}">/
34
+
35
+ ScmWeb::Browser.new(dir, history, raw, html, diff, child_dirs_pattern, child_files_pattern)
36
+ end
37
+
38
+ # Regexp used to find projects' home page
39
+ def home_page_regexp
40
+ # This seems a little volatile
41
+ /<a href=\"(\w*:\/\/[^\"]*)\"><img src=\"\/themes\/osx\/images\/ic\/home/
42
+ end
43
+
44
+ end
45
+ end
46
+ end
49
47
  end
@@ -1,191 +1,177 @@
1
- module MetaProject
2
- module Project
3
- module XForge
4
- # A Session object allows authenticated interaction with a Project,
5
- # such as releasing files.
6
- #
7
- # A Session object can be obtained via Project.login
8
- class Session
9
- # Simple enumeration of processors. Used from Session.release.
10
- class Processor
11
- I386 = 1000
12
- IA64 = 6000
13
- ALPHA = 7000
14
- ANY = 8000
15
- PPC = 2000
16
- MIPS = 3000
17
- SPARC = 4000
18
- ULTRA_SPARC = 5000
19
- OTHER_PLATFORM = 9999
20
- end
21
-
22
- BOUNDARY = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" #:nodoc:
23
-
24
- def initialize(host, project, cookie) # :nodoc:
25
- @host = host
26
- @project = project
27
- @headers = { "Cookie" => cookie }
28
- end
29
-
30
- PACKAGE_ID_PATTERN = %r{name="package_id"
31
- \s+
32
- value="([^"]+)"
33
- .*?
34
- name="package_name"
35
- \s+
36
- value="([^"]+)"}mxo #:nodoc:
37
-
38
- # This will get the +package_id+ for the project. This accepts an
39
- # optional name of the package that will be searched for results. A
40
- # given session will only work for one package.
41
- def package_id(name = nil)
42
- unless @package_id
43
- release_uri = "http://#{@host}/frs/admin/?group_id=#{@project.group_id}"
44
- release_data = better_open(release_uri, @headers).read
45
- packages = release_data.scan(PACKAGE_ID_PATTERN)
46
- first = packages[0][0]
47
- packages = Hash[*packages.map { |el| el.reverse }.flatten]
48
-
49
- if name
50
- @package_id = packages[name]
51
- else
52
- @package_id = first
53
- end
54
-
55
- unless @package_id
56
- File.open("package_id.html", "w") {|io| io.write(release_data)}
57
- raise "Couldn't get package_id from #{release_uri}. I was looking for /#{package_id_pattern.source}/. HTML saved to package_id.html for debugging."
58
- end
59
- end
60
- @package_id
61
- end
62
-
63
- # Creates a new release containing the files specified by
64
- # +filenames+ (Array) and named +release_name+. Optional parameters
65
- # are +processor+ (which should be one of the Processor constants),
66
- # +release_notes+, +release_changes+ and +preformatted+ which will
67
- # appear on the releas page of the associated project. The
68
- # +package_name+ parameter will help choose from the possible
69
- # multiple packages for a release.
70
- def release(release_name, filenames, release_notes = "",
71
- release_changes = "", package_name = nil,
72
- preformatted = true, processor = Processor::ANY)
73
- release_date = Time.now.strftime("%Y-%m-%d %H:%M")
74
- release_id = nil
75
-
76
- puts "About to release '#{release_name}'"
77
- puts "Files:"
78
- puts " " + filenames.join("\n ")
79
- puts "\nRelease Notes:\n"
80
- puts release_notes.split(/\n/)[0..10].join("\n")
81
- puts "\nRelease Changes:\n"
82
- puts release_changes.split(/\n/)[0..10].join("\n")
83
- puts "\nRelease Settings:\n"
84
- puts "Preformatted: #{preformatted}"
85
- puts "Processor: #{processor}"
86
- puts "\nStarting release..."
87
-
88
- xfiles = filenames.collect{|filename| XFile.new(filename)}
89
- xfiles.each_with_index do |xfile, i|
90
- first_file = (i == 0)
91
- puts "Releasing #{xfile.basename}..."
92
- release_response = Net::HTTP.start(@host, 80) do |http|
93
- query_hash = if first_file then
94
- {
95
- "group_id" => @project.group_id,
96
- "package_id" => package_id(package_name),
97
- "type_id" => xfile.bin_type_id,
98
- "processor_id" => processor,
99
-
100
- "release_name" => release_name,
101
- "release_date" => release_date,
102
- "release_notes" => release_notes,
103
- "release_changes" => release_changes,
104
- "preformatted" => preformatted ? "1" : "0",
105
- "submit" => "1"
106
- }
107
- else
108
- {
109
- "group_id" => @project.group_id,
110
- "package_id" => package_id(package_name),
111
- "type_id" => xfile.bin_type_id,
112
- "processor_id" => processor,
113
-
114
- "step2" => "1",
115
- "release_id" => release_id,
116
- "submit" => "Add This File"
117
- }
118
- end
119
-
120
- form = [
121
- "--#{BOUNDARY}",
122
- %Q(Content-Disposition: form-data; name="userfile"; ) +
123
- %Q(filename="#{xfile.basename}"),
124
- "Content-Type: application/octet-stream",
125
- "Content-Transfer-Encoding: binary",
126
- "", xfile.data, ""
127
- ]
128
-
129
- data = post_data(form, query_hash)
130
-
131
- headers = @headers.merge("Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}")
132
-
133
-
134
- target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
135
- http.post(target, data, headers)
136
- end
137
-
138
- if first_file then
139
- release_id = release_response.body[/release_id=(\d+)/, 1]
140
- raise("Couldn't get release id") unless release_id
141
- end
142
- end
143
- puts "Done!"
144
- end
145
-
146
- # Publish news relating to a project and a package.
147
- def publish_news(subject, details)
148
- puts "About to publish news"
149
- puts "Subject: '#{subject}'"
150
- puts "Details:"
151
- puts details
152
- puts ""
153
-
154
- release_response = Net::HTTP.start(@host, 80) do |http|
155
- query_hash = {
156
- "group_id" => @project.group_id,
157
- "post_changes" => "y",
158
- "summary" => subject,
159
- "details" => details
160
- }
161
-
162
- target = "/news/submit.php"
163
- headers = @headers.merge("Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}")
164
-
165
- http.post(target, post_data(query_hash), headers)
166
- end
167
- puts "Done!"
168
- end
169
-
170
- private
171
- def post_data(*args)
172
- form = []
173
- args.each do |arg|
174
- case arg
175
- when Array
176
- form << arg
177
- when Hash
178
- arg.each do |key, value|
179
- form <<
180
- "--#{BOUNDARY}" <<
181
- %Q(Content-Disposition: form-data; name="#{key}") <<
182
- "" << value
183
- end
184
- end
185
- end
186
- form.flatten.join("\r\n")
187
- end
188
- end
189
- end
190
- end
191
- end
1
+ module MetaProject
2
+ module Project
3
+ module XForge
4
+ # A Session object allows authenticated interaction with a Project,
5
+ # such as releasing files.
6
+ #
7
+ # A Session object can be obtained via Project.login
8
+ class Session
9
+ include HTTP::Multipart
10
+
11
+ # Simple enumeration of processors. Used from Session.release.
12
+ class Processor
13
+ I386 = 1000
14
+ IA64 = 6000
15
+ ALPHA = 7000
16
+ ANY = 8000
17
+ PPC = 2000
18
+ MIPS = 3000
19
+ SPARC = 4000
20
+ ULTRA_SPARC = 5000
21
+ OTHER_PLATFORM = 9999
22
+ end
23
+
24
+ PACKAGE_ID_PATTERN = %r{name="package_id"
25
+ \s+
26
+ value="([^"]+)"
27
+ .*?
28
+ name="package_name"
29
+ \s+
30
+ value="([^"]+)"}mxo #:nodoc:
31
+
32
+ attr_reader :request_headers
33
+
34
+ def initialize(host, project, cookie) # :nodoc:
35
+ @host = host
36
+ @project = project
37
+ @request_headers = { "Cookie" => cookie }
38
+ end
39
+
40
+ # This will get the +package_id+ for the project. This accepts an
41
+ # optional name of the package that will be searched for results. A
42
+ # given session will only work for one package.
43
+ def package_id(name = nil)
44
+ unless @package_id
45
+ release_uri = "http://#{@host}/frs/admin/?group_id=#{@project.group_id}"
46
+ release_data = better_open(release_uri, @request_headers).read
47
+ packages = release_data.scan(PACKAGE_ID_PATTERN)
48
+ first = packages[0][0]
49
+ packages = Hash[*packages.map { |el| el.reverse }.flatten]
50
+
51
+ if name
52
+ @package_id = packages[name]
53
+ else
54
+ @package_id = first
55
+ end
56
+
57
+ unless @package_id
58
+ File.open("package_id.html", "w") {|io| io.write(release_data)}
59
+ raise "Couldn't get package_id from #{release_uri}. I was looking for /#{package_id_pattern.source}/. HTML saved to package_id.html for debugging."
60
+ end
61
+ end
62
+ @package_id
63
+ end
64
+
65
+ # Creates a new release containing the files specified by
66
+ # +filenames+ (Array) and named +release_name+. Optional parameters
67
+ # are +processor+ (which should be one of the Processor constants),
68
+ # +release_notes+, +release_changes+ and +preformatted+ which will
69
+ # appear on the releas page of the associated project. The
70
+ # +package_name+ parameter will help choose from the possible
71
+ # multiple packages for a release.
72
+ # TODO: consider using a hash based signature with symbols. This is
73
+ # getting big!
74
+ def release(release_name, filenames, release_notes = "",
75
+ release_changes = "", package_name = nil,
76
+ preformatted = true, processor = Processor::ANY)
77
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
78
+ release_id = nil
79
+
80
+ puts "About to release '#{release_name}'"
81
+ puts "Files:"
82
+ puts " " + filenames.join("\n ")
83
+ puts "\nRelease Notes:\n"
84
+ puts release_notes.split(/\n/)[0..10].join("\n")
85
+ puts "\nRelease Changes:\n"
86
+ puts release_changes.split(/\n/)[0..10].join("\n")
87
+ puts "\nRelease Settings:\n"
88
+ puts "Preformatted: #{preformatted}"
89
+ puts "Processor: #{processor}"
90
+ puts "\nStarting release..."
91
+
92
+ xfiles = filenames.collect{|filename| XFile.new(filename)}
93
+ xfiles.each_with_index do |xfile, i|
94
+ first_file = (i == 0)
95
+ puts "Releasing #{xfile.basename}..."
96
+ release_response = Net::HTTP.start(@host, 80) do |http|
97
+ query_hash = if first_file then
98
+ {
99
+ "group_id" => @project.group_id,
100
+ "package_id" => package_id(package_name),
101
+ "type_id" => xfile.bin_type_id,
102
+ "processor_id" => processor,
103
+
104
+ "release_name" => release_name,
105
+ "release_date" => release_date,
106
+ "release_notes" => release_notes,
107
+ "release_changes" => release_changes,
108
+ "preformatted" => preformatted ? "1" : "0",
109
+ "submit" => "1"
110
+ }
111
+ else
112
+ {
113
+ "group_id" => @project.group_id,
114
+ "package_id" => package_id(package_name),
115
+ "type_id" => xfile.bin_type_id,
116
+ "processor_id" => processor,
117
+
118
+ "step2" => "1",
119
+ "release_id" => release_id,
120
+ "submit" => "Add This File"
121
+ }
122
+ end
123
+
124
+ form = [
125
+ "--#{BOUNDARY}",
126
+ %Q(Content-Disposition: form-data; name="userfile"; ) +
127
+ %Q(filename="#{xfile.basename}"),
128
+ "Content-Type: application/octet-stream",
129
+ "Content-Transfer-Encoding: binary",
130
+ "", xfile.data, ""
131
+ ]
132
+
133
+ data = post_data(form, query_hash)
134
+
135
+ headers = @request_headers.merge("Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}")
136
+
137
+
138
+ target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
139
+ http.post(target, data, headers)
140
+ end
141
+
142
+ if first_file then
143
+ release_id = release_response.body[/release_id=(\d+)/, 1]
144
+ raise("Couldn't get release id") unless release_id
145
+ end
146
+ end
147
+ puts "Done!"
148
+ end
149
+
150
+ # Publish news relating to a project and a package.
151
+ def publish_news(subject, details)
152
+ puts "About to publish news"
153
+ puts "Subject: '#{subject}'"
154
+ puts "Details:"
155
+ puts details
156
+ puts ""
157
+
158
+ release_response = Net::HTTP.start(@host, 80) do |http|
159
+ query_hash = {
160
+ "group_id" => @project.group_id,
161
+ "post_changes" => "y",
162
+ "summary" => subject,
163
+ "details" => details
164
+ }
165
+
166
+ target = "/news/submit.php"
167
+ headers = @request_headers.merge("Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}")
168
+
169
+ http.post(target, post_data(query_hash), headers)
170
+ end
171
+ puts "Done!"
172
+ end
173
+
174
+ end
175
+ end
176
+ end
177
+ end