chupa-text 1.0.8 → 1.0.9

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