rabbit 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +2 -1
- data/data/locale/en/LC_MESSAGES/rabbit.mo +0 -0
- data/data/locale/ja/LC_MESSAGES/rabbit.mo +0 -0
- data/doc/_config.yml +2 -2
- data/doc/_layouts/skeleton.html +0 -7
- data/doc/en/faq.rd +4 -2
- data/doc/en/install/homebrew.rd +8 -13
- data/doc/en/news.rd +158 -0
- data/doc/en/sample/hiki/rabbit.hiki +0 -4
- data/doc/en/sample/rd/rabbit.rd +0 -4
- data/doc/en/usage/rabbit-slide.rd +3 -3
- data/doc/images/screenshots/en/blue-circle-raw.png +0 -0
- data/doc/images/screenshots/en/blue-circle.png +0 -0
- data/doc/images/screenshots/en/clear-blue-raw.png +0 -0
- data/doc/images/screenshots/en/clear-blue.png +0 -0
- data/doc/images/screenshots/en/cozmixng-raw.png +0 -0
- data/doc/images/screenshots/en/cozmixng.png +0 -0
- data/doc/images/screenshots/en/dark-gradation-raw.png +0 -0
- data/doc/images/screenshots/en/dark-gradation.png +0 -0
- data/doc/images/screenshots/en/day-white-raw.png +0 -0
- data/doc/images/screenshots/en/day-white.png +0 -0
- data/doc/images/screenshots/en/debian-raw.png +0 -0
- data/doc/images/screenshots/en/debian.png +0 -0
- data/doc/images/screenshots/en/green-circle-raw.png +0 -0
- data/doc/images/screenshots/en/green-circle.png +0 -0
- data/doc/images/screenshots/en/night-black-raw.png +0 -0
- data/doc/images/screenshots/en/night-black.png +0 -0
- data/doc/images/screenshots/en/rabbit-raw.png +0 -0
- data/doc/images/screenshots/en/rabbit.png +0 -0
- data/doc/images/screenshots/en/ranguba-raw.png +0 -0
- data/doc/images/screenshots/en/ranguba.png +0 -0
- data/doc/images/screenshots/en/red-frame-raw.png +0 -0
- data/doc/images/screenshots/en/red-frame.png +0 -0
- data/doc/images/screenshots/en/ruby-gnome2-raw.png +0 -0
- data/doc/images/screenshots/en/ruby-gnome2.png +0 -0
- data/doc/images/screenshots/en/rubykaigi2011-raw.png +0 -0
- data/doc/images/screenshots/en/rubykaigi2011.png +0 -0
- data/doc/images/screenshots/ja/blue-circle-raw.png +0 -0
- data/doc/images/screenshots/ja/blue-circle.png +0 -0
- data/doc/images/screenshots/ja/clear-blue-raw.png +0 -0
- data/doc/images/screenshots/ja/clear-blue.png +0 -0
- data/doc/images/screenshots/ja/cozmixng-raw.png +0 -0
- data/doc/images/screenshots/ja/cozmixng.png +0 -0
- data/doc/images/screenshots/ja/dark-gradation-raw.png +0 -0
- data/doc/images/screenshots/ja/dark-gradation.png +0 -0
- data/doc/images/screenshots/ja/day-white-raw.png +0 -0
- data/doc/images/screenshots/ja/day-white.png +0 -0
- data/doc/images/screenshots/ja/debian-raw.png +0 -0
- data/doc/images/screenshots/ja/debian.png +0 -0
- data/doc/images/screenshots/ja/green-circle-raw.png +0 -0
- data/doc/images/screenshots/ja/green-circle.png +0 -0
- data/doc/images/screenshots/ja/night-black-raw.png +0 -0
- data/doc/images/screenshots/ja/night-black.png +0 -0
- data/doc/images/screenshots/ja/rabbit-raw.png +0 -0
- data/doc/images/screenshots/ja/rabbit.png +0 -0
- data/doc/images/screenshots/ja/ranguba-raw.png +0 -0
- data/doc/images/screenshots/ja/ranguba.png +0 -0
- data/doc/images/screenshots/ja/red-frame-raw.png +0 -0
- data/doc/images/screenshots/ja/red-frame.png +0 -0
- data/doc/images/screenshots/ja/ruby-gnome2-raw.png +0 -0
- data/doc/images/screenshots/ja/ruby-gnome2.png +0 -0
- data/doc/images/screenshots/ja/rubykaigi2011-raw.png +0 -0
- data/doc/images/screenshots/ja/rubykaigi2011.png +0 -0
- data/doc/index.html.en +1 -1
- data/doc/ja/faq.rd +2 -0
- data/doc/ja/install/homebrew.rd +8 -12
- data/doc/ja/news.rd +157 -0
- data/doc/ja/sample/hiki/rabbit.hiki +0 -4
- data/doc/ja/sample/rd/rabbit.rd +0 -4
- data/doc/ja/usage/rabbit-slide.rd +3 -3
- data/doc/ja/users.rd +7 -0
- data/lib/rabbit/action/toggle.rb +7 -0
- data/lib/rabbit/author-configuration.rb +3 -4
- data/lib/rabbit/canvas.rb +18 -6
- data/lib/rabbit/command/rabbit-slide.rb +59 -1
- data/lib/rabbit/command/rabbit-slide.ui +127 -49
- data/lib/rabbit/command/rabbit.rb +5 -9
- data/lib/rabbit/element/base.rb +1 -5
- data/lib/rabbit/element/image.rb +139 -89
- data/lib/rabbit/element/video.rb +3 -11
- data/lib/rabbit/error.rb +9 -3
- data/lib/rabbit/formatter.rb +1 -1
- data/lib/rabbit/frame.rb +102 -4
- data/lib/rabbit/gem-pusher.rb +29 -6
- data/lib/rabbit/image/base.rb +163 -28
- data/lib/rabbit/image/dia.rb +21 -14
- data/lib/rabbit/image/mermaid.rb +73 -0
- data/lib/rabbit/image/pdf.rb +22 -9
- data/lib/rabbit/image/svg.rb +1 -4
- data/lib/rabbit/image.rb +6 -6
- data/lib/rabbit/info-window.rb +106 -80
- data/lib/rabbit/keys.rb +6 -0
- data/lib/rabbit/menu.rb +2 -0
- data/lib/rabbit/parser/base.rb +2 -1
- data/lib/rabbit/parser/ext/blockdiag.rb +16 -14
- data/lib/rabbit/parser/ext/charty.rb +58 -0
- data/lib/rabbit/parser/ext/image.rb +38 -10
- data/lib/rabbit/parser/markdown/converter.rb +36 -30
- data/lib/rabbit/parser/rd/ext/block-verbatim.rb +33 -35
- data/lib/rabbit/parser/rd/ext/image.rb +23 -4
- data/lib/rabbit/parser/rd/rd2rabbit-lib.rb +3 -1
- data/lib/rabbit/parser/rd.rb +1 -1
- data/lib/rabbit/parser/wiki/output.rb +9 -9
- data/lib/rabbit/parser.rb +2 -2
- data/lib/rabbit/progress.rb +1 -1
- data/lib/rabbit/properties.rb +154 -0
- data/lib/rabbit/rabbit.rb +3 -1
- data/lib/rabbit/relative-size.rb +28 -0
- data/lib/rabbit/renderer/base.rb +6 -0
- data/lib/rabbit/renderer/display/drawing-area-base.rb +1 -2
- data/lib/rabbit/renderer/display/drawing-area-primitive.rb +1 -0
- data/lib/rabbit/renderer/display/info.rb +6 -1
- data/lib/rabbit/renderer/display/key-handler.rb +27 -2
- data/lib/rabbit/renderer/engine/cairo.rb +24 -3
- data/lib/rabbit/renderer/screen.rb +0 -1
- data/lib/rabbit/slide-configuration.rb +16 -8
- data/lib/rabbit/task/slide.rb +6 -33
- data/lib/rabbit/theme/background-image-toolkit/background-image-toolkit.rb +38 -0
- data/lib/rabbit/theme/clear-blue/clear-blue.rb +4 -2
- data/lib/rabbit/theme/edge-info-toolkit/edge-info-toolkit.rb +12 -2
- data/lib/rabbit/theme/image/image.rb +3 -0
- data/lib/rabbit/theme/image-slide-number/image-slide-number.rb +8 -3
- data/lib/rabbit/theme/image-timer/image-timer.rb +8 -3
- data/lib/rabbit/theme/pdf/pdf.rb +1 -1
- data/lib/rabbit/theme/slide-footer-info/slide-footer-info.rb +2 -0
- data/lib/rabbit/theme/tag/tag.rb +9 -2
- data/lib/rabbit/theme-configuration.rb +3 -4
- data/lib/rabbit/utils.rb +25 -2
- data/lib/rabbit/version.rb +2 -2
- data/lib/rabbit/video-window.rb +14 -3
- data/{test/test-slideshare.rb → lib/rabbit/yaml-loader.rb} +20 -15
- data/po/en/rabbit.edit.po +123 -121
- data/po/en/rabbit.po +28 -26
- data/po/fr/rabbit.edit.po +122 -120
- data/po/fr/rabbit.po +27 -25
- data/po/ja/rabbit.edit.po +156 -125
- data/po/ja/rabbit.po +34 -30
- data/rabbit.gemspec +0 -1
- data/sample/can_rabbit.rd +0 -24
- data/sample/rabbit-en.hiki +0 -4
- data/sample/rabbit-en.md +13 -0
- data/sample/rabbit-en.rd +10 -4
- data/sample/rabbit.hiki +0 -4
- data/sample/rabbit.md +21 -0
- data/sample/rabbit.rd +20 -4
- data/test/command/test-rabbit.rb +1 -0
- data/test/parser/test-markdown.rb +2 -2
- data/test/test-slide-configuration.rb +4 -2
- metadata +30 -46
- data/doc/css/jquery-ui/themes/ui-lightness.css +0 -573
- data/doc/javascripts/jquery-ui.js +0 -11544
- data/doc/javascripts/jquery.js +0 -7179
- data/lib/rabbit/slideshare.rb +0 -192
data/lib/rabbit/element/video.rb
CHANGED
|
@@ -14,7 +14,6 @@ module Rabbit
|
|
|
14
14
|
include TextRenderer
|
|
15
15
|
|
|
16
16
|
attr_reader :filename
|
|
17
|
-
attr_reader :normalized_width, :normalized_height
|
|
18
17
|
attr_reader :relative_width, :relative_height
|
|
19
18
|
attr_reader :relative_margin_top, :relative_margin_bottom
|
|
20
19
|
attr_reader :relative_margin_left, :relative_margin_right
|
|
@@ -34,7 +33,6 @@ module Rabbit
|
|
|
34
33
|
instance_variable_set("@#{name}", true_value?(prop[name]))
|
|
35
34
|
end
|
|
36
35
|
%w(width height
|
|
37
|
-
normalized_width normalized_height
|
|
38
36
|
relative_width relative_height
|
|
39
37
|
relative_margin_top relative_margin_bottom
|
|
40
38
|
relative_margin_left relative_margin_right
|
|
@@ -44,7 +42,7 @@ module Rabbit
|
|
|
44
42
|
begin
|
|
45
43
|
instance_variable_set("@#{name}", prop[name] && Integer(prop[name]))
|
|
46
44
|
rescue ArgumentError
|
|
47
|
-
raise
|
|
45
|
+
raise InvalidSizeError.new(filename, name, prop[name])
|
|
48
46
|
end
|
|
49
47
|
end
|
|
50
48
|
|
|
@@ -126,12 +124,10 @@ module Rabbit
|
|
|
126
124
|
iw = base_w
|
|
127
125
|
ih = base_h
|
|
128
126
|
else
|
|
129
|
-
nw = make_normalized_size(@normalized_width)
|
|
130
|
-
nh = make_normalized_size(@normalized_height)
|
|
131
127
|
rw = make_relative_size(@relative_width, base_w)
|
|
132
128
|
rh = make_relative_size(@relative_height, base_h)
|
|
133
|
-
iw =
|
|
134
|
-
ih =
|
|
129
|
+
iw = rw || base_w
|
|
130
|
+
ih = rh || base_h
|
|
135
131
|
end
|
|
136
132
|
resize(iw, ih)
|
|
137
133
|
end
|
|
@@ -151,10 +147,6 @@ module Rabbit
|
|
|
151
147
|
end
|
|
152
148
|
end
|
|
153
149
|
|
|
154
|
-
def make_normalized_size(size)
|
|
155
|
-
size && screen_size(size)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
150
|
def make_relative_size(size, parent_size)
|
|
159
151
|
size && parent_size && ((size / 100.0) * parent_size).ceil
|
|
160
152
|
end
|
data/lib/rabbit/error.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2004-
|
|
1
|
+
# Copyright (C) 2004-2022 Sutou Kouhei <kou@cozmixng.org>
|
|
2
2
|
#
|
|
3
3
|
# This program is free software; you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU General Public License as published by
|
|
@@ -87,6 +87,12 @@ module Rabbit
|
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
+
class MermaidCanNotHandleError < ImageLoadWithExternalCommandError
|
|
91
|
+
def initialize(command, additional_info=nil)
|
|
92
|
+
super("Mermaid", command, additional_info)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
90
96
|
class UnknownPropertyError < Error
|
|
91
97
|
attr_reader :name
|
|
92
98
|
def initialize(name)
|
|
@@ -181,7 +187,7 @@ module Rabbit
|
|
|
181
187
|
end
|
|
182
188
|
end
|
|
183
189
|
|
|
184
|
-
class
|
|
190
|
+
class InvalidSizeError < Error
|
|
185
191
|
attr_reader :filename, :prop_name, :value
|
|
186
192
|
def initialize(filename, prop_name, value)
|
|
187
193
|
@filename = filename
|
|
@@ -193,7 +199,7 @@ module Rabbit
|
|
|
193
199
|
:value => value,
|
|
194
200
|
}
|
|
195
201
|
super(_("invalid value of size property \"%{prop_name}\" " \
|
|
196
|
-
"of
|
|
202
|
+
"of \"%{filename}\": %{value}") % params)
|
|
197
203
|
end
|
|
198
204
|
end
|
|
199
205
|
|
data/lib/rabbit/formatter.rb
CHANGED
data/lib/rabbit/frame.rb
CHANGED
|
@@ -2,13 +2,16 @@ require "forwardable"
|
|
|
2
2
|
require "rabbit/gtk"
|
|
3
3
|
require "rexml/text"
|
|
4
4
|
|
|
5
|
+
begin
|
|
6
|
+
require "vte3"
|
|
7
|
+
rescue LoadError
|
|
8
|
+
end
|
|
9
|
+
|
|
5
10
|
require "rabbit/rabbit"
|
|
6
11
|
require "rabbit/utils"
|
|
7
12
|
|
|
8
13
|
module Rabbit
|
|
9
|
-
|
|
10
14
|
class Frame
|
|
11
|
-
|
|
12
15
|
include ScreenInfo
|
|
13
16
|
extend Forwardable
|
|
14
17
|
|
|
@@ -31,6 +34,9 @@ module Rabbit
|
|
|
31
34
|
@logger = logger
|
|
32
35
|
@canvas = canvas
|
|
33
36
|
@geometry = nil
|
|
37
|
+
@notebook = nil
|
|
38
|
+
@terminal = nil
|
|
39
|
+
@running = true
|
|
34
40
|
end
|
|
35
41
|
|
|
36
42
|
def destroyed?
|
|
@@ -38,6 +44,7 @@ module Rabbit
|
|
|
38
44
|
end
|
|
39
45
|
|
|
40
46
|
def quit
|
|
47
|
+
@running = false
|
|
41
48
|
@window.destroy unless destroyed?
|
|
42
49
|
@window = nil
|
|
43
50
|
true
|
|
@@ -87,6 +94,8 @@ module Rabbit
|
|
|
87
94
|
init_window(width, height, window_type)
|
|
88
95
|
@fullscreen = false
|
|
89
96
|
@main_window = main_window
|
|
97
|
+
@terminal.show if @terminal
|
|
98
|
+
@notebook.show if @notebook
|
|
90
99
|
@window.show
|
|
91
100
|
@canvas.post_init_gui
|
|
92
101
|
end
|
|
@@ -99,6 +108,21 @@ module Rabbit
|
|
|
99
108
|
true
|
|
100
109
|
end
|
|
101
110
|
|
|
111
|
+
def toggle_terminal
|
|
112
|
+
return if @terminal.nil?
|
|
113
|
+
terminal_page = @notebook.page_num(@terminal)
|
|
114
|
+
if @notebook.current_page == terminal_page
|
|
115
|
+
@notebook.current_page = 0
|
|
116
|
+
else
|
|
117
|
+
@notebook.current_page = terminal_page
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def in_terminal?
|
|
122
|
+
return false if @terminal.nil?
|
|
123
|
+
@notebook.current_page == @notebook.page_num(@terminal)
|
|
124
|
+
end
|
|
125
|
+
|
|
102
126
|
private
|
|
103
127
|
def init_window(width, height, window_type=nil)
|
|
104
128
|
window_type ||= :toplevel
|
|
@@ -106,9 +130,29 @@ module Rabbit
|
|
|
106
130
|
@window.set_default_size(width, height)
|
|
107
131
|
@window.parse_geometry(@geometry) if @geometry
|
|
108
132
|
@window.set_app_paintable(true)
|
|
133
|
+
if defined?(Vte::Terminal)
|
|
134
|
+
init_notebook
|
|
135
|
+
end
|
|
109
136
|
set_window_signal
|
|
110
137
|
setup_dnd
|
|
111
|
-
@canvas.attach_to(self, @window)
|
|
138
|
+
@canvas.attach_to(self, @window, @notebook)
|
|
139
|
+
if defined?(Vte::Terminal)
|
|
140
|
+
init_terminal
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def init_notebook
|
|
145
|
+
@notebook = Gtk::Notebook.new
|
|
146
|
+
@notebook.show_tabs = false
|
|
147
|
+
provider = Gtk::CssProvider.new
|
|
148
|
+
provider.load(data: <<-CSS)
|
|
149
|
+
notebook {
|
|
150
|
+
border-width: 0px;
|
|
151
|
+
}
|
|
152
|
+
CSS
|
|
153
|
+
@notebook.style_context.add_provider(provider,
|
|
154
|
+
Gtk::StyleProvider::PRIORITY_USER)
|
|
155
|
+
@window.add(@notebook)
|
|
112
156
|
end
|
|
113
157
|
|
|
114
158
|
def set_window_signal
|
|
@@ -160,6 +204,47 @@ module Rabbit
|
|
|
160
204
|
true
|
|
161
205
|
end
|
|
162
206
|
end
|
|
207
|
+
|
|
208
|
+
def init_terminal
|
|
209
|
+
@terminal = Vte::Terminal.new
|
|
210
|
+
# TODO: Support theme
|
|
211
|
+
terminal_font_description = ENV["RABBIT_TERMINAL_FONT_DESCRIPTION"]
|
|
212
|
+
if terminal_font_description
|
|
213
|
+
@terminal.font_desc =
|
|
214
|
+
Pango::FontDescription.new(terminal_font_description)
|
|
215
|
+
end
|
|
216
|
+
terminal_color_foreground = ENV["RABBIT_TERMINAL_COLOR_FOREGROUND"]
|
|
217
|
+
if terminal_color_foreground
|
|
218
|
+
@terminal.color_foreground = terminal_color_foreground
|
|
219
|
+
end
|
|
220
|
+
terminal_color_background = ENV["RABBIT_TERMINAL_COLOR_BACKGROUND"]
|
|
221
|
+
if terminal_color_background
|
|
222
|
+
@terminal.color_background = terminal_color_background
|
|
223
|
+
end
|
|
224
|
+
@terminal.enable_sixel = true if @terminal.respond_to?(:enable_sixel=)
|
|
225
|
+
@notebook.add(@terminal)
|
|
226
|
+
pid = nil
|
|
227
|
+
in_terminal = false
|
|
228
|
+
@notebook.signal_connect(:switch_page) do |_, page,|
|
|
229
|
+
if page == @terminal
|
|
230
|
+
if @running
|
|
231
|
+
pid = @terminal.spawn if pid.nil?
|
|
232
|
+
@canvas.pre_terminal unless in_terminal
|
|
233
|
+
in_terminal = true
|
|
234
|
+
end
|
|
235
|
+
else
|
|
236
|
+
@canvas.post_terminal if in_terminal
|
|
237
|
+
in_terminal = false
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
@terminal.signal_connect(:child_exited) do
|
|
241
|
+
pid = nil
|
|
242
|
+
terminal_page = @notebook.page_num(@terminal)
|
|
243
|
+
if @notebook.current_page == terminal_page
|
|
244
|
+
@canvas.activate("ToggleTerminal")
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
163
248
|
end
|
|
164
249
|
|
|
165
250
|
class NullFrame
|
|
@@ -184,10 +269,16 @@ module Rabbit
|
|
|
184
269
|
def iconify_available?
|
|
185
270
|
false
|
|
186
271
|
end
|
|
272
|
+
|
|
273
|
+
def toggle_terminal
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def in_terminal?
|
|
277
|
+
false
|
|
278
|
+
end
|
|
187
279
|
end
|
|
188
280
|
|
|
189
281
|
class EmbedFrame < Frame
|
|
190
|
-
|
|
191
282
|
def update_title(new_title)
|
|
192
283
|
end
|
|
193
284
|
|
|
@@ -199,6 +290,13 @@ module Rabbit
|
|
|
199
290
|
false
|
|
200
291
|
end
|
|
201
292
|
|
|
293
|
+
def toggle_terminal
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def in_terminal?
|
|
297
|
+
false
|
|
298
|
+
end
|
|
299
|
+
|
|
202
300
|
def init_gui(width, height, main_window, window_type=nil)
|
|
203
301
|
@window = Gtk::EventBox.new
|
|
204
302
|
@window.set_size_request(width, height)
|
data/lib/rabbit/gem-pusher.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2016 Kouhei
|
|
1
|
+
# Copyright (C) 2016-2023 Sutou Kouhei <kou@cozmixng.org>
|
|
2
2
|
#
|
|
3
3
|
# This program is free software; you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU General Public License as published by
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
16
16
|
|
|
17
17
|
require "rake"
|
|
18
|
-
require "yaml"
|
|
19
18
|
require "open-uri"
|
|
20
19
|
|
|
21
20
|
require "rabbit/gettext"
|
|
22
21
|
require "rabbit/password-reader"
|
|
22
|
+
require "rabbit/yaml-loader"
|
|
23
23
|
|
|
24
24
|
module Rabbit
|
|
25
25
|
class GemPusher
|
|
@@ -35,12 +35,13 @@ module Rabbit
|
|
|
35
35
|
credentials_path = File.expand_path("~/.gem/credentials")
|
|
36
36
|
credentials_path_exist = File.exist?(credentials_path)
|
|
37
37
|
if credentials_path_exist
|
|
38
|
-
credentials =
|
|
38
|
+
credentials = YAMLLoader.load(File.read(credentials_path))
|
|
39
39
|
else
|
|
40
40
|
credentials = {}
|
|
41
41
|
end
|
|
42
42
|
unless credentials.key?(@user.to_sym)
|
|
43
43
|
credentials[@user.to_sym] = retrieve_api_key
|
|
44
|
+
FileUtils.mkdir_p(File.dirname(credentials_path))
|
|
44
45
|
File.open(credentials_path, "w") do |credentials_file|
|
|
45
46
|
credentials_file.print(credentials.to_yaml)
|
|
46
47
|
end
|
|
@@ -57,10 +58,32 @@ module Rabbit
|
|
|
57
58
|
prompt = _("Enter password on RubyGems.org [%{user}]: ") % {:user => @user}
|
|
58
59
|
reader = PasswordReader.new(prompt)
|
|
59
60
|
password = reader.read
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
begin
|
|
62
|
+
URI.open("https://rubygems.org/api/v1/api_key.yaml",
|
|
63
|
+
:http_basic_authentication => [@user, password]) do |response|
|
|
64
|
+
YAMLLoader.load(response.read)[:rubygems_api_key]
|
|
65
|
+
end
|
|
66
|
+
rescue OpenURI::HTTPError => error
|
|
67
|
+
if mfa_error?(error)
|
|
68
|
+
prompt = _("Enter OTP on RubyGems.org [%{user}]: ") % {:user => @user}
|
|
69
|
+
# TODO: We don't need to hide input.
|
|
70
|
+
reader = PasswordReader.new(prompt)
|
|
71
|
+
otp = reader.read
|
|
72
|
+
URI.open("https://rubygems.org/api/v1/api_key.yaml",
|
|
73
|
+
:http_basic_authentication => [@user, password],
|
|
74
|
+
"OTP" => otp) do |response|
|
|
75
|
+
YAMLLoader.load(response.read)[:rubygems_api_key]
|
|
76
|
+
end
|
|
77
|
+
else
|
|
78
|
+
raise
|
|
79
|
+
end
|
|
63
80
|
end
|
|
64
81
|
end
|
|
82
|
+
|
|
83
|
+
def mfa_error?(error)
|
|
84
|
+
return false unless error.message.start_with?("401 ")
|
|
85
|
+
body = error.io.read
|
|
86
|
+
body.start_with?("You have enabled multifactor authentication")
|
|
87
|
+
end
|
|
65
88
|
end
|
|
66
89
|
end
|
data/lib/rabbit/image/base.rb
CHANGED
|
@@ -1,20 +1,64 @@
|
|
|
1
|
+
# Copyright (C) 2004-2022 Sutou Kouhei <kou@cozmixng.org>
|
|
2
|
+
#
|
|
3
|
+
# This program is free software; you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License along
|
|
14
|
+
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
15
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
16
|
+
|
|
17
|
+
require "forwardable"
|
|
18
|
+
require "digest/sha2"
|
|
19
|
+
|
|
1
20
|
require "gdk_pixbuf2"
|
|
2
21
|
|
|
3
|
-
require "rabbit/utils"
|
|
4
22
|
require "rabbit/image-data-loader"
|
|
23
|
+
require "rabbit/properties"
|
|
5
24
|
|
|
6
25
|
module Rabbit
|
|
7
26
|
module ImageManipulable
|
|
8
|
-
|
|
9
27
|
class Base
|
|
10
28
|
extend ModuleLoader
|
|
11
29
|
|
|
12
|
-
|
|
30
|
+
class << self
|
|
31
|
+
def delegate
|
|
32
|
+
extend Forwardable
|
|
33
|
+
|
|
34
|
+
def_delegators(:@delegated_loader,
|
|
35
|
+
:draw,
|
|
36
|
+
:ensure_resize,
|
|
37
|
+
:height,
|
|
38
|
+
:internal_pixbuf,
|
|
39
|
+
:keep_ratio,
|
|
40
|
+
:keep_ratio=,
|
|
41
|
+
:keep_ratio?,
|
|
42
|
+
:original_height,
|
|
43
|
+
:original_width,
|
|
44
|
+
:pixbuf,
|
|
45
|
+
:resize,
|
|
46
|
+
:update_size,
|
|
47
|
+
:width)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
attr_reader :filename
|
|
52
|
+
attr_reader :properties
|
|
53
|
+
attr_reader :original_width
|
|
54
|
+
attr_reader :original_height
|
|
13
55
|
attr_reader :animation
|
|
14
56
|
|
|
15
|
-
def initialize(filename, props)
|
|
57
|
+
def initialize(filename, props, canvas: nil)
|
|
16
58
|
@filename = filename
|
|
17
|
-
@
|
|
59
|
+
@properties = Properties.new(props)
|
|
60
|
+
@canvas = canvas
|
|
61
|
+
initialize_keep_ratio
|
|
18
62
|
@animation = nil
|
|
19
63
|
@animation_iterator = nil
|
|
20
64
|
@animation_timeout = nil
|
|
@@ -24,29 +68,57 @@ module Rabbit
|
|
|
24
68
|
end
|
|
25
69
|
|
|
26
70
|
def [](key)
|
|
27
|
-
@
|
|
71
|
+
@properties[key]
|
|
28
72
|
end
|
|
29
73
|
|
|
30
74
|
def []=(key, value)
|
|
31
|
-
@
|
|
75
|
+
@properties[key] = value
|
|
32
76
|
end
|
|
33
77
|
|
|
34
|
-
def keep_ratio
|
|
35
|
-
|
|
78
|
+
def keep_ratio?
|
|
79
|
+
@properties.keep_ratio
|
|
36
80
|
end
|
|
81
|
+
# For backward compatibility
|
|
82
|
+
alias_method :keep_ratio, :keep_ratio?
|
|
37
83
|
|
|
38
84
|
def keep_ratio=(value)
|
|
39
|
-
|
|
85
|
+
@properties.keep_ratio = value
|
|
40
86
|
end
|
|
41
87
|
|
|
42
88
|
def pixbuf
|
|
43
89
|
@pixbuf
|
|
44
90
|
end
|
|
45
91
|
|
|
92
|
+
def width
|
|
93
|
+
(relative_clip_width&.resolve(@width) || @width) -
|
|
94
|
+
(relative_clip_x&.resolve(@width) || 0)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def height
|
|
98
|
+
(relative_clip_height&.resolve(@height) || @height) -
|
|
99
|
+
(relative_clip_y&.resolve(@height) || 0)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def relative_clip_x
|
|
103
|
+
@properties.get_relative_size("relative_clip_x", @filename)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def relative_clip_y
|
|
107
|
+
@properties.get_relative_size("relative_clip_y", @filename)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def relative_clip_width
|
|
111
|
+
@properties.get_relative_size("relative_clip_width", @filename)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def relative_clip_height
|
|
115
|
+
@properties.get_relative_size("relative_clip_height", @filename)
|
|
116
|
+
end
|
|
117
|
+
|
|
46
118
|
def resize(w, h)
|
|
47
119
|
if w.nil? and h.nil?
|
|
48
120
|
return
|
|
49
|
-
elsif keep_ratio
|
|
121
|
+
elsif keep_ratio?
|
|
50
122
|
if w and h.nil?
|
|
51
123
|
h = (original_height * w.to_f / original_width).ceil
|
|
52
124
|
elsif w.nil? and h
|
|
@@ -65,10 +137,7 @@ module Rabbit
|
|
|
65
137
|
end
|
|
66
138
|
|
|
67
139
|
def draw(canvas, x, y, params={})
|
|
68
|
-
default_params =
|
|
69
|
-
:width => width,
|
|
70
|
-
:height => height,
|
|
71
|
-
}
|
|
140
|
+
default_params = default_draw_params(x, y)
|
|
72
141
|
target_pixbuf = pixbuf
|
|
73
142
|
if @animation_iterator
|
|
74
143
|
@animation_iterator.advance
|
|
@@ -79,20 +148,15 @@ module Rabbit
|
|
|
79
148
|
end
|
|
80
149
|
|
|
81
150
|
private
|
|
82
|
-
def
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
151
|
+
def initialize_keep_ratio
|
|
152
|
+
return unless @properties["keep_ratio"].nil?
|
|
153
|
+
# For backward compatibility
|
|
154
|
+
keep_scale = @properties["keep_scale"]
|
|
155
|
+
if keep_scale.nil?
|
|
156
|
+
@properties["keep_ratio"] = true
|
|
157
|
+
else
|
|
158
|
+
@properties["keep_ratio"] = keep_scale
|
|
90
159
|
end
|
|
91
|
-
normalized_props
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def normalize_prop_key(key)
|
|
95
|
-
key.to_s.gsub(/-/, "_")
|
|
96
160
|
end
|
|
97
161
|
|
|
98
162
|
def load_data(data)
|
|
@@ -129,6 +193,77 @@ module Rabbit
|
|
|
129
193
|
end
|
|
130
194
|
end
|
|
131
195
|
end
|
|
196
|
+
|
|
197
|
+
def default_draw_params(x, y)
|
|
198
|
+
_relative_clip_x = relative_clip_x
|
|
199
|
+
_relative_clip_y = relative_clip_y
|
|
200
|
+
_relative_clip_width = relative_clip_width
|
|
201
|
+
_relative_clip_height = relative_clip_height
|
|
202
|
+
if _relative_clip_x or
|
|
203
|
+
_relative_clip_y or
|
|
204
|
+
_relative_clip_width or
|
|
205
|
+
_relative_clip_height
|
|
206
|
+
clip_x = _relative_clip_x&.resolve(@width) || 0
|
|
207
|
+
clip_y = _relative_clip_y&.resolve(@height) || 0
|
|
208
|
+
clip_width = _relative_clip_width&.resolve(@width) || @width
|
|
209
|
+
clip_height = _relative_clip_height&.resolve(@height) || @height
|
|
210
|
+
uncliped_width = width - (clip_width - clip_x) + @width
|
|
211
|
+
uncliped_height = height - (clip_height - clip_y) + @height
|
|
212
|
+
{
|
|
213
|
+
width: uncliped_width,
|
|
214
|
+
height: uncliped_height,
|
|
215
|
+
clip_x: x + clip_x,
|
|
216
|
+
clip_y: y + clip_y,
|
|
217
|
+
clip_width: clip_width,
|
|
218
|
+
clip_height: clip_height,
|
|
219
|
+
}
|
|
220
|
+
else
|
|
221
|
+
{
|
|
222
|
+
width: width,
|
|
223
|
+
height: height,
|
|
224
|
+
}
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# TODO: Move to more suitable location
|
|
229
|
+
def cache_processed_data(canvas, input, extension)
|
|
230
|
+
tmp_dir_name = canvas&.tmp_dir_name
|
|
231
|
+
return yield unless tmp_dir_name
|
|
232
|
+
hash = compute_hash(input)
|
|
233
|
+
cached_path = File.join(tmp_dir_name, "#{hash}.#{extension}")
|
|
234
|
+
unless File.exist?(cached_path)
|
|
235
|
+
processed_path = yield
|
|
236
|
+
FileUtils.cp(processed_path, cached_path)
|
|
237
|
+
end
|
|
238
|
+
cached_path
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def compute_hash(input)
|
|
242
|
+
digest = Digest::SHA2.new
|
|
243
|
+
add_data = lambda do |data|
|
|
244
|
+
case data
|
|
245
|
+
when Array
|
|
246
|
+
data.each do |element|
|
|
247
|
+
add_data.call(element)
|
|
248
|
+
end
|
|
249
|
+
when Hash
|
|
250
|
+
data.each do |key, value|
|
|
251
|
+
add_data.call(key)
|
|
252
|
+
add_data.call(value)
|
|
253
|
+
end
|
|
254
|
+
when String
|
|
255
|
+
digest << data
|
|
256
|
+
when IO
|
|
257
|
+
loop do
|
|
258
|
+
chunk = data.read(4096)
|
|
259
|
+
break if chunk.nil?
|
|
260
|
+
digest << chunk
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
add_data.call(input)
|
|
265
|
+
digest.hexdigest
|
|
266
|
+
end
|
|
132
267
|
end
|
|
133
268
|
end
|
|
134
269
|
end
|
data/lib/rabbit/image/dia.rb
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
# Copyright (C) 2004-2022 Sutou Kouhei <kou@cozmixng.org>
|
|
2
|
+
#
|
|
3
|
+
# This program is free software; you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License along
|
|
14
|
+
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
15
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
2
16
|
|
|
3
|
-
require "rabbit/utils"
|
|
4
17
|
require "rabbit/image/base"
|
|
5
18
|
|
|
6
19
|
module Rabbit
|
|
@@ -11,7 +24,6 @@ module Rabbit
|
|
|
11
24
|
|
|
12
25
|
DIA_COMMANDS = %w(dia)
|
|
13
26
|
|
|
14
|
-
extend Forwardable
|
|
15
27
|
include SystemRunner
|
|
16
28
|
|
|
17
29
|
class << self
|
|
@@ -33,26 +45,21 @@ module Rabbit
|
|
|
33
45
|
end
|
|
34
46
|
end
|
|
35
47
|
|
|
36
|
-
|
|
37
|
-
def_delegators(:@svg_loader, :pixbuf, :internal_pixbuf)
|
|
38
|
-
def_delegators(:@svg_loader, :width, :height)
|
|
39
|
-
def_delegators(:@svg_loader, :original_width, :original_height)
|
|
40
|
-
def_delegators(:@svg_loader, :resize, :ensure_resize)
|
|
41
|
-
def_delegators(:@svg_loader, :update_size)
|
|
48
|
+
delegate
|
|
42
49
|
|
|
43
|
-
def initialize(filename,
|
|
44
|
-
|
|
50
|
+
def initialize(filename, props, canvas: nil)
|
|
51
|
+
init_delegated_loader(filename, props, canvas)
|
|
45
52
|
super
|
|
46
53
|
end
|
|
47
54
|
|
|
48
55
|
private
|
|
49
|
-
def
|
|
50
|
-
@svg_file = Tempfile.new(["rabbit-loader-dia", ".svg"])
|
|
56
|
+
def init_delegated_loader(filename, props, canvas)
|
|
57
|
+
@svg_file = Tempfile.new(["rabbit-image-loader-dia", ".svg"])
|
|
51
58
|
args = ["--export=#{@svg_file.path}"]
|
|
52
59
|
args << "--filter=svg"
|
|
53
60
|
args << filename
|
|
54
61
|
if DIA_COMMANDS.any? {|dia| run(dia, *args)}
|
|
55
|
-
@
|
|
62
|
+
@delegated_loader = SVG.new(@svg_file.path, props)
|
|
56
63
|
else
|
|
57
64
|
raise DiaCanNotHandleError.new("dia #{args.join(' ')}",
|
|
58
65
|
DIA_COMMANDS)
|