meta_project 0.4.12 → 0.4.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/CHANGES +283 -277
  2. data/MIT-LICENSE +21 -21
  3. data/README +130 -126
  4. data/Rakefile +152 -152
  5. data/doc/base_attrs.rdoc +2 -2
  6. data/lib/meta_project.rb +11 -11
  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 +31 -31
  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 -46
  20. data/lib/meta_project/project/xforge/session.rb +177 -177
  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 -81
  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 -33
  33. data/lib/meta_project/tracker/issue.rb +56 -56
  34. data/lib/meta_project/tracker/jira.rb +2 -2
  35. data/lib/meta_project/tracker/jira/jira_issues.rb +34 -34
  36. data/lib/meta_project/tracker/jira/jira_tracker.rb +148 -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 -190
  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 +4 -3
@@ -1 +1 @@
1
- require 'meta_project/project/codehaus/codehaus_project_svn'
1
+ require 'meta_project/project/codehaus/codehaus_project_svn'
@@ -1,31 +1,31 @@
1
- module MetaProject
2
- module Project
3
- module Codehaus
4
- class CodehausProjectSvn < Base
5
-
6
- def initialize(unix_name, svn_path, jira_id)
7
- @unix_name = unix_name
8
- @name = unix_name
9
- @scm = RSCM::Subversion.new("svn://svn.#{unix_name}.codehaus.org/#{unix_name}/scm/#{svn_path}", svn_path)
10
- @tracker = ::MetaProject::Tracker::Jira::JiraTracker.new("http://jira.codehaus.org", jira_id)
11
-
12
- dir = "http://svn.#{unix_name}.codehaus.org/#{svn_path}/\#{path}"
13
- history = dir
14
- raw = "#{history}?rev=\#{revision}"
15
- html = "#{raw}&view=markup"
16
- # http://svn.picocontainer.codehaus.org/java/picocontainer/trunk/container/project.xml?r1=2220&r2=2234&p1=java/picocontainer/trunk/container/project.xml&p2=java/picocontainer/trunk/container/project.xml
17
- diff = "#{history}?r1=\#{previous_revision}&r2=\#{revision}&p1=#{svn_path}/\#{path}&p2=#{svn_path}/\#{path}"
18
- child_dirs_pattern = /<a name="([^"]+)" href="([^"]+)">[\r\n\s]+<img src="\/icons\/small\/dir.gif"/
19
- child_files_pattern = /<a href="[^"]+\/([^\?]+)\?rev=([\d]+)&view=auto">/
20
-
21
- @scm_web = ScmWeb::Browser.new(dir, history, raw, html, diff, child_dirs_pattern, child_files_pattern)
22
- end
23
-
24
- def home_page
25
- "http://#{@unix_name}.codehaus.org/"
26
- end
27
-
28
- end
29
- end
30
- end
1
+ module MetaProject
2
+ module Project
3
+ module Codehaus
4
+ class CodehausProjectSvn < Base
5
+
6
+ def initialize(unix_name, svn_path, jira_id)
7
+ @unix_name = unix_name
8
+ @name = unix_name
9
+ @scm = RSCM::Subversion.new("svn://svn.#{unix_name}.codehaus.org/#{unix_name}/scm/#{svn_path}", svn_path)
10
+ @tracker = ::MetaProject::Tracker::Jira::JiraTracker.new("http://jira.codehaus.org", jira_id)
11
+
12
+ dir = "http://svn.#{unix_name}.codehaus.org/#{svn_path}/\#{path}"
13
+ history = dir
14
+ raw = "#{history}?rev=\#{revision}"
15
+ html = "#{raw}&view=markup"
16
+ # http://svn.picocontainer.codehaus.org/java/picocontainer/trunk/container/project.xml?r1=2220&r2=2234&p1=java/picocontainer/trunk/container/project.xml&p2=java/picocontainer/trunk/container/project.xml
17
+ diff = "#{history}?r1=\#{previous_revision}&r2=\#{revision}&p1=#{svn_path}/\#{path}&p2=#{svn_path}/\#{path}"
18
+ child_dirs_pattern = /<a name="([^"]+)" href="([^"]+)">[\r\n\s]+<img src="\/icons\/small\/dir.gif"/
19
+ child_files_pattern = /<a href="[^"]+\/([^\?]+)\?rev=([\d]+)&view=auto">/
20
+
21
+ @scm_web = ScmWeb::Browser.new(dir, history, raw, html, diff, child_dirs_pattern, child_files_pattern)
22
+ end
23
+
24
+ def home_page
25
+ "http://#{@unix_name}.codehaus.org/"
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
31
  end
@@ -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,47 +1,47 @@
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
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
47
47
  end
@@ -1,177 +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
- 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
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