fileconv 0.1.0

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 (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/Gemfile +8 -0
  4. data/Gemfile.lock +22 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +231 -0
  7. data/Rakefile +11 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/example/csv/add_column.rb +14 -0
  11. data/example/csv/add_header.rb +14 -0
  12. data/example/csv/output/test2.txt +4 -0
  13. data/example/csv/test.csv +3 -0
  14. data/example/csv/test2.txt +4 -0
  15. data/example/csv/with_header.rb +26 -0
  16. data/example/data/list_file.rb +24 -0
  17. data/example/data/output/result.txt +3 -0
  18. data/example/data/test.data +3 -0
  19. data/example/file/output/test.data +7 -0
  20. data/example/file/read_bytes.rb +20 -0
  21. data/example/file/test.data +1 -0
  22. data/example/json/address.json +1 -0
  23. data/example/json/modify_json.rb +18 -0
  24. data/example/json/output/address.json +1 -0
  25. data/example/json/pretty_json.rb +11 -0
  26. data/example/line/add_lineno.rb +19 -0
  27. data/example/line/count_lines.rb +14 -0
  28. data/example/line/filter_lines.rb +43 -0
  29. data/example/line/input_files.rb +22 -0
  30. data/example/line/modify_new_line.rb +14 -0
  31. data/example/line/output/test1.txt +5 -0
  32. data/example/line/output/test2.txt +7 -0
  33. data/example/line/output/test3.txt +10 -0
  34. data/example/line/output/test4.txt +5 -0
  35. data/example/line/sort_lines.rb +17 -0
  36. data/example/line/test1.txt +6 -0
  37. data/example/line/test2.txt +7 -0
  38. data/example/line/test3.txt +10 -0
  39. data/example/line/test4.txt +1 -0
  40. data/example/line/uniq_line.rb +32 -0
  41. data/example/meta_convertor/csv2json.rb +53 -0
  42. data/example/meta_convertor/output/test.csv +17 -0
  43. data/example/meta_convertor/test.csv +4 -0
  44. data/fileconv.gemspec +30 -0
  45. data/lib/fileconv/base.rb +212 -0
  46. data/lib/fileconv/csv.rb +39 -0
  47. data/lib/fileconv/data.rb +7 -0
  48. data/lib/fileconv/file.rb +20 -0
  49. data/lib/fileconv/json.rb +26 -0
  50. data/lib/fileconv/line.rb +25 -0
  51. data/lib/fileconv/version.rb +3 -0
  52. data/lib/fileconv.rb +10 -0
  53. metadata +124 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a11710da18bbef2f204f676c21b5827f01c0a84af1aa889353e9ef44de5043d5
4
+ data.tar.gz: c8c62864940a00b078e76c63459646aad1898a544569df233f49bde1d2ec9445
5
+ SHA512:
6
+ metadata.gz: a7ed3cbcd55d7a35fab31ffa3e372ed5a80ae207a50ae1c0076cc78c7007ad2919a19dfa39e5759a49d4bece4bcce035522280cb86bcef8ba0cd7e06eb3d6090
7
+ data.tar.gz: 3da1ed9b8b478a21cce27c4692e72e77010a7628636ec1881a59e4b2f0bf462bff3cbf796095e08c9a33a1db2cf64d2fe0b412a63cd54aaa6cb36e8f645e6f54
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ output/
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fileconv.gemspec
4
+ gemspec
5
+
6
+ group :doc do
7
+ gem 'yard', require: false
8
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fileconv (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ rake (10.5.0)
10
+ yard (0.9.20)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ bundler (~> 2.0)
17
+ fileconv!
18
+ rake (~> 10.0)
19
+ yard
20
+
21
+ BUNDLED WITH
22
+ 2.0.2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 hinastory
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # Fileconv
2
+
3
+ Extensible multi-file convertor. Simple text file, CSV file, JSON file binary file and so on.
4
+
5
+ `fileconv` gem is a simple to use and extensible library to convert multi-file format. You can extend your class with `MetaConvertor` and convert files into various format.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'fileconv'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install fileconv
22
+
23
+ ## Usage
24
+
25
+ You have to do a few things to build a Convertor with `fileconv` gem.
26
+
27
+ - include `MetaConvertor`(e.g. `Fileconv::Line`) into your object,
28
+ - add several hooks(e.g. `input_ext`) if you need.
29
+
30
+ Lets start with a simple example. It will be a convertor for simple text files.
31
+
32
+ ```ruby
33
+ require 'fileconv'
34
+
35
+ class AddLinenoConvertor
36
+ include Fileconv::Line
37
+ def input_ext
38
+ "txt"
39
+ end
40
+
41
+ def init_acc(acc)
42
+ acc[:lineno] = 0
43
+ end
44
+
45
+ def convert_line(line, acc)
46
+ acc[:lineno] += 1
47
+ "#{acc[:lineno]}: #{line}"
48
+ end
49
+ end
50
+
51
+ ```
52
+
53
+ That's it. Now you can use a method `#conv` to convert all text files(`.txt`) from into text files with line number.
54
+
55
+ ```
56
+ convertor = AddLinenoConvertor.new
57
+ covertor.conv
58
+ ```
59
+
60
+ If you have two text(`.txt`) files:
61
+
62
+ `aaa.txt`
63
+ ```
64
+ aaa
65
+ bbb
66
+ ccc
67
+ ```
68
+
69
+ `bbb.txt`
70
+ ```
71
+ 111
72
+ 222
73
+ 333
74
+ ```
75
+
76
+ the convertor convert it into:
77
+
78
+ `output/aaa.txt`
79
+ ```
80
+ 1: aaa
81
+ 2: bbb
82
+ 3: ccc
83
+ ```
84
+
85
+ `output/bbb.txt`
86
+ ```
87
+ 1: 111
88
+ 2: 222
89
+ 3: 333
90
+ ```
91
+
92
+ ### Variables
93
+
94
+ |variable|scope|descripton|
95
+ |---|---|---|
96
+ |acc|file|accumulator for a file|
97
+ |@meta|convertor|meta data for the convertor|
98
+ |@opts|convertor|options for the convertor(`#conv` can receive options.)|
99
+
100
+ ### Convertor Hooks
101
+
102
+ |hook|default|description|
103
+ |---|---|---|
104
+ |input_dir|"."(current directory)|input Directory|
105
+ |input_ext|`nil` (all files)|input extension|
106
+ |output_dir|"output"|output directory|
107
+ |input_files|`nil` (use `input_dir`)|input files(array of file names)|
108
+ |init_conv|`nil`|init convertor hook|
109
+ |init_acc(acc)|`nil`|init accumulator hook|
110
+ |read_file(filename, acc)|`nil` (use default reader)|read file hook|
111
+ |convert_line(line, acc)|`line`|convert line hook|
112
+ |convert_file(file, acc)|`file`|convert file hook|
113
+ |output_filename(filename, acc)|`filename`|output filename|
114
+ |result_filename|"result.txt"|result filename|
115
+ |conv_result|`nil`|conversion result|
116
+
117
+
118
+ ### Default MetaConvertor
119
+
120
+ `fileconv` gem have several default MetaConvertor:
121
+
122
+ |MetaConvertor|mode|description|
123
+ |---|---|---|
124
+ |Line|Line|raw line convertor|
125
+ |CSV|Line|CSV line convertor|
126
+ |Data|File|raw file data convertor|
127
+ |File|File|`File` convertor|
128
+ |JSON|File|JSON convertor|
129
+
130
+ A convertor(includes MetaConvertor) can be divided into two modes.
131
+
132
+ - Line Mode
133
+ - `#convert_line` hooks is called
134
+ - e.g. `Line`, `CSV`
135
+ - File Mode
136
+ - `#convert_line` hooks is not called
137
+ - e.g. `Data`, `File`, `JSON`
138
+
139
+ Let's see a JSON example.
140
+
141
+ ```ruby
142
+ require 'fileconv'
143
+
144
+ class ModifyJSON
145
+ include Fileconv::JSON
146
+
147
+ def input_ext
148
+ "json"
149
+ end
150
+
151
+ def convert_file(data, acc)
152
+ data.map do |e|
153
+ e["country"] = "USA"
154
+ e
155
+ end
156
+ end
157
+ end
158
+
159
+ ModifyJSON.new.conv
160
+ ```
161
+
162
+ original file (`address.json`) :
163
+ ```json
164
+ [{"name": "Mike", "Age": "21"}, {"name": "Jon", "Age": "33"}]
165
+ ```
166
+
167
+ converted file (`output/address.json`) :
168
+ ```json
169
+ [{"name":"Mike","Age":"21","country":"USA"},{"name":"Jon","Age":"33","country":"USA"}]
170
+ ```
171
+
172
+
173
+ ### Make MetaConvertor
174
+
175
+ You can make meta convertor easily.
176
+ `fileconv` gem's JSON MetaConvertor is below:
177
+
178
+ ```ruby
179
+ require "json"
180
+
181
+ module Fileconv
182
+ module JSON
183
+ include Fileconv::Base
184
+
185
+ def pre_init_conv
186
+ @opts[:read_json_opts] ||= {}
187
+ @opts[:write_json_opts] ||= {}
188
+ end
189
+
190
+ def pre_convert_file(data, acc)
191
+ ::JSON.parse(data, @opts[:read_json_opts])
192
+ end
193
+
194
+ def post_convert_file(obj, acc)
195
+ return unless obj
196
+ if @opts[:pretty_json]
197
+ ::JSON.pretty_generate(obj, @opts[:write_json_opts])
198
+ else
199
+ ::JSON.generate(obj, @opts[:write_json_opts])
200
+ end
201
+ end
202
+ end
203
+ end
204
+ ```
205
+
206
+ MetaConvertor can use below hooks:
207
+
208
+ - pre_init_conv
209
+ - post_init_conv
210
+ - pre_init_acc
211
+ - post_init_acc
212
+ - pre_convert_file
213
+ - pre_convert_line
214
+ - post_convert_line
215
+ - post_convert_file
216
+ - pre_conv_result
217
+ - post_conv_result
218
+
219
+ ## Development
220
+
221
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
222
+
223
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
224
+
225
+ ## Contributing
226
+
227
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hinastory/fileconv.
228
+
229
+ ## License
230
+
231
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'yard'
3
+ require 'yard/rake/yardoc_task'
4
+
5
+ task :default => :spec
6
+
7
+ YARD::Rake::YardocTask.new do |t|
8
+ t.files = %w(lib/*.rb lib/**/*.rb)
9
+ t.options = []
10
+ t.options = %w(--debug --verbose) if $trace
11
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "fileconv"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,14 @@
1
+ require 'fileconv'
2
+
3
+ class AddColumn
4
+ include Fileconv::CSV
5
+ def input_ext
6
+ "csv"
7
+ end
8
+
9
+ def convert_line(line, acc)
10
+ line.push "hoge"
11
+ end
12
+ end
13
+
14
+ AddColumn.new.conv
@@ -0,0 +1,14 @@
1
+ require 'fileconv'
2
+
3
+ class AddColumn
4
+ include Fileconv::CSV
5
+ def input_ext
6
+ "csv"
7
+ end
8
+
9
+ def convert_file(data, acc)
10
+ data.unshift ["No", "vehicle", "count"]
11
+ end
12
+ end
13
+
14
+ AddColumn.new.conv
@@ -0,0 +1,4 @@
1
+ Name,Age
2
+ Taro,20
3
+ Hanako,20
4
+ Hideki,20
@@ -0,0 +1,3 @@
1
+ 1,car,122
2
+ 2,bus,459
3
+ 3,bike,dsd
@@ -0,0 +1,4 @@
1
+ Name,Age
2
+ Taro,22
3
+ Hanako,18
4
+ Hideki,6
@@ -0,0 +1,26 @@
1
+ require 'fileconv'
2
+
3
+ class WithHeader
4
+ include Fileconv::CSV
5
+
6
+ def input_ext
7
+ "txt"
8
+ end
9
+
10
+ def init_conv
11
+ opts = @opts[:read_csv_opts]
12
+ opts[:headers] = true
13
+ opts[:return_headers] = true
14
+ opts[:write_headers] = true
15
+ end
16
+
17
+ def convert_line(row, acc)
18
+ unless row.header_row?
19
+ row["Age"] = 20
20
+ end
21
+
22
+ row
23
+ end
24
+ end
25
+
26
+ WithHeader.new.conv
@@ -0,0 +1,24 @@
1
+ require 'fileconv'
2
+
3
+ class ListFile
4
+ include Fileconv::Data
5
+
6
+ def init_conv
7
+ @meta[:files] = []
8
+ @opts[:disable_read_file] = true
9
+ end
10
+
11
+ def convert_file(data, acc)
12
+ stat = File.stat(acc[:orig_filename])
13
+ @meta[:files].push [File.basename(acc[:orig_filename]), stat.size, stat.mtime]
14
+ nil
15
+ end
16
+
17
+ def conv_result
18
+ total_size = @meta[:files].reduce(0){|sum, e| sum + e[1]}
19
+ str = @meta[:files].map{|e| "#{e[0]}: size=#{e[1]}, modified time=#{e[2]}"}.join("\n")
20
+ str << "\ntotal size: #{total_size} bytes"
21
+ end
22
+ end
23
+
24
+ ListFile.new.conv
@@ -0,0 +1,3 @@
1
+ test.data: size=11, modified time=2019-09-07 16:30:29 +0900
2
+ list_file.rb: size=553, modified time=2019-09-07 16:40:01 +0900
3
+ total size: 564 bytes
@@ -0,0 +1,3 @@
1
+ aaa
2
+ bbb
3
+ ccc
@@ -0,0 +1,7 @@
1
+ abcde
2
+ fghij
3
+ klmno
4
+ pqrst
5
+ uvwxy
6
+ z1234
7
+ 56789
@@ -0,0 +1,20 @@
1
+ require 'fileconv'
2
+
3
+ class ReadBytes
4
+ include Fileconv::File
5
+
6
+ def input_ext
7
+ "data"
8
+ end
9
+
10
+ def convert_file(file, acc)
11
+ str = ""
12
+ while data = file.read(5) do
13
+ str << data
14
+ str << "\n"
15
+ end
16
+ str
17
+ end
18
+ end
19
+
20
+ ReadBytes.new.conv
@@ -0,0 +1 @@
1
+ abcdefghijklmnopqrstuvwxyz123456789
@@ -0,0 +1 @@
1
+ [{"name": "Mike", "Age": "21"}, {"name": "Jon", "Age": "33"}]
@@ -0,0 +1,18 @@
1
+ require 'fileconv'
2
+
3
+ class ModifyJSON
4
+ include Fileconv::JSON
5
+
6
+ def input_ext
7
+ "json"
8
+ end
9
+
10
+ def convert_file(data, acc)
11
+ data.map do |e|
12
+ e["country"] = "USA"
13
+ e
14
+ end
15
+ end
16
+ end
17
+
18
+ ModifyJSON.new.conv
@@ -0,0 +1 @@
1
+ [{"name":"Mike","Age":"21","country":"USA"},{"name":"Jon","Age":"33","country":"USA"}]
@@ -0,0 +1,11 @@
1
+ require 'fileconv'
2
+
3
+ class PrettyJSON
4
+ include Fileconv::JSON
5
+
6
+ def input_ext
7
+ "json"
8
+ end
9
+ end
10
+
11
+ PrettyJSON.new.conv(pretty_json: true)
@@ -0,0 +1,19 @@
1
+ require 'fileconv'
2
+
3
+ class AddLineno
4
+ include Fileconv::Line
5
+ def input_ext
6
+ "txt"
7
+ end
8
+
9
+ def init_acc(acc)
10
+ acc[:lineno] = 0
11
+ end
12
+
13
+ def convert_line(line, acc)
14
+ acc[:lineno] += 1
15
+ "#{acc[:lineno]}: #{line}"
16
+ end
17
+ end
18
+
19
+ AddLineno.new.conv
@@ -0,0 +1,14 @@
1
+ require 'fileconv'
2
+
3
+ class CountLine
4
+ include Fileconv::Line
5
+ def input_ext
6
+ "txt"
7
+ end
8
+
9
+ def convert_file(data, acc)
10
+ puts "#{File.basename acc[:orig_filename]}: #{data.size} lines"
11
+ end
12
+ end
13
+
14
+ CountLine.new.conv
@@ -0,0 +1,43 @@
1
+ require 'fileconv'
2
+
3
+ class NumberFilter
4
+ include Fileconv::Line
5
+ def input_ext
6
+ "txt"
7
+ end
8
+
9
+ def init_conv
10
+ @meta[:total] = []
11
+ end
12
+
13
+ def init_acc(acc)
14
+ acc[:number] = 0
15
+ acc[:no_number] = 0
16
+ end
17
+
18
+ def convert_line(line, acc)
19
+ if line =~ /^\d+$/
20
+ acc[:number] += 1
21
+ line
22
+ else
23
+ acc[:no_number] += 1
24
+ nil
25
+ end
26
+ end
27
+
28
+ def convert_file(data, acc)
29
+ if @opts[:debug]
30
+ p acc
31
+ end
32
+ @meta[:total].push [File.basename(acc[:orig_filename]), acc[:number], acc[:no_number]]
33
+ data
34
+ end
35
+
36
+ def conv_result
37
+ @meta[:total].map do |e|
38
+ "filename: #{e[0]}, number: #{e[1]}, no number: #{e[2]}"
39
+ end.join("\n")
40
+ end
41
+ end
42
+
43
+ NumberFilter.new.conv(debug: true)
@@ -0,0 +1,22 @@
1
+ require 'fileconv'
2
+
3
+ class InputFiles
4
+ include Fileconv::Line
5
+ def input_ext
6
+ "txt"
7
+ end
8
+
9
+ def input_files
10
+ ["test1.txt", "test3.txt"]
11
+ end
12
+
13
+ def convert_line(line, acc)
14
+ line + "modify"
15
+ end
16
+
17
+ def output_filename(filename, acc)
18
+ File.basename(filename, ".txt") + "_modified.txt"
19
+ end
20
+ end
21
+
22
+ InputFiles.new.conv
@@ -0,0 +1,14 @@
1
+ require 'fileconv'
2
+
3
+ class ModifyNewLine
4
+ include Fileconv::Line
5
+ def input_ext
6
+ "txt"
7
+ end
8
+
9
+ def init_conv
10
+ @opts[:new_line] = "\r\n"
11
+ end
12
+ end
13
+
14
+ ModifyNewLine.new.conv
@@ -0,0 +1,5 @@
1
+ 111
2
+ aaa
3
+ bbb
4
+ ccc
5
+ ddd
@@ -0,0 +1,7 @@
1
+ 126
2
+ 2323
3
+ aaaa
4
+ aaaa
5
+ ddds
6
+ pppppp
7
+ rrrr
@@ -0,0 +1,10 @@
1
+ 2281
2
+ 6656
3
+ ddd
4
+ ggg
5
+ ggg
6
+ kkk
7
+ sssgg
8
+ sssgg
9
+ sssgg
10
+ ttt
@@ -0,0 +1,5 @@
1
+ 111
2
+ aaa
3
+ bbb
4
+ ccc
5
+ ddd