archiver 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.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.3-head@archiver --create
data/.travis.yml ADDED
@@ -0,0 +1,2 @@
1
+ rvm:
2
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # Created by Thomas Boerger on 2012-03-16.
2
+ # Copyright (c) 2012. All rights reserved.
3
+
4
+ source 'http://rubygems.org'
5
+ gem 'thor', '~> 0.14.6'
6
+ gem 'exifr', '~> 1.1.2'
7
+ gem 'progressbar', '~> 0.10.0'
8
+
9
+ group :development do
10
+ gem 'redcarpet', '~> 2.1.0'
11
+ gem 'yard', '~> 0.7.5'
12
+ gem 'jeweler', '~> 1.8.3'
13
+ end
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Thomas Boerger <tboerger@tbpro.de>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # Archiver [![Build Status](https://secure.travis-ci.org/tbpro/archiver.png)](https://secure.travis-ci.org/tbpro/archiver.png)
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ # Created by Thomas Boerger on 2012-03-16.
2
+ # Copyright (c) 2012. All rights reserved.
3
+
4
+ require 'rubygems'
5
+ require 'bundler'
6
+
7
+ begin
8
+ Bundler.setup(:default, :development)
9
+ rescue Bundler::BundlerError => e
10
+ $stderr.puts e.message
11
+ $stderr.puts 'Run `bundle install` to install missing gems'
12
+
13
+ exit e.status_code
14
+ end
15
+
16
+ require 'rake'
17
+ require 'jeweler'
18
+ require 'yard'
19
+
20
+ $:.push File.expand_path('../lib', __FILE__)
21
+ require 'archiver'
22
+
23
+ Jeweler::Tasks.new do |gem|
24
+ gem.name = 'archiver'
25
+ gem.version = Archiver::Version::STRING
26
+ gem.homepage = 'https://github.com/tbpro/archiver'
27
+ gem.license = 'MIT'
28
+ gem.summary = %Q{Archiver is a simple gem to rename photos and videos}
29
+ gem.description = %Q{Archiver is a simple gem to rename photos and videos depending on creation date and exif informations and it sorts out duplicate files}
30
+ gem.email = 'tboerger@tbpro.de'
31
+ gem.authors = ['Thomas Boerger']
32
+ end
33
+
34
+ Jeweler::RubygemsDotOrgTasks.new
35
+ YARD::Rake::YardocTask.new
36
+
37
+ task :default => :version
data/archiver.gemspec ADDED
@@ -0,0 +1,73 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "archiver"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Thomas Boerger"]
12
+ s.date = "2012-03-18"
13
+ s.description = "Archiver is a simple gem to rename photos and videos depending on creation date and exif informations and it sorts out duplicate files"
14
+ s.email = "tboerger@tbpro.de"
15
+ s.executables = ["archiver"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE.md",
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ ".rvmrc",
22
+ ".travis.yml",
23
+ "Gemfile",
24
+ "LICENSE.md",
25
+ "README.md",
26
+ "Rakefile",
27
+ "archiver.gemspec",
28
+ "bin/archiver",
29
+ "lib/archiver.rb",
30
+ "lib/archiver/action.rb",
31
+ "lib/archiver/action/renaming.rb",
32
+ "lib/archiver/cli.rb",
33
+ "lib/archiver/error.rb",
34
+ "lib/archiver/error/invalid_directory.rb",
35
+ "lib/archiver/output.rb",
36
+ "lib/archiver/output/cli.rb",
37
+ "lib/archiver/record.rb",
38
+ "lib/archiver/version.rb"
39
+ ]
40
+ s.homepage = "https://github.com/tbpro/archiver"
41
+ s.licenses = ["MIT"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = "1.8.10"
44
+ s.summary = "Archiver is a simple gem to rename photos and videos"
45
+
46
+ if s.respond_to? :specification_version then
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_runtime_dependency(%q<thor>, ["~> 0.14.6"])
51
+ s.add_runtime_dependency(%q<exifr>, ["~> 1.1.2"])
52
+ s.add_runtime_dependency(%q<progressbar>, ["~> 0.10.0"])
53
+ s.add_development_dependency(%q<redcarpet>, ["~> 2.1.0"])
54
+ s.add_development_dependency(%q<yard>, ["~> 0.7.5"])
55
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
56
+ else
57
+ s.add_dependency(%q<thor>, ["~> 0.14.6"])
58
+ s.add_dependency(%q<exifr>, ["~> 1.1.2"])
59
+ s.add_dependency(%q<progressbar>, ["~> 0.10.0"])
60
+ s.add_dependency(%q<redcarpet>, ["~> 2.1.0"])
61
+ s.add_dependency(%q<yard>, ["~> 0.7.5"])
62
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<thor>, ["~> 0.14.6"])
66
+ s.add_dependency(%q<exifr>, ["~> 1.1.2"])
67
+ s.add_dependency(%q<progressbar>, ["~> 0.10.0"])
68
+ s.add_dependency(%q<redcarpet>, ["~> 2.1.0"])
69
+ s.add_dependency(%q<yard>, ["~> 0.7.5"])
70
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
71
+ end
72
+ end
73
+
data/bin/archiver ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ $:.push File.expand_path('../../lib', __FILE__)
7
+
8
+ require 'rubygems'
9
+ require 'archiver'
10
+
11
+ trap('INT') { exit 0 }
12
+
13
+ Archiver::Cli.start
@@ -0,0 +1,61 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ module Archiver
7
+ module Action
8
+ class Renaming
9
+ attr_accessor :source
10
+ attr_accessor :destination
11
+ attr_accessor :output
12
+
13
+ attr_accessor :records
14
+
15
+ def initialize(source, destination, output)
16
+ @source = source
17
+ @destination = destination
18
+ @output = output
19
+
20
+ @records = []
21
+
22
+ check_directories
23
+ load_records
24
+ end
25
+
26
+ def process
27
+ records.each do |record|
28
+ next unless record.process?
29
+
30
+ record.move destination
31
+ output.process record
32
+ end
33
+
34
+ output.finish!
35
+ end
36
+
37
+ protected
38
+ def check_directories
39
+ unless File.directory? source
40
+ raise Archiver::Error::InvalidDirectory
41
+ end
42
+
43
+ unless File.directory? destination
44
+ raise Archiver::Error::InvalidDirectory
45
+ end
46
+
47
+ @source = File.realpath source
48
+ @destination = File.realpath destination
49
+ end
50
+
51
+ def load_records
52
+ Dir.glob([source, '**', '*'].join('/')).each do |record|
53
+ next if File.directory? record
54
+ @records << Archiver::Record.new(record)
55
+ end
56
+
57
+ output.count = records.count
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,10 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ module Archiver
7
+ module Action
8
+ autoload :Renaming, 'archiver/action/renaming'
9
+ end
10
+ end
@@ -0,0 +1,42 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ require 'thor'
7
+ require 'progressbar'
8
+
9
+ module Archiver
10
+ class Cli < Thor
11
+ include Thor::Actions
12
+
13
+ method_option :verbose, :type => :boolean, :aliases => '-V', :default => false
14
+ method_option :source, :type => :string, :aliases => '-s', :default => '.'
15
+
16
+ desc 'renaming [DESTINATION]', 'Rename all files in the defined directory'
17
+ def renaming(destination)
18
+ source = options['source']
19
+ verbose = options['verbose']
20
+
21
+ output = Archiver::Output::Cli.new(verbose)
22
+
23
+ begin
24
+ action = Archiver::Action::Renaming.new(
25
+ source,
26
+ destination,
27
+ output
28
+ )
29
+
30
+ action.process
31
+ rescue Archiver::Error::InvalidDirectory => e
32
+ raise Thor::Error.new 'Directories does not exist!'
33
+ rescue => e
34
+ if verbose
35
+ raise Thor::Error.new "Some action failed: #{e.message}"
36
+ else
37
+ raise Thor::Error.new 'Some action failed!'
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ module Archiver
7
+ module Error
8
+ class InvalidDirectory < StandardError
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ module Archiver
7
+ module Error
8
+ autoload :InvalidDirectory, 'archiver/error/invalid_directory'
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ require 'progressbar'
7
+
8
+ module Archiver
9
+ class Output
10
+ class Cli
11
+ attr_accessor :verbose
12
+ attr_accessor :count
13
+ attr_accessor :working
14
+ attr_accessor :progress
15
+
16
+ def initialize(verbose)
17
+ @verbose = verbose
18
+ @count = 0
19
+ @working = 0
20
+ end
21
+
22
+ def count=(value)
23
+ @progress = ProgressBar.new('Archiver', value) unless verbose
24
+ @count = value
25
+ end
26
+
27
+ def process(record)
28
+ @working += 1
29
+
30
+ if verbose
31
+ puts "#{sprintf('%05d', @working)}/#{sprintf('%05d', count)}: #{record.path} -> #{record.filename}"
32
+ else
33
+ progress.inc
34
+ end
35
+ end
36
+
37
+ def finish!
38
+ if verbose
39
+ puts "Processed #{count} records!"
40
+ else
41
+ progress.finish
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ module Archiver
7
+ class Output
8
+ autoload :Cli, 'archiver/output/cli'
9
+ end
10
+ end
@@ -0,0 +1,126 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ require 'exifr'
7
+ require 'digest/md5'
8
+
9
+ module Archiver
10
+ class Record
11
+ attr_accessor :path
12
+
13
+ def initialize(path)
14
+ @path = path
15
+ end
16
+
17
+ def filename(counter = 0)
18
+ append = if counter > 0
19
+ sprintf('-%03d', counter)
20
+ else
21
+ nil
22
+ end
23
+
24
+ [
25
+ created.strftime('%Y%m%d-%H%M%S'),
26
+ append,
27
+ extension
28
+ ].compact.join
29
+ end
30
+
31
+ def extension
32
+ if mime_type.match /^image\/jpeg$/i
33
+ return '.jpg'
34
+ end
35
+
36
+ if mime_type.match /^image\/gif$/i
37
+ return '.gif'
38
+ end
39
+
40
+ if mime_type.match /^image\/png$/i
41
+ return '.png'
42
+ end
43
+
44
+ if mime_type.match /^video\/3gpp$/i
45
+ return '.mp4'
46
+ end
47
+
48
+ File.extname(path).downcase
49
+ end
50
+
51
+ def created
52
+ if exif_data and exif_data.date_time_original
53
+ exif_data.date_time_original
54
+ else
55
+ File.mtime(path)
56
+ end
57
+ end
58
+
59
+ def checksum
60
+ @checksum ||= Digest::MD5.hexdigest(File.read(path))
61
+ end
62
+
63
+ def mime_type
64
+ @mime_type ||= mime_detect
65
+ .split(';')
66
+ .first
67
+ .strip
68
+ end
69
+
70
+ def exif_data
71
+ @exif_data ||= exif_detect
72
+ end
73
+
74
+ def process?
75
+ image? or video?
76
+ end
77
+
78
+ def image?
79
+ !!(mime_type.match /^image\/.*/i)
80
+ end
81
+
82
+ def video?
83
+ !!(mime_type.match /^video\/.*/i)
84
+ end
85
+
86
+ def same?(other)
87
+ if other.is_a? Record
88
+ checksum == other.checksum
89
+ else
90
+ checksum == Digest::MD5.hexdigest(File.read(other))
91
+ end
92
+ end
93
+
94
+ def move(directory, counter = 0)
95
+ destination = File.join(directory, filename(counter))
96
+
97
+ if File.exists? destination
98
+ if same? destination
99
+ FileUtils.rm_rf path
100
+ else
101
+ move(directory, counter + 1)
102
+ end
103
+ else
104
+ FileUtils.cp path, destination
105
+ FileUtils.rm_rf path
106
+ end
107
+ end
108
+
109
+ protected
110
+ def mime_detect
111
+ `/usr/bin/env file --brief --mime "#{path}"`
112
+ end
113
+
114
+ def exif_detect
115
+ if mime_type.match(/^image\/jpeg/i)
116
+ return EXIFR::JPEG.new(path)
117
+ end
118
+
119
+ if mime_type.match(/^image\/tiff/i)
120
+ return EXIFR::TIFF.new(path)
121
+ end
122
+
123
+ nil
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,15 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ module Archiver
7
+ module Version
8
+ MAJOR = 0
9
+ MINOR = 1
10
+ PATCH = 0
11
+ BUILD = nil
12
+
13
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
14
+ end
15
+ end
data/lib/archiver.rb ADDED
@@ -0,0 +1,13 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # Created by Thomas Boerger on 2012-03-16.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ module Archiver
7
+ autoload :Version, 'archiver/version'
8
+ autoload :Cli, 'archiver/cli'
9
+ autoload :Error, 'archiver/error'
10
+ autoload :Action, 'archiver/action'
11
+ autoload :Record, 'archiver/record'
12
+ autoload :Output, 'archiver/output'
13
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: archiver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Boerger
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: &70302533002720 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.14.6
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70302533002720
25
+ - !ruby/object:Gem::Dependency
26
+ name: exifr
27
+ requirement: &70302533001980 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.1.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70302533001980
36
+ - !ruby/object:Gem::Dependency
37
+ name: progressbar
38
+ requirement: &70302533000800 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.10.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70302533000800
47
+ - !ruby/object:Gem::Dependency
48
+ name: redcarpet
49
+ requirement: &70302532999960 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.1.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70302532999960
58
+ - !ruby/object:Gem::Dependency
59
+ name: yard
60
+ requirement: &70302532999420 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.7.5
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70302532999420
69
+ - !ruby/object:Gem::Dependency
70
+ name: jeweler
71
+ requirement: &70302532998880 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.8.3
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70302532998880
80
+ description: Archiver is a simple gem to rename photos and videos depending on creation
81
+ date and exif informations and it sorts out duplicate files
82
+ email: tboerger@tbpro.de
83
+ executables:
84
+ - archiver
85
+ extensions: []
86
+ extra_rdoc_files:
87
+ - LICENSE.md
88
+ - README.md
89
+ files:
90
+ - .rvmrc
91
+ - .travis.yml
92
+ - Gemfile
93
+ - LICENSE.md
94
+ - README.md
95
+ - Rakefile
96
+ - archiver.gemspec
97
+ - bin/archiver
98
+ - lib/archiver.rb
99
+ - lib/archiver/action.rb
100
+ - lib/archiver/action/renaming.rb
101
+ - lib/archiver/cli.rb
102
+ - lib/archiver/error.rb
103
+ - lib/archiver/error/invalid_directory.rb
104
+ - lib/archiver/output.rb
105
+ - lib/archiver/output/cli.rb
106
+ - lib/archiver/record.rb
107
+ - lib/archiver/version.rb
108
+ homepage: https://github.com/tbpro/archiver
109
+ licenses:
110
+ - MIT
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ segments:
122
+ - 0
123
+ hash: -885210058386209972
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 1.8.10
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: Archiver is a simple gem to rename photos and videos
136
+ test_files: []