master_splitter 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8d7a1e7298a56c92fc9eb2c6fc64fa91527cfae8
4
+ data.tar.gz: be9c96e1c33f54f1f9c8211ab215fddc3bc53ff1
5
+ SHA512:
6
+ metadata.gz: 0626cef0959779687722e3ab970b5f8b3e5e0131454dd2225fa61023c01815f56a2c6e1b432b7561cce17ab14e857d21bd918af88c3e01732d4c77d2104b9e05
7
+ data.tar.gz: 2c7374a0dc4beef073b05c4463c39139477da9008d9833cb91c4551cb10352f7e03c0ac4e04a15f745c461672883d91c989beebacae35dd0e4d1704be2faa8da
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in master_splitter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Pouya Gharib Pour
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # MasterSplitter
2
+
3
+ A simple file splitter and joiner.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'master_splitter'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install master_splitter
20
+
21
+ ## Usage
22
+
23
+ You can use executables 'master_join' and 'master_split'.
24
+ For more imformation just use them with a -h flag.
25
+ You can also include it as a library and use if methods
26
+ directly, like this:
27
+
28
+ ```ruby
29
+ include MasterSplitter
30
+
31
+ standard_split("path/to/file.pdf", 5)
32
+ # splits the file to 5 slices.
33
+
34
+ standard_join("path/to/slice.pdf.001")
35
+ ```
36
+
37
+
38
+ ## Contributing
39
+
40
+ The best way you can contribute now is to teach me a way
41
+ to write specs for file interactions. Or you can help as the following:
42
+
43
+ 1. Fork it ( https://github.com/psparabara/master_splitter/fork )
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/master_join ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'master_splitter'
5
+ include MasterSplitter
6
+
7
+ help = %q{here are the valid flags and switches:
8
+ -f, --first-slice-file Name of the first slice that you want to join. Can't be nil.
9
+ -o, --output-dir The directory you want the final file to be.
10
+ -n, --name-final-file The name you wish for the output file.
11
+ -h, --help You see this help.
12
+ }
13
+ options = {}
14
+ options[:join_options] = {}
15
+ option_parser = OptionParser.new do |opts|
16
+ opts.on("-f FIRST", "--first-slice-file FIRST") do |first|
17
+ options[:first_slice_name] = first
18
+ end
19
+
20
+ opts.on("-o DIRECTORY", "--output-dir DIRECTORY") do |output_dir|
21
+ options[:join_options][:output_dir] = output_dir
22
+ end
23
+
24
+ opts.on("-n NAME", "--name-final-file NAME") do |name|
25
+ options[:join_options][:output_file_name] = name
26
+ end
27
+
28
+ opts.on("-h", "--help") do
29
+ options[:needs_help?] = true
30
+ end
31
+ end
32
+
33
+ option_parser.parse!
34
+ if options[:needs_help?]
35
+ puts help
36
+ else
37
+ standard_joiner(options[:first_slice_name], options[:join_options])
38
+ end
data/bin/master_split ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'master_splitter'
5
+ include MasterSplitter
6
+
7
+ help = %q{here are the valid flags and switches:
8
+ -s, --source-file Name of file you want to split. Can't be nil.
9
+ -n, --number-of-slices Number of the slices you wish the file to be splitted to. Can't be nil.
10
+ -o, --output-dir The directory you want the slices to be.
11
+ -h, --help You see this help.
12
+ }
13
+ options = {}
14
+ options[:split_options] = {}
15
+ option_parser = OptionParser.new do |opts|
16
+ opts.on("-s SOURCE", "--source-file SOURCE") do |source|
17
+ options[:source_file] = source
18
+ end
19
+
20
+ opts.on("-n NUMBER", "--number-of-slices NUMBER") do |number|
21
+ options[:number_of_slices] = number
22
+ end
23
+
24
+ opts.on("-o DIRECTORY", "--output-dir DIRECTORY") do |output_dir|
25
+ options[:split_options][:output_dir] = output_dir
26
+ end
27
+
28
+ opts.on("-h", "--help") do
29
+ options[:needs_help?] = true
30
+ end
31
+ end
32
+
33
+ option_parser.parse!
34
+ if options[:needs_help?]
35
+ puts help
36
+ else
37
+ standard_splitter(options[:source_file], options[:number_of_slices].to_i, options[:split_options])
38
+ end
@@ -0,0 +1,13 @@
1
+ require "master_splitter/version"
2
+ require "master_splitter/constants"
3
+ require "master_splitter/joiner"
4
+ require "master_splitter/splitter"
5
+
6
+ module MasterSplitter
7
+ ##
8
+ # This gem can take file and splite it in to many slices,
9
+ # or join the slices of a splited file.
10
+ #
11
+ # Authour:: Pouya Gharib Pour
12
+ # License:: p.gharibpour@gmail.com
13
+ end
@@ -0,0 +1,5 @@
1
+ module MasterSplitter
2
+ MAX_CHUNK_SIZE = 1024 * 1024
3
+ STANDARD_SLICE_NAMING_FORMAT = /^(.*)\.(\d{3,})$/i
4
+ FILE_NAME_FINDER = /^.*\/(.*)$/i
5
+ end
@@ -0,0 +1,105 @@
1
+ module MasterSplitter
2
+ def custom_joiner(slice_names, options={})
3
+ ##
4
+ # With this method you can join a couple of file
5
+ # which their names does not follow the standard format.
6
+ # You can pass it a name for the output file and a directory
7
+ # to store it.
8
+ # Example:
9
+ # >> custom_joiner(["first.pdf", "second.pdf"],
10
+ # output_file_name: "book.pdf", output_dir: "Desktop/")
11
+ # Arguments:
12
+ # slice_names: (Array)
13
+ # options: (Hash)
14
+ #
15
+ output_dir = options[:output_dir]
16
+ output_file_name = options[:output_file_name]
17
+ slice_names.each do |slice_name|
18
+ unless File.exists? slice_name
19
+ raise Exception, "file '#{slice_name}' does not exist."
20
+ end
21
+ end
22
+
23
+ output_file_name ||= slice_names[0]
24
+ if output_dir
25
+ output_file_name = File.join(output_dir, output_file_name)
26
+ end
27
+ join(output_file_name, slice_names)
28
+ end
29
+
30
+ def standard_joiner(first_slice_name, options={})
31
+ ##
32
+ # This method joins slices of a splitted file which
33
+ # their names follow the standard format.
34
+ # You just have to pass it the name of the first slice.
35
+ # Remember that all slices must be in the same directory.
36
+ # Example:
37
+ # >> standard_joiner("path/to/first_slice.pdf.001",
38
+ # output_file_name: "book.pdf", output_dir: "Desktop/")
39
+ # Arguments:
40
+ # first_slice_name: (String)
41
+ # options: (Hash)
42
+ #
43
+ output_dir = options[:output_dir]
44
+ output_file_name = options[:output_file_name]
45
+ slice_names = []
46
+ match_result = STANDARD_SLICE_NAMING_FORMAT.
47
+ match(first_slice_name)
48
+
49
+ if match_result
50
+ if match_result[1].include?("/") && output_dir
51
+ output_file_name ||= FILE_NAME_FINDER.match(match_result[1])[1]
52
+ else
53
+ output_file_name ||= match_result[1]
54
+ end
55
+ slice_number = match_result[2].to_i
56
+ while true
57
+ temp = ("%3d"%[slice_number]).gsub(" ", "0")
58
+ slice_name = [match_result[1], temp].join('.')
59
+ if File.exists?(slice_name)
60
+ slice_names << slice_name
61
+ slice_number += 1
62
+ else
63
+ break
64
+ end
65
+ end #end of while
66
+
67
+ if output_dir
68
+ output_file_name = File.join(output_dir, output_file_name)
69
+ end
70
+ join(output_file_name, slice_names)
71
+ else
72
+ raise Exception, %q{Wrong naming format for the first slice!}
73
+ end
74
+ end #end of standard_joiner
75
+
76
+ def join(output_file_name, slice_names)
77
+ ##
78
+ # This method does the actual joining of slices.
79
+ # It gets an Array of slice names and name of the
80
+ # output file.
81
+ #
82
+ # Example:
83
+ # >> join("book.pdf", ["book.pdf.001", "book.pdf.002"])
84
+ # Arguments:
85
+ # output_file_name: (String)
86
+ # slice_names: (Array)
87
+ #
88
+ output_file = File.open(output_file_name, 'wb')
89
+
90
+ slice_names.each do |slice_name|
91
+ slice = File.open(slice_name, 'rb')
92
+ bytes_to_read = slice.size
93
+
94
+ while bytes_to_read > 0
95
+ chunk = MAX_CHUNK_SIZE
96
+ chunk = bytes_to_read if (bytes_to_read < MAX_CHUNK_SIZE)
97
+ output_file.write(slice.read(chunk))
98
+ bytes_to_read -= chunk
99
+ end #end of while
100
+ slice.close
101
+ end #end of each
102
+
103
+ output_file.close
104
+ end #end of join
105
+ end #end of module
@@ -0,0 +1,111 @@
1
+ module MasterSplitter
2
+ def custom_splitter(source_file_name, slice_sizes, options={})
3
+ ##
4
+ # With this method you can split a file to slices which
5
+ # you can specify size of each slice.
6
+ # Sum of all slice sizes must be equal to the size of the
7
+ # orginal fille.
8
+ # Needless to say, sizes must be in bytes.
9
+ # Example:
10
+ # >> custom_splitter("file.pdf",
11
+ # [1232, 5432], output_dir: "Desktop/")
12
+ # Arguments:
13
+ # source_file_name: (String)
14
+ # slice_sizes: (Array)
15
+ # options: (Hash)
16
+ #
17
+ slice_names = []
18
+ output_dir = options[:output_dir]
19
+ sum_of_sizes = slice_sizes.each(&:+)
20
+ source = File.open(source_file_name, 'rb')
21
+ if sum_of_sizes != source.size
22
+ source.close
23
+ raise Exception, "sum of slice sizes does not equal size of source file."
24
+ end
25
+ source.close
26
+ slice_sizes.count.times do |i|
27
+ temp = ("%3d"%[i + 1]).gsub(" ", "0")
28
+
29
+ if output_dir
30
+ slice_name = source_file_name
31
+ if source_file_name.include?("/")
32
+ slice_name = FILE_NAME_FINDER.match(source_file_name)[1]
33
+ end
34
+ slice_names << File.join(output_dir, [slice_name, temp].join('.'))
35
+ else
36
+ slice_names << [source_file_name, temp].join('.')
37
+ end
38
+ end #end of iteration
39
+ split(source_file_name, slice_names, slice_sizes)
40
+ end #end of custom_splitter
41
+
42
+ def standard_splitter(source_file_name, number_of_slices, options={})
43
+ ##
44
+ # This method splits a given file to a specified
45
+ # number of slices, equally.
46
+ # Example:
47
+ # >> standard_splitter("file.pdf",
48
+ # number_of_slices: 5,
49
+ # output_dir: "Desktop/")
50
+ # Arguments:
51
+ # source_file_name: (String)
52
+ # number_of_slices: (Fixnum)
53
+ # options: (Hash)
54
+ #
55
+ slice_sizes = []
56
+ slice_names = []
57
+ output_dir = options[:output_dir]
58
+ source = File.open(source_file_name, 'rb')
59
+ source_size = source.size
60
+ slice_size = source_size / number_of_slices
61
+ slice_name = source_file_name
62
+ if source_file_name.include?('/')
63
+ slice_name = FILE_NAME_FINDER.match(source_file_name)[1]
64
+ end
65
+
66
+ number_of_slices.times do |n|
67
+ slice_sizes << slice_size
68
+ temp = ("%3d"%[n + 1]).gsub(" ", "0")
69
+ if output_dir
70
+ slice_names << File.join(output_dir, [slice_name, temp].join('.'))
71
+ else
72
+ slice_names << [source_file_name, temp].join('.')
73
+ end
74
+ end
75
+ remain_bytes = source_size - (slice_size * number_of_slices)
76
+ slice_sizes[-1] += remain_bytes
77
+
78
+ source.close
79
+ split(source_file_name, slice_names, slice_sizes)
80
+ end #end of standard_splitter
81
+
82
+ def split(source_file_name, slice_names, slice_sizes)
83
+ ##
84
+ # This method does the actual splitting of file.
85
+ # It gets the name of the source file and two arrays.
86
+ # One contains names of the slices and the other their sizes.
87
+ # Example:
88
+ # >> split("book.pdf", ["book.pdf.001", "book.pdf.002"], [6456, 6456])
89
+ # Arguments:
90
+ # source_file_name: (String)
91
+ # slice_names: (Array)
92
+ # slice_sizes: (Array)
93
+ #
94
+ source = File.open(source_file_name, 'rb')
95
+
96
+ slice_names.size.times do |i|
97
+ slice = File.open(slice_names[i], 'wb')
98
+ bytes_to_write = slice_sizes[i]
99
+
100
+ while bytes_to_write > 0
101
+ chunk = MAX_CHUNK_SIZE
102
+ chunk = bytes_to_write if(bytes_to_write < MAX_CHUNK_SIZE)
103
+ slice.write(source.read(chunk))
104
+ bytes_to_write -= chunk
105
+ end #end of while
106
+ slice.close
107
+ end #end of iteration
108
+
109
+ source.close
110
+ end #end of split
111
+ end #end of module
@@ -0,0 +1,3 @@
1
+ module MasterSplitter
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'master_splitter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "master_splitter"
8
+ spec.version = MasterSplitter::VERSION
9
+ spec.authors = ["Pouya Gharib Pour"]
10
+ spec.email = ["p.gharibpour@gmail.com"]
11
+ spec.summary = %q{File spliter and joiner.}
12
+ spec.description = %q{Simple file spliter and joiner. But not compressor.}
13
+ spec.homepage = "https://www.github.com/psparabara/master_splitter"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: master_splitter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Pouya Gharib Pour
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Simple file spliter and joiner. But not compressor.
42
+ email:
43
+ - p.gharibpour@gmail.com
44
+ executables:
45
+ - master_join
46
+ - master_split
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".gitignore"
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - bin/master_join
56
+ - bin/master_split
57
+ - lib/master_splitter.rb
58
+ - lib/master_splitter/constants.rb
59
+ - lib/master_splitter/joiner.rb
60
+ - lib/master_splitter/splitter.rb
61
+ - lib/master_splitter/version.rb
62
+ - master_splitter.gemspec
63
+ homepage: https://www.github.com/psparabara/master_splitter
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.4.4
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: File spliter and joiner.
87
+ test_files: []