meta_project 0.4.12 → 0.4.13

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 (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