sangoro 1.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0979a808540bb82afbdded5353b2a410db01cd46f15f7652bfacbc79d6300c0d'
4
- data.tar.gz: 52875e9902027701639b3f25853f5fbb876c26e89e17089944bac535cef44d02
3
+ metadata.gz: 4971ce60b11ef459842179239e0c9e3529dc622d7e824c395aa448aef7858e87
4
+ data.tar.gz: b2e91a73d8426516f8ba5933bea3708701067f3e32a49a0d1d19cedaaea07e29
5
5
  SHA512:
6
- metadata.gz: 6b1051b2740b34f666b53bdbd40859f03e0a310b921f55a8c30cece21ec6fd75c1004453a9b8466ea2eae115ec15049c24a7302a9ec5490e061cc201ca236c3b
7
- data.tar.gz: eaf3807eae9cc1a0a41b9b26557397a7477b5fdd67fc91ffe334c1ec84e916b0ed0fe35c414f75e88c7f9d806882d0fe25c2c979457d50161daf44961c240532
6
+ metadata.gz: 8e307807a9b27004450067118a8d38618707a7560fd8d3db936113c2bf200404e5acdec5cdc6175bcc9d321bb4e19a980b56835760d453a50c63c3a7d984e368
7
+ data.tar.gz: cd6897497b58b01ee33a855ca48ac78e86656a98f60c3e75c4e76fffa6069f77e036e7e6f21f258cca2044e8b4b1451d7c9f208c536e7acdd9b1c0616387de15
data/README.md CHANGED
@@ -1,22 +1,24 @@
1
1
  # Sangoro
2
2
  A Ruby program to change the exif creation time stamp of JPEGs or PNGs.<br>
3
- Demo: https://www.youtube.com/watch?v=yAoQi_NcPWY
4
3
 
5
- # Installation
6
- Following needs to be installed prior to running the script:
7
- - ruby (v >= 2.3.3)
8
4
 
9
- Gems:
10
- - gtk3 (```gem install gtk3```)
11
- - fileutils (```gem install fileutils```)
12
- - fastimage (```gem install fastimage```)
13
- - mini_exiftool (```gem install mini_exiftool```)
5
+ # Installation
6
+ To use the Sangoro tool you require:
7
+ <ul>
8
+ <li> <a href="https://www.ruby-lang.org/en/downloads/"><code>ruby</code></a> (v>=2.3.3)
9
+ </ul>
10
+ as well as the following Ruby gems:
11
+ <ul>
12
+ <li><code>fastimage</code>
13
+ <li><code>fileutils</code>
14
+ <li><code>gtk3</code>
15
+ <li><code>mini_exiftool</code></li>
16
+ </ul>
14
17
 
15
18
  On Mac you might need the exiftool installed. I recommend installing it using the Brew package manager:
16
19
  ```brew install exiftool```
17
20
 
18
- After the you installed ruby and the gems, install the gem:
19
- ```git install sangoro```
21
+ Get the Sangoro tool by typing ```gem install sangoro``` in your command line. This will install the sangoro gem as well as the gems mentined above.
20
22
  Now you can just run ```sangoro``` in your command line.
21
23
 
22
24
  # Usage
@@ -25,4 +27,7 @@ Now you can just run ```sangoro``` in your command line.
25
27
  3. Now you can specify by how many hours, minutes and/or seconds you want the time stamp to move. You also need to choose whether to move the timestamp forward or back.
26
28
  4. If you want to apply this change to all images in the folder, check the box below.
27
29
  5. Click "Apply".
28
- 6. You are done. The creation timestamp of the selected image(s) was adjusted as specified.
30
+ 6. You are done. The exif creation timestamp of the selected image(s) was adjusted as specified.
31
+
32
+ # Remarks
33
+ If you have any remarks, bugs, questions etc. please tell me, I'd be happy to help.
@@ -0,0 +1,192 @@
1
+ module Sangoro
2
+ module Actions
3
+
4
+ # toggles the sensitivity between active and inactive
5
+ def self.toggle_sensitivity(button_set, img_parameters, sensitive_mode)
6
+ button_set[:apply_all_btn].sensitive = sensitive_mode
7
+ button_set[:forward_btn].sensitive = sensitive_mode
8
+ button_set[:backward_btn].sensitive = sensitive_mode
9
+ button_set[:apply_btn].sensitive = sensitive_mode
10
+ img_parameters[:new_hour_ent].sensitive = sensitive_mode
11
+ img_parameters[:new_min_ent].sensitive = sensitive_mode
12
+ img_parameters[:new_sec_ent].sensitive = sensitive_mode
13
+
14
+ return [button_set, img_parameters]
15
+ end
16
+
17
+ # prepare the box for the original meta data of an image
18
+ def self.prepare_orig_meta(label_text, box)
19
+ label = Gtk::Label.new("#{label_text}: ")
20
+ text = Gtk::Label.new(" --")
21
+ box.pack_start(label, :expand => false, :fill => false, :padding => 0)
22
+ box.pack_start(text, :expand => false, :fill => false, :padding => 10)
23
+ return [label, text]
24
+ end
25
+
26
+ # define the actions for the SELECT button
27
+ def self.run_select_action(window, img_parameters, button_set, img_name_text, img_time_text)
28
+ img_parameters[:hour_set] = false
29
+ img_parameters[:min_set] = false
30
+ img_parameters[:sec_set] = false
31
+ img_parameters[:new_hour_ent].set_text("")
32
+ img_parameters[:new_min_ent].set_text("")
33
+ img_parameters[:new_sec_ent].set_text("")
34
+ button_set[:apply_all_btn].set_active(false)
35
+ button_set[:forward_btn].set_active(true)
36
+ img_parameters[:success_label].set_markup("<span font_desc='0'>Creation time successfully changed!</span>")
37
+ dialog = Gtk::FileChooserDialog.new(:title => "select image", :parent => window, :action => Gtk::FileChooserAction::OPEN,
38
+ :buttons => [[Gtk::Stock::OPEN, Gtk::ResponseType::ACCEPT], [Gtk::Stock::CANCEL, Gtk::ResponseType::CANCEL]])
39
+
40
+ # process the selected image
41
+ if dialog.run == Gtk::ResponseType::ACCEPT
42
+ selected_file = dialog.filename
43
+ img_parameters[:photo] = MiniExiftool.new(selected_file)
44
+ img_name_text.set_text(" #{File.basename(selected_file)}")
45
+ if img_parameters[:photo].datetimeoriginal
46
+ img_time_text.set_text(" #{img_parameters[:photo].datetimeoriginal.to_s}")
47
+ button_set, img_parameters = toggle_sensitivity(button_set, img_parameters, true)
48
+ else
49
+ img_time_text.set_text(" No creation time available")
50
+ button_set, img_parameters = toggle_sensitivity(button_set, img_parameters, false)
51
+ img_parameters[:success_label].set_markup("<span font_desc='13' color='orange'>The original creation timestamp could not be detected. Therefore, it is not possible to change the timestamp.</span>")
52
+ end
53
+
54
+ dialog.destroy
55
+
56
+ return [selected_file, img_name_text, img_time_text]
57
+ end
58
+ end
59
+
60
+ # process the time shift entered by the user
61
+ def self.process_time_unit(time_ent)
62
+ new_time = []
63
+ single_digits = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09"]
64
+ if (time_ent.text.to_i.to_s == time_ent.text) || single_digits.include?(time_ent.text)
65
+ new_time << time_ent.text.to_i
66
+ new_time << true
67
+ else
68
+ time_ent.set_text("")
69
+ end
70
+ return new_time
71
+ end
72
+
73
+ # define the actions for the ACCEPT button
74
+ def self.run_accept_action(img_parameters, button_set, img_time_text, selected_file)
75
+ count = 0
76
+ time_diff = 0
77
+ image_wording = "image"
78
+ if img_parameters[:hour_set]
79
+ time_diff += img_parameters[:new_hour_val]*3600
80
+ end
81
+ if img_parameters[:min_set]
82
+ time_diff += img_parameters[:new_min_val]*60
83
+ end
84
+ if img_parameters[:sec_set]
85
+ time_diff += img_parameters[:new_sec_val]
86
+ end
87
+
88
+ if button_set[:backward_btn].active?
89
+ time_diff *= -1
90
+ end
91
+
92
+ # apply the new time for the selected image only
93
+ if !button_set[:apply_all_btn].active?
94
+ count = change_time_single(img_parameters, time_diff, count, img_time_text)
95
+ # apply the new time for all images in the folder
96
+ else
97
+ count = change_time_all(selected_file, time_diff, count, img_time_text)
98
+ image_wording = "images" if count > 1
99
+ end
100
+
101
+ img_parameters[:success_label].set_markup("<span font_desc='13' color='green'>Creation time successfully changed! #{count} #{image_wording} affected.</span>")
102
+ end
103
+
104
+ #change the creation time for a single image
105
+ def self.change_time_single(img_parameters, time_difference, count, img_time_text)
106
+ if img_parameters[:photo].datetimeoriginal
107
+ img_parameters[:photo].datetimeoriginal += time_difference
108
+ img_time_text.set_markup("<span color='green'> #{img_parameters[:photo].datetimeoriginal.to_s} </span>")
109
+ count += 1
110
+ end
111
+ if img_parameters[:photo].createdate
112
+ img_parameters[:photo].createdate += time_difference
113
+ end
114
+ img_parameters[:photo].save
115
+ return count
116
+ end
117
+
118
+ # change the creation time for all images in the folder
119
+ def self.change_time_all(selected_file, time_difference, count, img_time_text)
120
+ dir_path = File.dirname(selected_file)
121
+ all_images = []
122
+ all_entries = Dir.entries(dir_path)
123
+ all_entries.each do |el|
124
+ el_down = el.downcase
125
+ if el_down.include?(".jpg") || el_down.include?(".jpeg")
126
+ all_images << el
127
+ end
128
+ end
129
+
130
+ all_images.each do |im|
131
+ miniexif_img = MiniExiftool.new("#{dir_path}/#{im}")
132
+ if miniexif_img.datetimeoriginal
133
+ miniexif_img.datetimeoriginal += time_difference
134
+ count += 1
135
+ end
136
+ if miniexif_img.createdate
137
+ miniexif_img.createdate += time_difference
138
+ end
139
+ miniexif_img.save
140
+ if im.downcase == File.basename(selected_file).downcase
141
+ img_time_text.set_markup("<span color='green'> #{miniexif_img.datetimeoriginal.to_s} </span>")
142
+ end
143
+ end
144
+ return count
145
+ end
146
+
147
+ # packs all the boxes
148
+ def self.pack_boxes(box_set, button_set, img_parameters)
149
+
150
+ # pack the SELECT box
151
+ select_align = Gtk::Alignment.new 0,0,0,0
152
+ box_set[:select_box].pack_start(button_set[:select_img_btn], :expand => false, :fill => true, :padding => 0)
153
+ box_set[:select_box].pack_start(select_align, :expand => true, :fill => true, :padding => 0)
154
+ box_set[:select_box].pack_start(box_set[:img_name_time_box], :expand => true, :fill => true, :padding => 0)
155
+
156
+ # pack the FORWARD/BACK box
157
+ box_set[:for_back_box].pack_start(button_set[:forward_btn], :expand => true, :fill => true, :padding => 0)
158
+ box_set[:for_back_box].pack_start(button_set[:backward_btn], :expand => true, :fill => true, :padding => 0)
159
+
160
+ # pack the new time box
161
+ move_time_label = Gtk::Label.new("move the creation time ")
162
+ new_hour_label = Gtk::Label.new("h ")
163
+ new_min_label = Gtk::Label.new("min ")
164
+ new_sec_label = Gtk::Label.new("sec ")
165
+ box_set[:new_time_box].pack_start(move_time_label, :expand => true, :fill => true, :padding => 0)
166
+ box_set[:new_time_box].pack_start(img_parameters[:new_hour_ent], :expand => true, :fill => true, :padding => 0)
167
+ box_set[:new_time_box].pack_start(new_hour_label, :expand => true, :fill => true, :padding => 3)
168
+ box_set[:new_time_box].pack_start(img_parameters[:new_min_ent], :expand => true, :fill => true, :padding => 0)
169
+ box_set[:new_time_box].pack_start(new_min_label, :expand => true, :fill => true, :padding => 3)
170
+ box_set[:new_time_box].pack_start(img_parameters[:new_sec_ent], :expand => true, :fill => true, :padding => 0)
171
+ box_set[:new_time_box].pack_start(new_sec_label, :expand => true, :fill => true, :padding => 3)
172
+ box_set[:new_time_box].pack_start(box_set[:for_back_box], :expand => true, :fill => true, :padding => 10)
173
+
174
+ # pack the meta_change_box
175
+ box_set[:meta_data_box].pack_start(box_set[:select_box], :expand => true, :fill => true, :padding => 0)
176
+ box_set[:meta_data_box].pack_start(box_set[:new_time_box], :expand => true, :fill => true, :padding => 20)
177
+ box_set[:meta_data_box].pack_start(button_set[:apply_all_btn], :expand => true, :fill => true, :padding => 0)
178
+ box_set[:meta_data_box].pack_start(img_parameters[:success_label], :expand => true, :fill => true, :padding => 5)
179
+
180
+ # pack the @apply_cancel_box
181
+ apply_align = Gtk::Alignment.new 0, 0, 0, 0
182
+ box_set[:apply_cancel_box].pack_start(apply_align, :expand => true, :fill => true, :padding => 0)
183
+ box_set[:apply_cancel_box].pack_start(button_set[:quit_btn], :expand => false, :fill => true, :padding => 5)
184
+ box_set[:apply_cancel_box].pack_start(button_set[:apply_btn], :expand => false, :fill => true, :padding => 5)
185
+
186
+ # pack the main box
187
+ box_set[:main_box].pack_start(box_set[:meta_data_box], :expand => false, :fill => true, :padding => 0)
188
+ box_set[:main_box].pack_start(box_set[:apply_cancel_box], :expand => false, :fill => true, :padding => 0)
189
+ end
190
+
191
+ end
192
+ end
@@ -0,0 +1,74 @@
1
+ module Sangoro
2
+ module BasicElements
3
+
4
+ # define the parameters of the image
5
+ def self.define_img_parameters
6
+ img_parameters = {
7
+ hour_set: false,
8
+ min_set: false,
9
+ sec_set: false,
10
+ new_hour_val: 0,
11
+ new_min_val: 0,
12
+ new_sec_val: 0,
13
+ new_hour_ent: Gtk::Entry.new,
14
+ new_min_ent: Gtk::Entry.new,
15
+ new_sec_ent: Gtk::Entry.new,
16
+ photo: MiniExiftool.new(),
17
+ success_label: Gtk::Label.new()
18
+ }
19
+
20
+ img_parameters[:new_hour_ent].set_max_length(2)
21
+ img_parameters[:new_hour_ent].set_width_chars(5)
22
+ img_parameters[:new_min_ent].set_max_length(2)
23
+ img_parameters[:new_min_ent].set_width_chars(5)
24
+ img_parameters[:new_sec_ent].set_max_length(2)
25
+ img_parameters[:new_sec_ent].set_width_chars(5)
26
+
27
+ return img_parameters
28
+ end
29
+
30
+ # define the window
31
+ def self.define_window
32
+ window = Gtk::Window.new
33
+ window.title = "sangoro"
34
+ window.border_width = 20
35
+ window.signal_connect("destroy") {
36
+ Gtk.main_quit
37
+ false
38
+ }
39
+
40
+ return window
41
+ end
42
+
43
+ # define the individual boxes
44
+ def self.define_boxes
45
+
46
+ return {
47
+ apply_cancel_box: Gtk::Box.new(:horizontal, 0),
48
+ for_back_box: Gtk::Box.new(:vertical, 0),
49
+ forward_back_box: Gtk::Box.new(:vertical, 0),
50
+ img_name_box: Gtk::Box.new(:horizontal, 0),
51
+ img_name_time_box: Gtk::Box.new(:vertical, 0),
52
+ img_time_box: Gtk::Box.new(:horizontal, 0),
53
+ main_box: Gtk::Box.new(:vertical, 0),
54
+ meta_data_box: Gtk::Box.new(:vertical, 0),
55
+ new_time_box: Gtk::Box.new(:horizontal, 0),
56
+ select_box: Gtk::Box.new(:horizontal, 0)
57
+ }
58
+
59
+ end
60
+
61
+ # define all necessary buttons
62
+ def self.define_buttons
63
+ apply_all_btn = Gtk::CheckButton.new("apply to all images in the folder accordingly")
64
+ forward_btn = Gtk::RadioButton.new(:label => "forward")
65
+ backward_btn = Gtk::RadioButton.new(:label => "back", :member => forward_btn)
66
+ select_img_btn = Gtk::Button.new(:label => "Select image", :use_underline => nil, :stock_id => nil)
67
+ apply_btn = Gtk::Button.new(:label => "Apply", :use_underline => nil, :stock_id => nil)
68
+ quit_btn = Gtk::Button.new(:label => "Quit", :use_underline => nil, :stock_id => nil)
69
+
70
+ return {apply_all_btn: apply_all_btn, forward_btn: forward_btn, backward_btn: backward_btn, select_img_btn: select_img_btn, apply_btn: apply_btn, quit_btn: quit_btn }
71
+ end
72
+
73
+ end
74
+ end
@@ -2,303 +2,71 @@ require 'gtk3'
2
2
  require 'fileutils'
3
3
  require 'fastimage'
4
4
  require 'mini_exiftool'
5
+ require_relative 'basic_elements'
6
+ require_relative 'actions'
5
7
 
6
8
  module Sangoro
7
9
 
8
10
  class UserInterface
11
+ attr_reader :window, :button_set, :img_parameters, :box_set
9
12
 
10
- attr_reader :window, :apply_all_btn, :forward_btn, :backward_btn, :apply_btn, :new_hour_ent, :new_min_ent, :new_sec_ent, :img_name_box, :img_time_box
11
13
  def initialize
12
- @hour_set = false
13
- @min_set = false
14
- @sec_set = false
15
- @new_hour_val = 0
16
- @new_min_val = 0
17
- @new_sec_val = 0
18
- @new_hour_ent = Gtk::Entry.new
19
- @new_hour_ent.set_max_length(2)
20
- @new_hour_ent.set_width_chars(5)
21
- @new_min_ent = Gtk::Entry.new
22
- @new_min_ent.set_max_length(2)
23
- @new_min_ent.set_width_chars(5)
24
- @new_sec_ent = Gtk::Entry.new
25
- @new_sec_ent.set_max_length(2)
26
- @new_sec_ent.set_width_chars(5)
27
- @photo = MiniExiftool.new()
28
- @success_label = Gtk::Label.new()
29
14
 
30
- # define the window, the boxes and the buttons
31
- define_window
32
- define_boxes
33
- define_buttons
34
-
35
- end
36
-
37
- # define the window
38
- def define_window
39
- @window = Gtk::Window.new
40
- @window.title = "sangoro"
41
- @window.border_width = 20
42
- @window.signal_connect("destroy") {
43
- Gtk.main_quit
44
- false
45
- }
46
- end
47
-
48
- # define the individual boxes
49
- def define_boxes
50
- @apply_cancel_box = Gtk::Box.new(:horizontal, 0)
51
- @for_back_box = Gtk::Box.new(:vertical, 0)
52
- @forward_back_box = Gtk::Box.new(:vertical, 0)
53
- @img_name_box = Gtk::Box.new(:horizontal, 0)
54
- @img_name_time_box = Gtk::Box.new(:vertical, 0)
55
- @img_time_box = Gtk::Box.new(:horizontal, 0)
56
- @main_box = Gtk::Box.new(:vertical, 0)
57
- @meta_data_box = Gtk::Box.new(:vertical, 0)
58
- @new_time_box = Gtk::Box.new(:horizontal, 0)
59
- @select_box = Gtk::Box.new(:horizontal, 0)
60
- end
61
-
62
- # define all necessary buttons
63
- def define_buttons
64
- @apply_all_btn = Gtk::CheckButton.new("apply to all images in the folder accordingly")
65
- @forward_btn = Gtk::RadioButton.new(:label => "forward")
66
- @backward_btn = Gtk::RadioButton.new(:label => "back", :member => @forward_btn)
67
- @select_img_btn = Gtk::Button.new(:label => "Select image", :use_underline => nil, :stock_id => nil)
68
- @apply_btn = Gtk::Button.new(:label => "Apply", :use_underline => nil, :stock_id => nil)
69
- @quit_btn = Gtk::Button.new(:label => "Quit", :use_underline => nil, :stock_id => nil)
70
- toggle_btn_sensitivity(false)
71
- end
72
-
73
- def toggle_btn_sensitivity(sensitive_mode)
74
- @apply_all_btn.sensitive = sensitive_mode
75
- @forward_btn.sensitive = sensitive_mode
76
- @backward_btn.sensitive = sensitive_mode
77
- @apply_btn.sensitive = sensitive_mode
78
- @new_hour_ent.sensitive = sensitive_mode
79
- @new_min_ent.sensitive = sensitive_mode
80
- @new_sec_ent.sensitive = sensitive_mode
81
- end
82
-
83
- # define the actions for the SELECT button
84
- def run_select_action(img_name_text, img_time_text)
85
- @hour_set = false
86
- @min_set = false
87
- @sec_set = false
88
- @new_hour_ent.set_text("")
89
- @new_min_ent.set_text("")
90
- @new_sec_ent.set_text("")
91
- @apply_all_btn.set_active(false)
92
- @forward_btn.set_active(true)
93
- @success_label.set_markup("<span font_desc='0'>Creation time successfully changed!</span>")
94
- dialog = Gtk::FileChooserDialog.new(:title => "select image", :parent => @window, :action => Gtk::FileChooserAction::OPEN,
95
- :buttons => [[Gtk::Stock::OPEN, Gtk::ResponseType::ACCEPT], [Gtk::Stock::CANCEL, Gtk::ResponseType::CANCEL]])
96
-
97
- # process the selected image
98
- if dialog.run == Gtk::ResponseType::ACCEPT
99
- selected_file = dialog.filename
100
- @photo = MiniExiftool.new(selected_file)
101
- img_name_text.set_text(" #{File.basename(selected_file)}")
102
- if @photo.datetimeoriginal
103
- img_time_text.set_text(" #{@photo.datetimeoriginal.to_s}")
104
- toggle_btn_sensitivity(true)
105
- else
106
- img_time_text.set_text(" No creation time available")
107
- toggle_btn_sensitivity(false)
108
- @success_label.set_markup("<span font_desc='13' color='orange'>The original creation timestamp could not be detected. Therefore, it is not possible to change the timestamp.</span>")
109
- end
110
-
111
- dialog.destroy
112
-
113
- return [selected_file, img_name_text, img_time_text]
114
- end
115
- end
116
-
117
- # prepare the box for the original meta data of an image
118
- def prepare_orig_meta(label_text, box)
119
- label = Gtk::Label.new("#{label_text}: ")
120
- text = Gtk::Label.new(" --")
121
- box.pack_start(label, :expand => false, :fill => false, :padding => 0)
122
- box.pack_start(text, :expand => false, :fill => false, :padding => 10)
123
- return [label, text]
124
- end
125
-
126
- # process the time shift entered by the user
127
- def process_time_unit(time_ent)
128
- new_time = []
129
- single_digits = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09"]
130
- if (time_ent.text.to_i.to_s == time_ent.text) || single_digits.include?(time_ent.text)
131
- new_time << time_ent.text.to_i
132
- new_time << true
133
- else
134
- time_ent.set_text("")
135
- end
136
- return new_time
137
- end
138
-
139
- # define the actions for the ACCEPT button
140
- def run_accept_action(img_time_text, selected_file)
141
- count = 0
142
- time_diff = 0
143
- image_wording = "image"
144
- if @hour_set
145
- time_diff += @new_hour_val*3600
146
- end
147
- if @min_set
148
- time_diff += @new_min_val*60
149
- end
150
- if @sec_set
151
- time_diff += @new_sec_val
152
- end
153
-
154
- if @backward_btn.active?
155
- time_diff *= -1
156
- end
157
-
158
- # apply the new time for the selected image only
159
- if !@apply_all_btn.active?
160
- count = change_time_single(time_diff, count, img_time_text)
161
- # apply the new time for all images in the folder
162
- else
163
- count = change_time_all(selected_file, time_diff, count, img_time_text)
164
- image_wording = "images" if count > 1
165
- end
166
-
167
- @success_label.set_markup("<span font_desc='13' color='green'>Creation time successfully changed! #{count} #{image_wording} affected.</span>")
168
- end
169
-
170
- #change the creation time for a single image
171
- def change_time_single(time_difference, count, img_time_text)
172
- if @photo.datetimeoriginal
173
- @photo.datetimeoriginal += time_difference
174
- img_time_text.set_markup("<span color='green'> #{@photo.datetimeoriginal.to_s} </span>")
175
- count += 1
176
- end
177
- if @photo.createdate
178
- @photo.createdate += time_difference
179
- end
180
- @photo.save
181
- return count
182
- end
183
-
184
- # change the creation time for all images in the folder
185
- def change_time_all(selected_file, time_difference, count, img_time_text)
186
- dir_path = File.dirname(selected_file)
187
- all_images = []
188
- all_entries = Dir.entries(dir_path)
189
- all_entries.each do |el|
190
- el.downcase!
191
- if el.include?(".jpg") || el.include?(".jpeg")
192
- all_images << el
193
- end
194
- end
195
-
196
- all_images.each do |im|
197
- miniexif_img = MiniExiftool.new("#{dir_path}/#{im}")
198
- if miniexif_img.datetimeoriginal
199
- miniexif_img.datetimeoriginal += time_difference
200
- count += 1
201
- end
202
- if miniexif_img.createdate
203
- miniexif_img.createdate += time_difference
204
- end
205
- miniexif_img.save
206
- if im == File.basename(selected_file)
207
- img_time_text.set_markup("<span color='green'> #{miniexif_img.datetimeoriginal.to_s} </span>")
208
- end
209
- end
210
- return count
211
- end
15
+ # initialize parameters for the image
16
+ @img_parameters = BasicElements.define_img_parameters
212
17
 
18
+ # define the window, the boxes and the buttons
19
+ @window = BasicElements.define_window
20
+ @box_set = BasicElements.define_boxes
21
+ @button_set = BasicElements.define_buttons
22
+ @button_set, @img_parameters = Actions.toggle_sensitivity(@button_set, @img_parameters, false)
213
23
 
214
- # packs all the boxes
215
- def pack_boxes
216
-
217
- # pack the SELECT box
218
- select_align = Gtk::Alignment.new 0,0,0,0
219
- @select_box.pack_start(@select_img_btn, :expand => false, :fill => true, :padding => 0)
220
- @select_box.pack_start(select_align, :expand => true, :fill => true, :padding => 0)
221
- @select_box.pack_start(@img_name_time_box, :expand => true, :fill => true, :padding => 0)
222
-
223
- # pack the FORWARD/BACK box
224
- @for_back_box.pack_start(@forward_btn, :expand => true, :fill => true, :padding => 0)
225
- @for_back_box.pack_start(@backward_btn, :expand => true, :fill => true, :padding => 0)
226
-
227
- # pack the new time box
228
- move_time_label = Gtk::Label.new("move the creation time ")
229
- new_hour_label = Gtk::Label.new("h ")
230
- new_min_label = Gtk::Label.new("min ")
231
- new_sec_label = Gtk::Label.new("sec ")
232
- @new_time_box.pack_start(move_time_label, :expand => true, :fill => true, :padding => 0)
233
- @new_time_box.pack_start(@new_hour_ent, :expand => true, :fill => true, :padding => 0)
234
- @new_time_box.pack_start(new_hour_label, :expand => true, :fill => true, :padding => 3)
235
- @new_time_box.pack_start(@new_min_ent, :expand => true, :fill => true, :padding => 0)
236
- @new_time_box.pack_start(new_min_label, :expand => true, :fill => true, :padding => 3)
237
- @new_time_box.pack_start(@new_sec_ent, :expand => true, :fill => true, :padding => 0)
238
- @new_time_box.pack_start(new_sec_label, :expand => true, :fill => true, :padding => 3)
239
- @new_time_box.pack_start(@for_back_box, :expand => true, :fill => true, :padding => 10)
240
-
241
- # pack the meta_change_box
242
- @meta_data_box.pack_start(@select_box, :expand => true, :fill => true, :padding => 0)
243
- @meta_data_box.pack_start(@new_time_box, :expand => true, :fill => true, :padding => 20)
244
- @meta_data_box.pack_start(@apply_all_btn, :expand => true, :fill => true, :padding => 0)
245
- @meta_data_box.pack_start(@success_label, :expand => true, :fill => true, :padding => 5)
246
-
247
- # pack the @apply_cancel_box
248
- apply_align = Gtk::Alignment.new 0, 0, 0, 0
249
- @apply_cancel_box.pack_start(apply_align, :expand => true, :fill => true, :padding => 0)
250
- @apply_cancel_box.pack_start(@quit_btn, :expand => false, :fill => true, :padding => 5)
251
- @apply_cancel_box.pack_start(@apply_btn, :expand => false, :fill => true, :padding => 5)
252
-
253
- # pack the main box
254
- @main_box.pack_start(@meta_data_box, :expand => false, :fill => true, :padding => 0)
255
- @main_box.pack_start(@apply_cancel_box, :expand => false, :fill => true, :padding => 0)
256
24
  end
257
25
 
258
26
  # main method - shows the window with all the buttons and abilities to select images and change meta data
259
27
  def run
260
28
 
261
- @window.add(@main_box)
29
+ @window.add(@box_set[:main_box])
262
30
 
263
31
  # prepare meta data for the chosen image - file name and original creation time
264
- img_name_label, img_name_text = prepare_orig_meta("file name", @img_name_box)
265
- img_time_label, img_time_text = prepare_orig_meta("creation date & time", @img_time_box)
32
+ img_name_label, img_name_text = Actions.prepare_orig_meta("file name", @box_set[:img_name_box])
33
+ img_time_label, img_time_text = Actions.prepare_orig_meta("creation date & time", @box_set[:img_time_box])
266
34
 
267
- @img_name_time_box.pack_start(@img_name_box, :expand => true, :fill => true, :padding => 0)
268
- @img_name_time_box.pack_start(@img_time_box, :expand=> true, :fill => true, :padding => 0)
35
+ @box_set[:img_name_time_box].pack_start(@box_set[:img_name_box], :expand => true, :fill => true, :padding => 0)
36
+ @box_set[:img_name_time_box].pack_start(@box_set[:img_time_box], :expand=> true, :fill => true, :padding => 0)
269
37
 
270
38
  # execute the action for the SELECT button
271
39
  selected_file = ""
272
- @select_img_btn.signal_connect("clicked") {
273
- selected_file, img_name_text, img_time_text = run_select_action(img_name_text, img_time_text)
40
+ @button_set[:select_img_btn].signal_connect("clicked") {
41
+ selected_file, img_name_text, img_time_text = Actions.run_select_action(window, @img_parameters, @button_set, img_name_text, img_time_text)
274
42
  }
275
43
 
276
44
  # define new time - process the input for the new hour, minutes and seconds
277
- @new_hour_ent.signal_connect("key_release_event") {
278
- @new_hour_val, @hour_set = process_time_unit(@new_hour_ent)
45
+ @img_parameters[:new_hour_ent].signal_connect("key_release_event") {
46
+ @img_parameters[:new_hour_val], @img_parameters[:hour_set] = Actions.process_time_unit(@img_parameters[:new_hour_ent])
279
47
  }
280
48
 
281
- @new_min_ent.signal_connect("key_release_event") {
282
- @new_min_val, @min_set = process_time_unit(@new_min_ent)
49
+ @img_parameters[:new_min_ent].signal_connect("key_release_event") {
50
+ @img_parameters[:new_min_val], @img_parameters[:min_set] = Actions.process_time_unit(@img_parameters[:new_min_ent])
283
51
  }
284
52
 
285
- @new_sec_ent.signal_connect("key_release_event") {
286
- @new_sec_val, @sec_set = process_time_unit(@new_sec_ent)
53
+ @img_parameters[:new_sec_ent].signal_connect("key_release_event") {
54
+ @img_parameters[:new_sec_val], @img_parameters[:sec_set] = Actions.process_time_unit(@img_parameters[:new_sec_ent])
287
55
  }
288
56
 
289
57
  # execute the action when the the ACCEPT button is clicked
290
- @apply_btn.signal_connect("clicked") {
291
- run_accept_action(img_time_text, selected_file)
58
+ @button_set[:apply_btn].signal_connect("clicked") {
59
+ Actions.run_accept_action(@img_parameters, @button_set, img_time_text, selected_file)
292
60
  }
293
61
 
294
62
  # define the action for the QUIT button
295
- @quit_btn.signal_connect("clicked") do |w|
63
+ @button_set[:quit_btn].signal_connect("clicked") do |w|
296
64
  Gtk.main_quit
297
65
  false
298
66
  end
299
67
 
300
68
  # pack all the boxes
301
- pack_boxes
69
+ Actions.pack_boxes(@box_set, @button_set, @img_parameters)
302
70
 
303
71
  # show everything
304
72
  @window.show_all
@@ -3,6 +3,8 @@ require 'fileutils'
3
3
  require 'fastimage'
4
4
  require 'mini_exiftool'
5
5
  require 'sangoro/user_interface'
6
+ require 'sangoro/basic_elements'
7
+ require 'sangoro/actions'
6
8
 
7
9
  module Sangoro
8
10
  describe UserInterface do
@@ -16,25 +18,25 @@ module Sangoro
16
18
  end
17
19
 
18
20
  it "checks that the following buttons are deactivated at the beginning" do
19
- expect(@interface.apply_all_btn.sensitive?).to eq false
20
- expect(@interface.forward_btn.sensitive?).to eq false
21
- expect(@interface.backward_btn.sensitive?).to eq false
22
- expect(@interface.apply_btn.sensitive?).to eq false
23
- expect(@interface.new_hour_ent.sensitive?).to eq false
24
- expect(@interface.new_min_ent.sensitive?).to eq false
25
- expect(@interface.new_sec_ent.sensitive?).to eq false
21
+ expect(@interface.button_set[:apply_all_btn].sensitive?).to eq false
22
+ expect(@interface.button_set[:forward_btn].sensitive?).to eq false
23
+ expect(@interface.button_set[:backward_btn].sensitive?).to eq false
24
+ expect(@interface.button_set[:apply_btn].sensitive?).to eq false
25
+ expect(@interface.img_parameters[:new_hour_ent].sensitive?).to eq false
26
+ expect(@interface.img_parameters[:new_min_ent].sensitive?).to eq false
27
+ expect(@interface.img_parameters[:new_sec_ent].sensitive?).to eq false
26
28
  end
27
29
 
28
30
  it "checks the label and the placeholder for the file name" do
29
- @img_name_label, @img_name_text = @interface.prepare_orig_meta("file name", @interface.img_name_box)
30
- expect(@img_name_label.label).to eq "file name: "
31
- expect(@img_name_text.label).to eq " --"
31
+ img_name_label, img_name_text = Actions.prepare_orig_meta("file name", @interface.box_set[:img_name_box])
32
+ expect(img_name_label.label).to eq "file name: "
33
+ expect(img_name_text.label).to eq " --"
32
34
  end
33
35
 
34
36
  it "checks the label and the placeholder for the original creation time stamp" do
35
- @img_time_label, @img_time_text = @interface.prepare_orig_meta("creation date & time", @interface.img_time_box)
36
- expect(@img_time_label.label).to eq "creation date & time: "
37
- expect(@img_time_text.label).to eq " --"
37
+ img_time_label, img_time_text = Actions.prepare_orig_meta("creation date & time", @interface.box_set[:img_time_box])
38
+ expect(img_time_label.label).to eq "creation date & time: "
39
+ expect(img_time_text.label).to eq " --"
38
40
  end
39
41
  end
40
42
  end
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sangoro
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - BluePeony
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-26 00:00:00.000000000 Z
11
+ date: 2023-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gtk3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fileutils
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fastimage
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mini_exiftool
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
13
69
  - !ruby/object:Gem::Dependency
14
70
  name: rspec
15
71
  requirement: !ruby/object:Gem::Requirement
@@ -31,20 +87,22 @@ dependencies:
31
87
  - !ruby/object:Gem::Version
32
88
  version: 2.8.0
33
89
  description: "# Sangoro\nA Ruby program to change the exif creation time stamp of
34
- JPEGs or PNGs.<br>\nDemo: https://www.youtube.com/watch?v=yAoQi_NcPWY\n\n# Installation\nFollowing
35
- needs to be installed prior to running the script:\n- ruby (v >= 2.3.3)\n\nGems:\n-
36
- gtk3 (```gem install gtk3```)\n- fileutils (```gem install fileutils```)\n- fastimage
37
- (```gem install fastimage```)\n- mini_exiftool (```gem install mini_exiftool```)\n\nOn
38
- Mac you might need the exiftool installed. I recommend installing it using the Brew
39
- package manager:\n```brew install exiftool```\n\nAfter the you installed ruby and
40
- the gems, install the gem:\n```git install sangoro```\nNow you can just run ```sangoro```
41
- in your command line.\n\n# Usage\n1. Select a JPEG/PNG file by clicking on \"Select
42
- image\"\n2. You will see the file name and the creation date & time on the right
43
- side, if available.\n3. Now you can specify by how many hours, minutes and/or seconds
44
- you want the time stamp to move. You also need to choose whether to move the timestamp
45
- forward or back.\n4. If you want to apply this change to all images in the folder,
46
- check the box below.\n5. Click \"Apply\". \n6. You are done. The creation timestamp
47
- of the selected image(s) was adjusted as specified.\n"
90
+ JPEGs or PNGs.<br>\n\n\n# Installation\nTo use the Sangoro tool you require:\n<ul>\n
91
+ \ <li> <a href=\"https://www.ruby-lang.org/en/downloads/\"><code>ruby</code></a>
92
+ (v>=2.3.3)\n</ul>\nas well as the following Ruby gems: \n<ul>\n <li><code>fastimage</code>\n
93
+ \ <li><code>fileutils</code>\n <li><code>gtk3</code>\n <li><code>mini_exiftool</code></li>\n</ul>
94
+ \ \n\nOn Mac you might need the exiftool installed. I recommend installing it using
95
+ the Brew package manager:\n```brew install exiftool```\n\nGet the Sangoro tool by
96
+ typing ```gem install sangoro``` in your command line. This will install the sangoro
97
+ gem as well as the gems mentined above.\nNow you can just run ```sangoro``` in your
98
+ command line.\n\n# Usage\n1. Select a JPEG/PNG file by clicking on \"Select image\"\n2.
99
+ You will see the file name and the creation date & time on the right side, if available.\n3.
100
+ Now you can specify by how many hours, minutes and/or seconds you want the time
101
+ stamp to move. You also need to choose whether to move the timestamp forward or
102
+ back.\n4. If you want to apply this change to all images in the folder, check the
103
+ box below.\n5. Click \"Apply\". \n6. You are done. The exif creation timestamp of
104
+ the selected image(s) was adjusted as specified.\n\n# Remarks \nIf you have any
105
+ remarks, bugs, questions etc. please tell me, I'd be happy to help. "
48
106
  email: blue.peony2314@gmail.com
49
107
  executables:
50
108
  - sangoro
@@ -54,6 +112,8 @@ files:
54
112
  - LICENSE
55
113
  - README.md
56
114
  - bin/sangoro
115
+ - lib/sangoro/actions.rb
116
+ - lib/sangoro/basic_elements.rb
57
117
  - lib/sangoro/user_interface.rb
58
118
  - spec/sangoro/user_interface_spec.rb
59
119
  homepage: https://github.com/BluePeony/sangoro
@@ -68,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
128
  requirements:
69
129
  - - ">="
70
130
  - !ruby/object:Gem::Version
71
- version: '1.9'
131
+ version: 2.3.3
72
132
  required_rubygems_version: !ruby/object:Gem::Requirement
73
133
  requirements:
74
134
  - - ">="