fileconv 0.1.0

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