getpics 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dc21e026035f037a2f61dd5054460646e41c4bb72e8e236dee2ed7d24eeea428
4
+ data.tar.gz: 384fd39d788784969e906f376eac195d81f721a8cfa4e950b47e3a9490c2dc15
5
+ SHA512:
6
+ metadata.gz: 9e9321d7cd8ad4f5d57ab1b27e70e2d0c8b96990d66d7351e9fed52841f0364923f1ad4e33bd9088447a3c32ff4190e31b4529ad622edc48353b8653cbc3a2a1
7
+ data.tar.gz: 4e5832f060d18aa11818555e724aca6700a96e4a2eb0f4c038b6131b004be024a344a4db840b502a68984e781c2c43e5718f18473bd1ce4723ec4e2fe2d6f089
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.1
5
+ before_install: gem install bundler -v 1.14.6
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in getpics.gemspec
4
+ gemspec
5
+
6
+ gem 'mini_exiftool'
7
+ gem 'ruby-progressbar'
8
+ gem 'colorize'
9
+
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Doug P.
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,25 @@
1
+ # Getpics
2
+
3
+ Use this script to copy and organize media files in one step.
4
+
5
+ ## Installation
6
+
7
+ $ gem install getpics
8
+
9
+ ## Usage
10
+
11
+ Usage: getpics [options]
12
+ -s, --src DIR Source directory
13
+ -p, --photo DIR Photo Destination directory
14
+ -m, --movie DIR Movie Destination directory
15
+ -v, --verbose Verbose
16
+ -h, --help Show this message
17
+ Version: 0.2.0
18
+
19
+ ## Contributing
20
+
21
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dougsko/getpics.
22
+
23
+ ## License
24
+
25
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "getpics"
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/getpics ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "getpics"
5
+ require 'optparse'
6
+
7
+ ARGV << '-h' if ARGV.empty?
8
+
9
+ options = {}
10
+ OptionParser.new do |opts|
11
+ opts.banner = "Usage: getpics [options]"
12
+
13
+ opts.on("-s", "--src DIR", "Source directory") do |s|
14
+ options[:src] = s
15
+ end
16
+
17
+ opts.on("-p", "--photo DIR", "Photo Destination directory") do |p|
18
+ options[:photo_dest] = p
19
+ end
20
+
21
+ opts.on("-m", "--movie DIR", "Movie Destination directory") do |m|
22
+ options[:movie_dest] = m
23
+ end
24
+
25
+ opts.on("-v", "--verbose", "Verbose") do |v|
26
+ options[:verbose] = v
27
+ end
28
+
29
+ opts.on_tail("-h", "--help", "Show this message") do
30
+ puts opts
31
+ puts "Version: " + Getpics::VERSION
32
+ exit
33
+ end
34
+ end.parse!
35
+
36
+ dl = Getpics::Downloader.new(options[:verbose], options[:src], options[:photo_dest], options[:movie_dest])
37
+ dl.load_media
38
+ dl.copy_media
39
+ dl.convert_media
40
+
41
+ puts "Do you want to delete the media from #{options[:src]}? [y/N]".yellow
42
+ delete = gets.strip
43
+ if delete == 'y'
44
+ dl.delete_media
45
+ end
46
+
47
+ puts "All finished!".green
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
data/getpics.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'getpics/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "getpics"
8
+ spec.version = Getpics::VERSION
9
+ spec.authors = ["Doug P."]
10
+ spec.email = ["dougtko@gmail.com"]
11
+
12
+ spec.summary = %q{Download pictures from camera}
13
+ spec.description = %q{Download pictures from camera}
14
+ spec.homepage = "http://example.com"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
+ f.match(%r{^(test|spec|features)/})
22
+ end
23
+ spec.bindir = "bin"
24
+ spec.executables = "getpics" #spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.14"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rspec", "~> 3.0"
30
+
31
+ spec.add_runtime_dependency 'mini_exiftool'
32
+ spec.add_runtime_dependency 'colorize'
33
+ spec.add_runtime_dependency 'ruby-progressbar'
34
+ end
@@ -0,0 +1,105 @@
1
+ module Getpics
2
+ class Downloader
3
+ def initialize(verbose, src_dir, pic_dest, movie_dest)
4
+ @verbose = verbose
5
+ @src_dir = src_dir
6
+ @pic_dest = pic_dest
7
+ @movie_dest = movie_dest
8
+ @media_list = MediaList.new()
9
+ end
10
+
11
+ def load_media
12
+ puts "Searching for media..."
13
+ files = Dir.glob(@src_dir + "/**/*").reject { |p| File.directory? p }
14
+ files.each do |file|
15
+ if ! file.match(/\.xmp$/i)
16
+ media = Media.new(file)
17
+ if media.is_pic?
18
+ media.target_path = "#{@pic_dest}/#{media.target_path}"
19
+ media.target_folder = "#{@pic_dest}/#{media.target_folder}"
20
+ elsif media.is_movie?
21
+ media.target_path = "#{@movie_dest}/#{media.target_path}"
22
+ media.target_folder = "#{@movie_dest}/#{media.target_folder}"
23
+ end
24
+ @media_list.add(media)
25
+ end
26
+ end
27
+ if @media_list.size == 0
28
+ puts "No media found!".red
29
+ exit 1
30
+ end
31
+ puts "Found #{@media_list.raw_pics.size} RAW photos".blue if @media_list.raw_pics.size > 0
32
+ puts "Found #{@media_list.developed_pics.size} JPGs".blue if @media_list.developed_pics.size > 0
33
+ puts "Found #{@media_list.movies.size} movies".blue if @media_list.movies.size > 0
34
+ end
35
+
36
+ def copy_media
37
+ puts "Copying media..."
38
+ pb = ProgressBar.create(:title => "Media Copied", :total => @media_list.size)
39
+ @media_list.all_known_media.each do |media|
40
+ if ! File.exists?("#{media.target_path}")
41
+ pb.log ("Copying #{media.path} to #{media.target_path}").light_black if @verbose
42
+ FileUtils.mkdir_p(media.target_folder)
43
+ FileUtils.cp(media.path, media.target_path)
44
+ media.path = media.target_path
45
+ else
46
+ pb.log ("#{media.target_name}" + " already exists!").light_black if @verbose
47
+ end
48
+ pb.increment
49
+ end
50
+ end
51
+
52
+ def convert_media
53
+ return if @media_list.movies.size == 0
54
+ ffmpeg_path = which("ffmpeg")
55
+ if ffmpeg_path == nil
56
+ puts "ffmpeg not found!".red
57
+ return
58
+ end
59
+ movies_to_process = []
60
+ @media_list.movies.each do |movie|
61
+ dest_path = "#{movie.target_folder}/#{File.basename(movie.target_name, '.MOV')}.mp4"
62
+ if ! File.exists?(dest_path)
63
+ movies_to_process << movie
64
+ else
65
+ puts "#{dest_path} already exists!".light_black if @verbose
66
+ end
67
+ return if movies_to_process.size == 0
68
+ puts "Converting movies to MP4..."
69
+ pb = ProgressBar.create(:title => "Movies Converted", :total => movies_to_process.size)
70
+ movies_to_process.each do |movie|
71
+ system("#{ffmpeg_path} -i #{movie.target_path} -vcodec copy -acodec copy #{dest_path}")
72
+ pb.increment
73
+ end
74
+ end
75
+
76
+ puts "Do you want to delete the .MOV files you just converted? [y/N]".yellow
77
+ delete = gets.strip
78
+ if delete == 'y'
79
+ movies_to_process.each do |movie|
80
+ puts "Deleting #{movie.target_path}".red if @verbose
81
+ File.delete(movie.target_path)
82
+ end
83
+ end
84
+ end
85
+
86
+ def delete_media
87
+ @media_list.all_known_media.each do |media|
88
+ puts "Deleting #{media.orig_path}".red if @verbose
89
+ FileUtils.rm(media.orig_path)
90
+ end
91
+ end
92
+
93
+ def which(cmd)
94
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
95
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
96
+ exts.each do |ext|
97
+ exe = File.join(path, "#{cmd}#{ext}")
98
+ return exe if File.executable?(exe) && !File.directory?(exe)
99
+ end
100
+ end
101
+ return nil
102
+ end
103
+
104
+ end
105
+ end
@@ -0,0 +1,112 @@
1
+ require 'date'
2
+ require 'mini_exiftool'
3
+ require 'colorize'
4
+
5
+ module Getpics
6
+ class Media
7
+ attr_accessor :path, :orig_path, :date, :folder, :extension, :type, :target_name, :target_folder, :target_path
8
+
9
+ RAW_EXTENSIONS = ['.nef', '.dng']
10
+ DEVELOPED_EXTENSIONS = ['.jpg', '.jpeg']
11
+ MOVIE_EXTENSIONS = ['.mov']
12
+
13
+ def initialize(path)
14
+ @path = path
15
+ @orig_path = path
16
+ @name = File.basename(@path)
17
+ @folder = File.dirname(@path)
18
+ @extension = File.extname(@path).downcase
19
+
20
+ if ! @name.match?(/^_/)
21
+ @name = "_" + @name
22
+ end
23
+
24
+ begin
25
+ image = MiniExiftool.new(@path)
26
+ rescue
27
+ puts "Error while loading #{@path}".red
28
+ end
29
+
30
+ begin
31
+ @date = DateTime.parse(image.CreateDate.to_s)
32
+ rescue
33
+ puts "No valid CreateDate for #{@path}. Using mtime (#{File.mtime(@path)})".light_black
34
+ @date = File.mtime(@path)
35
+ end
36
+
37
+ if RAW_EXTENSIONS.include?(@extension)
38
+ @type = RawType.new
39
+ elsif DEVELOPED_EXTENSIONS.include?(@extension)
40
+ @type = DevelopedType.new
41
+ elsif MOVIE_EXTENSIONS.include?(@extension)
42
+ @type = MovieType.new
43
+ else
44
+ @type = UnknownType.new
45
+ end
46
+
47
+ @target_folder = "#{@type.folder}/#{year}/#{month}/#{day}/"
48
+ @target_name = year_month_day + @name
49
+ @target_path = @target_folder + @target_name
50
+
51
+ end
52
+
53
+ def path=(path)
54
+ @path = path
55
+ end
56
+
57
+ def name
58
+ File.basename(@path)
59
+ end
60
+
61
+ def folder
62
+ File.dirname(@path)
63
+ end
64
+
65
+ def is_developed?
66
+ return true if @type.name == :developed
67
+ return false
68
+ end
69
+
70
+ def is_raw?
71
+ return true if @type.name == :raw
72
+ return false
73
+ end
74
+
75
+ def is_pic?
76
+ return true if is_developed? or is_raw?
77
+ return false
78
+ end
79
+
80
+ def is_movie?
81
+ return true if @type.name == :movie
82
+ return false
83
+ end
84
+
85
+ def is_unknown?
86
+ return true if @type.name == :unknown
87
+ return false
88
+ end
89
+
90
+ def is_known?
91
+ return true if @type.name != :unknown
92
+ return false
93
+ end
94
+
95
+ def year
96
+ @date.year
97
+ end
98
+
99
+ def month
100
+ @date.strftime("%m")
101
+ end
102
+
103
+ def day
104
+ @date.strftime("%d")
105
+ end
106
+
107
+ def year_month_day
108
+ @date.strftime("%Y%m%d")
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,36 @@
1
+ module Getpics
2
+ class MediaList
3
+ def initialize
4
+ @media_list = []
5
+ end
6
+
7
+ def add(media)
8
+ @media_list << (media)
9
+ end
10
+
11
+ def size
12
+ @media_list.size()
13
+ end
14
+
15
+ def raw_pics
16
+ @media_list.select{ |media| media.is_raw? }
17
+ end
18
+
19
+ def developed_pics
20
+ @media_list.select{ |media| media.is_developed? }
21
+ end
22
+
23
+ def pics
24
+ @media_list.select{ |media| media.is_pic? }
25
+ end
26
+
27
+ def movies
28
+ @media_list.select{ |media| media.is_movie? }
29
+ end
30
+
31
+ def all_known_media
32
+ @media_list.select{ |media| media.is_known? }
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,34 @@
1
+ module Getpics
2
+ class MediaType
3
+ attr_accessor :name, :folder
4
+ end
5
+
6
+ class RawType < MediaType
7
+ def initialize
8
+ @name = :raw
9
+ @folder = 'RAW'
10
+ end
11
+ end
12
+
13
+ class DevelopedType < MediaType
14
+ def initialize
15
+ @name = :developed
16
+ @folder = 'developed'
17
+ end
18
+ end
19
+
20
+ class MovieType < MediaType
21
+ def initialize
22
+ @name = :movie
23
+ @folder = "Raw_Footage"
24
+ end
25
+ end
26
+
27
+ class UnknownType < MediaType
28
+ def initialize
29
+ @name = :unknown
30
+ @folder = "#{ENV['HOME']}/Desktop"
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,3 @@
1
+ module Getpics
2
+ VERSION = "0.2.0"
3
+ end
data/lib/getpics.rb ADDED
@@ -0,0 +1,19 @@
1
+ require "getpics/version"
2
+ require 'getpics/downloader'
3
+ require 'getpics/media'
4
+ require 'getpics/media_list'
5
+ require 'getpics/media_type'
6
+ require 'colorize'
7
+ require 'fileutils'
8
+ require 'ruby-progressbar'
9
+ require 'mini_exiftool'
10
+ require 'date'
11
+
12
+ module Getpics
13
+ if File.exists?("/usr/local/Cellar/exiftool/10.05/bin/exiftool")
14
+ MiniExiftool.command = '/usr/local/Cellar/exiftool/10.05/bin/exiftool'
15
+ else
16
+ MiniExiftool.command = `which exiftool`.chomp
17
+ end
18
+ end
19
+
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: getpics
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Doug P.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-18 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.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
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
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mini_exiftool
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: colorize
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ruby-progressbar
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Download pictures from camera
98
+ email:
99
+ - dougtko@gmail.com
100
+ executables:
101
+ - getpics
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".rspec"
107
+ - ".travis.yml"
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - bin/console
113
+ - bin/getpics
114
+ - bin/setup
115
+ - getpics.gemspec
116
+ - lib/getpics.rb
117
+ - lib/getpics/downloader.rb
118
+ - lib/getpics/media.rb
119
+ - lib/getpics/media_list.rb
120
+ - lib/getpics/media_type.rb
121
+ - lib/getpics/version.rb
122
+ homepage: http://example.com
123
+ licenses:
124
+ - MIT
125
+ metadata: {}
126
+ post_install_message:
127
+ rdoc_options: []
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 2.7.6
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Download pictures from camera
146
+ test_files: []