gps_extractor 0.1.1
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 +7 -0
- data/lib/extractor.rb +78 -0
- data/lib/file_scanner.rb +46 -0
- data/lib/gps_extractor.rb +25 -0
- data/lib/gps_extractor/version.rb +3 -0
- data/lib/template.rb +83 -0
- data/lib/templates/html/_footer.html.erb +4 -0
- data/lib/templates/html/_header.html.erb +16 -0
- data/lib/templates/html/_row.html.erb +5 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 33ef2db79a9d06cdf6eca32b2935ad45025cd8dfbffcf643f775474255eaa589
|
4
|
+
data.tar.gz: f6c57166e7b36b9db3ec3e797a8877daa90fa8c4b5c5228f33a71daeedc81d64
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a4b81d7f134ecab31bd578b8457d9cdfa2ad9cade505833e71f560b361d7062fe281c30ee3aa70efc343748042729051d9ae8a981223e966b10323abfc9135f2
|
7
|
+
data.tar.gz: aa239b760f08ff5f09da50861f4558bfbc5fa9c3bc5bd62fe208f40404b75862cc86188043b29738b2acc562d8d9f18bddcd7dc1a6da8dd2c4bf5ab03d95a141
|
data/lib/extractor.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'template'
|
5
|
+
require 'file_scanner'
|
6
|
+
|
7
|
+
class Extractor
|
8
|
+
def perform(options, args)
|
9
|
+
show_throughput('Setting directory', options[:verbose])
|
10
|
+
dir = get_directory(args)
|
11
|
+
|
12
|
+
show_throughput('Create output file', options[:verbose])
|
13
|
+
output_file = op_file(dir, options)
|
14
|
+
|
15
|
+
begin
|
16
|
+
show_throughput('Scan Started', options[:verbose])
|
17
|
+
FileScanner.new(dir, output_file, options[:verbose]).begin_scan
|
18
|
+
rescue SystemCallError => e
|
19
|
+
show_error('Unable to scan this directory', e)
|
20
|
+
rescue StandardError => e
|
21
|
+
show_error('', e)
|
22
|
+
end
|
23
|
+
show_throughput('Scan Completed', options[:verbose])
|
24
|
+
|
25
|
+
show_throughput('Finalising O/P File', options[:verbose])
|
26
|
+
output_file.close
|
27
|
+
|
28
|
+
show_throughput('Exit', options[:verbose])
|
29
|
+
show_throughput("OutPut Recorded in file: #{output_file.file_name}", true)
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_directory(args)
|
34
|
+
begin
|
35
|
+
case args.count
|
36
|
+
when 0
|
37
|
+
Dir.pwd
|
38
|
+
when 1
|
39
|
+
File.absolute_path(args.first)
|
40
|
+
else
|
41
|
+
raise ArgumentError, 'Arguments limit breached'
|
42
|
+
end
|
43
|
+
rescue ArgumentError => e
|
44
|
+
show_error('Unable to set directory', e)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def op_file(dir,options)
|
49
|
+
begin
|
50
|
+
attr_labels = %w[directory file_name latitude longitude]
|
51
|
+
dir_name = File.basename(dir)
|
52
|
+
if options[:html]
|
53
|
+
Template::Html.new(dir_name, attr_labels)
|
54
|
+
else
|
55
|
+
Template::Csv.new(dir_name, attr_labels)
|
56
|
+
end
|
57
|
+
|
58
|
+
rescue SystemCallError => e
|
59
|
+
STDERR.puts 'Unable to initialize the output file'
|
60
|
+
STDERR.puts 'Make sure you have write permission to your pwd'
|
61
|
+
if options[:html]
|
62
|
+
STDERR.puts 'If you have not installed the gem, check your config file'
|
63
|
+
end
|
64
|
+
STDERR.puts e.message
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def show_throughput(msg, verbose)
|
70
|
+
puts msg if verbose
|
71
|
+
end
|
72
|
+
|
73
|
+
def show_error(msg, e)
|
74
|
+
STDERR.puts msg
|
75
|
+
STDERR.puts e.message
|
76
|
+
exit
|
77
|
+
end
|
78
|
+
end
|
data/lib/file_scanner.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'image_reader'
|
5
|
+
require 'extractor'
|
6
|
+
|
7
|
+
class FileScanner
|
8
|
+
def initialize(directory, output_file, verbose)
|
9
|
+
@directory = Pathname.new(directory)
|
10
|
+
@output_file = output_file
|
11
|
+
@verbose = verbose
|
12
|
+
@allowed_formats = %w{.jpg .jpeg}
|
13
|
+
end
|
14
|
+
|
15
|
+
def begin_scan
|
16
|
+
directory_scanning(@directory)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Recursively scans directory searching for image files
|
22
|
+
def directory_scanning(dir)
|
23
|
+
Extractor.new.show_throughput("scanning path: #{dir}", @verbose)
|
24
|
+
|
25
|
+
dir.children.each do |child|
|
26
|
+
if child.file? && @allowed_formats.include?(File.extname(child).downcase)
|
27
|
+
begin
|
28
|
+
@output_file.insert(ImageReader.new(child.to_path).restructure)
|
29
|
+
rescue EXIFR::MalformedJPEG => e
|
30
|
+
Extractor.new.show_throughput("Unprocessable image: #{child.to_path}", @verbose)
|
31
|
+
Extractor.new.show_throughput(e.message, @verbose)
|
32
|
+
rescue SystemCallError => e
|
33
|
+
Extractor.new.show_throughput("An error occurred while processing image: #{child.to_path}", @verbose)
|
34
|
+
raise SystemCallError, "The error received was: #{e}"
|
35
|
+
end
|
36
|
+
elsif child.directory?
|
37
|
+
begin
|
38
|
+
directory_scanning(child)
|
39
|
+
rescue SystemCallError => e
|
40
|
+
Extractor.new.show_throughput("Unable to scan sub directory: #{child.to_path}", @verbose)
|
41
|
+
Extractor.new.show_throughput(e.message, @verbose)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "gps_extractor/version"
|
3
|
+
require 'optparse'
|
4
|
+
require 'extractor'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
parser = OptionParser.new do |opts|
|
8
|
+
opts.on('-html', 'Output HTML file') do
|
9
|
+
options[:html] = true
|
10
|
+
end
|
11
|
+
|
12
|
+
opts.on('-v', '--verbose', 'Run verbosely') do |v|
|
13
|
+
options[:verbose] = v
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
parser.parse!
|
19
|
+
rescue OptionParser::InvalidOption => e
|
20
|
+
STDERR.puts e.message
|
21
|
+
STDERR.puts parser
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
|
25
|
+
Extractor.new.perform(options, ARGV)
|
data/lib/template.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'gps_extractor/version'
|
5
|
+
|
6
|
+
module Template
|
7
|
+
|
8
|
+
|
9
|
+
# handles creating and writing CSV output files
|
10
|
+
class Csv
|
11
|
+
attr_reader :file_name
|
12
|
+
|
13
|
+
# dir: basename of root directory
|
14
|
+
# attr_labels: array of attributes labels as strings
|
15
|
+
def initialize(dir, attr_labels)
|
16
|
+
@file_name = "tmp/output/#{dir}_#{Time.now.to_i}.csv"
|
17
|
+
@file = File.new(@file_name, 'w')
|
18
|
+
@file.puts(attr_labels.join(','))
|
19
|
+
end
|
20
|
+
|
21
|
+
# Writes data row to file
|
22
|
+
def insert(img_attrs)
|
23
|
+
@file.puts(img_attrs.join(','))
|
24
|
+
end
|
25
|
+
|
26
|
+
def close
|
27
|
+
@file.close
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# This Class handles creating and writing HTML output files
|
33
|
+
class Html
|
34
|
+
attr_reader :file_name
|
35
|
+
|
36
|
+
# dir: basename of root directory
|
37
|
+
# attr_labels: array of attributes labels as strings
|
38
|
+
def initialize(dir, attr_labels)
|
39
|
+
@file_name = "tmp/output/#{dir}_#{Time.now.to_i}.html"
|
40
|
+
@file = File.new(@file_name, 'w')
|
41
|
+
@template_path = set_template_path
|
42
|
+
append_header(dir, attr_labels)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Writes data row to file
|
46
|
+
def insert(img_attrs)
|
47
|
+
@img_attrs = img_attrs
|
48
|
+
row = File.read("#{@template_path}_row.html.erb")
|
49
|
+
partial = ERB.new(row, nil, '-').result(binding)
|
50
|
+
@file.write(partial)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Writes footer to file and closes it
|
54
|
+
def close
|
55
|
+
footer = File.read("#{@template_path}_footer.html.erb")
|
56
|
+
partial = ERB.new(footer).result(binding)
|
57
|
+
@file.write(partial)
|
58
|
+
@file.close
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
# locate path to templates
|
64
|
+
def set_template_path
|
65
|
+
template_path = 'lib/templates/html/'
|
66
|
+
gem_path = "#{Gem.dir}/gems/gps_extractor-#{GpsExtractor::VERSION}/"
|
67
|
+
if File.exists?(gem_path)
|
68
|
+
return File.join(gem_path, template_path)
|
69
|
+
else
|
70
|
+
template_path
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Writes the header component of the HTML file
|
75
|
+
def append_header(dir, attr_labels)
|
76
|
+
@title = "Image GPS Scan for: #{dir}"
|
77
|
+
@attr_labels = attr_labels
|
78
|
+
header = File.read("#{@template_path}_header.html.erb")
|
79
|
+
partial = ERB.new(header, nil, '-').result(binding)
|
80
|
+
@file.write(partial)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gps_extractor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aashish Saini
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-12-14 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.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
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: exifr
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 1.3.4
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '1.3'
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 1.3.4
|
75
|
+
description: "\n A command line application that recursively reads all of the images
|
76
|
+
from the supplied directory of images,\n extracts their EXIF GPS data (longitude
|
77
|
+
and latitude), and then writes the name of that image and any\n GPS co-ordinates
|
78
|
+
it finds to a CSV file.\n\n Results are written to a file in the pwd as the scan
|
79
|
+
runs. CSV files will be\n produced by default, use -html for HTML files instead.
|
80
|
+
If the app is not\n installed as a gem, HTML output requires configuration.\n
|
81
|
+
\ "
|
82
|
+
email:
|
83
|
+
- aashusaini2684@gmail.com
|
84
|
+
executables: []
|
85
|
+
extensions: []
|
86
|
+
extra_rdoc_files: []
|
87
|
+
files:
|
88
|
+
- lib/extractor.rb
|
89
|
+
- lib/file_scanner.rb
|
90
|
+
- lib/gps_extractor.rb
|
91
|
+
- lib/gps_extractor/version.rb
|
92
|
+
- lib/template.rb
|
93
|
+
- lib/templates/html/_footer.html.erb
|
94
|
+
- lib/templates/html/_header.html.erb
|
95
|
+
- lib/templates/html/_row.html.erb
|
96
|
+
homepage: https://github.com/aashishsaini/
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata:
|
100
|
+
homepage_uri: https://github.com/aashishsaini/
|
101
|
+
source_code_uri: https://github.com/aashishsaini/gps_extractor
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.7.6
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: CL app to find JPEGs and extract their GPS coordinates
|
122
|
+
test_files: []
|