rabbit 3.0.0 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|