kenai_tools 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
6
+ require 'optparse'
7
+ require 'highline/import'
8
+ require 'kenai_tools'
9
+
10
+ $terminal = HighLine.new($stdin, $stderr)
11
+
12
+ def fail(message, exit_code = 2)
13
+ $stderr.puts(message)
14
+ exit exit_code
15
+ end
16
+
17
+ def check_project(kc, url, proj_name)
18
+ fail "Unable to find project '#{proj_name}' at #{url}" unless kc.project(proj_name)
19
+ end
20
+
21
+ def to_url(host_or_url)
22
+ host_or_url =~ %r{^http(s?)://} ? host_or_url : "https://#{host_or_url}/"
23
+ end
24
+
25
+ def copy_images(src_client, src_proj, dst_client, dst_proj)
26
+ if on_page = @options[:on_page]
27
+ images = src_client.wiki_images(src_proj, on_page)
28
+ puts "Found #{images.size} source wiki images on page #{on_page}"
29
+ else
30
+ images = src_client.wiki_images(src_proj)
31
+ puts "Found #{images.size} source wiki images"
32
+ end
33
+
34
+ images.each do |image|
35
+ filename = image['filename']
36
+ print "Copying wiki image #{filename}..."
37
+ image_data = src_client.wiki_image_data(image)
38
+ unless @options[:dry_run]
39
+ tries = 0
40
+ begin
41
+ tries += 1
42
+ dst_client.create_or_update_wiki_image(dst_proj, :image_data => image_data,
43
+ :content_type => image['image_content_type'], :filename => filename,
44
+ :comments => image['comments'])
45
+ rescue IOError => ex
46
+ if (tries < 4)
47
+ print " retrying..."
48
+ sleep(2**tries) # Wait for 2, 4, or 8 secs
49
+ retry
50
+ end
51
+ end
52
+ end
53
+ puts "done"
54
+ end
55
+ end
56
+
57
+ def copy_pages(src_client, src_proj, dst_client, dst_proj)
58
+ if on_page = @options[:on_page]
59
+ pages = src_client.wiki_pages(src_proj, on_page)
60
+ puts "Found #{pages.size} source wiki pages on page #{on_page}"
61
+ else
62
+ pages = src_client.wiki_pages(src_proj)
63
+ puts "Found #{pages.size} source wiki pages"
64
+ end
65
+
66
+ pages.each do |page|
67
+ page_name = page['name']
68
+ print "Copying page #{page_name}..."
69
+ contents = src_client.wiki_page(src_proj, page_name)['text']
70
+ unless @options[:dry_run]
71
+ dst_client.edit_wiki_page(dst_proj, page_name) { |s| contents }
72
+ end
73
+ puts "done"
74
+ end
75
+ end
76
+
77
+ def usage
78
+ puts @opts
79
+ exit 1
80
+ end
81
+
82
+ def parse_endpoint_spec(spec, type)
83
+ usage unless spec
84
+ host, project = spec.split(',')
85
+ fail "Bad #{type}_ENDPOINT: PROJECT not specified" unless project
86
+ [host, project]
87
+ end
88
+
89
+ def get_credentials(option, url)
90
+ user, password = nil
91
+ if option[:prompt]
92
+ say "Please enter your login credentials for #{url}"
93
+ user = ask('Username: ')
94
+ password = ask('Password: ') { |q| q.echo = '*' }
95
+ else
96
+ File.open(option[:file]) do |f|
97
+ user, password = f.read.split
98
+ end
99
+ end
100
+ [user, password]
101
+ end
102
+
103
+ def main
104
+ program = File.basename(__FILE__)
105
+ @options = {}
106
+ @opts = OptionParser.new do |opts|
107
+ opts.banner = "Usage: #{program} [options] SRC_ENDPOINT DST_ENDPOINT"
108
+ opts.separator " where ENDPOINT is HOST,PROJECT"
109
+ opts.separator "Note: unix-like OS is recommended as this tool may fail on Windows"
110
+ opts.separator "Examples:"
111
+ opts.separator " #{program} kenai.com,my-project java.net,my-project"
112
+ opts.separator " #{program} --text-only kenai.com,my-project java.net,my-project"
113
+ opts.separator ""
114
+ opts.separator "Specific options:"
115
+
116
+ opts.on("-p", "--password FILE", "Read DST nl-separated username/password from file") do |v|
117
+ @options[:password] = {:prompt => !v, :file => v}
118
+ end
119
+
120
+ opts.on("-s", "--source-password [FILE]", "Prompt or read SRC username/password from file") do |v|
121
+ @options[:source_password] = {:prompt => !v, :file => v}
122
+ end
123
+
124
+ opts.on("--images-only", "Copy images only") do |v|
125
+ @options[:images_only] = v
126
+ end
127
+
128
+ opts.on("--text-only", "Copy text only") do |v|
129
+ @options[:text_only] = v
130
+ end
131
+
132
+ opts.on("-n", "--dry-run", "No writes, dry run only") do |v|
133
+ @options[:dry_run] = v
134
+ end
135
+
136
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
137
+ @options[:verbose] = v
138
+ end
139
+
140
+ opts.on_tail("--on-page API_PAGE", "Copy only text or images on API_PAGE") do |v|
141
+ @options[:on_page] = v
142
+ end
143
+
144
+ opts.on_tail("--version", "Show kenai_tools gem version") do |v|
145
+ puts KenaiTools::VERSION
146
+ exit
147
+ end
148
+
149
+ opts.on_tail("-h", "--help", "Show this message") do
150
+ usage
151
+ end
152
+ end
153
+
154
+ begin
155
+ @opts.parse!
156
+ rescue Exception => ex
157
+ fail ex
158
+ end
159
+
160
+ kc_opts = {}
161
+ kc_opts[:log] = $stderr if @options[:verbose]
162
+
163
+ if @options[:dry_run]
164
+ puts "Dry run, no actual writes will be performed..."
165
+ end
166
+
167
+ src_host, src_proj = parse_endpoint_spec(ARGV.shift, "SRC")
168
+ dst_host, dst_proj = parse_endpoint_spec(ARGV.shift, "DST")
169
+
170
+ unless src_host && src_proj
171
+ usage
172
+ end
173
+ src_url = to_url(src_host)
174
+
175
+ unless dst_host && dst_proj
176
+ usage
177
+ end
178
+ dst_url = to_url(dst_host)
179
+
180
+ dst_client = KenaiTools::KenaiClient.new(dst_url, kc_opts)
181
+ user, password = get_credentials(@options[:password], dst_url)
182
+ result = dst_client.authenticate(user, password)
183
+ fail "Invalid DST_ENDPOINT credentials for #{dst_url}" unless result
184
+ check_project(dst_client, dst_url, dst_proj)
185
+
186
+ src_client = KenaiTools::KenaiClient.new(src_url, kc_opts)
187
+ user, password = get_credentials(@options[:source_password], src_url)
188
+ result = src_client.authenticate(user, password)
189
+ fail "Invalid SRC_ENDPOINT credentials #{src_url}" unless result
190
+ check_project(src_client, src_url, src_proj)
191
+
192
+ unless @options[:dry_run]
193
+ copy_images(src_client, src_proj, dst_client, dst_proj) unless @options[:text_only]
194
+ copy_pages(src_client, src_proj, dst_client, dst_proj) unless @options[:images_only]
195
+ end
196
+ end
197
+
198
+ begin
199
+ main
200
+ rescue SystemExit
201
+ end
@@ -9,8 +9,9 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Edwin Goei", "Project Kenai Team"]
10
10
  s.email = ["edwin.goei@oracle.com"]
11
11
  s.homepage = "http://kenai.com/projects/kenaiapis"
12
- s.summary = %q{Tools for sites hosted on the Kenai platform. Use dlutil to upload and download files.}
13
- s.description = %q{Tools for sites such as java.net that are hosted on the Kenai platform. Use dlutil to upload and download files.}
12
+ s.summary = %q{Tools for sites hosted on the Kenai platform. Use dlutil to manage downloads and wiki-copy to copy wikis.}
13
+ s.description = %q{Tools for sites such as java.net that are hosted on the Kenai platform. Use dlutil to upload and download files.
14
+ Use wiki-copy to copy wiki contents and images from one project to another across sites.}
14
15
  s.post_install_message = %q{
15
16
  ==============================================================================
16
17
 
@@ -40,4 +41,5 @@ OS. For more info, see http://kenai.com/jira/browse/KENAI-2853.
40
41
  s.add_dependency("rest-client", "~> 1.6")
41
42
  s.add_dependency("json", "~> 1.5")
42
43
  s.add_dependency("highline", "~> 1.6")
44
+ s.add_dependency("multipart-post", "~> 1.1")
43
45
  end
@@ -2,6 +2,7 @@ require 'rubygems'
2
2
 
3
3
  require 'rest_client'
4
4
  require 'json'
5
+ require 'net/http/post/multipart'
5
6
 
6
7
  module KenaiTools
7
8
  class KenaiClient
@@ -12,6 +13,7 @@ module KenaiTools
12
13
  attr_reader :host, :user, :password
13
14
 
14
15
  def initialize(host = nil, opts = {})
16
+ RestClient.log = opts[:log] if opts[:log]
15
17
  @host = host || DEFAULT_HOST
16
18
  @opts = opts
17
19
  end
@@ -81,7 +83,9 @@ module KenaiTools
81
83
 
82
84
  # get wiki images for a project
83
85
  def wiki_images(project, on_page = nil)
84
- fetch_all("projects/#{project}/features/wiki/images", 'images', :page => on_page)
86
+ opts = {}
87
+ opts[:page] = on_page if on_page
88
+ fetch_all("projects/#{project}/features/wiki/images", 'images', opts)
85
89
  end
86
90
 
87
91
  # get the wiki raw image data for an image
@@ -89,25 +93,33 @@ module KenaiTools
89
93
  RestClient.get(image['image_url'], :accept => image['image_content_type'])
90
94
  end
91
95
 
92
- # hash has the following keys
93
- # +:uploaded_data+ = raw image data, required only if creating a new image
96
+ # opts has the following keys
97
+ # +:image_data+ = raw image data, required only if creating a new image
98
+ # +:content_type+ = image_data content-type
99
+ # +:filename+ = filename for multipart
100
+ #
94
101
  # +:comments+ = optional comments for the image
95
102
  # throws IOError unless create or update was successful
96
- def create_or_update_wiki_image(proj_name, image_filename, hash)
103
+ def create_or_update_wiki_image(proj_name, opts)
97
104
  req_params = {}
98
- if data = hash[:uploaded_data]
99
- upload_io = UploadIO.new(StringIO.new(data), "image/png", image_filename)
100
- req_params["image[uploaded_data]"] = upload_io
105
+ if data = opts[:image_data]
106
+ content_type = opts[:content_type]
107
+ filename = opts[:filename]
108
+ req_params["image[uploaded_data]"] = UploadIO.new(StringIO.new(data), content_type, filename)
101
109
  end
102
- if comments = hash[:comments]
110
+ if comments = opts[:comments]
103
111
  req_params["image[comments]"] = comments
104
112
  end
105
113
  return false if req_params.empty?
114
+
115
+ self["projects/#{proj_name}/features/wiki/images/#{filename}"].put(req_params)
106
116
  end
107
117
 
108
118
  # get wiki pages for a project
109
119
  def wiki_pages(project, on_page = nil)
110
- fetch_all("projects/#{project}/features/wiki/pages", 'pages', :page => on_page)
120
+ opts = {}
121
+ opts[:page] = on_page if on_page
122
+ fetch_all("projects/#{project}/features/wiki/pages", 'pages', opts)
111
123
  end
112
124
 
113
125
  def wiki_page(proj_name, page_name)
@@ -1,3 +1,3 @@
1
1
  module KenaiTools
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
metadata CHANGED
@@ -1,97 +1,147 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: kenai_tools
3
- version: !ruby/object:Gem::Version
4
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
5
  prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 1
10
+ version: 1.0.1
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Edwin Goei
9
14
  - Project Kenai Team
10
15
  autorequire:
11
16
  bindir: bin
12
17
  cert_chain: []
13
- date: 2012-03-22 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
18
+
19
+ date: 2012-05-15 00:00:00 -07:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
16
23
  name: rspec
17
- requirement: &2152634940 !ruby/object:Gem::Requirement
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
18
26
  none: false
19
- requirements:
27
+ requirements:
20
28
  - - ~>
21
- - !ruby/object:Gem::Version
22
- version: '2.5'
29
+ - !ruby/object:Gem::Version
30
+ hash: 9
31
+ segments:
32
+ - 2
33
+ - 5
34
+ version: "2.5"
23
35
  type: :development
24
- prerelease: false
25
- version_requirements: *2152634940
26
- - !ruby/object:Gem::Dependency
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
27
38
  name: bundler
28
- requirement: &2152634380 !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
29
41
  none: false
30
- requirements:
42
+ requirements:
31
43
  - - ~>
32
- - !ruby/object:Gem::Version
33
- version: '1.0'
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 1
48
+ - 0
49
+ version: "1.0"
34
50
  type: :development
35
- prerelease: false
36
- version_requirements: *2152634380
37
- - !ruby/object:Gem::Dependency
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
38
53
  name: gemcutter
39
- requirement: &2152633980 !ruby/object:Gem::Requirement
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
40
56
  none: false
41
- requirements:
42
- - - ! '>='
43
- - !ruby/object:Gem::Version
44
- version: '0'
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
45
64
  type: :development
46
- prerelease: false
47
- version_requirements: *2152633980
48
- - !ruby/object:Gem::Dependency
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
49
67
  name: rest-client
50
- requirement: &2152633340 !ruby/object:Gem::Requirement
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
51
70
  none: false
52
- requirements:
71
+ requirements:
53
72
  - - ~>
54
- - !ruby/object:Gem::Version
55
- version: '1.6'
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 1
77
+ - 6
78
+ version: "1.6"
56
79
  type: :runtime
57
- prerelease: false
58
- version_requirements: *2152633340
59
- - !ruby/object:Gem::Dependency
80
+ version_requirements: *id004
81
+ - !ruby/object:Gem::Dependency
60
82
  name: json
61
- requirement: &2152632760 !ruby/object:Gem::Requirement
83
+ prerelease: false
84
+ requirement: &id005 !ruby/object:Gem::Requirement
62
85
  none: false
63
- requirements:
86
+ requirements:
64
87
  - - ~>
65
- - !ruby/object:Gem::Version
66
- version: '1.5'
88
+ - !ruby/object:Gem::Version
89
+ hash: 5
90
+ segments:
91
+ - 1
92
+ - 5
93
+ version: "1.5"
67
94
  type: :runtime
68
- prerelease: false
69
- version_requirements: *2152632760
70
- - !ruby/object:Gem::Dependency
95
+ version_requirements: *id005
96
+ - !ruby/object:Gem::Dependency
71
97
  name: highline
72
- requirement: &2152632280 !ruby/object:Gem::Requirement
98
+ prerelease: false
99
+ requirement: &id006 !ruby/object:Gem::Requirement
73
100
  none: false
74
- requirements:
101
+ requirements:
75
102
  - - ~>
76
- - !ruby/object:Gem::Version
77
- version: '1.6'
103
+ - !ruby/object:Gem::Version
104
+ hash: 3
105
+ segments:
106
+ - 1
107
+ - 6
108
+ version: "1.6"
78
109
  type: :runtime
110
+ version_requirements: *id006
111
+ - !ruby/object:Gem::Dependency
112
+ name: multipart-post
79
113
  prerelease: false
80
- version_requirements: *2152632280
81
- description: Tools for sites such as java.net that are hosted on the Kenai platform.
82
- Use dlutil to upload and download files.
83
- email:
114
+ requirement: &id007 !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ~>
118
+ - !ruby/object:Gem::Version
119
+ hash: 13
120
+ segments:
121
+ - 1
122
+ - 1
123
+ version: "1.1"
124
+ type: :runtime
125
+ version_requirements: *id007
126
+ description: |-
127
+ Tools for sites such as java.net that are hosted on the Kenai platform. Use dlutil to upload and download files.
128
+ Use wiki-copy to copy wiki contents and images from one project to another across sites.
129
+ email:
84
130
  - edwin.goei@oracle.com
85
- executables:
131
+ executables:
86
132
  - dlutil
133
+ - wiki-copy
87
134
  extensions: []
135
+
88
136
  extra_rdoc_files: []
89
- files:
137
+
138
+ files:
90
139
  - .gitignore
91
140
  - Gemfile
92
141
  - README.md
93
142
  - Rakefile
94
143
  - bin/dlutil
144
+ - bin/wiki-copy
95
145
  - kenai_tools.gemspec
96
146
  - lib/kenai_tools.rb
97
147
  - lib/kenai_tools/downloads_client.rb
@@ -115,35 +165,55 @@ files:
115
165
  - spec/fixtures/data/sax2r2.jar
116
166
  - spec/fixtures/data/text1.txt
117
167
  - spec/spec_helper.rb
168
+ has_rdoc: true
118
169
  homepage: http://kenai.com/projects/kenaiapis
119
170
  licenses: []
120
- post_install_message: ! "\n==============================================================================\n\nThanks
121
- for installing kenai_tools. Run the following command for what to do\nnext:\n\n
122
- \ dlutil --help\n\nWarning: this tool is not yet supported on Windows. Please use
123
- a unix-based\nOS. For more info, see http://kenai.com/jira/browse/KENAI-2853.\n\n==============================================================================\n\n\n"
171
+
172
+ post_install_message: |+
173
+
174
+ ==============================================================================
175
+
176
+ Thanks for installing kenai_tools. Run the following command for what to do
177
+ next:
178
+
179
+ dlutil --help
180
+
181
+ Warning: this tool is not yet supported on Windows. Please use a unix-based
182
+ OS. For more info, see http://kenai.com/jira/browse/KENAI-2853.
183
+
184
+ ==============================================================================
185
+
186
+
124
187
  rdoc_options: []
125
- require_paths:
188
+
189
+ require_paths:
126
190
  - lib
127
- required_ruby_version: !ruby/object:Gem::Requirement
191
+ required_ruby_version: !ruby/object:Gem::Requirement
128
192
  none: false
129
- requirements:
130
- - - ! '>='
131
- - !ruby/object:Gem::Version
132
- version: '0'
133
- required_rubygems_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ hash: 3
197
+ segments:
198
+ - 0
199
+ version: "0"
200
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
201
  none: false
135
- requirements:
136
- - - ! '>='
137
- - !ruby/object:Gem::Version
138
- version: '0'
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ hash: 3
206
+ segments:
207
+ - 0
208
+ version: "0"
139
209
  requirements: []
210
+
140
211
  rubyforge_project: kenai_tools
141
- rubygems_version: 1.8.17
212
+ rubygems_version: 1.6.2
142
213
  signing_key:
143
214
  specification_version: 3
144
- summary: Tools for sites hosted on the Kenai platform. Use dlutil to upload and download
145
- files.
146
- test_files:
215
+ summary: Tools for sites hosted on the Kenai platform. Use dlutil to manage downloads and wiki-copy to copy wikis.
216
+ test_files:
147
217
  - spec/downloads_client_spec.rb
148
218
  - spec/fixtures/data/irs_docs/irs-form-1040.pdf
149
219
  - spec/fixtures/data/irs_docs/irs-p555.pdf