filmrolls 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cfda4ddc50406fe47135099abc8df5ff236cb6b6
4
- data.tar.gz: ea118d58dbed88d834655d415e0a06006597fc92
2
+ SHA256:
3
+ metadata.gz: 3b26c01d199b8c0d15625d83aeaa6d90865808820bd57bc114919429f2aaff58
4
+ data.tar.gz: 3369d49d9416dbbde432869b871cce83f6fc559c7a3287cbe867a7bb4b512043
5
5
  SHA512:
6
- metadata.gz: fbc09d0798e834f807cd62ed396352d2470ebc7bc2b337ec5bee4c147a71c4a278437ca05cb757b6c1b8db11f5000989493571543a540a30ef6f0e1bc8432a1e
7
- data.tar.gz: 0aea4f82a5bf2f9a4827af9dd5338633b5cc633e314fe785ab8d3b3df18b9d57002e79f7902ff7d90c60b239c47dfa4ab451f299250f362f78ad2f67c9a5a908
6
+ metadata.gz: e30f40902c26e0fc230905c701b9e93b8f1b9ee4b349ec6102367f5967854b328b58650639db1f832804425886c424f48f5557e81a36088ef0c247689c1a610e
7
+ data.tar.gz: b791d3eacc96426b5a3bcf7de02af2acbf57d1389d7b890f6538596781b1cef0cf9f8bc52077f3c6f51052f3891b49c0172d85b6c44288e0f3e816a6ddace43a
data/LICENSE.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # ISC License
2
2
 
3
- ```
4
- Copyright (c) 2016, Simon Sigurdhsson
3
+ Copyright (c) 2017, Simon Sigurdhsson
5
4
 
6
5
  Permission to use, copy, modify, and/or distribute this software for any
7
6
  purpose with or without fee is hereby granted, provided that the above
@@ -14,4 +13,3 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
13
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
14
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
15
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
- ```
data/README.md CHANGED
@@ -1,22 +1,20 @@
1
1
  # Film Rolls EXIF tagger
2
2
 
3
- [![Build Status](https://img.shields.io/travis/urdh/roll2exif/master.svg)][build-status]
3
+ [![Build Status](https://img.shields.io/travis/urdh/filmrolls/master.svg)][build-status]
4
4
  [![Code Quality](https://img.shields.io/codacy/grade/ad6e6ba15806436ea9cb80c41fc75fb0/master.svg)][codacy]
5
5
  [![Code Coverage](https://img.shields.io/codacy/coverage/ad6e6ba15806436ea9cb80c41fc75fb0/master.svg)][codacy]
6
6
  [![Gem](https://img.shields.io/gem/v/filmrolls.svg)][release]
7
- [![License](https://img.shields.io/github/license/urdh/roll2exif.svg)][license]
7
+ [![License](https://img.shields.io/github/license/urdh/filmrolls.svg)](LICENSE.md)
8
8
  [![Semantic Versioning](https://img.shields.io/badge/semver-2.0.0-blue.svg)][semver]
9
9
 
10
10
  This is a utility designed to read the XML files used by the [Film Rolls iOS app][film-rolls], and enable batch EXIF tagging of scanned negatives in TIFF format based on the information in these XML files.
11
11
 
12
- The gem is released under the [ISC license][license].
13
- Eventually there will be some sort of [changelog][changelog] as well.
12
+ The gem is released under the [ISC license](LICENSE.md).
13
+ Eventually there will be some sort of [changelog](CHANGELOG.md) as well.
14
14
 
15
15
  [film-rolls]: https://itunes.apple.com/se/app/film-rolls-app-for-film-photographers/id675626559
16
16
  [semver]: http://semver.org/spec/v2.0.0.html
17
17
 
18
- [build-status]: https://travis-ci.org/urdh/roll2exif
19
- [codacy]: https://www.codacy.com/app/Sigurdhsson/roll2exif
18
+ [build-status]: https://travis-ci.org/urdh/filmrolls
19
+ [codacy]: https://www.codacy.com/app/Sigurdhsson/filmrolls
20
20
  [release]: https://rubygems.org/gems/filmrolls
21
- [license]: https://github.com/urdh/roll2exif/blob/master/LICENSE.md
22
- [changelog]: https://github.com/urdh/roll2exif/blob/master/CHANGELOG.md
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rake/testtask'
2
+ require 'rdoc/task'
3
+ require 'rubygems/package_task'
4
+
5
+ def gemspec
6
+ require 'rubygems/specification'
7
+ @gemspec ||= Gem::Specification.load(
8
+ File.expand_path(File.dirname(__FILE__) + '/filmrolls.gemspec')
9
+ )
10
+ end
11
+
12
+ rule(/\.[0-9]$/ => [proc { |name| "#{name}.ronn" }]) do |task|
13
+ require 'ronn'
14
+ appname, section = File.basename(task.name).split('.')
15
+ File.open(task.name, 'w') do |man|
16
+ man.write Ronn.new(
17
+ task.source,
18
+ name: appname,
19
+ section: section,
20
+ tagline: gemspec.summary,
21
+ manual: "#{gemspec.name} v#{gemspec.version}"
22
+ ).to_roff
23
+ end
24
+ end
25
+
26
+ desc 'Build all manual pages'
27
+ task ronn: gemspec.files.select { |f| f[/\.[0-9]$/] }
28
+
29
+ Gem::PackageTask.new(gemspec) {}
30
+
31
+ RDoc::Task.new(:rdoc) do |r|
32
+ r.options = gemspec.rdoc_options
33
+ r.rdoc_files.include(gemspec.require_paths)
34
+ r.rdoc_files.include(gemspec.extra_rdoc_files)
35
+ end
36
+
37
+ Rake::TestTask.new(:test) do |t|
38
+ t.libs = gemspec.require_paths + %w[test]
39
+ t.test_files = gemspec.test_files
40
+ end
41
+
42
+ task default: :test
data/bin/filmrolls CHANGED
@@ -1,45 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- require 'rubygems'
3
2
  require 'commander/import'
4
- require 'filmrolls'
3
+ require 'filmrolls/cli'
5
4
 
6
- begin
7
- GEMSPEC = Gem::Specification.find_by_name('filmrolls')
8
- SPECFILE = GEMSPEC.loaded_from
9
- rescue Gem::LoadError
10
- SPECFILE = File.expand_path(File.dirname(__FILE__) + '/../filmrolls.gemspec')
11
- GEMSPEC = Gem::Specification.load(SPECFILE)
12
- end
13
-
14
- program :version, GEMSPEC.version.to_s
15
- program :description, GEMSPEC.summary
16
-
17
- command :list do |c|
18
- c.syntax = 'filmrolls list [options] xml-file'
19
- c.summary = 'List film rolls'
20
- c.description = 'List ID and additional data for all film rolls in xml-file.'
21
-
22
- c.action do |args, _options|
23
- filename = args.shift
24
- abort 'Missing xml-file argument.' if filename.nil?
25
-
26
- begin
27
- xml = File.read(filename)
28
- rescue SystemCallError
29
- abort "Could not read XML input from `#{filename}`."
30
- end
31
-
32
- rolls =
33
- Filmrolls::FilmRolls.load(xml)[:rolls].map do |roll|
34
- roll = roll.to_h
35
- roll[:frames] = roll[:frames].length
36
- end
37
-
38
- unless rolls.empty?
39
- require 'terminal-table'
40
- head = rolls.first.keys.map(&:capitalize)
41
- rows = rolls.map(&:values)
42
- say Terminal::Table.new(headings: head, rows: rows)
43
- end
44
- end
45
- end
5
+ Filmrolls::Cli.run
data/filmrolls.gemspec ADDED
@@ -0,0 +1,76 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+ require 'filmrolls/version'
3
+ require 'rake'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'filmrolls'
7
+ s.version = Filmrolls::VERSION
8
+ s.summary = 'Tag TIFF files with EXIF data extracted from XML data'
9
+
10
+ s.author = 'Simon Sigurdhsson'
11
+ s.email = 'Sigurdhsson@gmail.com'
12
+ s.homepage = 'https://github.com/urdh/filmrolls'
13
+ s.license = 'ISC'
14
+
15
+ s.description = <<-EOF
16
+ This is a utility designed to read the XML files used by the Film Rolls
17
+ iOS app, and enable batch EXIF tagging of scanned negatives in TIFF format
18
+ based on the information in these XML files.
19
+ EOF
20
+
21
+ s.files = %w[
22
+ filmrolls.gemspec
23
+ Rakefile
24
+ README.md
25
+ LICENSE.md
26
+ bin/filmrolls
27
+ man/filmrolls.1
28
+ lib/filmrolls.rb
29
+ lib/filmrolls/cli.rb
30
+ lib/filmrolls/exiftool.rb
31
+ lib/filmrolls/negative.rb
32
+ lib/filmrolls/version.rb
33
+ lib/filmrolls/xmlformat.rb
34
+ test/test_helper.rb
35
+ test/test_exiftool.rb
36
+ test/test_xmlformat.rb
37
+ test/data/filmrolls.xml
38
+ test/data/with-exif.tiff
39
+ test/data/without-exif.tiff
40
+ ]
41
+ # TODO: how to generate the man page and inclue in the gem?
42
+
43
+ s.bindir = 'bin'
44
+ s.executables = %w[
45
+ filmrolls
46
+ ]
47
+
48
+ s.require_paths = 'lib'
49
+ s.test_files = %w[
50
+ test/test_exiftool.rb
51
+ test/test_xmlformat.rb
52
+ ]
53
+
54
+ s.extra_rdoc_files = %w[README.md LICENSE.md bin/filmrolls]
55
+ s.rdoc_options = [
56
+ '--line-numbers', '--inline-source',
57
+ '--title', 'Film Rolls EXIF tagger',
58
+ '--main', 'README.md'
59
+ ]
60
+
61
+ s.add_dependency 'mini_exiftool', ['~> 2.8']
62
+ s.add_dependency 'exiftool_vendored', ['~> 11']
63
+ s.add_dependency 'nokogiri', ['~> 1.10']
64
+ s.add_dependency 'geokit', ['~> 1.11']
65
+ s.add_dependency 'commander', ['~> 4.4']
66
+ s.add_dependency 'terminal-table', ['~> 1.8']
67
+
68
+ s.add_development_dependency 'rake', ['~> 12']
69
+ s.add_development_dependency 'rdoc', ['~> 6']
70
+ s.add_development_dependency 'bundler', ['~> 2']
71
+ s.add_development_dependency 'simplecov', ['~> 0.14']
72
+ s.add_development_dependency 'codacy-coverage', ['~> 2']
73
+ s.add_development_dependency 'minitest', ['~> 5.8']
74
+ s.add_development_dependency 'minitest-reporters', ['~> 1.3']
75
+ s.add_development_dependency 'ronn', ['~> 0.7']
76
+ end
@@ -0,0 +1,131 @@
1
+ require 'filmrolls'
2
+ require 'commander'
3
+
4
+ module Filmrolls
5
+ module Cli
6
+ include Commander::Methods
7
+
8
+ def self.run
9
+ program :version, Filmrolls::VERSION
10
+ program :description, 'Tag TIFF files with EXIF data extracted from XML.'
11
+ program :help_formatter, :compact
12
+
13
+ global_option '-r', '--rolls FILE', 'Film Rolls XML file (default: stdin)' do |r|
14
+ $rolls_file = r
15
+ end
16
+
17
+ command 'list-rolls' do |c|
18
+ c.syntax = 'filmrolls list-rolls [--rolls FILE]'
19
+ c.summary = 'List film rolls'
20
+ c.description = 'List ID and additional data for all film rolls ' \
21
+ 'in input.'
22
+
23
+ c.action do |_args, _options|
24
+ rolls = get_rolls($rolls_file).map do |roll|
25
+ roll.merge(
26
+ frames: roll[:frames].length,
27
+ unload: roll[:unload].to_date,
28
+ load: roll[:load].to_date
29
+ )
30
+ end
31
+
32
+ unless rolls.empty?
33
+ require 'terminal-table'
34
+ head = rolls.first.keys.map(&:capitalize)
35
+ rows = rolls.map(&:values)
36
+ say Terminal::Table.new(headings: head, rows: rows)
37
+ end
38
+ end
39
+ end
40
+
41
+ command 'list-frames' do |c|
42
+ c.syntax = 'filmrolls list-frames [--rolls FILE] --id ID'
43
+ c.summary = 'List frames'
44
+ c.description = 'List frames from film roll with ID in input.'
45
+ c.option '-i', '--id ID', 'Use data from roll with id ID'
46
+
47
+ c.action do |_args, options|
48
+ abort "A film roll ID must be supplied" if options.id.nil?
49
+
50
+ roll = get_rolls($rolls_file).detect do |r|
51
+ r[:id] == options.id
52
+ end
53
+
54
+ abort "Could not find film roll with ID #{options.id}" if roll.nil?
55
+
56
+ unless roll.nil?
57
+ require 'terminal-table'
58
+ head = roll[:frames].first.keys.map(&:capitalize)
59
+ rows = roll[:frames].map(&:values)
60
+ say Terminal::Table.new(headings: head, rows: rows)
61
+ end
62
+ end
63
+ end
64
+
65
+ command :tag do |c|
66
+ c.syntax = 'filmrolls tag [--dry-run] [--rolls FILE] --id ID IMAGE...'
67
+ c.summary = 'Write EXIF tags'
68
+ c.description = 'Write EXIF tags to a set of images using data from ' \
69
+ 'film roll with ID in input.'
70
+ c.option '-i', '--id ID', 'Use data from roll with id ID'
71
+ c.option '-n', '--dry-run', "Don't actually modify any files"
72
+
73
+ c.action do |args, options|
74
+ abort "A film roll ID must be supplied" if options.id.nil?
75
+
76
+ roll = get_rolls($rolls_file).detect do |r|
77
+ r[:id] == options.id
78
+ end
79
+
80
+ abort "Could not find film roll with ID #{options.id}" if roll.nil?
81
+
82
+ unless args.length == roll[:frames].length
83
+ abort "Expected #{roll[:frames].length} images, got #{args.length}"
84
+ end
85
+
86
+ roll[:frames].zip(args).each do |frame, file|
87
+ log 'Path', file
88
+ negative = Filmrolls::Negative.new(file)
89
+ log 'Date', frame[:date]
90
+ negative.date = frame[:date]
91
+ log 'Camera', roll[:camera]
92
+ negative.camera = roll[:camera]
93
+ log 'Lens', frame[:lens]
94
+ negative.lens = frame[:lens]
95
+ log 'Film', roll[:film]
96
+ negative.film = roll[:film]
97
+ log 'ISO', roll[:speed]
98
+ negative.speed = roll[:speed]
99
+ if frame[:shutter_speed] != 0 and frame[:aperture] != 0
100
+ log 'Shutter speed', "#{frame[:shutter_speed]}s"
101
+ negative.shutter_speed = frame[:shutter_speed]
102
+ log 'Aperture', "ƒ/#{frame[:aperture]}"
103
+ negative.aperture = frame[:aperture]
104
+ end
105
+ if frame[:compensation] != 0
106
+ log 'Compensation', frame[:compensation]
107
+ negative.compensation = frame[:compensation]
108
+ end
109
+ if frame[:position] != Geokit::LatLng.new(0.0, 0.0)
110
+ log 'Position', frame[:position]
111
+ negative.position = frame[:position]
112
+ end
113
+ negative.save! unless options.dry_run
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ class << self
120
+ private
121
+
122
+ def get_rolls(file)
123
+ begin
124
+ Filmrolls::XMLFormat.load(file.nil? ? $stdin.read : File.read(file))[:rolls]
125
+ rescue SystemCallError => err
126
+ abort "Could not read input XML: #{err.message}"
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,13 @@
1
+ require 'exiftool_vendored'
2
+ require 'mini_exiftool'
3
+
4
+ module Filmrolls
5
+ class Exiftool < MiniExiftool
6
+ self.command = ExiftoolVendored.path_to_exiftool
7
+
8
+ def initialize(filename_or_io = nil, opts = {})
9
+ opts[:timestamps] = DateTime unless opts.key? :timestamps
10
+ super(filename_or_io, opts)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,77 @@
1
+ require 'filmrolls/exiftool'
2
+
3
+ module Filmrolls
4
+ class Negative
5
+ def initialize(path)
6
+ @file = Exiftool.new(path, :coord_format => "%.6f degrees")
7
+ end
8
+
9
+ def merge(*args)
10
+ args.each do |key, value|
11
+ method = "#{key}="
12
+ @self.public_send(method, value) if @self.respond_to? method
13
+ end
14
+ end
15
+
16
+ def to_s
17
+ require 'yaml'
18
+ @file.to_yaml
19
+ end
20
+
21
+ def changed?
22
+ @file.changed?
23
+ end
24
+
25
+ def save!
26
+ @file.save!
27
+ end
28
+
29
+ def aperture=(val)
30
+ @file[:ApertureValue] = val
31
+ end
32
+
33
+ def speed=(val)
34
+ @file[:ISO] = val
35
+ end
36
+
37
+ def shutter_speed=(val)
38
+ @file[:ShutterSpeedValue] = val
39
+ end
40
+
41
+ def compensation=(val)
42
+ @file[:ExposureCompensation] = val
43
+ end
44
+
45
+ def position=(val)
46
+ @file[:GPSLatitude] = "#{val.lat} degrees"
47
+ @file[:GPSLatitudeRef] = 1 # Positive number interpreted as East
48
+ @file[:GPSLongitude] = "#{val.lng} degrees"
49
+ @file[:GPSLongitudeRef] = 1 # Positive number interpreted as North
50
+ end
51
+
52
+ def film=(val)
53
+ @file[:UserComment] = val
54
+ end
55
+
56
+ def date=(val)
57
+ @file[:DateTimeOriginal] = val
58
+ end
59
+
60
+ def lens=(val)
61
+ # TODO: this is hacky as f
62
+ make = val.strip.split(/\s+/)[0]
63
+ model = val.strip[(make.length)..-1]
64
+ @file[:Lens] = val
65
+ @file[:LensMake] = make
66
+ @file[:LensModel] = model
67
+ end
68
+
69
+ def camera=(val)
70
+ make = val.strip.split(/\s+/)[0]
71
+ model = val.strip[(make.length)..-1]
72
+ @file[:LocalizedCameraModel] = val
73
+ @file[:Make] = make
74
+ @file[:Model] = model
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,3 @@
1
+ module Filmrolls
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,72 @@
1
+ require 'nokogiri'
2
+ require 'date'
3
+ require 'geokit'
4
+
5
+ module Filmrolls
6
+ module XMLFormat
7
+ class Parser
8
+ def self.load(io)
9
+ doc = Nokogiri::XML(io)
10
+ doc.remove_namespaces!
11
+ {
12
+ cameras:
13
+ doc.xpath('/data/cameras/camera').map { |n| load_camera(n) },
14
+ lenses:
15
+ doc.xpath('/data/lenses/lens').map { |n| load_lens(n) },
16
+ accessories:
17
+ doc.xpath('/data/accessories/accessory').map { |n| load_accessory(n) },
18
+ rolls:
19
+ doc.xpath('/data/filmRolls/filmRoll').map { |n| load_filmroll(n) }
20
+ }
21
+ end
22
+
23
+ class << self
24
+ private
25
+
26
+ def load_camera(node)
27
+ node.text
28
+ end
29
+
30
+ def load_lens(node)
31
+ node.text
32
+ end
33
+
34
+ def load_accessory(node)
35
+ node.text
36
+ end
37
+
38
+ def load_filmroll(node)
39
+ {
40
+ id: node.at_xpath('./note').text,
41
+ film: node.at_xpath('./title').text,
42
+ speed: node.at_xpath('./speed').text.to_i,
43
+ camera: node.at_xpath('./camera').text,
44
+ load: DateTime.iso8601(node.at_xpath('./load').text),
45
+ unload: DateTime.iso8601(node.at_xpath('./unload').text),
46
+ frames: node.xpath('./frames/frame').map { |n| load_frame(n) }
47
+ }
48
+ end
49
+
50
+ def load_frame(node)
51
+ {
52
+ lens: node.at_xpath('./lens').text,
53
+ aperture: node.at_xpath('./aperture').text.to_f,
54
+ shutter_speed: node.at_xpath('./shutterSpeed').text.to_r,
55
+ compensation: node.at_xpath('./compensation').text.to_f,
56
+ accessory: node.at_xpath('./accessory').text,
57
+ date: DateTime.iso8601(node.at_xpath('./date').text),
58
+ note: node.at_xpath('./note').text,
59
+ position: Geokit::LatLng.new(
60
+ node.at_xpath('./latitude').text.to_f,
61
+ node.at_xpath('./longitude').text.to_f
62
+ )
63
+ }
64
+ end
65
+ end
66
+ end
67
+
68
+ def self.load(io)
69
+ Parser.load(io)
70
+ end
71
+ end
72
+ end
data/lib/filmrolls.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  require 'filmrolls/version'
2
- require 'filmrolls/exiftool'
3
- require 'filmrolls/filmrolls'
2
+ require 'filmrolls/negative'
3
+ require 'filmrolls/xmlformat'
data/man/filmrolls.1 ADDED
@@ -0,0 +1,47 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "FILMROLLS" "1" "May 2019" "" "filmrolls v0.1.0"
5
+ .
6
+ .SH "NAME"
7
+ \fBfilmrolls\fR \- Tag TIFF files with EXIF data extracted from XML data
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBfilmrolls list\-rolls [\-\-rolls FILE]\fR \fBfilmrolls list\-frames [\-\-rolls FILE] \-\-id ID\fR \fBfilmrolls tag [\-\-rolls FILE] \-\-id ID FILES\.\.\.\fR
11
+ .
12
+ .SH "DESCRIPTION"
13
+ Reads XML data from the \fIFilm Rolls\fR iOS app and displays or applies this data as EXIF tags to a given set of files\.
14
+ .
15
+ .SH "OPTIONS"
16
+ .
17
+ .TP
18
+ \fB\-r\fR, \fB\-\-rolls\fR
19
+ Input XML file\. If this argument is not present, XML is read from standard input\.
20
+ .
21
+ .TP
22
+ \fB\-i\fR, \fB\-\-id\fR
23
+ A specific film roll to work with, keyed by the \fINotes\fR field of the \fIFilm Rolls\fR content\.
24
+ .
25
+ .TP
26
+ \fB\-n\fR, \fB\-\-dry\-run\fR
27
+ Don\'t actually modify any files\.
28
+ .
29
+ .SH "COMMANDS"
30
+ .
31
+ .TP
32
+ \fBlist\-rolls\fR
33
+ List all film rolls in the input XML, along with some common metadata\.
34
+ .
35
+ .TP
36
+ \fBlist\-frames\fR
37
+ List all frames of the given roll in the input XML, along with all the relevant metadata\.
38
+ .
39
+ .TP
40
+ \fBtag\fR
41
+ Tag the given input files with EXIF data based on the given roll in the input XML\. All file formats supported by exiftool(1) are supported\. The number of files to tag must match the number of frames in the given roll\.
42
+ .
43
+ .IP
44
+ \fBNote:\fR No attempt to validate the file format of the target files will be made, and the command will exit after the first failure\. Use the \fB\-\-dry\-run\fR flag to verify the command\-line arguments before performing real actions\.
45
+ .
46
+ .SH "SEE ALSO"
47
+ exiftool(1)
@@ -0,0 +1,39 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <data xmlns="http://www.w3schools.com"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://www.w3schools.com export.xsd">
5
+ <cameras>
6
+ <camera>Yashica Electro 35 GT</camera>
7
+ <camera>Voigtländer Bessa R2M</camera>
8
+ </cameras>
9
+ <lenses>
10
+ <lens>Yashinon 45mm f/1.7</lens>
11
+ <lens>Color Skopar 35/2.5 Pancake II</lens>
12
+ </lenses>
13
+ <accessories>
14
+ </accessories>
15
+ <filmRolls>
16
+ <filmRoll>
17
+ <title>Ilford Delta 100</title>
18
+ <speed>100</speed>
19
+ <camera>Voigtländer Bessa R2M</camera>
20
+ <load>2016-03-28T15:16:36Z</load>
21
+ <unload>2016-05-21T14:13:15Z</unload>
22
+ <note>A0012</note>
23
+ <frames>
24
+ <frame>
25
+ <lens>Color Skopar 35/2.5 Pancake II</lens>
26
+ <aperture>5.6</aperture>
27
+ <shutterSpeed>1/500</shutterSpeed>
28
+ <compensation></compensation>
29
+ <accessory></accessory>
30
+ <number>1</number>
31
+ <date>2016-05-13T14:12:40Z</date>
32
+ <latitude>57.700767</latitude>
33
+ <longitude>11.953715</longitude>
34
+ <note></note>
35
+ </frame>
36
+ </frames>
37
+ </filmRoll>
38
+ </filmRolls>
39
+ </data>
Binary file
Binary file
data/test/test_helper.rb CHANGED
@@ -1,7 +1,4 @@
1
- if ENV['CI']
2
- require 'codacy-coverage'
3
- Codacy::Reporter.start
4
- else
5
- require 'minitest/reporters'
6
- Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
7
- end
1
+ require 'simplecov' if ENV['CI'] || ENV['COVERAGE']
2
+
3
+ require 'minitest/reporters'
4
+ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
@@ -1,10 +1,10 @@
1
1
  require 'test_helper'
2
2
  require 'minitest/autorun'
3
- require 'filmrolls/filmrolls'
3
+ require 'filmrolls/xmlformat'
4
4
 
5
- describe 'Filmrolls::FilmRolls.load' do
5
+ describe 'Filmrolls::XMLFormat.load' do
6
6
  let(:data) do
7
- @output ||= Filmrolls::FilmRolls.load(File.read('test/data/filmrolls.xml'))
7
+ @output ||= Filmrolls::XMLFormat.load(File.read('test/data/filmrolls.xml'))
8
8
  end
9
9
 
10
10
  describe 'the parser output' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filmrolls
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Sigurdhsson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-30 00:00:00.000000000 Z
11
+ date: 2019-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_exiftool
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.49'
33
+ version: '11'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.49'
40
+ version: '11'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: nokogiri
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.7'
47
+ version: '1.10'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.7'
54
+ version: '1.10'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: geokit
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -108,34 +108,62 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '12'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rdoc
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '6'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '6'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: bundler
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - "~>"
116
130
  - !ruby/object:Gem::Version
117
- version: '1.14'
131
+ version: '2'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.14'
118
146
  type: :development
119
147
  prerelease: false
120
148
  version_requirements: !ruby/object:Gem::Requirement
121
149
  requirements:
122
150
  - - "~>"
123
151
  - !ruby/object:Gem::Version
124
- version: '1.14'
152
+ version: '0.14'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: codacy-coverage
127
155
  requirement: !ruby/object:Gem::Requirement
128
156
  requirements:
129
157
  - - "~>"
130
158
  - !ruby/object:Gem::Version
131
- version: '1.1'
159
+ version: '2'
132
160
  type: :development
133
161
  prerelease: false
134
162
  version_requirements: !ruby/object:Gem::Requirement
135
163
  requirements:
136
164
  - - "~>"
137
165
  - !ruby/object:Gem::Version
138
- version: '1.1'
166
+ version: '2'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: minitest
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -156,14 +184,28 @@ dependencies:
156
184
  requirements:
157
185
  - - "~>"
158
186
  - !ruby/object:Gem::Version
159
- version: '1.1'
187
+ version: '1.3'
160
188
  type: :development
161
189
  prerelease: false
162
190
  version_requirements: !ruby/object:Gem::Requirement
163
191
  requirements:
164
192
  - - "~>"
165
193
  - !ruby/object:Gem::Version
166
- version: '1.1'
194
+ version: '1.3'
195
+ - !ruby/object:Gem::Dependency
196
+ name: ronn
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.7'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.7'
167
209
  description: |2
168
210
  This is a utility designed to read the XML files used by the Film Rolls
169
211
  iOS app, and enable batch EXIF tagging of scanned negatives in TIFF format
@@ -172,21 +214,41 @@ email: Sigurdhsson@gmail.com
172
214
  executables:
173
215
  - filmrolls
174
216
  extensions: []
175
- extra_rdoc_files: []
217
+ extra_rdoc_files:
218
+ - README.md
219
+ - LICENSE.md
220
+ - bin/filmrolls
176
221
  files:
177
222
  - LICENSE.md
178
223
  - README.md
224
+ - Rakefile
179
225
  - bin/filmrolls
226
+ - filmrolls.gemspec
180
227
  - lib/filmrolls.rb
228
+ - lib/filmrolls/cli.rb
229
+ - lib/filmrolls/exiftool.rb
230
+ - lib/filmrolls/negative.rb
231
+ - lib/filmrolls/version.rb
232
+ - lib/filmrolls/xmlformat.rb
233
+ - man/filmrolls.1
234
+ - test/data/filmrolls.xml
235
+ - test/data/with-exif.tiff
236
+ - test/data/without-exif.tiff
181
237
  - test/test_exiftool.rb
182
- - test/test_filmrolls.rb
183
238
  - test/test_helper.rb
184
- homepage: https://github.com/urdh/roll2exif
239
+ - test/test_xmlformat.rb
240
+ homepage: https://github.com/urdh/filmrolls
185
241
  licenses:
186
242
  - ISC
187
243
  metadata: {}
188
244
  post_install_message:
189
- rdoc_options: []
245
+ rdoc_options:
246
+ - "--line-numbers"
247
+ - "--inline-source"
248
+ - "--title"
249
+ - Film Rolls EXIF tagger
250
+ - "--main"
251
+ - README.md
190
252
  require_paths:
191
253
  - lib
192
254
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -200,9 +262,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
262
  - !ruby/object:Gem::Version
201
263
  version: '0'
202
264
  requirements: []
203
- rubyforge_project:
204
- rubygems_version: 2.6.11
265
+ rubygems_version: 3.0.3
205
266
  signing_key:
206
267
  specification_version: 4
207
268
  summary: Tag TIFF files with EXIF data extracted from XML data
208
- test_files: []
269
+ test_files:
270
+ - test/test_exiftool.rb
271
+ - test/test_xmlformat.rb