photein 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -1
- data/data/tz_coords.json +599 -0
- data/lib/photein/config.rb +42 -1
- data/lib/photein/image.rb +24 -4
- data/lib/photein/media_file.rb +63 -48
- data/lib/photein/version.rb +1 -1
- data/lib/photein/video.rb +62 -9
- metadata +102 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 362d9c0535398b17f736549119b3079e52fdc7c22451014d8039b1ff7172914f
|
4
|
+
data.tar.gz: f2a87140f5c536f5bc36663bf7d40c42314199ec3a3247d88a2b619507a360c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93814ee95d41d740892978276ed15863daa8832a4c6d4dcc62cbda22d114781e910d74fdbacbb508a78dce9cbbd1e14c5f9c131215b680c3c11865863dc11d18
|
7
|
+
data.tar.gz: 31384d711c87386c22b52439985ce4aec5d4d413ab8271e184f0b32cd4dad1f2628d0d88bf74f27e0a248beb304b45d0b33f20961e33b72e343cbe8affdcc7e7
|
data/README.md
CHANGED
@@ -41,7 +41,39 @@ based on metadata timestamps, filename timestamps, or file creation times.
|
|
41
41
|
> where and how your photos should be stored on disk
|
42
42
|
> (looking at you, Apple Photos 👀), Photein is not for you.
|
43
43
|
|
44
|
-
It can also
|
44
|
+
It can also:
|
45
|
+
|
46
|
+
* optimize photos and videos for reduced file size
|
47
|
+
* shift all timestamps by a given interval
|
48
|
+
(for when you forget to update the clock on your camera
|
49
|
+
for, _e.g.,_ daylight savings or traveling across time zones)
|
50
|
+
* backfill GPS metadata / `OffsetTime*` tags based on a given IANA time zone
|
51
|
+
|
52
|
+
> 🤔 **Why would you want that?**
|
53
|
+
>
|
54
|
+
> One unfortunate quirk of this problem space is that
|
55
|
+
> the EXIF standard does not cover video file formats,
|
56
|
+
> meaning photos and videos do not have the same set of metadata fields.
|
57
|
+
> Worse yet, the field we care about most (timestamps) is inconsistently defined,
|
58
|
+
> with **photo timestamps recorded in local time and video timestamps in UTC**.
|
59
|
+
>
|
60
|
+
> (I haven’t been able to find the text of these specs—supposedly,
|
61
|
+
> they are expensive—but it’s been [stated on a few occasions
|
62
|
+
> by a pretty authoritative member of the Exiftool forum](https://exiftool.org/forum/index.php?msg=51915).
|
63
|
+
> [That same user has noted that](https://exiftool.org/forum/index.php?msg=59329)
|
64
|
+
> “there is no standard for embedding EXIF data in a video file.
|
65
|
+
> Not that that has stopped a lot of camera makers from forcing it into the file.”)
|
66
|
+
>
|
67
|
+
> Photein attempts to set _all_ filenames in local time,
|
68
|
+
> applying an offset to videos based on the time zone inferred
|
69
|
+
> from their GPS location tags—which is only possible if they are present.
|
70
|
+
> Other photo utilities (like [immich](https://immich.app)) follow the same strategy,
|
71
|
+
> meaning that setting GPS tags can improve filename consistency elsewhere, too.
|
72
|
+
>
|
73
|
+
> (What about `OffsetTime*`, then? Those tags are superfluous for our needs
|
74
|
+
> since they can only be set on photos, which are already in local time—but
|
75
|
+
> implementation was straightforward, and they serve the parallel purpose
|
76
|
+
> of backfilling missing time zone info, so I figured what the heck. ¯\\\_(ツ)\_/¯)
|
45
77
|
|
46
78
|
What _doesn’t_ it do?
|
47
79
|
---------------------
|
data/data/tz_coords.json
ADDED
@@ -0,0 +1,599 @@
|
|
1
|
+
{
|
2
|
+
"Africa/Abidjan": [5.3252258,-4.019603],
|
3
|
+
"Africa/Accra": [5.559284600000001,-0.1974306],
|
4
|
+
"Africa/Addis_Ababa": [9.019193599999999,38.7524635],
|
5
|
+
"Africa/Algiers": [36.753768,3.0587561],
|
6
|
+
"Africa/Asmara": [15.3317304,38.9300394],
|
7
|
+
"Africa/Asmera": [15.3317304,38.9300394],
|
8
|
+
"Africa/Bamako": [12.6391699,-8.0025475],
|
9
|
+
"Africa/Bangui": [4.362156,18.5827765],
|
10
|
+
"Africa/Banjul": [13.454375,-16.5753186],
|
11
|
+
"Africa/Bissau": [11.8632196,-15.5843227],
|
12
|
+
"Africa/Blantyre": [-15.7666707,35.0167866],
|
13
|
+
"Africa/Brazzaville": [-4.2744405,15.2812803],
|
14
|
+
"Africa/Bujumbura": [-3.361378,29.3598782],
|
15
|
+
"Africa/Cairo": [30.0444196,31.2357116],
|
16
|
+
"Africa/Casablanca": [33.5731104,-7.589843399999999],
|
17
|
+
"Africa/Ceuta": [35.8893874,-5.3213455],
|
18
|
+
"Africa/Conakry": [9.5090945,-13.7119312],
|
19
|
+
"Africa/Dakar": [14.716677,-17.4676861],
|
20
|
+
"Africa/Dar_es_Salaam": [-6.8158925,39.2819353],
|
21
|
+
"Africa/Djibouti": [11.825138,42.590275],
|
22
|
+
"Africa/Douala": [4.0510564,9.767868699999999],
|
23
|
+
"Africa/El_Aaiun": [27.1500384,-13.1990758],
|
24
|
+
"Africa/Freetown": [8.487080299999999,-13.2354918],
|
25
|
+
"Africa/Gaborone": [-24.6580003,25.9077037],
|
26
|
+
"Africa/Harare": [-17.8262928,31.0503723],
|
27
|
+
"Africa/Johannesburg": [-26.205647,28.0337185],
|
28
|
+
"Africa/Juba": [4.853856599999999,31.58252539999999],
|
29
|
+
"Africa/Kampala": [0.3151692,32.5816313],
|
30
|
+
"Africa/Khartoum": [15.597431,32.535587],
|
31
|
+
"Africa/Kigali": [-1.9440727,30.0618851],
|
32
|
+
"Africa/Kinshasa": [-4.3032527,15.310528],
|
33
|
+
"Africa/Lagos": [6.5243793,3.3792057],
|
34
|
+
"Africa/Libreville": [0.4077972,9.440283299999999],
|
35
|
+
"Africa/Lome": [6.129557699999999,1.2196502],
|
36
|
+
"Africa/Luanda": [-8.8146556,13.2301756],
|
37
|
+
"Africa/Lubumbashi": [-11.6876026,27.5026174],
|
38
|
+
"Africa/Lusaka": [-15.4154677,28.2773267],
|
39
|
+
"Africa/Malabo": [3.7549606,8.7821344],
|
40
|
+
"Africa/Maputo": [-25.969248,32.5731746],
|
41
|
+
"Africa/Maseru": [-29.3150767,27.4869229],
|
42
|
+
"Africa/Mbabane": [-26.3263561,31.1441558],
|
43
|
+
"Africa/Mogadishu": [2.037148,45.3379067],
|
44
|
+
"Africa/Monrovia": [6.3156068,-10.8073698],
|
45
|
+
"Africa/Nairobi": [-1.2920659,36.8219462],
|
46
|
+
"Africa/Ndjamena": [12.1191352,15.0502875],
|
47
|
+
"Africa/Niamey": [13.5115963,2.1253854],
|
48
|
+
"Africa/Nouakchott": [18.0735299,-15.9582372],
|
49
|
+
"Africa/Ouagadougou": [12.3714277,-1.5196603],
|
50
|
+
"Africa/Porto-Novo": [6.478623799999999,2.6203212],
|
51
|
+
"Africa/Sao_Tome": [0.18636,6.613080999999999],
|
52
|
+
"Africa/Timbuktu": [16.7665887,-3.0025615],
|
53
|
+
"Africa/Tripoli": [32.8877109,13.187186],
|
54
|
+
"Africa/Tunis": [36.7994568,10.1831972],
|
55
|
+
"Africa/Windhoek": [-22.5649344,17.0842147],
|
56
|
+
"America/Adak": [51.8667982,-176.6385354],
|
57
|
+
"America/Anchorage": [61.2175758,-149.8996785],
|
58
|
+
"America/Anguilla": [18.220554,-63.06861499999999],
|
59
|
+
"America/Antigua": [17.060816,-61.796428],
|
60
|
+
"America/Araguaina": [-7.191563299999999,-48.2094801],
|
61
|
+
"America/Argentina/Buenos_Aires": [-34.6036844,-58.3815591],
|
62
|
+
"America/Argentina/Catamarca": [-28.469581,-65.7795441],
|
63
|
+
"America/Argentina/ComodRivadavia": [-45.7901229,-67.46797939999999],
|
64
|
+
"America/Argentina/Cordoba": [-31.42008329999999,-64.1887761],
|
65
|
+
"America/Argentina/Jujuy": [-22.6633212,-66.2367172],
|
66
|
+
"America/Argentina/La_Rioja": [-29.9001725,-66.99880109999999],
|
67
|
+
"America/Argentina/Mendoza": [-32.8894587,-68.84583859999999],
|
68
|
+
"America/Argentina/Rio_Gallegos": [-51.6230485,-69.2168291],
|
69
|
+
"America/Argentina/Salta": [-25.2529539,-64.7162415],
|
70
|
+
"America/Argentina/San_Juan": [-31.5351074,-68.5385941],
|
71
|
+
"America/Argentina/San_Luis": [-33.8769018,-66.2367172],
|
72
|
+
"America/Argentina/Tucuman": [-26.8082848,-65.2175903],
|
73
|
+
"America/Argentina/Ushuaia": [-54.8019121,-68.3029511],
|
74
|
+
"America/Aruba": [12.52111,-69.968338],
|
75
|
+
"America/Asuncion": [-25.2637399,-57.57592599999999],
|
76
|
+
"America/Atikokan": [48.7575098,-91.62182919999999],
|
77
|
+
"America/Atka": [52.2099851,-174.2030272],
|
78
|
+
"America/Bahia": [-11.4098737,-41.2808577],
|
79
|
+
"America/Bahia_Banderas": [20.8074834,-105.2480864],
|
80
|
+
"America/Barbados": [13.193887,-59.543198],
|
81
|
+
"America/Belem": [-1.4563432,-48.501299],
|
82
|
+
"America/Belize": [17.189877,-88.49764999999999],
|
83
|
+
"America/Blanc-Sablon": [51.4264451,-57.1313148],
|
84
|
+
"America/Boa_Vista": [-2.7670314,-65.2945869],
|
85
|
+
"America/Bogota": [4.710988599999999,-74.072092],
|
86
|
+
"America/Boise": [43.6150186,-116.2023137],
|
87
|
+
"America/Buenos_Aires": [-35.4891431,-62.97563270000001],
|
88
|
+
"America/Cambridge_Bay": [69.1168641,-105.0596814],
|
89
|
+
"America/Campo_Grande": [-20.4648517,-54.6218477],
|
90
|
+
"America/Cancun": [21.161908,-86.85152789999999],
|
91
|
+
"America/Caracas": [10.4805937,-66.90360629999999],
|
92
|
+
"America/Catamarca": [-28.469581,-65.7795441],
|
93
|
+
"America/Cayenne": [4.937977399999999,-52.3354386],
|
94
|
+
"America/Cayman": [19.3133,-81.2546],
|
95
|
+
"America/Chicago": [41.8781136,-87.6297982],
|
96
|
+
"America/Chihuahua": [28.6433753,-106.0587908],
|
97
|
+
"America/Ciudad_Juarez": [31.6903638,-106.4245478],
|
98
|
+
"America/Coral_Harbour": [64.138834,-83.16989699999999],
|
99
|
+
"America/Cordoba": [-31.42008329999999,-64.1887761],
|
100
|
+
"America/Costa_Rica": [9.748916999999999,-83.753428],
|
101
|
+
"America/Creston": [49.0955401,-116.5135079],
|
102
|
+
"America/Cuiaba": [-15.5954635,-56.0925824],
|
103
|
+
"America/Curacao": [12.16957,-68.99002],
|
104
|
+
"America/Danmarkshavn": [76.7721545,-18.6787352],
|
105
|
+
"America/Dawson": [64.0639058,-139.4332999],
|
106
|
+
"America/Dawson_Creek": [55.75962740000001,-120.2376623],
|
107
|
+
"America/Denver": [39.7392358,-104.990251],
|
108
|
+
"America/Detroit": [42.331427,-83.0457538],
|
109
|
+
"America/Dominica": [15.414999,-61.37097600000001],
|
110
|
+
"America/Edmonton": [53.5460983,-113.4937266],
|
111
|
+
"America/Eirunepe": [-6.6623703,-69.8674302],
|
112
|
+
"America/El_Salvador": [13.794185,-88.89653],
|
113
|
+
"America/Ensenada": [31.8667427,-116.5963713],
|
114
|
+
"America/Fort_Nelson": [58.8050174,-122.697236],
|
115
|
+
"America/Fort_Wayne": [41.079273,-85.1393513],
|
116
|
+
"America/Fortaleza": [-3.7327203,-38.5270134],
|
117
|
+
"America/Glace_Bay": [46.1969191,-59.9570044],
|
118
|
+
"America/Godthab": [64.17432339999999,-51.7372787],
|
119
|
+
"America/Goose_Bay": [53.3086181,-60.37623929999999],
|
120
|
+
"America/Grand_Turk": [21.4674584,-71.13891009999999],
|
121
|
+
"America/Grenada": [12.1165,-61.67899999999999],
|
122
|
+
"America/Guadeloupe": [16.265,-61.55099999999999],
|
123
|
+
"America/Guatemala": [15.783471,-90.23075899999999],
|
124
|
+
"America/Guayaquil": [-2.1891341,-79.8899031],
|
125
|
+
"America/Guyana": [4.860416,-58.93018],
|
126
|
+
"America/Halifax": [44.6508608,-63.5923256],
|
127
|
+
"America/Havana": [23.133865,-82.3585654],
|
128
|
+
"America/Hermosillo": [29.0729673,-110.9559192],
|
129
|
+
"America/Indiana/Indianapolis": [39.76909,-86.158018],
|
130
|
+
"America/Indiana/Knox": [41.2958751,-86.6250139],
|
131
|
+
"America/Indiana/Marengo": [38.36922759999999,-86.34359169999999],
|
132
|
+
"America/Indiana/Petersburg": [38.4919935,-87.2786244],
|
133
|
+
"America/Indiana/Tell_City": [37.9514447,-86.76776629999999],
|
134
|
+
"America/Indiana/Vevay": [38.7478401,-85.0671725],
|
135
|
+
"America/Indiana/Vincennes": [38.677269,-87.5286325],
|
136
|
+
"America/Indiana/Winamac": [41.0514299,-86.6030648],
|
137
|
+
"America/Indianapolis": [39.76909,-86.158018],
|
138
|
+
"America/Inuvik": [68.3593674,-133.7294462],
|
139
|
+
"America/Iqaluit": [63.74669300000001,-68.5169669],
|
140
|
+
"America/Jamaica": [18.109581,-77.29750799999999],
|
141
|
+
"America/Jujuy": [-24.1857864,-65.2994767],
|
142
|
+
"America/Juneau": [58.30049329999999,-134.4201306],
|
143
|
+
"America/Kentucky/Louisville": [38.2468618,-85.76637239999999],
|
144
|
+
"America/Kentucky/Monticello": [36.8297937,-84.8491126],
|
145
|
+
"America/Knox_IN": [41.2958751,-86.6250139],
|
146
|
+
"America/Kralendijk": [12.1498095,-68.27631289999999],
|
147
|
+
"America/La_Paz": [-16.489689,-68.11929359999999],
|
148
|
+
"America/Lima": [-12.0466888,-77.04308859999999],
|
149
|
+
"America/Los_Angeles": [34.0549076,-118.242643],
|
150
|
+
"America/Louisville": [38.2468618,-85.76637239999999],
|
151
|
+
"America/Lower_Princes": [38.7945952,-106.5348379],
|
152
|
+
"America/Maceio": [-9.666041699999999,-35.7352167],
|
153
|
+
"America/Managua": [12.1149926,-86.2361744],
|
154
|
+
"America/Manaus": [-3.1190275,-60.0217314],
|
155
|
+
"America/Marigot": [38.7945952,-106.5348379],
|
156
|
+
"America/Martinique": [14.641528,-61.024174],
|
157
|
+
"America/Matamoros": [25.8690294,-97.50273759999999],
|
158
|
+
"America/Mazatlan": [23.2494148,-106.4111425],
|
159
|
+
"America/Mendoza": [-32.8894587,-68.84583859999999],
|
160
|
+
"America/Menominee": [45.10776269999999,-87.6142737],
|
161
|
+
"America/Merida": [20.9673702,-89.5925857],
|
162
|
+
"America/Metlakatla": [55.12878600000001,-131.5744824],
|
163
|
+
"America/Mexico_City": [19.4326077,-99.133208],
|
164
|
+
"America/Miquelon": [46.8852,-56.3159],
|
165
|
+
"America/Moncton": [46.0878165,-64.7782313],
|
166
|
+
"America/Monterrey": [25.6866142,-100.3161126],
|
167
|
+
"America/Montevideo": [-34.9055016,-56.1851147],
|
168
|
+
"America/Montreal": [45.5018869,-73.56739189999999],
|
169
|
+
"America/Montserrat": [16.742498,-62.187366],
|
170
|
+
"America/Nassau": [25.0443312,-77.3503609],
|
171
|
+
"America/New_York": [40.7127753,-74.0059728],
|
172
|
+
"America/Nipigon": [49.0125155,-88.26328050000001],
|
173
|
+
"America/Nome": [64.50059089999999,-165.4086406],
|
174
|
+
"America/Noronha": [-3.844797615405311,-32.42689168991757],
|
175
|
+
"America/North_Dakota/Beulah": [47.2633403,-101.7779462],
|
176
|
+
"America/North_Dakota/Center": [47.1163849,-101.299594],
|
177
|
+
"America/North_Dakota/New_Salem": [46.844999,-101.4112545],
|
178
|
+
"America/Nuuk": [64.17432339999999,-51.7372787],
|
179
|
+
"America/Ojinaga": [29.5458844,-104.4082908],
|
180
|
+
"America/Panama": [8.537981,-80.782127],
|
181
|
+
"America/Pangnirtung": [66.1465578,-65.7012182],
|
182
|
+
"America/Paramaribo": [5.8520355,-55.2038278],
|
183
|
+
"America/Phoenix": [33.4483771,-112.0740373],
|
184
|
+
"America/Port-au-Prince": [18.594395,-72.3074326],
|
185
|
+
"America/Port_of_Spain": [10.6603435,-61.5086355],
|
186
|
+
"America/Porto_Acre": [-9.5936386,-67.5411079],
|
187
|
+
"America/Porto_Velho": [-8.7635475,-63.89717229999999],
|
188
|
+
"America/Puerto_Rico": [18.220833,-66.590149],
|
189
|
+
"America/Punta_Arenas": [-53.1633845,-70.9078263],
|
190
|
+
"America/Rainy_River": [48.68071439696585,-94.02755887688653],
|
191
|
+
"America/Rankin_Inlet": [62.808375,-92.0852853],
|
192
|
+
"America/Recife": [-8.0578381,-34.8828969],
|
193
|
+
"America/Regina": [50.4452112,-104.6188944],
|
194
|
+
"America/Resolute": [38.7945952,-106.5348379],
|
195
|
+
"America/Rio_Branco": [-9.9740249,-67.8098191],
|
196
|
+
"America/Rosario": [-32.9587022,-60.69304159999999],
|
197
|
+
"America/Santa_Isabel": [38.7945952,-106.5348379],
|
198
|
+
"America/Santarem": [39.2366618,-8.686011900000002],
|
199
|
+
"America/Santiago": [-33.4488897,-70.66926549999999],
|
200
|
+
"America/Santo_Domingo": [18.4626178,-69.93609239999999],
|
201
|
+
"America/Sao_Paulo": [-23.5557714,-46.6395571],
|
202
|
+
"America/Scoresbysund": [70.5,-25],
|
203
|
+
"America/Shiprock": [36.7855543,-108.6870322],
|
204
|
+
"America/Sitka": [57.05321929999999,-135.3345513],
|
205
|
+
"America/St_Barthelemy": [17.9,-62.833333],
|
206
|
+
"America/St_Johns": [47.5556097,-52.7452511],
|
207
|
+
"America/St_Kitts": [17.357822,-62.782998],
|
208
|
+
"America/St_Lucia": [13.909444,-60.978893],
|
209
|
+
"America/St_Thomas": [18.3380965,-64.8940946],
|
210
|
+
"America/St_Vincent": [12.984305,-61.287228],
|
211
|
+
"America/Swift_Current": [50.285069,-107.7971722],
|
212
|
+
"America/Tegucigalpa": [14.065049,-87.1715002],
|
213
|
+
"America/Thule": [76.5308268,-68.7071466],
|
214
|
+
"America/Thunder_Bay": [48.3808951,-89.24768229999999],
|
215
|
+
"America/Tijuana": [32.5149469,-117.0382471],
|
216
|
+
"America/Toronto": [43.653226,-79.3831843],
|
217
|
+
"America/Tortola": [18.4334704,-64.63327819999999],
|
218
|
+
"America/Vancouver": [49.2827291,-123.1207375],
|
219
|
+
"America/Virgin": [18.335765,-64.89633499999999],
|
220
|
+
"America/Whitehorse": [60.7197137,-135.0522761],
|
221
|
+
"America/Winnipeg": [49.8954221,-97.1385145],
|
222
|
+
"America/Yakutat": [59.54533929999999,-139.7268441],
|
223
|
+
"America/Yellowknife": [62.4539717,-114.3717886],
|
224
|
+
"Antarctica/Casey": [-82.86275189999999,135],
|
225
|
+
"Antarctica/Davis": [-82.86275189999999,135],
|
226
|
+
"Antarctica/DumontDUrville": [-82.86275189999999,135],
|
227
|
+
"Antarctica/Macquarie": [-82.86275189999999,135],
|
228
|
+
"Antarctica/Mawson": [-82.86275189999999,135],
|
229
|
+
"Antarctica/McMurdo": [-77.8455159,166.6697692],
|
230
|
+
"Antarctica/Palmer": [-82.86275189999999,135],
|
231
|
+
"Antarctica/Rothera": [-67.5682461,-68.1241591],
|
232
|
+
"Antarctica/South_Pole": [-90.0000,45.0000],
|
233
|
+
"Antarctica/Syowa": [-82.86275189999999,135],
|
234
|
+
"Antarctica/Troll": [-72.01138899999999,2.535],
|
235
|
+
"Antarctica/Vostok": [-82.86275189999999,135],
|
236
|
+
"Arctic/Longyearbyen": [78.2253231,15.6256365],
|
237
|
+
"Asia/Aden": [15.552727,48.516388],
|
238
|
+
"Asia/Almaty": [43.2379761,76.8828618],
|
239
|
+
"Asia/Amman": [31.9543786,35.9105776],
|
240
|
+
"Asia/Anadyr": [64.73366129999999,177.4968266],
|
241
|
+
"Asia/Aqtau": [43.67186299999999,51.2120512],
|
242
|
+
"Asia/Aqtobe": [50.2839339,57.166978],
|
243
|
+
"Asia/Ashgabat": [37.9600766,58.32606289999999],
|
244
|
+
"Asia/Ashkhabad": [37.9600766,58.32606289999999],
|
245
|
+
"Asia/Atyrau": [47.0944959,51.9238373],
|
246
|
+
"Asia/Baghdad": [33.315241,44.3660671],
|
247
|
+
"Asia/Bahrain": [26.0667,50.5577],
|
248
|
+
"Asia/Baku": [40.40926169999999,49.8670924],
|
249
|
+
"Asia/Bangkok": [13.7563309,100.5017651],
|
250
|
+
"Asia/Barnaul": [53.3497499,83.78357369999999],
|
251
|
+
"Asia/Beirut": [33.8937913,35.5017767],
|
252
|
+
"Asia/Bishkek": [42.8746212,74.5697617],
|
253
|
+
"Asia/Brunei": [4.535277,114.727669],
|
254
|
+
"Asia/Calcutta": [22.5743545,88.3628734],
|
255
|
+
"Asia/Chita": [34.047863,100.6196553],
|
256
|
+
"Asia/Choibalsan": [48.0951271,114.5356247],
|
257
|
+
"Asia/Chongqing": [29.5656843,106.5511838],
|
258
|
+
"Asia/Chungking": [29.5656843,106.5511838],
|
259
|
+
"Asia/Colombo": [6.9270786,79.861243],
|
260
|
+
"Asia/Dacca": [23.804093,90.4152376],
|
261
|
+
"Asia/Damascus": [33.5132192,36.2768193],
|
262
|
+
"Asia/Dhaka": [23.804093,90.4152376],
|
263
|
+
"Asia/Dili": [-8.5563336,125.5798233],
|
264
|
+
"Asia/Dubai": [25.2048493,55.2707828],
|
265
|
+
"Asia/Dushanbe": [38.5597722,68.7870384],
|
266
|
+
"Asia/Famagusta": [35.1208296,33.9382218],
|
267
|
+
"Asia/Gaza": [31.5016951,34.4668445],
|
268
|
+
"Asia/Harbin": [45.7567307,126.6424173],
|
269
|
+
"Asia/Hebron": [31.532569,35.09982600000001],
|
270
|
+
"Asia/Ho_Chi_Minh": [10.8230989,106.6296638],
|
271
|
+
"Asia/Hong_Kong": [22.3193039,114.1693611],
|
272
|
+
"Asia/Hovd": [47.9795218,91.634756],
|
273
|
+
"Asia/Irkutsk": [52.2854834,104.2890222],
|
274
|
+
"Asia/Istanbul": [41.0082376,28.9783589],
|
275
|
+
"Asia/Jakarta": [-6.1944491,106.8229198],
|
276
|
+
"Asia/Jayapura": [-2.5916025,140.6689995],
|
277
|
+
"Asia/Jerusalem": [31.768319,35.21371],
|
278
|
+
"Asia/Kabul": [34.5553494,69.207486],
|
279
|
+
"Asia/Kamchatka": [56.1327377,159.5314398],
|
280
|
+
"Asia/Karachi": [24.8607343,67.00113639999999],
|
281
|
+
"Asia/Kashgar": [39.4677199,75.99381],
|
282
|
+
"Asia/Kathmandu": [27.7103145,85.32216339999999],
|
283
|
+
"Asia/Katmandu": [27.7103145,85.32216339999999],
|
284
|
+
"Asia/Khandyga": [62.65640789999999,135.5539801],
|
285
|
+
"Asia/Kolkata": [22.5743545,88.3628734],
|
286
|
+
"Asia/Krasnoyarsk": [56.01528339999999,92.8932476],
|
287
|
+
"Asia/Kuala_Lumpur": [3.1499222,101.6944619],
|
288
|
+
"Asia/Kuching": [1.5533785,110.359503],
|
289
|
+
"Asia/Kuwait": [29.31166,47.481766],
|
290
|
+
"Asia/Macao": [22.198745,113.543873],
|
291
|
+
"Asia/Macau": [22.198745,113.543873],
|
292
|
+
"Asia/Magadan": [59.55943970000001,150.8127537],
|
293
|
+
"Asia/Makassar": [-5.1615828,119.4359281],
|
294
|
+
"Asia/Manila": [14.5995124,120.9842195],
|
295
|
+
"Asia/Muscat": [23.5880307,58.3828717],
|
296
|
+
"Asia/Nicosia": [35.1855659,33.38227639999999],
|
297
|
+
"Asia/Novokuznetsk": [53.7595935,87.12157049999999],
|
298
|
+
"Asia/Novosibirsk": [54.9832693,82.89638309999999],
|
299
|
+
"Asia/Omsk": [54.9913545,73.3645204],
|
300
|
+
"Asia/Oral": [51.227821,51.3865431],
|
301
|
+
"Asia/Phnom_Penh": [11.5563738,104.9282099],
|
302
|
+
"Asia/Pontianak": [-0.0263303,109.3425039],
|
303
|
+
"Asia/Pyongyang": [39.0392193,125.7625241],
|
304
|
+
"Asia/Qatar": [25.354826,51.183884],
|
305
|
+
"Asia/Qostanay": [53.2198089,63.6354232],
|
306
|
+
"Asia/Qyzylorda": [44.84883139999999,65.4822686],
|
307
|
+
"Asia/Rangoon": [16.840939,96.173526],
|
308
|
+
"Asia/Riyadh": [24.7135517,46.6752957],
|
309
|
+
"Asia/Saigon": [10.8230989,106.6296638],
|
310
|
+
"Asia/Sakhalin": [50.6909848,142.9505689],
|
311
|
+
"Asia/Samarkand": [39.6585987,66.9756694],
|
312
|
+
"Asia/Seoul": [37.550263,126.9970831],
|
313
|
+
"Asia/Shanghai": [31.230416,121.473701],
|
314
|
+
"Asia/Singapore": [1.352083,103.819836],
|
315
|
+
"Asia/Srednekolymsk": [67.43730699999999,153.728674],
|
316
|
+
"Asia/Taipei": [25.0329694,121.5654177],
|
317
|
+
"Asia/Tashkent": [41.2994958,69.2400734],
|
318
|
+
"Asia/Tbilisi": [41.6938026,44.80151679999999],
|
319
|
+
"Asia/Tehran": [35.7218583,51.3346954],
|
320
|
+
"Asia/Tel_Aviv": [32.0852999,34.78176759999999],
|
321
|
+
"Asia/Thimbu": [27.471586,89.6386108],
|
322
|
+
"Asia/Thimphu": [27.471586,89.6386108],
|
323
|
+
"Asia/Tokyo": [35.6764225,139.650027],
|
324
|
+
"Asia/Tomsk": [56.4884295,84.94804689999999],
|
325
|
+
"Asia/Ujung_Pandang": [-5.1615828,119.4359281],
|
326
|
+
"Asia/Ulaanbaatar": [47.9220509,106.9155007],
|
327
|
+
"Asia/Ulan_Bator": [47.9220509,106.9155007],
|
328
|
+
"Asia/Urumqi": [43.8266299,87.61687999999999],
|
329
|
+
"Asia/Ust-Nera": [64.5671689,143.2265266],
|
330
|
+
"Asia/Vientiane": [17.9757058,102.6331035],
|
331
|
+
"Asia/Vladivostok": [43.1332484,131.9112975],
|
332
|
+
"Asia/Yakutsk": [62.03969120000001,129.7422193],
|
333
|
+
"Asia/Yangon": [16.840939,96.173526],
|
334
|
+
"Asia/Yekaterinburg": [56.8430993,60.64540859999999],
|
335
|
+
"Asia/Yerevan": [40.1872023,44.515209],
|
336
|
+
"Atlantic/Azores": [37.7412488,-25.6755944],
|
337
|
+
"Atlantic/Bermuda": [32.3078,-64.7505],
|
338
|
+
"Atlantic/Canary": [28.2915637,-16.6291304],
|
339
|
+
"Atlantic/Cape_Verde": [16.5388,-23.0418],
|
340
|
+
"Atlantic/Faeroe": [61.89263500000001,-6.911805999999999],
|
341
|
+
"Atlantic/Faroe": [61.89263500000001,-6.911805999999999],
|
342
|
+
"Atlantic/Jan_Mayen": [71.031818,-8.2920347],
|
343
|
+
"Atlantic/Madeira": [32.6371816,-16.9289441],
|
344
|
+
"Atlantic/Reykjavik": [64.14698679999999,-21.9407552],
|
345
|
+
"Atlantic/South_Georgia": [-54.4138333,-36.5827165],
|
346
|
+
"Atlantic/St_Helena": [-15.9650104,-5.7089241],
|
347
|
+
"Atlantic/Stanley": [-51.6927517,-57.86196],
|
348
|
+
"Australia/ACT": [-35.4734679,149.0123679],
|
349
|
+
"Australia/Adelaide": [-34.9284989,138.6007456],
|
350
|
+
"Australia/Brisbane": [-27.4704528,153.0260341],
|
351
|
+
"Australia/Broken_Hill": [-31.9595859,141.4608138],
|
352
|
+
"Australia/Canberra": [-35.2801846,149.1310324],
|
353
|
+
"Australia/Currie": [-39.9301004,143.8537837],
|
354
|
+
"Australia/Darwin": [-12.4637333,130.8444446],
|
355
|
+
"Australia/Eucla": [-31.6750185,128.8835431],
|
356
|
+
"Australia/Hobart": [-42.8826055,147.3257196],
|
357
|
+
"Australia/LHI": [-31.5212683,159.0675466],
|
358
|
+
"Australia/Lindeman": [-25.274398,133.775136],
|
359
|
+
"Australia/Lord_Howe": [-31.5553263,159.0821211],
|
360
|
+
"Australia/Melbourne": [-37.8136276,144.9630576],
|
361
|
+
"Australia/NSW": [-31.2532183,146.921099],
|
362
|
+
"Australia/North": [-25.274398,133.775136],
|
363
|
+
"Australia/Perth": [-31.9513993,115.8616783],
|
364
|
+
"Australia/Queensland": [-22.575197,144.0847926],
|
365
|
+
"Australia/South": [-30.0002315,136.2091547],
|
366
|
+
"Australia/Sydney": [-33.8688197,151.2092955],
|
367
|
+
"Australia/Tasmania": [-42.0409059,146.8087322],
|
368
|
+
"Australia/Victoria": [-36.9847807,143.3906074],
|
369
|
+
"Australia/West": [-27.6728168,121.6283098],
|
370
|
+
"Australia/Yancowinna": [-25.274398,133.775136],
|
371
|
+
"Brazil/Acre": [-9.0237964,-70.81199529999999],
|
372
|
+
"Brazil/DeNoronha": [-3.844797615405311,-32.42689168991757],
|
373
|
+
"Brazil/East": [-14.235004,-51.92528],
|
374
|
+
"Brazil/West": [-14.235004,-51.92528],
|
375
|
+
"CET": [50.84770289999999,4.357200100000001],
|
376
|
+
"CST6CDT": [41.8781136,-87.6297982],
|
377
|
+
"Canada/Atlantic": [43.37822,-64.9405185],
|
378
|
+
"Canada/Central": [56.130366,-106.346771],
|
379
|
+
"Canada/Eastern": [56.130366,-106.346771],
|
380
|
+
"Canada/Mountain": [56.130366,-106.346771],
|
381
|
+
"Canada/Newfoundland": [54.2730918,-61.7387586],
|
382
|
+
"Canada/Pacific": [56.130366,-106.346771],
|
383
|
+
"Canada/Saskatchewan": [52.9399159,-106.4508639],
|
384
|
+
"Canada/Yukon": [64.2823274,-135],
|
385
|
+
"Chile/Continental": [-35.675147,-71.542969],
|
386
|
+
"Chile/EasterIsland": [-27.112723,-109.3496865],
|
387
|
+
"Cuba": [21.521757,-77.781167],
|
388
|
+
"EET": [37.9838096,23.7275388],
|
389
|
+
"EST": [8.537981,-80.782127],
|
390
|
+
"EST5EDT": [40.7127753,-74.0059728],
|
391
|
+
"Egypt": [26.820553,30.802498],
|
392
|
+
"Eire": [53.41291,-8.24389],
|
393
|
+
"Etc/GMT": null,
|
394
|
+
"Etc/GMT+0": null,
|
395
|
+
"Etc/GMT+1": null,
|
396
|
+
"Etc/GMT+10": null,
|
397
|
+
"Etc/GMT+11": null,
|
398
|
+
"Etc/GMT+12": null,
|
399
|
+
"Etc/GMT+2": null,
|
400
|
+
"Etc/GMT+3": null,
|
401
|
+
"Etc/GMT+4": null,
|
402
|
+
"Etc/GMT+5": null,
|
403
|
+
"Etc/GMT+6": null,
|
404
|
+
"Etc/GMT+7": null,
|
405
|
+
"Etc/GMT+8": null,
|
406
|
+
"Etc/GMT+9": null,
|
407
|
+
"Etc/GMT-0": null,
|
408
|
+
"Etc/GMT-1": null,
|
409
|
+
"Etc/GMT-10": null,
|
410
|
+
"Etc/GMT-11": null,
|
411
|
+
"Etc/GMT-12": null,
|
412
|
+
"Etc/GMT-13": null,
|
413
|
+
"Etc/GMT-14": null,
|
414
|
+
"Etc/GMT-2": null,
|
415
|
+
"Etc/GMT-3": null,
|
416
|
+
"Etc/GMT-4": null,
|
417
|
+
"Etc/GMT-5": null,
|
418
|
+
"Etc/GMT-6": null,
|
419
|
+
"Etc/GMT-7": null,
|
420
|
+
"Etc/GMT-8": null,
|
421
|
+
"Etc/GMT-9": null,
|
422
|
+
"Etc/GMT0": null,
|
423
|
+
"Etc/Greenwich": null,
|
424
|
+
"Etc/UCT": null,
|
425
|
+
"Etc/UTC": null,
|
426
|
+
"Etc/Universal": null,
|
427
|
+
"Etc/Zulu": null,
|
428
|
+
"Europe/Amsterdam": [52.3675734,4.9041389],
|
429
|
+
"Europe/Andorra": [42.506285,1.521801],
|
430
|
+
"Europe/Astrakhan": [46.3586008,48.0569482],
|
431
|
+
"Europe/Athens": [37.9838096,23.7275388],
|
432
|
+
"Europe/Belfast": [54.59728500000001,-5.93012],
|
433
|
+
"Europe/Belgrade": [44.8125449,20.46123],
|
434
|
+
"Europe/Berlin": [52.52000659999999,13.404954],
|
435
|
+
"Europe/Bratislava": [48.1485965,17.1077477],
|
436
|
+
"Europe/Brussels": [50.84770289999999,4.357200100000001],
|
437
|
+
"Europe/Bucharest": [44.4267674,26.1025384],
|
438
|
+
"Europe/Budapest": [47.497912,19.040235],
|
439
|
+
"Europe/Busingen": [47.6969939,8.6904196],
|
440
|
+
"Europe/Chisinau": [47.0104529,28.8638103],
|
441
|
+
"Europe/Copenhagen": [55.6760968,12.5683371],
|
442
|
+
"Europe/Dublin": [53.3498053,-6.2603097],
|
443
|
+
"Europe/Gibraltar": [36.140751,-5.353585],
|
444
|
+
"Europe/Guernsey": [49.4481982,-2.58949],
|
445
|
+
"Europe/Helsinki": [60.16985569999999,24.938379],
|
446
|
+
"Europe/Isle_of_Man": [54.236107,-4.548056],
|
447
|
+
"Europe/Istanbul": [41.0082376,28.9783589],
|
448
|
+
"Europe/Jersey": [49.2137711,-2.1357662],
|
449
|
+
"Europe/Kaliningrad": [54.7104264,20.4522144],
|
450
|
+
"Europe/Kiev": [50.4503596,30.5245025],
|
451
|
+
"Europe/Kirov": [58.6030012,49.6679437],
|
452
|
+
"Europe/Kyiv": [50.4503596,30.5245025],
|
453
|
+
"Europe/Lisbon": [38.7222524,-9.1393366],
|
454
|
+
"Europe/Ljubljana": [46.0569465,14.5057515],
|
455
|
+
"Europe/London": [51.5072178,-0.1275862],
|
456
|
+
"Europe/Luxembourg": [49.815273,6.129582999999999],
|
457
|
+
"Europe/Madrid": [40.41672790000001,-3.7032905],
|
458
|
+
"Europe/Malta": [35.937496,14.375416],
|
459
|
+
"Europe/Mariehamn": [60.0970945,19.9348339],
|
460
|
+
"Europe/Minsk": [53.9006011,27.558972],
|
461
|
+
"Europe/Monaco": [43.73841760000001,7.424615799999999],
|
462
|
+
"Europe/Moscow": [55.755826,37.6173],
|
463
|
+
"Europe/Nicosia": [35.1855659,33.38227639999999],
|
464
|
+
"Europe/Oslo": [59.9138688,10.7522454],
|
465
|
+
"Europe/Paris": [48.8766796,2.3189725],
|
466
|
+
"Europe/Podgorica": [42.4304196,19.2593642],
|
467
|
+
"Europe/Prague": [50.0755381,14.4378005],
|
468
|
+
"Europe/Riga": [56.9676941,24.1056221],
|
469
|
+
"Europe/Rome": [41.8967068,12.4822025],
|
470
|
+
"Europe/Samara": [53.203772,50.1606382],
|
471
|
+
"Europe/San_Marino": [43.94236,12.457777],
|
472
|
+
"Europe/Sarajevo": [43.8562586,18.4130763],
|
473
|
+
"Europe/Saratov": [51.5461754,46.0154123],
|
474
|
+
"Europe/Simferopol": [44.952117,34.102417],
|
475
|
+
"Europe/Skopje": [41.9981294,21.4254355],
|
476
|
+
"Europe/Sofia": [42.6977082,23.3218675],
|
477
|
+
"Europe/Stockholm": [59.3327036,18.0656255],
|
478
|
+
"Europe/Tallinn": [59.43696079999999,24.7535746],
|
479
|
+
"Europe/Tirane": [41.3275459,19.8186982],
|
480
|
+
"Europe/Tiraspol": [46.84818500000001,29.596805],
|
481
|
+
"Europe/Ulyanovsk": [54.3186575,48.397776],
|
482
|
+
"Europe/Uzhgorod": [48.6208,22.287883],
|
483
|
+
"Europe/Vaduz": [47.1410843,9.5210732],
|
484
|
+
"Europe/Vatican": [41.902916,12.453389],
|
485
|
+
"Europe/Vienna": [48.20806959999999,16.3713095],
|
486
|
+
"Europe/Vilnius": [54.6871555,25.2796514],
|
487
|
+
"Europe/Volgograd": [48.708048,44.5133034],
|
488
|
+
"Europe/Warsaw": [52.2296756,21.0122287],
|
489
|
+
"Europe/Zagreb": [45.8150108,15.981919],
|
490
|
+
"Europe/Zaporozhye": [47.83928419999999,35.13870970000001],
|
491
|
+
"Europe/Zurich": [47.3768866,8.541694],
|
492
|
+
"Factory": null,
|
493
|
+
"GB": [55.378051,-3.435973],
|
494
|
+
"GB-Eire": [53.41291,-8.24389],
|
495
|
+
"GMT": null,
|
496
|
+
"GMT+0": null,
|
497
|
+
"GMT-0": null,
|
498
|
+
"GMT0": null,
|
499
|
+
"Greenwich": [51.4933675,0.009821399999999999],
|
500
|
+
"HST": [19.8986819,-155.6658568],
|
501
|
+
"Hongkong": [22.3193039,114.1693611],
|
502
|
+
"Iceland": [64.96305099999999,-19.020835],
|
503
|
+
"Indian/Antananarivo": [-18.9184607,47.5211293],
|
504
|
+
"Indian/Chagos": [-6.1217629,72.01135874999999],
|
505
|
+
"Indian/Christmas": [20.593684,78.96288],
|
506
|
+
"Indian/Cocos": [-12.164165,96.87095599999999],
|
507
|
+
"Indian/Comoro": [-11.6455,43.3333],
|
508
|
+
"Indian/Kerguelen": [-49.3948275,69.35446259999999],
|
509
|
+
"Indian/Mahe": [11.7001957,75.5343014],
|
510
|
+
"Indian/Maldives": [3.202778,73.22068],
|
511
|
+
"Indian/Mauritius": [-20.348404,57.55215200000001],
|
512
|
+
"Indian/Mayotte": [-12.8275,45.166244],
|
513
|
+
"Indian/Reunion": [-21.115141,55.536384],
|
514
|
+
"Iran": [32.427908,53.688046],
|
515
|
+
"Israel": [31.046051,34.851612],
|
516
|
+
"Jamaica": [18.109581,-77.29750799999999],
|
517
|
+
"Japan": [36.204824,138.252924],
|
518
|
+
"Kwajalein": [9.189823499999999,167.4242972],
|
519
|
+
"Libya": [26.3351,17.228331],
|
520
|
+
"MET": [40.7794366,-73.963244],
|
521
|
+
"MST": [33.4483771,-112.0740373],
|
522
|
+
"MST7MDT": [39.7392358,-104.990251],
|
523
|
+
"Mexico/BajaNorte": [30.8406338,-115.2837585],
|
524
|
+
"Mexico/BajaSur": [26.0444446,-111.6660725],
|
525
|
+
"Mexico/General": [23.634501,-102.552784],
|
526
|
+
"NZ": [-36.85088270000001,174.7644881],
|
527
|
+
"NZ-CHAT": [-43.9271098,-176.4592091],
|
528
|
+
"Navajo": [36.0672173,-109.1880047],
|
529
|
+
"PRC": [31.230416,121.473701],
|
530
|
+
"PST8PDT": [34.0549076,-118.242643],
|
531
|
+
"Pacific/Apia": [-13.831609,-171.7689086],
|
532
|
+
"Pacific/Auckland": [-36.85088270000001,174.7644881],
|
533
|
+
"Pacific/Bougainville": [-6.375391899999999,155.3807101],
|
534
|
+
"Pacific/Chatham": [-43.9271098,-176.4592091],
|
535
|
+
"Pacific/Chuuk": [7.134462467372186,151.5074133217651],
|
536
|
+
"Pacific/Easter": [-27.112723,-109.3496865],
|
537
|
+
"Pacific/Efate": [-17.6577479,168.4297187],
|
538
|
+
"Pacific/Enderbury": [-3.1272412,-171.0837442],
|
539
|
+
"Pacific/Fakaofo": [-9.380255499999999,-171.2188355],
|
540
|
+
"Pacific/Fiji": [-17.713371,178.065032],
|
541
|
+
"Pacific/Funafuti": [-8.5211471,179.1961926],
|
542
|
+
"Pacific/Galapagos": [-0.3831059167914707,-90.42333442620028],
|
543
|
+
"Pacific/Gambier": [40.3759296,-82.397183],
|
544
|
+
"Pacific/Guadalcanal": [-9.577328399999999,160.1455805],
|
545
|
+
"Pacific/Guam": [13.3823791,144.6972774],
|
546
|
+
"Pacific/Honolulu": [21.3098845,-157.8581401],
|
547
|
+
"Pacific/Johnston": [41.6729856,-93.6977354],
|
548
|
+
"Pacific/Kanton": [-2.8039843,-171.6432353],
|
549
|
+
"Pacific/Kiritimati": [1.8721347,-157.4278119],
|
550
|
+
"Pacific/Kosrae": [5.3095618,162.9814877],
|
551
|
+
"Pacific/Kwajalein": [9.189823499999999,167.4242972],
|
552
|
+
"Pacific/Majuro": [7.066667,171.266667],
|
553
|
+
"Pacific/Marquesas": [-9.781216200000001,-139.0817124],
|
554
|
+
"Pacific/Midway": [28.2072168,-177.3734926],
|
555
|
+
"Pacific/Nauru": [-0.522778,166.931503],
|
556
|
+
"Pacific/Niue": [-19.054445,-169.867233],
|
557
|
+
"Pacific/Norfolk": [36.8507689,-76.28587259999999],
|
558
|
+
"Pacific/Noumea": [-22.2716866,166.4398627],
|
559
|
+
"Pacific/Pago_Pago": [-14.2732232,-170.7030309],
|
560
|
+
"Pacific/Palau": [7.514979999999999,134.58252],
|
561
|
+
"Pacific/Pitcairn": [-24.3767537,-128.3242376],
|
562
|
+
"Pacific/Pohnpei": [6.951991599999999,158.2793165],
|
563
|
+
"Pacific/Ponape": [6.951991599999999,158.2793165],
|
564
|
+
"Pacific/Port_Moresby": [-9.4790043,147.1494164],
|
565
|
+
"Pacific/Rarotonga": [-21.2292371,-159.7763491],
|
566
|
+
"Pacific/Saipan": [15.1850483,145.7467259],
|
567
|
+
"Pacific/Samoa": [-13.759029,-172.104629],
|
568
|
+
"Pacific/Tahiti": [-17.6509195,-149.4260421],
|
569
|
+
"Pacific/Tarawa": [1.4518171,172.9716617],
|
570
|
+
"Pacific/Tongatapu": [-21.1465968,-175.2515482],
|
571
|
+
"Pacific/Truk": [7.134462467372186,151.5074133217651],
|
572
|
+
"Pacific/Wake": [19.279619,166.6499348],
|
573
|
+
"Pacific/Wallis": [-14.2938,-178.1165],
|
574
|
+
"Pacific/Yap": [9.5556503,138.1399232],
|
575
|
+
"Poland": [51.919438,19.145136],
|
576
|
+
"Portugal": [39.39987199999999,-8.224454],
|
577
|
+
"ROC": [25.0329694,121.5654177],
|
578
|
+
"ROK": [37.550263,126.9970831],
|
579
|
+
"Singapore": [1.352083,103.819836],
|
580
|
+
"Turkey": [38.963745,35.243322],
|
581
|
+
"UCT": [-33.957652,18.4611991],
|
582
|
+
"US/Alaska": [63.588753,-154.4930619],
|
583
|
+
"US/Aleutian": [54.83193995,-165.89470295],
|
584
|
+
"US/Arizona": [34.0489281,-111.0937311],
|
585
|
+
"US/Central": [38.7945952,-106.5348379],
|
586
|
+
"US/East-Indiana": [40.5512165,-85.60236429999999],
|
587
|
+
"US/Eastern": [40.7127753,-74.0059728],
|
588
|
+
"US/Hawaii": [19.8986819,-155.6658568],
|
589
|
+
"US/Indiana-Starke": [41.2715616,-86.6207943],
|
590
|
+
"US/Michigan": [44.3148443,-85.60236429999999],
|
591
|
+
"US/Mountain": [38.7945952,-106.5348379],
|
592
|
+
"US/Pacific": [38.7945952,-106.5348379],
|
593
|
+
"Pacific/Samoa": [-13.759029,-172.104629],
|
594
|
+
"UTC": null,
|
595
|
+
"Universal": null,
|
596
|
+
"W-SU": null,
|
597
|
+
"WET": null,
|
598
|
+
"Zulu": null
|
599
|
+
}
|
data/lib/photein/config.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
3
4
|
require 'singleton'
|
4
5
|
require 'optparse'
|
5
6
|
|
7
|
+
require 'tzinfo'
|
8
|
+
|
6
9
|
module Photein
|
7
10
|
class Config
|
8
11
|
include Singleton
|
@@ -17,7 +20,9 @@ module Photein
|
|
17
20
|
['-k', '--keep', 'do not delete source files'],
|
18
21
|
['-i', '--interactive', 'ask whether to import each file found'],
|
19
22
|
['-n', '--dry-run', 'perform a "no-op" trial run'],
|
20
|
-
[ '--
|
23
|
+
[ '--shift-timestamp=N', 'adjust metadata timestamps by N hours'],
|
24
|
+
[ '--local-tz=TIMEZONE', "backfill missing GPS* metadata on videos\n (to name files in local time instead of UTC)"],
|
25
|
+
[ '--safe', 'skip files in use by other processes']
|
21
26
|
].freeze
|
22
27
|
|
23
28
|
OPTION_NAMES = OPTIONS
|
@@ -26,6 +31,13 @@ module Photein
|
|
26
31
|
.map { |option| option[/\w[a-z\-]+/] }
|
27
32
|
.map(&:to_sym)
|
28
33
|
|
34
|
+
SECONDS_PER_HOUR = 60 * 60
|
35
|
+
|
36
|
+
TZ_GEOCOORDS = File.expand_path('../../data/tz_coords.json', File.dirname(__FILE__))
|
37
|
+
.then(&File.method(:read))
|
38
|
+
.then(&JSON.method(:parse))
|
39
|
+
.freeze
|
40
|
+
|
29
41
|
@params = {}
|
30
42
|
|
31
43
|
class << self
|
@@ -44,6 +56,19 @@ module Photein
|
|
44
56
|
end.tap { |p| p.parse!(into: @params) }
|
45
57
|
|
46
58
|
@params[:verbose] ||= @params[:'dry-run']
|
59
|
+
|
60
|
+
raise "invalid --shift-timestamp option (must be integer)" if @params.key?(:'shift-timestamp') && !@params[:'shift-timestamp'].match?(/^-?\d+$/)
|
61
|
+
|
62
|
+
if @params.key?(:'local-tz')
|
63
|
+
if !TZInfo::Timezone.all_identifiers.include?(@params[:'local-tz'])
|
64
|
+
raise 'invalid --local-tz option (must be from IANA tz database)'
|
65
|
+
end
|
66
|
+
|
67
|
+
if tz_coordinates.nil?
|
68
|
+
raise 'invalid --local-tz option (must reference a location)'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
47
72
|
@params.freeze
|
48
73
|
|
49
74
|
raise "no source directory given" if !@params.key?(:source)
|
@@ -79,6 +104,22 @@ module Photein
|
|
79
104
|
web: @params[:'library-web']
|
80
105
|
}.compact.transform_values(&Pathname.method(:new))
|
81
106
|
end
|
107
|
+
|
108
|
+
def timestamp_delta
|
109
|
+
@timestamp_delta ||= @params[:'shift-timestamp'].to_i * SECONDS_PER_HOUR
|
110
|
+
end
|
111
|
+
|
112
|
+
def local_tz
|
113
|
+
return @local_tz if defined? @local_tz
|
114
|
+
|
115
|
+
@local_tz = @params.key?(:'local-tz') ? TZInfo::Timezone.get(@params[:'local-tz']) : nil
|
116
|
+
end
|
117
|
+
|
118
|
+
def tz_coordinates
|
119
|
+
return @tz_coordinates if defined? @tz_coordinates
|
120
|
+
|
121
|
+
@tz_coordinates = @params.key?(:'local-tz') ? TZ_GEOCOORDS[@params[:'local-tz']] : nil
|
122
|
+
end
|
82
123
|
end
|
83
124
|
end
|
84
125
|
end
|
data/lib/photein/image.rb
CHANGED
@@ -63,7 +63,7 @@ module Photein
|
|
63
63
|
raise
|
64
64
|
end
|
65
65
|
|
66
|
-
def
|
66
|
+
def timestamp_from_metadata
|
67
67
|
MiniExiftool.new(path.to_s).date_time_original
|
68
68
|
rescue MiniExiftool::Error => e
|
69
69
|
Photein.logger.error(<<~MSG) if e.message.match?(/exiftool: not found/)
|
@@ -74,7 +74,7 @@ module Photein
|
|
74
74
|
|
75
75
|
# NOTE: This may be largely unnecessary:
|
76
76
|
# metadata timestamps are generally present in all cases except WhatsApp
|
77
|
-
def
|
77
|
+
def timestamp_from_filename
|
78
78
|
path.basename(path.extname).to_s.then do |filename|
|
79
79
|
case filename
|
80
80
|
when /^IMG_\d{8}_\d{6}(_\d{3})?$/ # Android DCIM: datetime + optional counter
|
@@ -85,8 +85,8 @@ module Photein
|
|
85
85
|
Time.strptime(filename, 'IMG-%Y%m%d-WA%M%S')
|
86
86
|
when /^IMG_\d{8}_\d{6}_\d{3}$/ # Telegram: datetime in milliseconds (at download)
|
87
87
|
Time.strptime(filename, 'IMG_%Y%m%d_%H%M%S_%L')
|
88
|
-
when /^signal-\d{4}
|
89
|
-
Time.strptime(filename[0,
|
88
|
+
when /^signal-\d{4}-\d{2}-\d{2}-\d{6}( \(\d+\))?$/ # Signal: datetime + optional counter (at receipt)
|
89
|
+
Time.strptime(filename[0, 24], 'signal-%F-%H%M%S')
|
90
90
|
when /^\d{13}$/ # LINE: UNIX time in milliseconds (at download)
|
91
91
|
Time.strptime(filename[0..-4], '%s')
|
92
92
|
else
|
@@ -100,5 +100,25 @@ module Photein
|
|
100
100
|
|
101
101
|
return false
|
102
102
|
end
|
103
|
+
|
104
|
+
def update_exif_tags(path)
|
105
|
+
return if Photein::Config.timestamp_delta.zero? && Photein::Config.local_tz.nil?
|
106
|
+
|
107
|
+
file = MiniExiftool.new(path)
|
108
|
+
file.all_dates = new_timestamp.strftime('%Y:%m:%d %H:%M:%S') if Photein::Config.timestamp_delta != 0
|
109
|
+
|
110
|
+
if !Photein::Config.local_tz.nil?
|
111
|
+
new_timestamp.to_s # "2020-02-14 22:55:30 -0800"
|
112
|
+
.split.tap(&:pop).join(' ').then { |time| time + ' UTC' } # "2020-02-14 22:55:30 UTC"
|
113
|
+
.then(&Time.method(:parse)) # 2020-02-14 22:55:30 UTC
|
114
|
+
.then(&Photein::Config.local_tz.method(:to_local)) # 2020-02-14 22:55:30 +0800
|
115
|
+
.strftime('%z').insert(3, ':') # "+08:00"
|
116
|
+
.tap { |offset| file.offset_time = offset }
|
117
|
+
.tap { |offset| file.offset_time_digitized = offset }
|
118
|
+
.tap { |offset| file.offset_time_original = offset }
|
119
|
+
end
|
120
|
+
|
121
|
+
file.save!
|
122
|
+
end
|
103
123
|
end
|
104
124
|
end
|
data/lib/photein/media_file.rb
CHANGED
@@ -7,7 +7,7 @@ require 'time'
|
|
7
7
|
|
8
8
|
module Photein
|
9
9
|
class MediaFile
|
10
|
-
DATE_FORMAT = '%F_%H%M%S'
|
10
|
+
DATE_FORMAT = '%F_%H%M%S'
|
11
11
|
|
12
12
|
NORMAL_EXTNAME_MAP = {
|
13
13
|
'.jpeg' => '.jpg'
|
@@ -28,16 +28,15 @@ module Photein
|
|
28
28
|
next if non_optimizable_format?(lib_type)
|
29
29
|
|
30
30
|
Thread.new do
|
31
|
-
dest_basename = timestamp.strftime(DATE_FORMAT)
|
32
31
|
dest_extname = self.class::OPTIMIZATION_FORMAT_MAP.dig(lib_type, extname) || extname
|
33
32
|
dest_path = lib_path
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
.join(Time.parse(dest_filename).strftime('%Y'))
|
34
|
+
.join("#{dest_filename}#{dest_extname}")
|
35
|
+
.then(&method(:resolve_name_collision))
|
37
36
|
tempfile = Pathname(Dir.tmpdir)
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
.join('photein').join(lib_type.to_s)
|
38
|
+
.tap(&FileUtils.method(:mkdir_p))
|
39
|
+
.join(dest_path.basename)
|
41
40
|
|
42
41
|
optimize(tempfile: tempfile, lib_type: lib_type)
|
43
42
|
|
@@ -53,16 +52,19 @@ module Photein
|
|
53
52
|
FileUtils.cp(path, dest_path, noop: Photein::Config.dry_run)
|
54
53
|
FileUtils.chmod('-x', dest_path, noop: Photein::Config.dry_run)
|
55
54
|
end
|
56
|
-
end
|
57
|
-
end.compact.each(&:join)
|
58
55
|
|
59
|
-
|
56
|
+
update_exif_tags(dest_path.realdirpath.to_s) if !Photein::Config.dry_run
|
57
|
+
end
|
58
|
+
end.compact.map(&:join).then do |threads|
|
59
|
+
# e.g.: with --library-web only, .dngs are skipped, so DON'T DELETE!
|
60
|
+
FileUtils.rm(path, noop: threads.empty? || Photein::Config.dry_run || Photein::Config.keep)
|
61
|
+
end
|
60
62
|
end
|
61
63
|
|
62
64
|
private
|
63
65
|
|
64
66
|
def corrupted?(result = false)
|
65
|
-
|
67
|
+
result.tap do |r|
|
66
68
|
Photein.logger.error("#{path.basename}: cannot import corrupted file") if r
|
67
69
|
end
|
68
70
|
end
|
@@ -75,56 +77,69 @@ module Photein
|
|
75
77
|
def in_use?
|
76
78
|
out, _err, status = Open3.capture3("lsof '#{path}'")
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
return false unless status.success? # Do open files ALWAYS return exit status 0? (I think so.)
|
81
|
+
|
82
|
+
cmd, pid = out.lines[1]&.split&.first(2)
|
83
|
+
Photein.logger.fatal("skipping #{path}: file in use by #{cmd} (PID #{pid})")
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
def non_optimizable_format?(_lib_type = :master) # may be overridden by subclasses
|
88
|
+
false
|
85
89
|
end
|
86
90
|
|
87
|
-
def
|
88
|
-
|
91
|
+
def new_timestamp
|
92
|
+
@new_timestamp ||= (
|
93
|
+
timestamp_from_metadata ||
|
94
|
+
timestamp_from_filename ||
|
95
|
+
timestamp_from_filesystem
|
96
|
+
) + Photein::Config.timestamp_delta
|
89
97
|
end
|
90
98
|
|
91
|
-
def
|
92
|
-
|
99
|
+
def timestamp_from_metadata
|
100
|
+
raise NotImplementedError
|
93
101
|
end
|
94
102
|
|
95
|
-
def
|
103
|
+
def timestamp_from_filename
|
96
104
|
Time.parse(path.basename(path.extname).to_s)
|
97
105
|
rescue ArgumentError
|
98
|
-
|
99
|
-
File.birthtime(path)
|
100
|
-
rescue NotImplementedError
|
101
|
-
File.mtime(path)
|
102
|
-
end
|
106
|
+
nil
|
103
107
|
end
|
104
108
|
|
105
|
-
def
|
106
|
-
|
109
|
+
def timestamp_from_filesystem
|
110
|
+
File.birthtime(path)
|
111
|
+
rescue NotImplementedError
|
112
|
+
File.mtime(path)
|
107
113
|
end
|
108
114
|
|
109
|
-
def
|
110
|
-
|
115
|
+
def dest_filename
|
116
|
+
@dest_filename ||= new_timestamp.strftime(DATE_FORMAT)
|
117
|
+
end
|
111
118
|
|
112
|
-
|
119
|
+
def extname
|
120
|
+
@extname ||= NORMAL_EXTNAME_MAP[path.extname.downcase] || path.extname.downcase
|
121
|
+
end
|
113
122
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
123
|
+
def resolve_name_collision(pathname)
|
124
|
+
raise ArgumentError, 'Invalid filename' if pathname.to_s.include?('*')
|
125
|
+
|
126
|
+
collisions = Dir[pathname.sub_ext("*#{pathname.extname}")]
|
127
|
+
|
128
|
+
case collisions.length
|
129
|
+
when 0
|
130
|
+
pathname
|
131
|
+
when 1
|
132
|
+
pathname.sub_ext("+1#{pathname.extname}")
|
133
|
+
else # TODO: what to do for heterogeneous suffixes?
|
134
|
+
collisions.tap { |c| c.delete(pathname.to_s) }.max
|
135
|
+
.slice(/(?<=^#{pathname.to_s.delete_suffix(pathname.extname)}).*(?=#{pathname.extname}$)/)
|
136
|
+
.tap { |counter| raise 'Unresolved timestamp conflict' unless counter&.match?(/^\+[1-8]$/) }
|
137
|
+
.then { |counter| pathname.sub_ext("#{counter.next}#{pathname.extname}") }
|
122
138
|
end
|
139
|
+
end
|
123
140
|
|
124
|
-
|
125
|
-
|
126
|
-
.tap { |counter| raise 'Unresolved timestamp conflict' unless [*Array('a'..'z'), nil].include?(counter) }
|
127
|
-
.then { |counter| filename.sub_ext("#{counter}#{filename.extname}") }
|
141
|
+
def update_exif_tags(path)
|
142
|
+
raise NotImplementedError
|
128
143
|
end
|
129
144
|
|
130
145
|
class << self
|
@@ -133,8 +148,8 @@ module Photein
|
|
133
148
|
raise Errno::ENOENT, "#{file}" unless file.exist?
|
134
149
|
|
135
150
|
[Image, Video].find { |type| type::SUPPORTED_FORMATS.include?(file.extname.downcase) }
|
136
|
-
|
137
|
-
|
151
|
+
.tap { |type| raise ArgumentError, "#{file}: Invalid media file" if type.nil? }
|
152
|
+
.then { |type| type.new(file) }
|
138
153
|
end
|
139
154
|
end
|
140
155
|
end
|
data/lib/photein/version.rb
CHANGED
data/lib/photein/video.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'json'
|
4
5
|
require 'time'
|
5
6
|
|
6
7
|
require 'photein/media_file'
|
8
|
+
require 'active_support/core_ext/string/zones'
|
9
|
+
require 'active_support/core_ext/time/zones'
|
10
|
+
require 'active_support/values/time_zone'
|
7
11
|
require 'mediainfo'
|
12
|
+
require 'mini_exiftool'
|
8
13
|
require 'streamio-ffmpeg'
|
14
|
+
require 'wheretz'
|
9
15
|
require_relative '../../vendor/terminal-size/lib/terminal-size'
|
10
16
|
|
11
17
|
module Photein
|
@@ -65,9 +71,10 @@ module Photein
|
|
65
71
|
raise
|
66
72
|
end
|
67
73
|
|
68
|
-
|
69
|
-
|
70
|
-
|
74
|
+
# Video timestamps are typically UTC, and must be adjusted to local TZ.
|
75
|
+
# Look for GPS tags first, then default to system local TZ.
|
76
|
+
def timestamp_from_metadata
|
77
|
+
MediaInfo.from(path.to_s).general.encoded_date
|
71
78
|
rescue MediaInfo::EnvironmentError
|
72
79
|
Photein.logger.error('mediainfo is required to read timestamp metadata')
|
73
80
|
raise
|
@@ -75,23 +82,55 @@ module Photein
|
|
75
82
|
|
76
83
|
# NOTE: This may be largely unnecessary:
|
77
84
|
# metadata timestamps are generally present in all cases except WhatsApp
|
78
|
-
def
|
85
|
+
def timestamp_from_filename
|
79
86
|
path.basename(path.extname).to_s.then do |filename|
|
80
87
|
case filename
|
81
88
|
when /^LINE_MOVIE_\d{13}$/ # LINE: UNIX time in milliseconds (at download)
|
82
|
-
|
89
|
+
local_tz.strptime(filename[0..-4], 'LINE_MOVIE_%s')
|
83
90
|
when /^VID-\d{8}-WA\d{4}$/ # WhatsApp: date + counter (at receipt)
|
84
|
-
|
91
|
+
local_tz.strptime(filename, 'VID-%Y%m%d-WA%M%S')
|
85
92
|
when /^VID_\d{8}_\d{6}_\d{3}$/ # Telegram: datetime in milliseconds (at download)
|
86
|
-
|
93
|
+
local_tz.strptime(filename, 'VID_%Y%m%d_%H%M%S_%L')
|
87
94
|
when /^signal-\d{4}-\d{2}-\d{2}-\d{6}( \(\d+\))?$/ # Signal: datetime + optional counter (at receipt)
|
88
|
-
|
95
|
+
local_tz.strptime(filename[0, 24], 'signal-%F-%H%M%S')
|
89
96
|
else
|
90
|
-
super
|
97
|
+
super&.asctime&.in_time_zone(local_tz)
|
98
|
+
end
|
99
|
+
end&.utc
|
100
|
+
end
|
101
|
+
|
102
|
+
def timestamp_from_filesystem
|
103
|
+
super.asctime.in_time_zone(local_tz).utc
|
104
|
+
end
|
105
|
+
|
106
|
+
def dest_filename
|
107
|
+
@dest_filename ||= local_tz.tzinfo.to_local(new_timestamp).strftime(DATE_FORMAT)
|
108
|
+
end
|
109
|
+
|
110
|
+
def local_tz
|
111
|
+
@local_tz ||= ActiveSupport::TimeZone[
|
112
|
+
MiniExiftool.new(path).then(&method(:gps_coords))&.then(&method(:coords_to_tz)) ||
|
113
|
+
Photein::Config.local_tz ||
|
114
|
+
Time.now.gmt_offset
|
115
|
+
]
|
116
|
+
end
|
117
|
+
|
118
|
+
def gps_coords(exif)
|
119
|
+
return nil if exif.gps_latitude.nil? || exif.gps_longitude.nil?
|
120
|
+
|
121
|
+
[exif.gps_latitude, exif.gps_longitude].map do |str|
|
122
|
+
# `str' follows the format %(xx deg xx' xx.xx" x)
|
123
|
+
str.split(/[^\d.NESW]+/).then do |deg, min, sec, dir|
|
124
|
+
(deg.to_i + (min.to_f / 60) + (sec.to_f / 3600)) * (%(N E).include?(dir) ? 1 : -1)
|
91
125
|
end
|
92
126
|
end
|
93
127
|
end
|
94
128
|
|
129
|
+
def coords_to_tz(coords)
|
130
|
+
# WhereTZ::get() can return a single element OR an array -_-'
|
131
|
+
Array(WhereTZ.get(coords[0], coords[1])).first
|
132
|
+
end
|
133
|
+
|
95
134
|
def display_progress_bar(progress)
|
96
135
|
return unless $stdout.tty?
|
97
136
|
|
@@ -103,5 +142,19 @@ module Photein
|
|
103
142
|
progress_bar = "[#{'#' * progress_len}#{'-' * bg_len}]#{percentage}"
|
104
143
|
print "#{progress_bar}\r"
|
105
144
|
end
|
145
|
+
|
146
|
+
def update_exif_tags(path)
|
147
|
+
return if Photein::Config.timestamp_delta.zero? && Photein::Config.local_tz.nil?
|
148
|
+
|
149
|
+
args = []
|
150
|
+
args.push("-AllDates=#{new_timestamp.strftime('%Y:%m:%d\\ %H:%M:%S')}") if Photein::Config.timestamp_delta != 0
|
151
|
+
|
152
|
+
if (lat, lon = Photein::Config.tz_coordinates)
|
153
|
+
args.push("-xmp:GPSLatitude=#{lat}")
|
154
|
+
args.push("-xmp:GPSLongitude=#{lon}")
|
155
|
+
end
|
156
|
+
|
157
|
+
system("exiftool -overwrite_original #{args.join(' ')} #{path}", out: File::NULL, err: File::NULL)
|
158
|
+
end
|
106
159
|
end
|
107
160
|
end
|
metadata
CHANGED
@@ -1,15 +1,42 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: photein
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Lue
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2024-12-31 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: activesupport
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '8.0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '8.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: logger
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.6'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.6'
|
13
40
|
- !ruby/object:Gem::Dependency
|
14
41
|
name: mediainfo
|
15
42
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +107,48 @@ dependencies:
|
|
80
107
|
- - "~>"
|
81
108
|
- !ruby/object:Gem::Version
|
82
109
|
version: '0.2'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: ostruct
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0.6'
|
117
|
+
type: :runtime
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0.6'
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: pstore
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0.1'
|
131
|
+
type: :runtime
|
132
|
+
prerelease: false
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0.1'
|
138
|
+
- !ruby/object:Gem::Dependency
|
139
|
+
name: rexml
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '3.4'
|
145
|
+
type: :runtime
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '3.4'
|
83
152
|
- !ruby/object:Gem::Dependency
|
84
153
|
name: streamio-ffmpeg
|
85
154
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +163,34 @@ dependencies:
|
|
94
163
|
- - "~>"
|
95
164
|
- !ruby/object:Gem::Version
|
96
165
|
version: '3.0'
|
166
|
+
- !ruby/object:Gem::Dependency
|
167
|
+
name: tzinfo
|
168
|
+
requirement: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - "~>"
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '2.0'
|
173
|
+
type: :runtime
|
174
|
+
prerelease: false
|
175
|
+
version_requirements: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - "~>"
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '2.0'
|
180
|
+
- !ruby/object:Gem::Dependency
|
181
|
+
name: wheretz
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - "~>"
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0.0'
|
187
|
+
type: :runtime
|
188
|
+
prerelease: false
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - "~>"
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0.0'
|
97
194
|
- !ruby/object:Gem::Dependency
|
98
195
|
name: pry-remote
|
99
196
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,6 +228,7 @@ extra_rdoc_files: []
|
|
131
228
|
files:
|
132
229
|
- README.md
|
133
230
|
- bin/photein
|
231
|
+
- data/tz_coords.json
|
134
232
|
- lib/photein.rb
|
135
233
|
- lib/photein/config.rb
|
136
234
|
- lib/photein/image.rb
|
@@ -144,7 +242,6 @@ licenses:
|
|
144
242
|
- MIT
|
145
243
|
metadata:
|
146
244
|
source_code_uri: https://github.com/rlue/photein
|
147
|
-
post_install_message:
|
148
245
|
rdoc_options: []
|
149
246
|
require_paths:
|
150
247
|
- lib
|
@@ -159,8 +256,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
159
256
|
- !ruby/object:Gem::Version
|
160
257
|
version: '0'
|
161
258
|
requirements: []
|
162
|
-
rubygems_version: 3.
|
163
|
-
signing_key:
|
259
|
+
rubygems_version: 3.6.2
|
164
260
|
specification_version: 4
|
165
261
|
summary: Import/rename photos & videos from one directory to another.
|
166
262
|
test_files: []
|