chupa-text 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 996c7628251b6467736c48363ff31cf3b2eedb8a
4
- data.tar.gz: 53a0af15b4e03a8f59747bdbc30ff49209bdd796
3
+ metadata.gz: 683591985ea7d93bfde2dc2643964120d18c6a04
4
+ data.tar.gz: e0b1419f2d3a020d4036afbeb56c4b1366b8e4d8
5
5
  SHA512:
6
- metadata.gz: e62ddb8fac42f82f1dea609b18fee3102ce4019a1e93d04dccc72505a14f5a2fb0b722a210cffb67a0cfa3857ae2af480137cd21ddb3624accf5ce9349e9a13f
7
- data.tar.gz: 20496a45e2bee52e16d081a4fbdd3d41dd477183e82bd086a945ffc61ea955ece66d0a3e6094b324070315af3dd34375898bd9450e7bb801195b52a645ff9e7d
6
+ metadata.gz: c9b33ecfc733c19827d0ce2a8484f7cd4a128a1435616dae03bf42707b11e8c99bd3402b885fa2af073424a87e786220008f8bf5c02912aaad5874a1f9a5add4
7
+ data.tar.gz: 85f8df4be72276db69c8938120c9ccd99bbf424493cf69f8b2357cb5e81053da9fcc35c386c3d1816ad53ea39d3de478ee9606e49783e2ed9b74631296cc413a
@@ -50,6 +50,8 @@ Gem::Specification.new do |spec|
50
50
  spec.executables = Dir.glob("*")
51
51
  end
52
52
 
53
+ spec.add_runtime_dependency("archive-zip")
54
+
53
55
  spec.add_development_dependency("bundler")
54
56
  spec.add_development_dependency("rake")
55
57
  spec.add_development_dependency("test-unit")
@@ -7,6 +7,8 @@ mime_types["tgz"] = "application/x-gtar-compressed"
7
7
 
8
8
  mime_types["tar"] = "application/x-tar"
9
9
 
10
+ mime_types["zip"] = "application/zip"
11
+
10
12
  mime_types["htm"] = "text/html"
11
13
  mime_types["html"] = "text/html"
12
14
  mime_types["xhtml"] = "application/xhtml+xml"
@@ -1,5 +1,21 @@
1
1
  # News
2
2
 
3
+ ## 1.0.9: 2017-07-11
4
+
5
+ ### Improvements
6
+
7
+ * `ChupaText::TextData`: Changed extension to ".txt".
8
+
9
+ * `chupa-text`: Added `--uri` option.
10
+
11
+ * `chupa-text`: Added `--mime-type` option.
12
+
13
+ * `ChupaText::DownloadError`: Added.
14
+
15
+ * Supported zip.
16
+
17
+ * `ChupaText::ExternalCommand#path`: Added.
18
+
3
19
  ## 1.0.8: 2017-07-10
4
20
 
5
21
  ### Improvements
@@ -43,6 +43,8 @@ module ChupaText
43
43
  @input = nil
44
44
  @configuration = Configuration.load_default
45
45
  @enable_gems = true
46
+ @uri = nil
47
+ @mime_type = nil
46
48
  @format = :json
47
49
  @need_screenshot = true
48
50
  @expected_screenshot_size = [200, 200]
@@ -106,6 +108,17 @@ module ChupaText
106
108
  $LOAD_PATH << path
107
109
  end
108
110
 
111
+ parser.separator("")
112
+ parser.separator("Input related options")
113
+ parser.on("--uri=URI",
114
+ "Input data URI.") do |uri|
115
+ @uri = URI.parse(uri)
116
+ end
117
+ parser.on("--mime-type=MIME_TYPE",
118
+ "Input data MIME type.") do |mime_type|
119
+ @mime_type = mime_type
120
+ end
121
+
109
122
  parser.separator("")
110
123
  parser.separator("Output related options")
111
124
  parser.on("--format=FORMAT", AVAILABLE_FORMATS,
@@ -178,7 +191,7 @@ module ChupaText
178
191
 
179
192
  def create_data
180
193
  if @input.nil?
181
- data = VirtualFileData.new(nil, $stdin)
194
+ data = VirtualFileData.new(@uri, $stdin)
182
195
  else
183
196
  case @input
184
197
  when /\A[a-z]+:\/\//i
@@ -186,8 +199,15 @@ module ChupaText
186
199
  else
187
200
  input = Pathname(@input)
188
201
  end
189
- data = InputData.new(input)
202
+ if @uri
203
+ input.open("rb") do |io|
204
+ data = VirtualFileData.new(@uri, io)
205
+ end
206
+ else
207
+ data = InputData.new(input)
208
+ end
190
209
  end
210
+ data.mime_type = @mime_type if @mime_type
191
211
  data.need_screenshot = @need_screenshot
192
212
  data.expected_screenshot_size = @expected_screenshot_size
193
213
  data
@@ -31,8 +31,13 @@ module ChupaText
31
31
  Gem::Package::TarReader.new(StringIO.new(data.body)) do |reader|
32
32
  reader.each do |entry|
33
33
  next unless entry.file?
34
+
34
35
  entry.extend(CopyStreamable)
35
- extracted = VirtualFileData.new(entry.full_name, entry,
36
+ entry_uri = data.uri.dup
37
+ base_path = entry_uri.path.gsub(/\.tar\z/i, "")
38
+ entry_uri.path = "#{base_path}/#{entry.full_name}"
39
+ extracted = VirtualFileData.new(entry_uri,
40
+ entry,
36
41
  :source_data => data)
37
42
  yield(extracted)
38
43
  end
@@ -0,0 +1,58 @@
1
+ # Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ require "stringio"
18
+ require "tmpdir"
19
+
20
+ require "archive/zip"
21
+
22
+ module ChupaText
23
+ module Decomposers
24
+ class Zip < Decomposer
25
+ registry.register("zip", self)
26
+
27
+ def target?(data)
28
+ return true if data.extension == "zip"
29
+ return true if data.mime_type == "application/zip"
30
+
31
+ false
32
+ end
33
+
34
+ def decompose(data)
35
+ Archive::Zip.open(StringIO.new(data.body)) do |zip|
36
+ zip.each do |entry|
37
+ next unless entry.file?
38
+
39
+ case entry.encryption_codec
40
+ when Archive::Zip::Codec::NullEncryption
41
+ else
42
+ # TODO
43
+ # entry.password = ...
44
+ raise EncryptedError.new(data)
45
+ end
46
+ entry_uri = data.uri.dup
47
+ base_path = entry_uri.path.gsub(/\.zip\z/i, "")
48
+ entry_uri.path = "#{base_path}/#{entry.zip_path}"
49
+ entry_data = VirtualFileData.new(entry_uri,
50
+ entry.file_data,
51
+ source_data: data)
52
+ yield(entry_data)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -18,6 +18,16 @@ module ChupaText
18
18
  class Error < StandardError
19
19
  end
20
20
 
21
+ class DownloadError < Error
22
+ attr_reader :uri
23
+ attr_reader :reason
24
+ def initialize(uri, reason)
25
+ @uri = uri
26
+ @reason = reason
27
+ super("Download error: <#{uri}>: #{reason}")
28
+ end
29
+ end
30
+
21
31
  class EncryptedError < Error
22
32
  attr_reader :data
23
33
  def initialize(data)
@@ -20,8 +20,9 @@ require "pathname"
20
20
 
21
21
  module ChupaText
22
22
  class ExternalCommand
23
- def initialize(command)
24
- @command = Pathname.new(command)
23
+ attr_reader :path
24
+ def initialize(path)
25
+ @path = Pathname.new(path)
25
26
  end
26
27
 
27
28
  def run(*arguments)
@@ -32,19 +33,19 @@ module ChupaText
32
33
  end
33
34
  spawn_options = options[:spawn_options] || {}
34
35
  pid = spawn(options[:env] || {},
35
- @command.to_s,
36
+ @path.to_s,
36
37
  *arguments,
37
- spawn_options.merge(default_spawn_options))
38
+ default_spawn_options.merge(spawn_options))
38
39
  pid, status = Process.waitpid2(pid)
39
40
  status.success?
40
41
  end
41
42
 
42
43
  def exist?
43
- if @command.absolute?
44
- @command.file? and @command.executable?
44
+ if @path.absolute?
45
+ @path.file? and @path.executable?
45
46
  else
46
47
  (ENV['PATH'] || "").split(File::PATH_SEPARATOR).any? do |path|
47
- (Pathname.new(path) + @command).expand_path.exist?
48
+ (Pathname.new(path) + @path).expand_path.exist?
48
49
  end
49
50
  end
50
51
  end
@@ -47,9 +47,13 @@ module ChupaText
47
47
  def download
48
48
  path = @uri.path
49
49
  path += "index.html" if path.end_with?("/")
50
- @uri.open("rb") do |input|
51
- self.mime_type = input.content_type.split(/;/).first
52
- VirtualContent.new(input, path)
50
+ begin
51
+ @uri.open("rb") do |input|
52
+ self.mime_type = input.content_type.split(/;/).first
53
+ VirtualContent.new(input, path)
54
+ end
55
+ rescue OpenURI::HTTPError => error
56
+ raise DownloadError.new(@uri, error.message.strip)
53
57
  end
54
58
  end
55
59
  end
@@ -18,6 +18,8 @@ module ChupaText
18
18
  class TextData < Data
19
19
  def initialize(text, options={})
20
20
  super(options)
21
+ self.uri = uri.to_s.gsub(/\.[^.]+\z/, ".txt")
22
+ self.path = path.to_s.gsub(/\.[^.]+\z/, ".txt")
21
23
  self.mime_type = "text/plain"
22
24
  self.body = text
23
25
  self.size = text.bytesize
@@ -15,5 +15,5 @@
15
15
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
  module ChupaText
18
- VERSION = "1.0.8"
18
+ VERSION = "1.0.9"
19
19
  end
@@ -116,7 +116,7 @@ class TestCommandChupaText < Test::Unit::TestCase
116
116
  @www_server_thread.kill
117
117
  end
118
118
 
119
- def test_single
119
+ test("default") do
120
120
  @html = "<html><body>Hello</body></html>"
121
121
  assert_equal([
122
122
  true,
@@ -136,10 +136,53 @@ class TestCommandChupaText < Test::Unit::TestCase
136
136
  ],
137
137
  run_command(@uri))
138
138
  end
139
+
140
+ test("--uri") do
141
+ virtual_uri = "http://127.0.0.1/hello.html"
142
+ @html = "<html><body>Hello</body></html>"
143
+ assert_equal([
144
+ true,
145
+ {
146
+ "mime-type" => "text/html",
147
+ "size" => @html.bytesize,
148
+ "uri" => virtual_uri,
149
+ "texts" => [
150
+ {
151
+ "mime-type" => "text/html",
152
+ "size" => @html.bytesize,
153
+ "uri" => virtual_uri,
154
+ "body" => @html,
155
+ },
156
+ ],
157
+ },
158
+ ],
159
+ run_command(@uri, "--uri", virtual_uri))
160
+ end
161
+
162
+ test("--mime-type") do
163
+ @html = "<html><body>Hello</body></html>"
164
+ assert_equal([
165
+ true,
166
+ {
167
+ "mime-type" => "text/plain",
168
+ "size" => @html.bytesize,
169
+ "uri" => @uri,
170
+ "texts" => [
171
+ {
172
+ "mime-type" => "text/plain",
173
+ "size" => @html.bytesize,
174
+ "uri" => @uri,
175
+ "body" => @html,
176
+ },
177
+ ],
178
+ },
179
+ ],
180
+ run_command(@uri, "--mime-type", "text/plain"))
181
+ end
139
182
  end
140
183
 
141
184
  sub_test_case("standard input") do
142
- def test_single
185
+ test("default") do
143
186
  body = "Hello\n"
144
187
  @stdin << "Hello\n"
145
188
  @stdin.rewind
@@ -159,6 +202,51 @@ class TestCommandChupaText < Test::Unit::TestCase
159
202
  ],
160
203
  run_command)
161
204
  end
205
+
206
+ test("--uri") do
207
+ body = "Hello\n"
208
+ uri = "http://127.0.0.1/hello.txt"
209
+ @stdin << "Hello\n"
210
+ @stdin.rewind
211
+ assert_equal([
212
+ true,
213
+ {
214
+ "mime-type" => "text/plain",
215
+ "size" => body.bytesize,
216
+ "uri" => uri,
217
+ "texts" => [
218
+ {
219
+ "mime-type" => "text/plain",
220
+ "size" => body.bytesize,
221
+ "body" => body,
222
+ "uri" => uri,
223
+ },
224
+ ],
225
+ },
226
+ ],
227
+ run_command("--uri", "http://127.0.0.1/hello.txt"))
228
+ end
229
+
230
+ test("--mime-type") do
231
+ body = "Hello\n"
232
+ @stdin << "Hello\n"
233
+ @stdin.rewind
234
+ assert_equal([
235
+ true,
236
+ {
237
+ "mime-type" => "text/html",
238
+ "size" => body.bytesize,
239
+ "texts" => [
240
+ {
241
+ "mime-type" => "text/html",
242
+ "size" => body.bytesize,
243
+ "body" => body,
244
+ },
245
+ ],
246
+ },
247
+ ],
248
+ run_command("--mime-type", "text/html"))
249
+ end
162
250
  end
163
251
  end
164
252
 
@@ -197,8 +285,8 @@ class TestCommandChupaText < Test::Unit::TestCase
197
285
  "size" => path.stat.size,
198
286
  "texts" => [
199
287
  {
200
- "uri" => uri.to_s,
201
- "path" => path.to_s,
288
+ "uri" => uri.to_s.gsub(/\.csv\z/, ".txt"),
289
+ "path" => path.sub_ext(".txt").to_s,
202
290
  "mime-type" => "text/plain",
203
291
  "source-mime-types" => ["text/csv"],
204
292
  "body" => "1 2 3\n4 5 6\n7 8 9\n",
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -40,38 +40,34 @@ class TestDecomposersTar < Test::Unit::TestCase
40
40
  end
41
41
 
42
42
  sub_test_case("top-level") do
43
- def setup
44
- super
45
- @data = ChupaText::InputData.new(fixture_path("top-level.tar"))
46
- end
47
-
48
43
  def test_decompose
44
+ data_path = Pathname.new(fixture_path("top-level.tar"))
45
+ base_path = data_path.sub_ext("")
46
+ data = ChupaText::InputData.new(data_path)
49
47
  assert_equal([
50
48
  {
51
- :uri => "top-level.txt",
49
+ :uri => "file:#{base_path}/top-level.txt",
52
50
  :body => "top level\n",
53
- :source => @data.uri.to_s,
51
+ :source => data.uri.to_s,
54
52
  },
55
53
  ],
56
- decompose(@data))
54
+ decompose(data))
57
55
  end
58
56
  end
59
57
 
60
58
  sub_test_case("directory") do
61
- def setup
62
- super
63
- @data = ChupaText::InputData.new(fixture_path("directory.tar"))
64
- end
65
-
66
59
  def test_decompose
60
+ data_path = Pathname.new(fixture_path("directory.tar"))
61
+ base_path = data_path.sub_ext("")
62
+ data = ChupaText::InputData.new(data_path)
67
63
  assert_equal([
68
64
  {
69
- :uri => "directory/hello.txt",
65
+ :uri => "file:#{base_path}/directory/hello.txt",
70
66
  :body => "Hello in directory\n",
71
- :source => @data.uri.to_s,
67
+ :source => data.uri.to_s,
72
68
  },
73
69
  ],
74
- decompose(@data))
70
+ decompose(data))
75
71
  end
76
72
  end
77
73
  end
@@ -0,0 +1,100 @@
1
+ # Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ class TestDecomposersZip < Test::Unit::TestCase
18
+ include Helper
19
+
20
+ def setup
21
+ @decomposer = ChupaText::Decomposers::Zip.new({})
22
+ end
23
+
24
+ private
25
+ def fixture_path(*components)
26
+ super("zip", *components)
27
+ end
28
+
29
+ sub_test_case("decompose") do
30
+ def decompose(data_path)
31
+ data = ChupaText::InputData.new(data_path)
32
+ decomposed = []
33
+ @decomposer.decompose(data) do |decomposed_data|
34
+ decomposed << {
35
+ :uri => decomposed_data.uri.to_s,
36
+ :body => decomposed_data.body,
37
+ :source => decomposed_data.source.uri.to_s,
38
+ }
39
+ end
40
+ decomposed
41
+ end
42
+
43
+ test("multiple") do
44
+ data_path = Pathname.new(fixture_path("hello.zip"))
45
+ base_path = data_path.sub_ext("")
46
+ assert_equal([
47
+ {
48
+ :uri => "file:#{base_path}/hello.txt",
49
+ :body => "Hello!\n",
50
+ :source => "file:#{data_path}",
51
+ },
52
+ {
53
+ :uri => "file:#{base_path}/hello.csv",
54
+ :body => "Hello,World\n",
55
+ :source => "file:#{data_path}",
56
+ },
57
+ {
58
+ :uri => "file:#{base_path}/hello/world.txt",
59
+ :body => "World!\n",
60
+ :source => "file:#{data_path}",
61
+ },
62
+ ],
63
+ decompose(data_path))
64
+ end
65
+
66
+ sub_test_case("encrypted") do
67
+ test("without password") do
68
+ data_path = Pathname.new(fixture_path("password.zip"))
69
+ data = ChupaText::InputData.new(data_path)
70
+ assert_raise(ChupaText::EncryptedError.new(data)) do
71
+ @decomposer.decompose(data)
72
+ end
73
+ end
74
+
75
+ test("with password") do
76
+ omit("password is 'password'")
77
+ data_path = Pathname.new(fixture_path("password.zip"))
78
+ base_path = data_path.sub_ext("")
79
+ assert_equal([
80
+ {
81
+ :uri => "file:#{base_path}/hello.txt",
82
+ :body => "Hello!\n",
83
+ :source => "file:#{data_path}",
84
+ },
85
+ {
86
+ :uri => "file:#{base_path}/hello.csv",
87
+ :body => "Hello,World\n",
88
+ :source => "file:#{data_path}",
89
+ },
90
+ {
91
+ :uri => "file:#{base_path}/hello/world.txt",
92
+ :body => "World!\n",
93
+ :source => "file:#{data_path}",
94
+ },
95
+ ],
96
+ decompose(data_path))
97
+ end
98
+ end
99
+ end
100
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chupa-text
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kouhei Sutou
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-10 00:00:00.000000000 Z
11
+ date: 2017-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: archive-zip
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -118,6 +132,7 @@ files:
118
132
  - lib/chupa-text/decomposers/gzip.rb
119
133
  - lib/chupa-text/decomposers/tar.rb
120
134
  - lib/chupa-text/decomposers/xml.rb
135
+ - lib/chupa-text/decomposers/zip.rb
121
136
  - lib/chupa-text/default-logger.rb
122
137
  - lib/chupa-text/error.rb
123
138
  - lib/chupa-text/external-command.rb
@@ -143,6 +158,7 @@ files:
143
158
  - test/decomposers/test-gzip.rb
144
159
  - test/decomposers/test-tar.rb
145
160
  - test/decomposers/test-xml.rb
161
+ - test/decomposers/test-zip.rb
146
162
  - test/fixture/command/chupa-text/hello.txt
147
163
  - test/fixture/command/chupa-text/hello.txt.gz
148
164
  - test/fixture/command/chupa-text/no-decomposer.conf
@@ -153,6 +169,8 @@ files:
153
169
  - test/fixture/gzip/hello.txt.gz
154
170
  - test/fixture/tar/directory.tar
155
171
  - test/fixture/tar/top-level.tar
172
+ - test/fixture/zip/hello.zip
173
+ - test/fixture/zip/password.zip
156
174
  - test/helper.rb
157
175
  - test/run-test.rb
158
176
  - test/test-attributes.rb