adri 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +42 -26
  4. data/bin/adri +40 -5
  5. metadata +22 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fc54b8d1ef7e4486a3d5926fc8c28633ceab6709d0a9160d026ae8497e99e65
4
- data.tar.gz: ea3895da8d463f866fe4b702f0204a31596dd0047d401fc6cdcf2ff4321d676d
3
+ metadata.gz: 90377a82643327c5d87bcb74efc72d75f5ada30761b194a518f4755dc6c0068c
4
+ data.tar.gz: f924d6679ed5e00f4ad8b8fab22f0210602e96c34dfb793bbbd87d9d4af013a7
5
5
  SHA512:
6
- metadata.gz: 5433f1bafa362f9d04e5c1c6401195941c82ba08aa86ce8f597b23459b58889311ca65e827ad5ebce9c018dea393d1a89274e840adac4926abe41c99ad7756bd
7
- data.tar.gz: e9b46b82b46126ba281fd895154093bb339f9c3fb0bcc928acd888251e9ceb87323bd01f483432a8177e78c0dbd11beaa6c245dc828c512b37a96fb5f212d884
6
+ metadata.gz: d8b94ea5b8b0dcd583283f5b41aa2e670dfd8524bee5931a34ce302be69c7cce7a4e1684cdf781427a2b2f47547ff7e0be0704aa77ab8815e5a2f36580da16a7
7
+ data.tar.gz: cbfcaf8200e317b1c1d75d48a2d740063f099dc1e016184779538165dd1fe0ba7c72ac8688da7e8c08ebad6db0a8a4ef6dad8957bdf60a70dbf0dcafd1023b32
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog][] and this project adheres to
6
+ [Semantic Versioning][].
7
+
8
+ ## [Unreleased][]
9
+
10
+ ## [0.1.0][] - 2020-09-06
11
+
12
+ ### Added
13
+
14
+ - Make language of geocoding results configurable through the
15
+ `GEOCODER_LANGUAGE` environment variable (default is `en` for English)
16
+
17
+ ### Changed
18
+
19
+ - Update README file
20
+ - Update Gem dependencies
21
+ - Improve specificity of extracted location
22
+ - Increase geocoding timeout from 3 to 10 seconds
23
+ - Handle geocoding timeout errors
24
+
25
+ ## [0.0.1][] - 2018-12-06
26
+
27
+ Initial release.
28
+
29
+ [Keep a Changelog]: http://keepachangelog.com/en/1.0.0/
30
+ [Semantic Versioning]: http://semver.org/spec/v2.0.0.html
31
+ [Unreleased]: https://github.com/agorf/adri/compare/0.1.0...HEAD
32
+ [0.1.0]: https://github.com/agorf/adri/compare/0.0.1...0.1.0
33
+ [0.0.1]: https://github.com/agorf/adri/releases/tag/0.0.1
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # adri
1
+ # adri [![Gem Version](https://badge.fury.io/rb/adri.svg)](http://badge.fury.io/rb/adri)
2
2
 
3
3
  adri organizes JPEG/TIFF photographs according to their EXIF date and location
4
4
  data into a custom directory structure.
@@ -6,23 +6,25 @@ data into a custom directory structure.
6
6
  In other words, it turns this:
7
7
 
8
8
  ```sh
9
- $ ls -1 photos/*.jpg
10
- IMG100001.jpg
11
- IMG100002.jpg
12
- IMG100003.jpg
9
+ $ tree photos/
10
+ photos/
11
+ ├── IMG100001.jpg
12
+ ├── IMG100002.jpg
13
+ └── IMG100003.jpg
13
14
  ```
14
15
 
15
16
  To this:
16
17
 
17
18
  ```sh
18
- $ tree photos/2018/
19
- photos/2018/
20
- └── 10/
21
- └── 14/
22
- └── London
23
- ├── IMG100001.jpg
24
- ├── IMG100002.jpg
25
- └── IMG100003.jpg
19
+ $ tree photos/
20
+ photos/
21
+ └── 2018/
22
+ └── 10/
23
+ └── 14/
24
+ └── London
25
+ ├── IMG100001.jpg
26
+ ├── IMG100002.jpg
27
+ └── IMG100003.jpg
26
28
  ```
27
29
 
28
30
  ## Installation
@@ -76,26 +78,33 @@ usage: adri [options] <path>...
76
78
  -h, --help Print help text
77
79
  ```
78
80
 
79
- **By default, adri runs in dry run mode.** This means it simply prints out what
80
- it would do, without actually doing it:
81
+ ### Dry run mode (default)
82
+
83
+ By default, adri runs in dry run mode, printing `(DRY RUN)` at the end of each
84
+ line. This means it simply prints out what it would do, without actually doing
85
+ it:
81
86
 
82
87
  ```sh
83
88
  $ pwd
84
89
  /home/agorf/work/adri/
85
- $ ls -1 photos/*.jpg
86
- IMG100001.jpg
87
- IMG100002.jpg
88
- IMG100003.jpg
90
+ $ tree photos/
91
+ photos/
92
+ ├── IMG100001.jpg
93
+ ├── IMG100002.jpg
94
+ └── IMG100003.jpg
89
95
  $ adri photos/*.jpg
90
96
  /home/agorf/work/adri/photos/IMG100001.jpg -> /home/agorf/work/adri/photos/2018/10/14/London/IMG100001.jpg (DRY RUN)
91
97
  /home/agorf/work/adri/photos/IMG100002.jpg -> /home/agorf/work/adri/photos/2018/10/14/London/IMG100002.jpg (DRY RUN)
92
98
  /home/agorf/work/adri/photos/IMG100003.jpg -> /home/agorf/work/adri/photos/2018/10/14/London/IMG100003.jpg (DRY RUN)
93
- $ ls -1 photos/
94
- IMG100001.jpg
95
- IMG100002.jpg
96
- IMG100003.jpg
99
+ $ tree photos/
100
+ photos/
101
+ ├── IMG100001.jpg
102
+ ├── IMG100002.jpg
103
+ └── IMG100003.jpg
97
104
  ```
98
105
 
106
+ ### Run mode
107
+
99
108
  To apply the changes, use the `--run` option:
100
109
 
101
110
  ```sh
@@ -114,6 +123,8 @@ photos/
114
123
  └── IMG100003.jpg
115
124
  ```
116
125
 
126
+ ### Path prefix
127
+
117
128
  To place everything under a path other than the parent directory of each
118
129
  photograph, use the `--prefix` option:
119
130
 
@@ -124,8 +135,13 @@ $ adri --prefix . photos/*.jpg
124
135
  /home/agorf/work/adri/photos/IMG100003.jpg -> /home/agorf/work/adri/2018/10/14/London/IMG100003.jpg (DRY RUN)
125
136
  ```
126
137
 
127
- The default path format is year/month/day/location. It is possible to specify a
128
- custom one with the `--path-format` option:
138
+ ### Path format
139
+
140
+ The default path format is `%Y/%m/%d/%{location}` which stands for
141
+ _year/month/day/location_. Everything other than `%{location}` is formatted
142
+ according to [strftime(3)][strftime].
143
+
144
+ It is possible to specify a custom path with the `--path-format` option:
129
145
 
130
146
  ```sh
131
147
  $ adri --path-format '%{location}/%b %Y/%d' photos/*.jpg
@@ -134,7 +150,7 @@ $ adri --path-format '%{location}/%b %Y/%d' photos/*.jpg
134
150
  /home/agorf/work/adri/photos/IMG100003.jpg -> /home/agorf/work/adri/photos/London/Oct 2018/14/IMG100003.jpg (DRY RUN)
135
151
  ```
136
152
 
137
- The date is formatted according to [strftime(3)][strftime].
153
+ ### Processing many photos
138
154
 
139
155
  It's also possible to process many photos at once by passing space-separated
140
156
  file names and directories (in which case adri will [recurse][]):
data/bin/adri CHANGED
@@ -16,8 +16,18 @@ module Adri
16
16
  DEFAULT_PATH_FORMAT = '%Y/%m/%d/%{location}'.freeze
17
17
  EXTENSIONS = %w[jpg jpeg JPG JPEG tif tiff TIF TIFF].freeze
18
18
  GEOCODE_MAX_DELAY = 60 # Seconds
19
+ GEOCODER_TIMEOUT = 10 # Seconds
20
+ GEOCODER_LANGUAGE = ENV.fetch('GEOCODER_LANGUAGE', 'en').freeze
19
21
  LOCATION_CACHE_SCALE = 2
20
- VERSION = '0.0.1'.freeze
22
+ LOCATION_ADDRESS_TYPES = %i[
23
+ locality
24
+ sublocality
25
+ administrative_area_level_5
26
+ administrative_area_level_4
27
+ administrative_area_level_3
28
+ administrative_area_level_2
29
+ ].freeze
30
+ VERSION = '0.1.0'.freeze
21
31
 
22
32
  class Photo
23
33
  class << self
@@ -172,8 +182,9 @@ module Adri
172
182
 
173
183
  begin
174
184
  geocode_results = Geocoder.search(latlng)
175
- rescue Geocoder::OverQueryLimitError
176
- puts 'Got OverQueryLimitError' if verbose
185
+ rescue Geocoder::OverQueryLimitError,
186
+ Geocoder::LookupTimeout => e
187
+ puts "Got #{e.class.name}" if verbose
177
188
 
178
189
  if current_delay > GEOCODE_MAX_DELAY
179
190
  puts "Exceeded max delay of #{GEOCODE_MAX_DELAY} seconds" if verbose
@@ -187,7 +198,27 @@ module Adri
187
198
  retry
188
199
  end
189
200
 
190
- geocode_results.map(&:city).compact.uniq.first
201
+ geocode_results.each do |result|
202
+ location = location_from_geocode_result(result)
203
+
204
+ if location
205
+ return location
206
+ end
207
+ end
208
+
209
+ nil
210
+ end
211
+
212
+ private def location_from_geocode_result(result)
213
+ LOCATION_ADDRESS_TYPES.each do |type|
214
+ entity = result.address_components_of_type(type).first
215
+
216
+ if entity
217
+ return entity['long_name']
218
+ end
219
+ end
220
+
221
+ nil
191
222
  end
192
223
 
193
224
  private def location_cache_key
@@ -251,6 +282,8 @@ module Adri
251
282
  end
252
283
  end
253
284
 
285
+ # This is necessary to support both files and directories as paths. It also
286
+ # performs some basic sanity checks.
254
287
  def self.expand_paths(paths, verbose)
255
288
  glob_pattern = File.join('**', "*.{#{EXTENSIONS.join(',')}}")
256
289
 
@@ -298,7 +331,9 @@ end
298
331
  Geocoder.configure(
299
332
  always_raise: :all,
300
333
  lookup: :google,
301
- api_key: options[:api_key]
334
+ api_key: options[:api_key],
335
+ timeout: Adri::GEOCODER_TIMEOUT,
336
+ language: Adri::GEOCODER_LANGUAGE
302
337
  )
303
338
 
304
339
  Adri.expand_paths(args, !options[:quiet]).each do |path|
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adri
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Angelos Orfanakos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-06 00:00:00.000000000 Z
11
+ date: 2020-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: exif
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.2'
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
19
  version: 2.2.0
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.2'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: '2.2'
30
27
  - - ">="
31
28
  - !ruby/object:Gem::Version
32
29
  version: 2.2.0
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.2'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: geocoder
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '1.5'
40
37
  - - ">="
41
38
  - !ruby/object:Gem::Version
42
39
  version: 1.5.0
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '1.5'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - "~>"
48
- - !ruby/object:Gem::Version
49
- version: '1.5'
50
47
  - - ">="
51
48
  - !ruby/object:Gem::Version
52
49
  version: 1.5.0
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '1.5'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: slop
55
55
  requirement: !ruby/object:Gem::Requirement
@@ -74,22 +74,22 @@ dependencies:
74
74
  name: dotenv
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
- - - "~>"
78
- - !ruby/object:Gem::Version
79
- version: '2.5'
80
77
  - - ">="
81
78
  - !ruby/object:Gem::Version
82
79
  version: 2.5.0
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.5'
83
83
  type: :development
84
84
  prerelease: false
85
85
  version_requirements: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '2.5'
90
87
  - - ">="
91
88
  - !ruby/object:Gem::Version
92
89
  version: 2.5.0
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: '2.5'
93
93
  description:
94
94
  email: me@agorf.gr
95
95
  executables:
@@ -97,6 +97,7 @@ executables:
97
97
  extensions: []
98
98
  extra_rdoc_files: []
99
99
  files:
100
+ - CHANGELOG.md
100
101
  - LICENSE.txt
101
102
  - README.md
102
103
  - bin/adri
@@ -119,8 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
120
  - !ruby/object:Gem::Version
120
121
  version: '0'
121
122
  requirements: []
122
- rubyforge_project:
123
- rubygems_version: 2.7.6
123
+ rubygems_version: 3.0.3
124
124
  signing_key:
125
125
  specification_version: 4
126
126
  summary: Organize photos by date and location in a directory structure