bconv 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/bin/bconv +194 -0
  3. data/data/bconv.glade +215 -0
  4. data/lib/bconv.rb +116 -0
  5. metadata +63 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0a2ee9a53ba762929e67f01c9250b8f5d41ff9ea
4
+ data.tar.gz: 848942f749535612beb4c00a0c21f800b40e0881
5
+ SHA512:
6
+ metadata.gz: cd24ae77b608b5466535fadf0e39be5ca0fc89bb151bede6e8bfb749ae85c2ae2db8f68f1b629bfd064882bfa092351fba7b8adb2026fc99938626dd6358987b
7
+ data.tar.gz: 9f64cc426f59bd05940d5ac5ea1340e0e782b8b5158d2249bf59dab4c229f5377b341512770d3807d5b1c5c7444b3d191d507c2b152b1772af1f818cd12d0a16
data/bin/bconv ADDED
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env ruby19
2
+ # encoding: UTF-8
3
+
4
+ #############################################################################
5
+ # Yet Another ImageMagic Frontend #
6
+ # (C) 2010-2011, Vasiliy Yeremeyev <vayerx@gmail.com> #
7
+ # #
8
+ # This program is free software: you can redistribute it and/or modify #
9
+ # it under the terms of the GNU General Public License as published by #
10
+ # the Free Software Foundation, either version 3 of the License, or #
11
+ # (at your option) any later version. #
12
+ # #
13
+ # This program is distributed in the hope that it will be useful, #
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
16
+ # GNU General Public License for more details. #
17
+ # #
18
+ # You should have received a copy of the GNU General Public License #
19
+ # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20
+ #############################################################################
21
+
22
+ # TODO humanist config interface (parseconfig -> /dev/null)
23
+ # TODO thinking of 'libglade2 -> raw gtk2'
24
+ # TODO humanist errors notification
25
+
26
+
27
+ require 'bconv'
28
+ require 'parseconfig'
29
+ require 'libglade2'
30
+
31
+ class ConverterGUI
32
+ MIN_RATIO = 65
33
+ MAX_RATIO = 100
34
+
35
+ def initialize(file_or_data)
36
+ @semaphore = Mutex.new
37
+ @counting_thread = nil
38
+ @source_files = []
39
+
40
+ @config_file = RUBY_PLATFORM =~ /linux|bsd|darwin|cygwin/i ? File.expand_path('~/.bconv.conf') : 'bconv.ini'
41
+ @config = ParseConfig.new(@config_file) rescue nil
42
+
43
+ @converter = Converter.new
44
+ @builder = Gtk::Builder.new
45
+ @builder << file_or_data
46
+ @builder.connect_signals { |name| method(name) }
47
+
48
+ %w[src_edit dest_edit size_edit ratio_scale run_button src_button dest_button
49
+ textview progress_bar status_bar main_window].each do |control|
50
+ instance_variable_set('@' + control, @builder[ control ])
51
+ end
52
+
53
+ @src_edit.text = @config['source'] rescue ''
54
+ @dest_edit.text = @config['destination'] rescue ''
55
+ @size_edit.text = @config['size'] rescue '1600x1200'
56
+
57
+ @ratio_scale.set_range(MIN_RATIO, MAX_RATIO)
58
+ ratio = @config['ratio'].to_i rescue 95
59
+ @ratio_scale.value = (ratio < MIN_RATIO ? MIN_RATIO : (ratio > MAX_RATIO ? MAX_RATIO : ratio))
60
+
61
+ @main_window.show
62
+
63
+ preload_dir(@src_edit.text) unless @src_edit.text.empty?
64
+ end
65
+
66
+ def run
67
+ Gtk.main
68
+ end
69
+
70
+ def on_src_button_clicked
71
+ dialog = Gtk::FileChooserDialog.new("Выбери исходную папку",
72
+ @main_window,
73
+ Gtk::FileChooser::ACTION_SELECT_FOLDER,
74
+ nil,
75
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
76
+ [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
77
+
78
+ dialog.current_folder = @src_edit.text
79
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
80
+ preload_dir(@src_edit.text = dialog.filename)
81
+ end
82
+ dialog.destroy
83
+ end
84
+
85
+ def preload_dir(dir)
86
+ @converter.preload_dir(dir) do |amount|
87
+ @status_bar.push(@status_bar.get_context_id(:init.to_s), "Найдено #{amount} файл(ов)") rescue nil
88
+ end
89
+ end
90
+
91
+ def on_dest_button_clicked
92
+ dialog = Gtk::FileChooserDialog.new("Выбери папку для результата",
93
+ @main_window,
94
+ Gtk::FileChooser::ACTION_SELECT_FOLDER,
95
+ nil,
96
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
97
+ [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
98
+
99
+ dialog.current_folder = @dest_edit.text
100
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
101
+ @dest_edit.text = dialog.filename
102
+ end
103
+ dialog.destroy
104
+ end
105
+
106
+ # Save configuration
107
+ def save_config
108
+ File.open(@config_file, 'w') do |f|
109
+ f << 'source=' << @src_edit.text << "\n"
110
+ f << 'destination=' << @dest_edit.text << "\n"
111
+ f << 'size=' << @size_edit.text << "\n"
112
+ f << 'ratio=' << @ratio_scale.value.to_i << "\n"
113
+ end
114
+ end
115
+
116
+ # Execute main job
117
+ def on_run_button_clicked
118
+ save_config
119
+
120
+ # check format of image size
121
+ img_size = @size_edit.text.gsub(/\s/, '')
122
+ begin
123
+ if img_size.index('%') || img_size.index('@')
124
+ raise img_size unless img_size.gsub!(/^(\d*)([%@])/, '\1\2')
125
+ else
126
+ raise img_size unless img_size.gsub!(/^(\d*)\w?(\d*)(\D?)$/, '\1x\2\3')
127
+ end
128
+ rescue
129
+ @textview.buffer.text = "Некорретный размер изображения '#{@size_edit.text}'"
130
+ return
131
+ end
132
+
133
+ ratio = @ratio_scale.value.to_i
134
+ if (ratio < 1 || ratio > 100)
135
+ @textview.buffer.text = "Недопустимый диапазон сжатия '#{ratio}'"
136
+ return
137
+ end
138
+
139
+ return unless check_directories(@src_edit.text, @dest_edit.text)
140
+
141
+ @textview.buffer.text = ""
142
+ @progress_bar.fraction = 0
143
+
144
+ lockUI
145
+ @converter.process(@src_edit.text, @dest_edit.text, img_size, ratio) { |file, step, done|
146
+ pulse_progress(file, step, done)
147
+ }
148
+ end
149
+
150
+ # Exit main loop
151
+ def on_main_window_destroy
152
+ @converter.stop
153
+ Gtk.main_quit
154
+ end
155
+
156
+ def lockUI
157
+ [ @run_button, @src_button, @dest_button ].each { |button| button.hide }
158
+ @progress_bar.show
159
+ end
160
+
161
+ def unlockUI
162
+ [ @run_button, @src_button, @dest_button ].each { |button| button.show }
163
+ @progress_bar.hide
164
+ end
165
+
166
+ # Check source/destination directories
167
+ def check_directories(src_dir, dest_dir)
168
+ # check source
169
+ if !FileTest.directory?(src_dir)
170
+ @textview.buffer.text = "#{src_dir} должно быть директорией"
171
+ return false
172
+ end
173
+
174
+ # check destination
175
+ Dir.mkdir(dest_dir, 0775) unless FileTest.exists?(dest_dir)
176
+ if !FileTest.directory?(dest_dir)
177
+ @textview.buffer.text = "#{dest_dir} должно быть директорией"
178
+ return false
179
+ end
180
+ true
181
+ end
182
+
183
+ def pulse_progress(file, step, done)
184
+ @semaphore.synchronize do
185
+ @textview.buffer.text = file + "\n" + @textview.buffer.text if file
186
+ @progress_bar.fraction += step if step
187
+ unlockUI if done
188
+ end
189
+ end
190
+ end
191
+
192
+ Encoding.default_external = 'UTF-8'
193
+ gui = ConverterGUI.new(File.read(File.expand_path('data/bconv.glade', File.dirname(__FILE__)+'/..')))
194
+ gui.run
data/data/bconv.glade ADDED
@@ -0,0 +1,215 @@
1
+ <?xml version="1.0"?>
2
+ <interface>
3
+ <requires lib="gtk+" version="2.16"/>
4
+ <!-- interface-naming-policy project-wide -->
5
+ <object class="GtkWindow" id="main_window">
6
+ <property name="width_request">700</property>
7
+ <property name="title" translatable="yes">&#x41F;&#x430;&#x43A;&#x435;&#x442;&#x43D;&#x43E;&#x435; &#x441;&#x436;&#x430;&#x442;&#x438;&#x435;</property>
8
+ <property name="window_position">center</property>
9
+ <signal name="destroy" handler="on_main_window_destroy"/>
10
+ <child>
11
+ <object class="GtkTable" id="table1">
12
+ <property name="visible">True</property>
13
+ <property name="n_rows">7</property>
14
+ <property name="n_columns">3</property>
15
+ <property name="column_spacing">2</property>
16
+ <property name="row_spacing">2</property>
17
+ <child>
18
+ <object class="GtkEntry" id="dest_edit">
19
+ <property name="visible">True</property>
20
+ <property name="can_focus">True</property>
21
+ <property name="tooltip_text" translatable="yes">&#x41A;&#x430;&#x442;&#x430;&#x43B;&#x43E;&#x433;, &#x43A;&#x443;&#x434;&#x430; &#x437;&#x430;&#x43F;&#x438;&#x441;&#x44B;&#x432;&#x430;&#x442;&#x44C; &#x43F;&#x43E;&#x436;&#x430;&#x442;&#x44B;&#x435; &#x444;&#x43E;&#x442;&#x43E;&#x433;&#x440;&#x430;&#x444;&#x438;&#x438;</property>
22
+ <property name="invisible_char">&#x25CF;</property>
23
+ </object>
24
+ <packing>
25
+ <property name="left_attach">1</property>
26
+ <property name="right_attach">2</property>
27
+ <property name="top_attach">1</property>
28
+ <property name="bottom_attach">2</property>
29
+ <property name="y_options"></property>
30
+ </packing>
31
+ </child>
32
+ <child>
33
+ <object class="GtkLabel" id="label1">
34
+ <property name="visible">True</property>
35
+ <property name="xpad">3</property>
36
+ <property name="ypad">3</property>
37
+ <property name="label" translatable="yes">&#x418;&#x441;&#x445;&#x43E;&#x434;&#x43D;&#x44B;&#x439; &#x43A;&#x430;&#x442;&#x430;&#x43B;&#x43E;&#x433;</property>
38
+ <property name="justify">right</property>
39
+ <property name="single_line_mode">True</property>
40
+ </object>
41
+ <packing>
42
+ <property name="x_options">GTK_FILL</property>
43
+ <property name="y_options"></property>
44
+ </packing>
45
+ </child>
46
+ <child>
47
+ <object class="GtkLabel" id="label2">
48
+ <property name="visible">True</property>
49
+ <property name="xpad">3</property>
50
+ <property name="ypad">3</property>
51
+ <property name="label" translatable="yes">&#x420;&#x435;&#x437;&#x443;&#x43B;&#x44C;&#x442;&#x438;&#x440;&#x443;&#x44E;&#x449;&#x438;&#x439; &#x43A;&#x430;&#x442;&#x430;&#x43B;&#x43E;&#x433;</property>
52
+ <property name="justify">right</property>
53
+ <property name="single_line_mode">True</property>
54
+ </object>
55
+ <packing>
56
+ <property name="top_attach">1</property>
57
+ <property name="bottom_attach">2</property>
58
+ <property name="x_options">GTK_FILL</property>
59
+ <property name="y_options"></property>
60
+ </packing>
61
+ </child>
62
+ <child>
63
+ <object class="GtkButton" id="dest_button">
64
+ <property name="label" translatable="yes">&#x412;&#x44B;&#x431;&#x440;&#x430;&#x442;&#x44C;...</property>
65
+ <property name="visible">True</property>
66
+ <property name="can_focus">True</property>
67
+ <property name="receives_default">True</property>
68
+ <signal name="clicked" handler="on_dest_button_clicked"/>
69
+ </object>
70
+ <packing>
71
+ <property name="left_attach">2</property>
72
+ <property name="right_attach">3</property>
73
+ <property name="top_attach">1</property>
74
+ <property name="bottom_attach">2</property>
75
+ <property name="x_options"></property>
76
+ <property name="y_options"></property>
77
+ </packing>
78
+ </child>
79
+ <child>
80
+ <object class="GtkButton" id="src_button">
81
+ <property name="label" translatable="yes">&#x412;&#x44B;&#x431;&#x440;&#x430;&#x442;&#x44C;...</property>
82
+ <property name="visible">True</property>
83
+ <property name="can_focus">True</property>
84
+ <property name="receives_default">True</property>
85
+ <signal name="clicked" handler="on_src_button_clicked"/>
86
+ </object>
87
+ <packing>
88
+ <property name="left_attach">2</property>
89
+ <property name="right_attach">3</property>
90
+ <property name="x_options"></property>
91
+ <property name="y_options"></property>
92
+ </packing>
93
+ </child>
94
+ <child>
95
+ <object class="GtkButton" id="run_button">
96
+ <property name="label" translatable="yes">&#x424;&#x438;&#x433;&#x430;&#x447;&#x438;&#x442;&#x44C;!</property>
97
+ <property name="visible">True</property>
98
+ <property name="can_focus">True</property>
99
+ <property name="receives_default">True</property>
100
+ <signal name="clicked" handler="on_run_button_clicked"/>
101
+ </object>
102
+ <packing>
103
+ <property name="right_attach">3</property>
104
+ <property name="top_attach">4</property>
105
+ <property name="bottom_attach">5</property>
106
+ <property name="x_options"></property>
107
+ <property name="y_options"></property>
108
+ </packing>
109
+ </child>
110
+ <child>
111
+ <object class="GtkLabel" id="label3">
112
+ <property name="visible">True</property>
113
+ <property name="xpad">3</property>
114
+ <property name="ypad">3</property>
115
+ <property name="label" translatable="yes">&#x421;&#x436;&#x430;&#x442;&#x438;&#x435;</property>
116
+ <property name="justify">right</property>
117
+ <property name="single_line_mode">True</property>
118
+ </object>
119
+ <packing>
120
+ <property name="top_attach">2</property>
121
+ <property name="bottom_attach">3</property>
122
+ <property name="x_options">GTK_FILL</property>
123
+ <property name="y_options"></property>
124
+ </packing>
125
+ </child>
126
+ <child>
127
+ <object class="GtkHScale" id="ratio_scale">
128
+ <property name="visible">True</property>
129
+ <property name="can_focus">True</property>
130
+ <property name="fill_level">100</property>
131
+ <property name="digits">0</property>
132
+ </object>
133
+ <packing>
134
+ <property name="left_attach">2</property>
135
+ <property name="right_attach">3</property>
136
+ <property name="top_attach">2</property>
137
+ <property name="bottom_attach">3</property>
138
+ <property name="y_options"></property>
139
+ </packing>
140
+ </child>
141
+ <child>
142
+ <object class="GtkEntry" id="size_edit">
143
+ <property name="visible">True</property>
144
+ <property name="can_focus">True</property>
145
+ <property name="tooltip_text" translatable="yes">&#x41C;&#x430;&#x43A;&#x441;&#x438;&#x43C;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x439; &#x440;&#x430;&#x437;&#x43C;&#x435;&#x440; &#x444;&#x43E;&#x442;&#x43E;&#x433;&#x440;&#x430;&#x444;&#x438;&#x438;: &#x428;&#x418;&#x420;&#x418;&#x41D;&#x410; x &#x412;&#x42B;&#x421;&#x41E;&#x422;&#x410; &#x438;&#x43B;&#x438; &#x41F;&#x420;&#x41E;&#x426;&#x415;&#x41D;&#x422;%</property>
146
+ <property name="invisible_char">&#x25CF;</property>
147
+ </object>
148
+ <packing>
149
+ <property name="left_attach">1</property>
150
+ <property name="right_attach">2</property>
151
+ <property name="top_attach">2</property>
152
+ <property name="bottom_attach">3</property>
153
+ <property name="y_options"></property>
154
+ </packing>
155
+ </child>
156
+ <child>
157
+ <object class="GtkProgressBar" id="progress_bar"/>
158
+ <packing>
159
+ <property name="right_attach">3</property>
160
+ <property name="top_attach">5</property>
161
+ <property name="bottom_attach">6</property>
162
+ <property name="y_options"></property>
163
+ </packing>
164
+ </child>
165
+ <child>
166
+ <object class="GtkStatusbar" id="status_bar">
167
+ <property name="visible">True</property>
168
+ <property name="spacing">2</property>
169
+ </object>
170
+ <packing>
171
+ <property name="right_attach">3</property>
172
+ <property name="top_attach">6</property>
173
+ <property name="bottom_attach">7</property>
174
+ <property name="y_options"></property>
175
+ </packing>
176
+ </child>
177
+ <child>
178
+ <object class="GtkEntry" id="src_edit">
179
+ <property name="visible">True</property>
180
+ <property name="can_focus">True</property>
181
+ <property name="tooltip_text" translatable="yes">&#x41A;&#x430;&#x442;&#x430;&#x43B;&#x43E;&#x433; &#x441; &#x438;&#x441;&#x445;&#x43E;&#x434;&#x43D;&#x44B;&#x43C;&#x438; &#x444;&#x43E;&#x442;&#x43E;&#x433;&#x440;&#x430;&#x444;&#x438;&#x44F;&#x43C;&#x438;</property>
182
+ <property name="invisible_char">&#x25CF;</property>
183
+ </object>
184
+ <packing>
185
+ <property name="left_attach">1</property>
186
+ <property name="right_attach">2</property>
187
+ <property name="y_options"></property>
188
+ </packing>
189
+ </child>
190
+ <child>
191
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
192
+ <property name="visible">True</property>
193
+ <property name="can_focus">True</property>
194
+ <property name="hscrollbar_policy">automatic</property>
195
+ <property name="vscrollbar_policy">automatic</property>
196
+ <child>
197
+ <object class="GtkTextView" id="textview">
198
+ <property name="visible">True</property>
199
+ <property name="can_focus">True</property>
200
+ <property name="editable">False</property>
201
+ <property name="cursor_visible">False</property>
202
+ <property name="accepts_tab">False</property>
203
+ </object>
204
+ </child>
205
+ </object>
206
+ <packing>
207
+ <property name="right_attach">3</property>
208
+ <property name="top_attach">3</property>
209
+ <property name="bottom_attach">4</property>
210
+ </packing>
211
+ </child>
212
+ </object>
213
+ </child>
214
+ </object>
215
+ </interface>
data/lib/bconv.rb ADDED
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env ruby
2
+ #############################################################################
3
+ # Yet Another ImageMagic Frontend #
4
+ # (C) 2010-2011, Vasiliy Yeremeyev <vayerx@gmail.com> #
5
+ # #
6
+ # This program is free software: you can redistribute it and/or modify #
7
+ # it under the terms of the GNU General Public License as published by #
8
+ # the Free Software Foundation, either version 3 of the License, or #
9
+ # (at your option) any later version. #
10
+ # #
11
+ # This program is distributed in the hope that it will be useful, #
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14
+ # GNU General Public License for more details. #
15
+ # #
16
+ # You should have received a copy of the GNU General Public License #
17
+ # along with this program. If not, see <http://www.gnu.org/licenses/>. #
18
+ #############################################################################
19
+
20
+ # TODO use 'rmagic' interface instead of Kernel.system
21
+
22
+
23
+ require 'enumerator'
24
+
25
+ def number_of_processors
26
+ raise "Can't determine 'number_of_processors' for '#{RUBY_PLATFORM}'" unless RUBY_PLATFORM =~ /linux/
27
+ %x[cat /proc/cpuinfo | grep processor | wc -l].to_i
28
+ end
29
+
30
+ class Converter
31
+ def initialize
32
+ @source_files = []
33
+ @launcher_thread = nil
34
+ @semaphore = Mutex.new
35
+ @jobs_slots = (number_of_processors * 1.25 + 1).to_i rescue 1
36
+ @jobs_slots = 1 if @jobs_slots < 1
37
+ end
38
+
39
+ # Asynchronously get directory listing
40
+ def preload_dir(dir, &block)
41
+ @counting_thread.terminate if @counting_thread
42
+ @counting_thread = Thread.new {
43
+ list_directory(dir)
44
+ block.call(@source_files.size) if block_given?
45
+ }
46
+ end
47
+
48
+ # Process directory
49
+ def process(src_dir, dest_dir, size, ratio, &progress)
50
+ @launcher_thread.join if @launcher_thread # supposed to be quick enough
51
+ @launcher_thread = Thread.new {
52
+ # get directory listing
53
+ if @counting_thread
54
+ @counting_thread.join
55
+ @counting_thread = nil
56
+ else
57
+ list_directory(src_dir)
58
+ end
59
+
60
+ unless @source_files.empty?
61
+ pulse_step = 1 / @source_files.size.to_f
62
+ @jobs=[]
63
+ @source_files.each_slice(((@source_files.size + @jobs_slots - 1) / @jobs_slots).to_i) do |files|
64
+ @jobs << Thread.new do
65
+ process_directory(src_dir, dest_dir, files, size, ratio, pulse_step, &progress)
66
+ end
67
+ end
68
+ else
69
+ progress.call(nil, nil, true)
70
+ end
71
+ }
72
+ end
73
+
74
+ # Terminate all running threads
75
+ def stop
76
+ @launcher_thread.terminate if @launcher_thread
77
+ @jobs.each { |thread| thread.terminate } if @jobs
78
+ @launcher_thread, @jobs = nil, nil
79
+ end
80
+
81
+ private
82
+
83
+ # Convert files
84
+ def process_directory(src_dir, dest_dir, source_files, size, ratio, pulse_step, &progress)
85
+ # rename files if destination is a source directory
86
+ file_rename =
87
+ if src_dir == dest_dir
88
+ Proc.new { |file| file.gsub(/(.*)(\.jpe?g)$/i, "\\1_#{size}\\2") }
89
+ else
90
+ Proc.new { |file| file }
91
+ end
92
+
93
+ # process files
94
+ size_opt = size && size.length != 0 ? "-resize #{size}" : ""
95
+ source_files.each do |file|
96
+ src_file = "#{src_dir}/#{file}".gsub(/([\s'()"])/, '\\\\\1')
97
+ dest_file = "#{dest_dir}/#{file_rename[file]}".gsub(/([\s'()"])/, '\\\\\1')
98
+ if src_file != dest_file
99
+ progress.call(file, nil, false)
100
+ system("convert -quality #{ratio} #{size_opt} #{src_file} #{dest_file}")
101
+ else
102
+ progress.call('SKIPPING ' + file, nil, false)
103
+ end
104
+ progress.call(nil, pulse_step, false)
105
+ end
106
+ ensure
107
+ @semaphore.synchronize {
108
+ progress.call(nil, nil, true) if (@jobs_slots -= 1) == 0
109
+ }
110
+ end
111
+
112
+ # Find JPEG files in a directory
113
+ def list_directory(dir)
114
+ @source_files = Dir.entries(dir).find_all { |file| /.*jpe?g$/i =~ file }
115
+ end
116
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bconv
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Vasiliy Yeremeyev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parseconfig
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.4
27
+ description: Yet another ImageMagick hardcore gui-frontend with multi-threading. Only
28
+ Russian language is supported.
29
+ email: vayerx@gmail.com
30
+ executables:
31
+ - bconv
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - lib/bconv.rb
36
+ - data/bconv.glade
37
+ - bin/bconv
38
+ homepage: http://github.com/vayerx/bconv
39
+ licenses:
40
+ - GPL-3
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ~>
49
+ - !ruby/object:Gem::Version
50
+ version: 1.9.2
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements:
57
+ - libglade2, v2.6 or higher
58
+ rubyforge_project:
59
+ rubygems_version: 2.0.14
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: ImageMagick frontend for fast jpeg compression.
63
+ test_files: []