xferase 0.1.4 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 445f21fea4fd88d2e7d5f2a90909837d7ad87cfaac4ab0f203d946a40baa54e2
4
- data.tar.gz: daf77691cc61be839ea0a347243768c2662364d3b1f9a6585182cac1e412aa3a
3
+ metadata.gz: 8cfeb3a0c461ed62ea34b8e80475afb578f8106c612c4adea4d9b3ed3ccc8f8d
4
+ data.tar.gz: e5705058a3493f17747960340db567a72d5baa54594a5fe7584d651f3e42f954
5
5
  SHA512:
6
- metadata.gz: 3bc5e2922cc0a0286c4d73c0547a7d91135e16f99e18e939c28eba2269b4a95dc3c41a49cac06a76639c552968b9dfe29bbd213b99ec00d6cec3c495481896de
7
- data.tar.gz: 322c2a45cd9e233f77ffbee6807477ef7483afb9252bea8f9f828cdf6587fdeb9f7706ead6aed4cf716648f2caaf0c1d56aa183d9889896d93ed5cdddfb69170
6
+ metadata.gz: d04eb91e1238fe7cdeada301402ebcd2c38abef8cac5725d741dc62c887fc964679a5b44c0e84840c3d150c100fcefbfa83d1943c83d126b1ed1b62f7a384d25
7
+ data.tar.gz: aa4d7503e35ca5e64b0a83576e948f464196899b45eea371b5a2792c6d76c159f68df368e8c0ecfa00a299971c668c823fcc73dd5ccbd1dcc1ae512430704fdd
data/README.md CHANGED
@@ -221,6 +221,33 @@ it will be automatically deleted from the other.
221
221
  > if you shoot RAW+JPEG, deleting a .jpg will cause Xferase to delete the
222
222
  > corresponding raw image file (and vice versa).
223
223
 
224
+ #### Better yet: Using Docker Compose
225
+
226
+ With [Docker Compose][], you can store your deployment parameters
227
+ in a static configuration file:
228
+
229
+ ```yaml
230
+ # docker-compose.yml
231
+
232
+ version: '3.4'
233
+
234
+ services:
235
+ xferase:
236
+ image: rlue/xferase:latest
237
+ container_name: xferase
238
+ user: 1000:1000
239
+ environment:
240
+ TZ: America/Los_Angeles
241
+ INBOX: /data/.inbox
242
+ LIBRARY: /data/master
243
+ LIBRARY_WEB: /data/web
244
+ volumes:
245
+ - $HOME/Pictures:/data
246
+ restart: unless-stopped
247
+ ```
248
+
249
+ [Docker Compose]: https://docs.docker.com/compose/
250
+
224
251
  Guides
225
252
  ------
226
253
 
@@ -237,6 +264,46 @@ Guides
237
264
 
238
265
  * [🖥️🔄📱 Sync your library (back) to other devices](guides/propagate.md)
239
266
 
267
+ Bonus Features
268
+ --------------
269
+
270
+ Whenever you’re shooting on devices that need their clocks set manually,
271
+ the timestamps on all your stuff can end up out of whack. For instance:
272
+
273
+ * I often forget to adjust the clock on my camera when DST changes,
274
+ or when I fly across time zones.
275
+ In these cases, you will want to **shift timestamps**
276
+ by some fixed number of hours.
277
+
278
+ To apply this change automatically during import,
279
+ simply place your files in a directory named `shift-timestamp:<n>h`
280
+ (where `<n>` is an integer number of hours to shift by; _e.g.,_ `4` or `-8`).
281
+
282
+ * Video timestamps should always be in UTC,
283
+ while photo timestamps should always be in local time.
284
+ (Don’t ask me for a source on this one;
285
+ supposedly it’s in the EXIF and MP4/MOV specs, which I don’t have access to,
286
+ but this fact is repeated all over the place on the Exiftool forums.)
287
+
288
+ If your camera doesn’t have GPS capabilities
289
+ or any other way of knowing what time zone it’s in,
290
+ your video timestamps will _not_ be in UTC.
291
+ In these cases, you will want to **backfill the missing time zone data**.
292
+
293
+ To apply this change automatically during import,
294
+ simply place your files in a directory named `local-tz:<timezone>`
295
+ (where `<timezone>` is a [valid IANA time zone][], with colons in place of slashes;
296
+ _e.g.,_ `America:Argentina:Buenos_Aires` or `Asia:Calcutta`).
297
+
298
+ Xferase is smart enough to make the right adjustments when you do this:
299
+ metadata timestamps will be set to UTC, and filename timestamps will be set to local time.
300
+
301
+ [valid IANA time zone]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
302
+
303
+ To apply both changes, simply nest the folders within each other.
304
+ If multiple conflicting directories are found,
305
+ Xferase will use the one nearest to the file being imported.
306
+
240
307
  License
241
308
  -------
242
309
 
data/bin/xferase CHANGED
@@ -16,7 +16,7 @@ Photein.logger = Xferase.logger
16
16
 
17
17
  ENV['MEDIAINFO_XML_PARSER'] ||= 'nokogiri'
18
18
 
19
- FORMAT_GROUPS = [%w(.jpg .dng .heic), %w(.mov .mp4), %w(.png)]
19
+ FORMAT_GROUPS = [%w(.jpg .dng), %w(.heic), %w(.mov .mp4), %w(.png)]
20
20
 
21
21
  # Setup ------------------------------------------------------------------------
22
22
  require 'debouncer'
@@ -45,14 +45,16 @@ def import(file)
45
45
  Pathname(file)
46
46
  end.cleanpath
47
47
 
48
+ opts = Xferase::Config.extract_photein_opts(file)
49
+
48
50
  return unless file.exist?
49
51
  return if file.basename.fnmatch?('.*')
50
52
  return if file.dirname.join(".syncthing.#{file.basename}.tmp").exist?
51
53
 
52
54
  Xferase.logger.debug("#{file.basename}: new file detected in watch directory; importing...")
53
55
 
54
- Photein::MediaFile.for(file)&.import ||
55
- Xferase.logger.debug("#{file.basename}: unrecognize media type")
56
+ Photein::MediaFile.for(file, opts: opts)&.import ||
57
+ Xferase.logger.debug("#{file.basename}: unrecognized media type")
56
58
  rescue => e
57
59
  warn e.message
58
60
  end
@@ -3,6 +3,8 @@
3
3
  require 'singleton'
4
4
  require 'optparse'
5
5
 
6
+ require 'photein/config'
7
+
6
8
  module Xferase
7
9
  class Config
8
10
  include Singleton
@@ -56,6 +58,36 @@ module Xferase
56
58
  def respond_to_missing?(m, *args)
57
59
  @params.key?(m.to_s.tr('_', '-').to_sym) || super
58
60
  end
61
+
62
+ def extract_photein_opts(path)
63
+ path.to_s.split('/')
64
+ .grep(/^(shift-timestamp|local-tz):.+$/)
65
+ .map { |opt| opt.split(':', 2) }
66
+ .select(&method(:validate_photein_opt))
67
+ .map(&method(:normalize_photein_opt)).to_h
68
+ end
69
+
70
+ private
71
+
72
+ def validate_photein_opt(opt)
73
+ case opt.first
74
+ when 'shift-timestamp'
75
+ opt.last.match?(/^[+-]?\d+h$/)
76
+ when 'local-tz'
77
+ Photein::Config::TZ_GEOCOORDS
78
+ .transform_keys(&:downcase)
79
+ .key?(opt.last.tr(':', '/').downcase)
80
+ end
81
+ end
82
+
83
+ def normalize_photein_opt(opt)
84
+ case opt.first
85
+ when 'shift-timestamp'
86
+ [:shift_timestamp, opt.last.tr('+h', '')]
87
+ when 'local-tz'
88
+ [:local_tz, opt.last.tr(':', '/')]
89
+ end
90
+ end
59
91
  end
60
92
  end
61
93
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Xferase
4
- VERSION = '0.1.4'
4
+ VERSION = '0.1.6'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xferase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Lue
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-09-06 00:00:00.000000000 Z
10
+ date: 2025-01-05 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: debouncer
@@ -30,20 +29,20 @@ dependencies:
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: '0.1'
32
+ version: '0.2'
34
33
  - - ">="
35
34
  - !ruby/object:Gem::Version
36
- version: 0.1.5
35
+ version: 0.2.5
37
36
  type: :runtime
38
37
  prerelease: false
39
38
  version_requirements: !ruby/object:Gem::Requirement
40
39
  requirements:
41
40
  - - "~>"
42
41
  - !ruby/object:Gem::Version
43
- version: '0.1'
42
+ version: '0.2'
44
43
  - - ">="
45
44
  - !ruby/object:Gem::Version
46
- version: 0.1.5
45
+ version: 0.2.5
47
46
  - !ruby/object:Gem::Dependency
48
47
  name: rb-inotify
49
48
  requirement: !ruby/object:Gem::Requirement
@@ -104,7 +103,6 @@ licenses:
104
103
  - MIT
105
104
  metadata:
106
105
  source_code_uri: https://github.com/rlue/xferase
107
- post_install_message:
108
106
  rdoc_options: []
109
107
  require_paths:
110
108
  - lib
@@ -119,8 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
117
  - !ruby/object:Gem::Version
120
118
  version: '0'
121
119
  requirements: []
122
- rubygems_version: 3.3.7
123
- signing_key:
120
+ rubygems_version: 3.6.2
124
121
  specification_version: 4
125
122
  summary: Import/rename photos & videos from one directory to another.
126
123
  test_files: []