move_media 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 96324a9faf26f71f34af9eeb59a72d440ab4c9c10cb0f30f2a1749b3c56c43b2
4
+ data.tar.gz: f75f768d3a3bdea408c1c0dffd31e8df0a1d7b06e02b2647724d14e0e9f2f740
5
+ SHA512:
6
+ metadata.gz: 8f4195c166973d455e113afbe8712371c0ff5c8c00aafc35d08db4ff96b0bcbff5042bd872c5b07b28fafc1f39181a01f430f59debdf2dad900bb8bb5cc3c0db
7
+ data.tar.gz: fdcbb6978f8773bbc4bd1d5f30a27fe8c6780515387de85e79a4e74cce1e04cf99a17847127e87125ec4e1bfdc834da7f3ed08cc2344247f9feaeb0de1b066e6
data/.rubocop.yml ADDED
@@ -0,0 +1,25 @@
1
+ AllCops:
2
+ Exclude:
3
+ - vendor/**/*
4
+ - Gemfile*
5
+ - '*.gemspec' # This does nothing. Why?
6
+ NewCops: enable
7
+ TargetRubyVersion: 2.7
8
+
9
+ Layout/HashAlignment:
10
+ Enabled: false
11
+
12
+ Layout/LineLength:
13
+ Max: 150
14
+
15
+ Metrics/MethodLength:
16
+ Max: 20
17
+
18
+ Style/StringLiterals:
19
+ EnforcedStyle: single_quotes
20
+
21
+ Style/CommandLiteral:
22
+ EnforcedStyle: percent_x
23
+
24
+ # Gemspec/RequireMFA:
25
+ # enable: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ ## 0.1.0 / 2022-08-20
2
+ * Initial version, described at https://www.mslinn.com/av_studio/210-sony-a7iii.html
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Mike Slinn
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,93 @@
1
+ `move_media`
2
+ [![Gem Version](https://badge.fury.io/rb/move_media.svg)](https://badge.fury.io/rb/move_media)
3
+ ===========
4
+
5
+ `move_media` moves files from Sony Camera memory cards to permanent storage.
6
+
7
+ ## Usage
8
+
9
+ ```
10
+ move_media
11
+ ```
12
+
13
+
14
+ ## Installation
15
+
16
+ Modify the following and save as $HOME/.move_media:
17
+
18
+ ```yaml
19
+ destination: /mnt/e/media/staging
20
+ drive: 'h:'
21
+ topic: sony
22
+ ```
23
+
24
+ Install like this:
25
+ ```
26
+ $ gem install move_media
27
+ ```
28
+
29
+ ## Additional Information
30
+ More information is available on
31
+ [Mike Slinn’s website](https://www.mslinn.com/av_studio/210-sony-a7iii.html).
32
+
33
+
34
+ ## Development
35
+
36
+ After checking out the repo, run `bin/setup` to install dependencies.
37
+
38
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
39
+
40
+
41
+ ### Build and Install Locally
42
+ To build and install this gem onto your local machine, run:
43
+ ```shell
44
+ $ rake install:local
45
+ ```
46
+
47
+ The following also does the same thing:
48
+ ```shell
49
+ $ bundle exec rake install
50
+ move_media 0.1.0 built to pkg/move_media-0.1.0.gem.
51
+ move_media (0.1.0) installed.
52
+ ```
53
+
54
+ Examine the newly built gem:
55
+ ```
56
+ $ gem info move_media
57
+
58
+ *** LOCAL GEMS ***
59
+
60
+ move_media (0.1.0)
61
+ Author: Mike Slinn
62
+ Homepage:
63
+ https://github.com/mslinn/move_media
64
+ License: MIT
65
+ Installed at: /home/mslinn/.gems
66
+
67
+ Moves files from Sony Camera memory cards to permanent storage
68
+ ```
69
+
70
+
71
+ ### Build and Push to RubyGems
72
+ To release a new version,
73
+ 1. Update the version number in `version.rb`.
74
+ 2. Commit all changes to git; if you don't the next step might fail with an unexplainable error message.
75
+ 3. Run the following:
76
+ ```shell
77
+ $ bundle exec rake release
78
+ ```
79
+ The above creates a git tag for the version, commits the created tag,
80
+ and pushes the new `.gem` file to [RubyGems.org](https://rubygems.org).
81
+
82
+
83
+ ## Contributing
84
+
85
+ 1. Fork the project
86
+ 2. Create a descriptively named feature branch
87
+ 3. Add your feature
88
+ 4. Submit a pull request
89
+
90
+
91
+ ## License
92
+
93
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ task :default => :spec
data/exe/move_media ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'move_media' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("move_media", "move_media")
data/lib/mm_util.rb ADDED
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'yaml'
5
+
6
+ # Monkey patch the String class
7
+ class String
8
+ def present?
9
+ !strip.empty?
10
+ end
11
+
12
+ def integer?
13
+ !!match(/^(\d)+$/)
14
+ end
15
+ end
16
+
17
+ def delete_mp4s(source)
18
+ Dir[source]
19
+ end
20
+
21
+ # @param mount_path [String] contains the mount path to be verified.
22
+ def drive_mounted?(mount_path)
23
+ %x(mount | grep #{mount_path}).present?
24
+ end
25
+
26
+ # @return [Boolean] true if memory card was already mounted
27
+ def mount_memory_card(drive)
28
+ drive_path = mount_point(drive)
29
+ return true if drive_mounted?(drive_path)
30
+
31
+ %x(sudo mkdir #{drive_path}) unless File.exist?(drive_path)
32
+ %x(sudo mount -t drvfs #{drive.upcase} #{drive_path})
33
+ false
34
+ end
35
+
36
+ # @param dos_drive [String] has format X:
37
+ # @return Linux mount point for DOS drive under /mnt, for example /mnt/x
38
+ def mount_point(dos_drive)
39
+ match_data = dos_drive.match(/^([a-zA-Z]):/)
40
+ raise "#{dos_drive} is an invalid DOS drive specification." unless match_data && match_data.length == 2
41
+
42
+ "/mnt/#{match_data[1].downcase}"
43
+ end
44
+
45
+ # @param old_path [String] file to be moved; raises exception if not present
46
+ def move_and_rename(old_path, new_path)
47
+ File.rename(old_path, new_path)
48
+ end
49
+
50
+ # @param source [String] Directory containing videos.
51
+ # @param stem [String] File name of video, without extension
52
+ # @return [[String]] JPG filenames on memory card
53
+ # example: [ /mnt/h/PRIVATE/M4ROOT/THMBNL/C0001T01.JPG ]
54
+ def sony_thumbnail(source, stem)
55
+ thumb_source_names = "#{source}/PRIVATE/M4ROOT/THMBNL/#{stem}*.JPG"
56
+ Dir[thumb_source_names][0]
57
+ end
58
+
59
+ def unmount_memory_card(mount_point)
60
+ %x(sudo umount #{mount_point})
61
+ end
62
+
63
+ # /mnt/h/PRIVATE/M4ROOT/CLIP/C0001.MP4
64
+ def video_filenames(source)
65
+ Dir["#{source}/**/*.MP4"].sort
66
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MoveMediaVersion
4
+ VERSION = '0.1.0'
5
+ end
data/lib/move_media.rb ADDED
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ CONFIGURATION_FILE = "#{Dir.home}/.move_media"
4
+
5
+ require 'date'
6
+ require_relative 'mm_util'
7
+
8
+ # Moves media from a Sony memory card to permanent storage
9
+ class MoveMedia
10
+ attr_reader :destination_images, :destination_video, :drive, :topic
11
+
12
+ SIGNIFICANT_DIGITS = 7
13
+
14
+ def initialize
15
+ read_configuration
16
+ @seq = 1
17
+ end
18
+
19
+ def make_video_name(fn_fq)
20
+ date = File.ctime(fn_fq).to_date
21
+ seq = @seq.to_s.rjust(SIGNIFICANT_DIGITS, '0')
22
+ "#{@topic}_#{date}_#{seq}"
23
+ end
24
+
25
+ # Move Sony camera thumbnail for video_filename from source to destination
26
+ # @return new path for thumbnail
27
+ def move_thumbnail(video_filename_stem)
28
+ old_path = sony_thumbnail(@source, video_filename_stem)
29
+ old_name = File.basename(old_path, '.*')
30
+ new_path = "#{@destination_images}/#{old_name}.jpg"
31
+ move_and_rename(old_path, new_path)
32
+ new_path
33
+ end
34
+
35
+ # Destination files are yyyy-mm-dd_topic_0001234.{mp4,jpg}
36
+ def process_video(fn_fq)
37
+ new_name = make_video_name(fn_fq)
38
+ new_name_fq = "#{@destination_video}/#{new_name}.mp4"
39
+ move_and_rename(fn_fq, new_name_fq)
40
+ @seq += 1
41
+ new_name_fq
42
+ end
43
+
44
+ def read_configuration
45
+ raise "Error: #{CONFIGURATION_FILE} does not exist." unless File.exist? CONFIGURATION_FILE
46
+
47
+ config = YAML.load_file(CONFIGURATION_FILE)
48
+ @destination_images = config['destination_images']
49
+ @destination_video = config['destination_video']
50
+ @drive = config['drive']
51
+ @source = mount_point(@drive)
52
+ @topic = config['topic']
53
+ end
54
+
55
+ # Scans video file names in destination
56
+ # Files are ideally named like: sony_2022-08-22_000001.mp4
57
+ # @return [int] next sequence number based on what is already present in destination
58
+ def scan_for_next_seq(destination)
59
+ files = Dir["#{destination}/#{topic}_*"]
60
+ @seq = files.length
61
+ files.each do |path|
62
+ basename = File.basename(path, '.*')
63
+ seq = basename.split('_')[-1]
64
+ @seq = [@seq, seq.to_i].max if seq.integer?
65
+ end
66
+ @seq += 1
67
+ end
68
+
69
+ # Leaves memory card mounted if it was already mounted
70
+ def main
71
+ already_mounted = mount_memory_card(@drive)
72
+ scan_for_next_seq(@destination_video)
73
+ video_filenames(@source).each do |fn_fq|
74
+ process_video(fn_fq)
75
+ video_filename_stem = File.basename(fn_fq, '.*')
76
+ move_thumbnail(video_filename_stem)
77
+ end
78
+ unmount_memory_card(@source) unless already_mounted
79
+ end
80
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/move_media/version'
4
+
5
+ # rubocop:disable Metrics/BlockLength
6
+ Gem::Specification.new do |spec|
7
+ github = 'https://github.com/mslinn/move_media'
8
+
9
+ spec.authors = ['Mike Slinn']
10
+ spec.description = <<~END_OF_DESC
11
+ Moves files from Sony Camera memory cards to permanent storage.
12
+ END_OF_DESC
13
+ spec.bindir = 'exe'
14
+ spec.email = ['mslinn@mslinn.com']
15
+ spec.files = Dir['.rubocop.yml', 'LICENSE.*', 'Rakefile', '{lib,spec}/**/*', '*.gemspec', '*.md']
16
+ spec.executables = 'move_media'
17
+ spec.homepage = 'https://www.mslinn.com/av_studio/210-sony-a7iii.html'
18
+ spec.license = 'MIT'
19
+ spec.metadata = {
20
+ 'allowed_push_host' => 'https://rubygems.org',
21
+ 'bug_tracker_uri' => "#{github}/issues",
22
+ 'changelog_uri' => "#{github}/CHANGELOG.md",
23
+ 'homepage_uri' => spec.homepage,
24
+ 'source_code_uri' => github,
25
+ }
26
+ spec.name = 'move_media'
27
+ spec.post_install_message = <<~END_MESSAGE
28
+
29
+ Thanks for installing #{spec.name}!
30
+
31
+ END_MESSAGE
32
+ spec.require_paths = ['lib']
33
+ spec.required_ruby_version = '>= 2.6.0'
34
+ spec.summary = 'Moves files from Sony Camera memory cards to permanent storage.'
35
+ spec.test_files = spec.files.grep(%r!^(test|spec|features)/!)
36
+ spec.version = MoveMediaVersion::VERSION
37
+ end
38
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/move_media'
4
+ require_relative '../lib/mm_util'
5
+ require 'fileutils'
6
+
7
+ # Monkey patch class
8
+ class MoveMedia
9
+ attr_accessor :destination_images, :destination_video, :drive, :seq, :source
10
+ end
11
+
12
+ RSpec.describe(MoveMedia) do # rubocop:disable Metrics/BlockLength
13
+ include MoveMediaVersion
14
+
15
+ let(:destination_images) { 'spec/fixtures/destination/images' }
16
+ let(:destination_video) { 'spec/fixtures/destination/videos' }
17
+ let(:source) { 'spec/fixtures/source' }
18
+
19
+ let(:file_to_copy) { "#{source}/PRIVATE/M4ROOT/CLIP/C0001.MP4" }
20
+
21
+ def copy_videos_to_destination
22
+ FileUtils.cp(
23
+ file_to_copy,
24
+ "#{destination_video}/sony_#{Date.today}_0000041.mp4"
25
+ )
26
+ end
27
+
28
+ it 'reads config file' do
29
+ mm = MoveMedia.new
30
+ mm.read_configuration
31
+ expect(mm.destination_images).to eq('/mnt/e/media/staging/THMBNL')
32
+ expect(mm.destination_video).to eq('/mnt/e/media/staging/CLIP')
33
+ expect(mm.drive.length).to eq(2)
34
+ expect(mm.topic).to eq('sony')
35
+ end
36
+
37
+ it 'verifies mount point' do
38
+ drive = 'h:'
39
+ expect(mount_point(drive)).to eq('/mnt/h')
40
+
41
+ drive = 'H:'
42
+ expect(mount_point(drive)).to eq('/mnt/h')
43
+ end
44
+
45
+ it 'verifies mounted drive' do
46
+ mm = MoveMedia.new
47
+ mm.read_configuration
48
+ already_mounted = mount_memory_card(mm.drive)
49
+ unmount_memory_card(mm.source) if already_mounted
50
+ end
51
+
52
+ it 'finds videos' do
53
+ fns = video_filenames(source)
54
+ expect(fns.length).to eq(1)
55
+ expect(fns[0]).to eq("#{source}/PRIVATE/M4ROOT/CLIP/C0001.MP4")
56
+ end
57
+
58
+ it 'finds thumbnails for video file stem C0001' do
59
+ thumb = sony_thumbnail(source, 'C0001')
60
+ expect(thumb).to eq("#{source}/PRIVATE/M4ROOT/THMBNL/C0001T01.JPG")
61
+ end
62
+
63
+ it 'scans for next sequence number' do
64
+ mm = MoveMedia.new
65
+ mm.source = source
66
+ copy_videos_to_destination
67
+ expect(mm.scan_for_next_seq(destination_video)).to eq(42)
68
+ end
69
+
70
+ it 'makes video name' do
71
+ mm = MoveMedia.new
72
+ mm.source = source
73
+ copy_videos_to_destination
74
+ mm.scan_for_next_seq(destination_video)
75
+ file_date = File.ctime(file_to_copy).to_date
76
+ expect(mm.make_video_name(file_to_copy)).to eq("sony_#{file_date}_0000042")
77
+
78
+ mm.seq = 666
79
+ expect(mm.make_video_name(file_to_copy)).to eq("sony_#{file_date}_0000666")
80
+ end
81
+
82
+ it 'processes a video' do
83
+ mm = MoveMedia.new
84
+ mm.destination_video = destination_video
85
+ mm.destination_images = destination_images
86
+ mm.source = source
87
+ old_name = "#{source}/PRIVATE/M4ROOT/CLIP/C0001.MP4"
88
+ new_name = mm.process_video(old_name)
89
+ expect(File.exist?(old_name)).to be false
90
+ expect(File.exist?(new_name)).to be true
91
+ end
92
+
93
+ it 'processes video thumbnails' do
94
+ mm = MoveMedia.new
95
+ mm.destination_images = destination_images
96
+ mm.destination_video = destination_video
97
+ mm.source = source
98
+ video_filename_stem = 'C0001'
99
+ new_name = mm.move_thumbnail(video_filename_stem)
100
+ expect(File.exist?(new_name)).to be true
101
+ end
102
+
103
+ it 'processes video thumbnails' do
104
+ mm = MoveMedia.new
105
+ mm.destination_images = destination_images
106
+ mm.destination_video = destination_video
107
+ mm.source = source
108
+ mm.main
109
+
110
+ video_file = "#{mm.destination_video}/sony_#{Date.today}_0000041.mp4"
111
+ # p "video_file=#{video_file}"
112
+ # p "Listing files in #{mm.destination_video}"
113
+ # %x(ls "#{mm.destination_video}")
114
+ expect(File.exist?(video_file)).to be true
115
+ end
116
+
117
+ after(:all) do
118
+ %x(
119
+ git restore --source=HEAD --staged --worktree -- spec/fixtures
120
+ git clean -f spec/fixtures
121
+ )
122
+ end
123
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/move_media'
4
+
5
+ RSpec.configure do |config|
6
+ config.filter_run :focus
7
+ config.order = 'defined'
8
+ config.run_all_when_everything_filtered = true
9
+
10
+ # See https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures
11
+ config.example_status_persistence_file_path = 'spec/status_persistence.txt'
12
+ end
@@ -0,0 +1,12 @@
1
+ example_id | status | run_time |
2
+ ------------------------------- | ------ | --------------- |
3
+ ./spec/move_media_spec.rb[1:1] | passed | 0.00074 seconds |
4
+ ./spec/move_media_spec.rb[1:2] | passed | 0.00008 seconds |
5
+ ./spec/move_media_spec.rb[1:3] | passed | 0.0214 seconds |
6
+ ./spec/move_media_spec.rb[1:4] | passed | 0.00024 seconds |
7
+ ./spec/move_media_spec.rb[1:5] | passed | 0.00009 seconds |
8
+ ./spec/move_media_spec.rb[1:6] | passed | 0.00054 seconds |
9
+ ./spec/move_media_spec.rb[1:7] | passed | 0.00155 seconds |
10
+ ./spec/move_media_spec.rb[1:8] | passed | 0.00093 seconds |
11
+ ./spec/move_media_spec.rb[1:9] | passed | 0.00036 seconds |
12
+ ./spec/move_media_spec.rb[1:10] | passed | 0.03275 seconds |
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: move_media
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mike Slinn
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-08-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'Moves files from Sony Camera memory cards to permanent storage.
14
+
15
+ '
16
+ email:
17
+ - mslinn@mslinn.com
18
+ executables:
19
+ - move_media
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - ".rubocop.yml"
24
+ - CHANGELOG.md
25
+ - LICENSE.txt
26
+ - README.md
27
+ - Rakefile
28
+ - exe/move_media
29
+ - lib/mm_util.rb
30
+ - lib/move_media.rb
31
+ - lib/move_media/version.rb
32
+ - move_media.gemspec
33
+ - spec/fixtures/source/PRIVATE/M4ROOT/CLIP/C0001.MP4
34
+ - spec/fixtures/source/PRIVATE/M4ROOT/THMBNL/C0001T01.JPG
35
+ - spec/fixtures/source/PRIVATE/M4ROOT/THMBNL/C0001T02.JPG
36
+ - spec/fixtures/source/PRIVATE/M4ROOT/THMBNL/C0001T03.JPG
37
+ - spec/fixtures/source/PRIVATE/M4ROOT/THMBNL/C0001T04.JPG
38
+ - spec/move_media_spec.rb
39
+ - spec/spec_helper.rb
40
+ - spec/status_persistence.txt
41
+ homepage: https://www.mslinn.com/av_studio/210-sony-a7iii.html
42
+ licenses:
43
+ - MIT
44
+ metadata:
45
+ allowed_push_host: https://rubygems.org
46
+ bug_tracker_uri: https://github.com/mslinn/move_media/issues
47
+ changelog_uri: https://github.com/mslinn/move_media/CHANGELOG.md
48
+ homepage_uri: https://www.mslinn.com/av_studio/210-sony-a7iii.html
49
+ source_code_uri: https://github.com/mslinn/move_media
50
+ post_install_message: |2+
51
+
52
+ Thanks for installing move_media!
53
+
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.6.0
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 3.3.3
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Moves files from Sony Camera memory cards to permanent storage.
72
+ test_files:
73
+ - spec/fixtures/source/PRIVATE/M4ROOT/CLIP/C0001.MP4
74
+ - spec/fixtures/source/PRIVATE/M4ROOT/THMBNL/C0001T01.JPG
75
+ - spec/fixtures/source/PRIVATE/M4ROOT/THMBNL/C0001T02.JPG
76
+ - spec/fixtures/source/PRIVATE/M4ROOT/THMBNL/C0001T03.JPG
77
+ - spec/fixtures/source/PRIVATE/M4ROOT/THMBNL/C0001T04.JPG
78
+ - spec/move_media_spec.rb
79
+ - spec/spec_helper.rb
80
+ - spec/status_persistence.txt
81
+ ...