kenai_tools 1.0.0 → 1.0.1

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