neruda 0.2.4 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,299 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'time'
4
- require 'fileutils'
5
- # neruda/config is required by htmlizer
6
- require 'neruda/org_file/htmlizer'
7
- require 'neruda/org_file/extracter'
8
- require 'neruda/org_file/class_methods'
9
- require 'neruda/index'
10
- require 'neruda/version'
11
-
12
- module Neruda
13
- # Handles org files.
14
- #
15
- # This class is responsible for reading or writing existing or new org
16
- # files, and formating their content to be used on the generated
17
- # website.
18
- class OrgFile
19
- # @return [String] the title of the current org document, taken from
20
- # the ~#+title:~ header.
21
- attr_reader :title
22
-
23
- # @return [String] the subtitle of the current org document, taken
24
- # from the ~#+subtitle:~ header.
25
- attr_reader :subtitle
26
-
27
- # @return [DateTime] the date and time of the current org document,
28
- # taken from the ~#+date:~ header.
29
- attr_reader :date
30
-
31
- # @return [Boolean] wether a time has been extracted from the
32
- # current org document ~#+date:~ header.
33
- attr_reader :notime
34
-
35
- # The author of the current org document, taken from the ~#+author:~
36
- # header.
37
- #
38
- # If the current document doesn't have any authorship information,
39
- # the one from the ~config.yml~ file will be used instead
40
- #
41
- # @return [String] the author name
42
- attr_reader :author
43
-
44
- # @return [Array] the keywords list of the current org document,
45
- # taken from the ~#+keywords:~ header.
46
- attr_reader :keywords
47
-
48
- # @return [String] the description of this org document, taken from
49
- # the ~#+description:~ header.
50
- attr_reader :excerpt
51
-
52
- # The locale of the current org document, taken from the
53
- # ~#+language:~ header.
54
- #
55
- # If the current document doesn't have any language information, the
56
- # one from the ~config.yml~ file will be used instead, or "en" by
57
- # default.
58
- #
59
- # @return [String] the document lang
60
- attr_reader :lang
61
-
62
- # @return [String] the relative path to the source of this document.
63
- attr_reader :file
64
-
65
- # @return [String] the relative path to the generated html file of
66
- # this document.
67
- attr_reader :html_file
68
-
69
- # @return [String] the url of this document, build from the ~domain~
70
- # settings and the above {#html_file @html_file} attribute.
71
- attr_reader :url
72
-
73
- # @return [String] the project owning this document.
74
- attr_reader :project
75
-
76
- extend Neruda::OrgFileClassMethods
77
-
78
- include Neruda::OrgFileExtracter
79
- include Neruda::OrgFileHtmlizer
80
-
81
- # Prepares the file named by ~file_name~ for read and write
82
- # operations.
83
- #
84
- # If the file ~file_name~ does not exist, the new instance may be
85
- # populated by data given in the ~opts~ parameter.
86
- #
87
- # @example
88
- # File.exist? './test.org'
89
- # => true
90
- # o = Neruda::OrgFile.new('./test.org')
91
- # => #<Neruda::OrgFile @file='./test.org'...>
92
- # o.title
93
- # => "This is an existing test file"
94
- # File.exist? '/tmp/does_not_exist.org'
95
- # => false
96
- # o = Neruda::OrgFile.new('/tmp/does_not_exist.org')
97
- # => #<Neruda::OrgFile @file='/tmp/does_not_exist.org'...>
98
- # o.title
99
- # => ""
100
- # File.exist? '/tmp/other.org'
101
- # => false
102
- # o = Neruda::OrgFile.new('/tmp/other.org', title: 'New file')
103
- # => #<Neruda::OrgFile @file='/tmp/other.org'...>
104
- # o.title
105
- # => "New file"
106
- #
107
- # @param file_name [String] path to the corresponding Org file
108
- # @param opts [Hash] optional data to initialize new Org file
109
- # @option opts [String] title ('') the title of the new Org file
110
- # @option opts [String] author (system user or '') the author of the
111
- # document
112
- # @option opts [Boolean] verbose (false) if the
113
- # {Neruda::OrgFileHtmlizer#publish publish} method should output
114
- # emacs process messages
115
- # @option opts [String] project the project owning this file
116
- # must be stored
117
- # @return [Neruda::OrgFile] the new instance of Neruda::OrgFile
118
- def initialize(file_name, opts = {})
119
- file_name = nil if file_name == ''
120
- @file = file_name
121
- @html_file = nil
122
- @url = nil
123
- @project = opts.delete :project
124
- @options = opts
125
- build_html_file_and_url
126
- if @file && File.exist?(@file)
127
- extract_data
128
- else
129
- init_empty_file
130
- end
131
- end
132
-
133
- # Returns a String representation of the document date, which aims
134
- # to be used to sort several OrgFiles.
135
- #
136
- # The format used for the key is ~%Y%m%d%H%M%S~. If the current
137
- # OrgFile instance does not have a date, this mehod return
138
- # ~00000000000000~. If the current OrgFile instance does not have
139
- # time information, the date is padded with zeros.
140
- #
141
- # @example with the org header ~#+date: <2019-07-03 Wed 20:52:49>~
142
- # org_file.date
143
- # => #<DateTime: 2019-07-03T20:52:49+02:00...>
144
- # org_file.timekey
145
- # => "20190703205349"
146
- #
147
- # @example with the org header ~#+date: <2019-07-03 Wed>~
148
- # org_file.date
149
- # => #<DateTime: 2019-07-03T00:00:00+02:00...>
150
- # org_file.timekey
151
- # => "20190703000000"
152
- #
153
- # @example with no date header in the org file
154
- # org_file.date
155
- # => nil
156
- # org_file.timekey
157
- # => "00000000000000"
158
- #
159
- # @return [String] the document key
160
- def timekey
161
- return '00000000000000' if @date.nil?
162
- @date.strftime('%Y%m%d%H%M%S')
163
- end
164
-
165
- # Returns the current OrgFile instance DateTime as a String.
166
- #
167
- # This method accepts three values for the ~dateformat~ parameter:
168
- #
169
- # - ~:full~ (or ~:long~) :: outputs a complete date and time
170
- # representation, localized through R18n;
171
- # - ~:short~ :: outputs a short date representation (without time),
172
- # localized with R18n;
173
- # - ~:rfc3339~ :: outputs the RFC 3339 date and time representation,
174
- # used in atom feed.
175
- #
176
- # @param dateformat [Symbol] the format to use to convert DateTime
177
- # into String
178
- # @param year [Boolean] wether or not the ~:full~ format must
179
- # contain the year
180
- # @return [String] the document DateTime string representation
181
- def datestring(dateformat = :full, year: true)
182
- return '' if @date.nil?
183
- return R18n.l @date.to_date if dateformat == :short
184
- return @date.rfc3339 if dateformat == :rfc3339
185
- locale = R18n.get.locale
186
- long_fmt = R18n.t.neruda.index.full_date_format(
187
- date: locale.format_date_full(@date, year)
188
- )
189
- unless @notime
190
- long_fmt = R18n.t.neruda.index.full_date_with_time_format(
191
- date: long_fmt, time: locale.time_format.delete('_').strip
192
- )
193
- end
194
- locale.strftime(@date, long_fmt)
195
- end
196
-
197
- # Formats given ~string~ with values of the current OrgFile.
198
- #
199
- # This method expects to find percent-tags in the given ~string~ and
200
- # replace them by their corresponding value.
201
- #
202
- # *** Format:
203
- #
204
- # - %a :: the raw author name
205
- # - %A :: the HTML rendering of the author name, equivalent to
206
- # ~<span class="author">%a</span>~
207
- # - %d :: the ~:short~ date HTML representation, equivalent
208
- # to ~<time datetime="%I">%i</time>~
209
- # - %D :: the ~:full~ date and time HTML representation
210
- # - %i :: the raw ~:short~ date and time
211
- # - %I :: the raw ~:rfc3339~ date and time
212
- # - %k :: the keywords separated by a comma
213
- # - %K :: the HTML list rendering of the keywords
214
- # - %l :: the lang of the document
215
- # - %L :: the license information, taken from the
216
- # {Neruda::Config#settings}
217
- # - %n :: the Neruda name and version
218
- # - %N :: the Neruda name and version with a link to the project
219
- # home on the name
220
- # - %s :: the subtitle of the document
221
- # - %t :: the title of the document
222
- # - %u :: the web path to the related published HTML document
223
- # - %x :: the raw description (eXcerpt)
224
- # - %X :: the description, enclosed in an HTML ~p~ tag, equivalent
225
- # to ~<p>%x</p>~
226
- #
227
- # @example
228
- # org_file.format("Article written by %a the %d")
229
- # => "Article written by Alice Smith the Wednesday 3rd July"
230
- #
231
- # @return [String] the given ~string~ after replacement occurs
232
- # rubocop:disable Metrics/MethodLength
233
- # rubocop:disable Layout/LineLength
234
- def format(string)
235
- string.gsub('%a', @author)
236
- .gsub('%A', author_to_html)
237
- .gsub('%d', date_to_html(:short))
238
- .gsub('%D', date_to_html)
239
- .gsub('%i', datestring(:short))
240
- .gsub('%I', datestring(:rfc3339))
241
- .gsub('%k', @keywords.join(', '))
242
- .gsub('%K', keywords_to_html)
243
- .gsub('%l', @lang)
244
- .gsub('%L', (Neruda::Config.settings['license'] || '').gsub(/\s+/, ' ').strip)
245
- .gsub('%n', "Neruda #{Neruda::VERSION}")
246
- .gsub('%N', "<a href=\"https://git.umaneti.net/neruda/about/\">Neruda</a> #{Neruda::VERSION}")
247
- .gsub('%s', @subtitle)
248
- .gsub('%t', @title)
249
- .gsub('%u', @html_file || '')
250
- .gsub('%x', @excerpt)
251
- .gsub('%X', "<p>#{@excerpt}</p>")
252
- end
253
- # rubocop:enable Layout/LineLength
254
- # rubocop:enable Metrics/MethodLength
255
-
256
- # Writes the current OrgFile content to the underlying file.
257
- #
258
- # The intermediate parent folders are created if necessary.
259
- #
260
- # @return [Integer] the length written (as returned by the
261
- # underlying ~IO.write~ method call)
262
- def write
263
- raise TypeError, 'no conversion from nil file name to path.' if @file.nil?
264
- file_dir = File.dirname @file
265
- FileUtils.mkdir_p file_dir unless Dir.exist? file_dir
266
- IO.write @file, @content
267
- end
268
-
269
- private
270
-
271
- def build_html_file_and_url
272
- return if @file.nil?
273
- @html_file = Neruda::OrgFile.target_for_source(
274
- @file, @project, with_public_folder: false
275
- )
276
- @url = "#{Neruda::Config.settings['domain']}/#{@html_file}"
277
- end
278
-
279
- def init_empty_file
280
- @title = @options[:title] || ''
281
- @subtitle = ''
282
- @date = DateTime.now
283
- @notime = false
284
- @author = @options[:author] || Neruda::Config.settings['author']
285
- @keywords = []
286
- @lang = @options[:lang] || Neruda::Config.settings['lang']
287
- @excerpt = ''
288
- body = @options[:content] || ''
289
- @content = @options[:raw_content] || <<~ORG
290
- #+title: #{@title}
291
- #+date: <#{@date.strftime('%Y-%m-%d %a. %H:%M:%S')}>
292
- #+author: #{@author}
293
- #+language: #{@lang}
294
-
295
- #{body}
296
- ORG
297
- end
298
- end
299
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'webrick'
4
- require 'neruda/config'
5
-
6
- module Neruda # rubocop:disable Style/Documentation
7
- # A tiny preview server, which main goal is to replace references to
8
- # the target domain by localhost.
9
- class PreviewServlet < WEBrick::HTTPServlet::AbstractServlet
10
- include WEBrick::HTTPUtils
11
-
12
- def do_GET(request, response) # rubocop:disable Naming/MethodName
13
- file = local_path(request.path)
14
- response.body = parse_body(file, "http://#{request.host}:#{request.port}")
15
- response.status = 200
16
- response.content_type = mime_type(file, DefaultMimeTypes)
17
- end
18
-
19
- private
20
-
21
- def local_path(requested_path)
22
- routes = Neruda::Config.settings.dig('preview', 'routes') || {}
23
- return routes[requested_path] if routes.has_key? requested_path
24
- local_path = Neruda::Config.settings['public_folder'] + requested_path
25
- if File.directory? local_path
26
- local_path = format(
27
- '%<path>s/index.html', path: local_path.delete_suffix('/')
28
- )
29
- end
30
- return local_path if File.exist? local_path
31
- raise WEBrick::HTTPStatus::NotFound, 'Not found.'
32
- end
33
-
34
- def parse_body(local_path, local_host)
35
- body = IO.read local_path
36
- return body unless local_path.match?(/\.(?:ht|x)ml\z/)
37
- domain = Neruda::Config.settings['domain']
38
- return body if domain == ''
39
- body.gsub(/"file:\/\//, format('"%<host>s', host: local_host))
40
- .gsub(/"#{domain}/, format('"%<host>s', host: local_host))
41
- end
42
- end
43
-
44
- class << self
45
- def start_preview
46
- # Inspired by ruby un.rb library, which allows normally to start a
47
- # webrick server in one line: ruby -run -e httpd public_html -p 5000
48
- port = Neruda::Config.settings.dig('preview', 'server_port') || 5000
49
- s = WEBrick::HTTPServer.new(Port: port)
50
- s.mount '/', Neruda::PreviewServlet
51
- ['TERM', 'QUIT', 'INT'].each { |sig| trap(sig, proc { s.shutdown }) }
52
- s.start
53
- end
54
- end
55
- end
@@ -1,118 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'nokogiri'
4
- require 'digest/md5'
5
- require 'neruda/org_file'
6
-
7
- module Neruda
8
- # Insert custom part inside generated HTML files.
9
- class Templater
10
- def initialize(source, dom, opts = {})
11
- @dom = dom
12
- @org_file = source
13
- @position = opts['type'] || 'after'
14
- @content = extract_content opts
15
- @element = @dom.css(opts['selector'])
16
- digest = Digest::MD5.hexdigest(@content)
17
- @check_line = " Neruda Template: #{digest} "
18
- end
19
-
20
- def apply
21
- flag_head
22
- content = @org_file.format(@content)
23
- @element.each do |e|
24
- insert_new_node_at e, content
25
- end
26
- end
27
-
28
- def in_head?
29
- @dom.xpath('//head').children.to_a.filter(&:comment?).each do |c|
30
- return true if c.text == @check_line
31
- end
32
- false
33
- end
34
-
35
- class << self
36
- def customize_output(file_name, source = nil)
37
- templates_to_apply = filter_templates(file_name)
38
- return if templates_to_apply.empty?
39
- if source.nil?
40
- sourcepath = Neruda::OrgFile.source_for_target(file_name)
41
- source = Neruda::OrgFile.new(sourcepath)
42
- end
43
- dom = open_dom(file_name)
44
- templates_to_apply.each do |t|
45
- tpl = Neruda::Templater.new(source, dom, t)
46
- next if tpl.in_head?
47
- tpl.apply
48
- end
49
- write_dom(file_name, dom)
50
- end
51
-
52
- private
53
-
54
- def filter_templates(file_name)
55
- templates = Neruda::Config.settings['templates']
56
- return [] if templates.nil? || templates.empty?
57
- templates.filter { |t| check_required_keys(t, file_name) }
58
- end
59
-
60
- def open_dom(file_name)
61
- file = File.new file_name, 'r'
62
- dom = Nokogiri::HTML file
63
- file.close
64
- dom
65
- end
66
-
67
- def write_dom(file_name, dom)
68
- file = File.new file_name, 'w'
69
- dom.write_to file
70
- file.close
71
- end
72
-
73
- def check_path(file_name, pathes)
74
- pub_folder = Neruda::Config.settings['public_folder']
75
- if pathes.is_a?(Array)
76
- pathes.each do |tp|
77
- return true if File.fnmatch?("#{pub_folder}#{tp}",
78
- file_name, File::FNM_DOTMATCH)
79
- end
80
- return false
81
- end
82
- File.fnmatch?("#{pub_folder}#{pathes}",
83
- file_name, File::FNM_DOTMATCH)
84
- end
85
-
86
- def check_required_keys(opts, file_name)
87
- return false unless opts.has_key?('selector')
88
- return false unless opts.has_key?('content') || opts.has_key?('source')
89
- return check_path(file_name, opts['path']) if opts.has_key?('path')
90
- true
91
- end
92
- end
93
-
94
- private
95
-
96
- def flag_head
97
- @dom.xpath('//head').first.prepend_child("<!--#{@check_line}-->\n")
98
- end
99
-
100
- def insert_new_node_at(elem, content)
101
- case @position
102
- when 'before'
103
- elem.add_previous_sibling content
104
- when 'replace'
105
- elem.replace content
106
- else
107
- elem.add_next_sibling content
108
- end
109
- end
110
-
111
- def extract_content(opts)
112
- return opts['content'] if opts['content']
113
- # If we don't have a content option, then we must have a source
114
- # one.
115
- @dom.css(opts['source']).unlink.to_s
116
- end
117
- end
118
- end
data/lib/neruda/utils.rb DELETED
@@ -1,214 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'uri'
4
- require 'rainbow'
5
- require 'net/http'
6
- require 'r18n-core'
7
- require 'neruda/config'
8
-
9
- module Neruda
10
- # Embeds usefull methods, mainly used in rake tasks.
11
- module Utils
12
- # @return [Hash] the possible throbber themes
13
- THROBBER_FRAMES = {
14
- 'basic' => '-\|/',
15
- 'basicdots' => '⋯⋱⋮⋰',
16
- 'moon' => '🌑🌒🌓🌔🌕🌖🌗🌘',
17
- 'clock' => '🕛🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚',
18
- 'bricks' => '⣷⣯⣟⡿⢿⣻⣽⣾',
19
- 'points' => '·⁘∷⁛∷⁘',
20
- 'quadrant2' => '▙▛▜▟',
21
- 'default' => ['⠁ ⠂ ⠄ ⡀ ⠄ ⠂ ⠁', '⠂ ⠁ ⠂ ⠄ ⡀ ⠄ ⠂', '⠄ ⠂ ⠁ ⠂ ⠄ ⡀ ⠄',
22
- '⡀ ⠄ ⠂ ⠁ ⠂ ⠄ ⡀', '⠄ ⡀ ⠄ ⠂ ⠁ ⠂ ⠄', '⠂ ⠄ ⡀ ⠄ ⠂ ⠁ ⠂']
23
- }.freeze
24
-
25
- # @return [Hash] the possible ~pablo~ options and their
26
- # configuration
27
- PABLO_OPTIONS = {
28
- '-a' => { long: 'author' },
29
- '-f' => { long: 'force', boolean: true },
30
- '-h' => { long: 'help', boolean: true, meth: :on_tail },
31
- '-l' => { long: 'lang', keyword: 'LOCALE' },
32
- '-p' => { long: 'path' },
33
- '-t' => { long: 'title' },
34
- '-v' => { long: 'verbose', boolean: true, meth: :on_tail },
35
- '-V' => { long: 'version', boolean: true, meth: :on_tail }
36
- }.freeze
37
-
38
- # @return [Hash] the possible ~pablo~ subcommands and their
39
- # configuration
40
- PABLO_COMMANDS = {
41
- 'init' => { opts: ['-a', '-h', '-l', '-t', '-v'] },
42
- 'config' => { alias: 'init' },
43
- 'preview' => { opts: ['-h'] },
44
- 'open' => { opts: ['-a', '-h', '-l', '-p', '-t', '-v'] },
45
- 'edit' => { alias: 'open' },
46
- 'build' => { opts: ['-f', '-h'] },
47
- 'publish' => { opts: ['-h'] },
48
- 'help' => { opts: ['-h'] },
49
- 'basic' => { opts: ['-h', '-V'], label: '<command>' }
50
- }.freeze
51
-
52
- class << self
53
- # Animates strings in the user console to alert him that something
54
- # is running in the background.
55
- #
56
- # The animation is chosen among a bunch of themes, with the
57
- # configuration option ~throbber~ (retrieved via
58
- # {Neruda::Config#settings}).
59
- #
60
- # @example
61
- # long_stuff = Thread.new { very_long_operation }
62
- # Neruda::Utils.throbber(long_stuff, 'Computing hard stuff:')
63
- #
64
- # @param thread [Thread] the long-running operation to decorate
65
- # @param message [String] the message to display before the throbber
66
- # @return [void]
67
- def throbber(thread, message)
68
- frames = select_throbber_frames
69
- begin
70
- run_and_decorate_thread thread, message, frames
71
- rescue RuntimeError => e
72
- throbber_error message
73
- raise e
74
- else
75
- done = Rainbow('done'.ljust(frames[0].length)).green
76
- puts "#{message} #{done}"
77
- end
78
- end
79
-
80
- # Returns the short and long options specification for a given
81
- # short option.
82
- #
83
- # This method use the {Neruda::Utils::PABLO_OPTIONS} Hash to
84
- # retrieve corresponding values.
85
- #
86
- # @example
87
- # spec = Neruda::Utils.decorate_option('-a')
88
- # => ['-a AUTHOR', '--author AUTHOR']
89
- #
90
- # @param short [String] the short option to decorate
91
- # @return [Array] the short and long specification for an option
92
- def decorate_option(short)
93
- opt = Neruda::Utils::PABLO_OPTIONS[short]
94
- long = "--#{opt[:long]}"
95
- return [short, long] if opt[:boolean]
96
- key = opt[:keyword] || opt[:long].upcase
97
- [short + key, format('%<long>s %<key>s', long: long, key: key)]
98
- end
99
-
100
- # Returns the ~pablo~ help summary for a given command.
101
- #
102
- # @param command [String] the command for which a summary
103
- # should be given
104
- # @return [String]
105
- def summarize_command(command)
106
- Neruda::Utils::PABLO_COMMANDS[command][:opts].map do |k|
107
- short, long = Neruda::Utils.decorate_option(k)
108
- opt = Neruda::Utils::PABLO_OPTIONS[k]
109
- label = [short, long].join(', ')
110
- line = [format(' %<opt>s', opt: label).ljust(30)]
111
- if R18n.t.pablo.options[opt[:long]].translated?
112
- line << R18n.t.pablo.options[opt[:long]]
113
- end
114
- line.join(' ')
115
- end.join("\n")
116
- end
117
-
118
- # Returns a formatted list of available commands for ~pablo~.
119
- #
120
- # @return [String]
121
- def list_commands
122
- lines = []
123
- Neruda::Utils::PABLO_COMMANDS.each do |cmd, opt|
124
- next if cmd == 'basic'
125
- line = [' ', cmd.ljust(10)]
126
- if opt.has_key? :alias
127
- line << R18n.t.pablo.commands.alias(opt[:alias])
128
- else
129
- line << R18n.t.pablo.commands[cmd]
130
- end
131
- lines << line.join(' ')
132
- end
133
- lines.join("\n")
134
- end
135
-
136
- # Returns the real command name for a given command, which may be
137
- # an alias.
138
- #
139
- # @param command [String] the command to resolve
140
- # @return [String]
141
- def resolve_possible_alias(command)
142
- return 'basic' unless Neruda::Utils::PABLO_COMMANDS.include?(command)
143
- cmd_opt = Neruda::Utils::PABLO_COMMANDS[command]
144
- return cmd_opt[:alias] if cmd_opt.has_key?(:alias)
145
- command
146
- end
147
-
148
- # Try to discover the current host operating system.
149
- #
150
- # @return [String] either apple, windows or linux (default)
151
- # :nocov:
152
- def current_os
153
- if ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM.include?('cygwin')
154
- return 'windows'
155
- end
156
- return 'apple' if RUBY_PLATFORM.include?('darwin')
157
- 'linux'
158
- end
159
- # :nocov:
160
-
161
- # Download latest org-mode tarball.
162
- #
163
- # @return [String] the downloaded org-mode version
164
- def download_org
165
- # :nocov:
166
- return if Neruda::Config.org_last_version.nil?
167
- # :nocov:
168
- tarball = "org-#{Neruda::Config.org_last_version}.tar.gz"
169
- # Remove version number in dest file to allow easy rake file
170
- # task naming
171
- dest_file = 'tmp/org.tar.gz'
172
- return if File.exist?(dest_file)
173
- uri = URI("https://orgmode.org/#{tarball}")
174
- # Will crash on purpose if anything goes wrong
175
- Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
176
- http.request(Net::HTTP::Get.new(uri)) do |response|
177
- File.open(dest_file, 'w') do |io|
178
- response.read_body { |chunk| io.write chunk }
179
- end
180
- end
181
- end
182
- end
183
-
184
- private
185
-
186
- def throbber_error(message)
187
- warn(
188
- format(
189
- "%<message>s %<label>s\n%<explanation>s",
190
- message: message,
191
- label: Rainbow(R18n.t.neruda.error.label).bold.red,
192
- explanation: Rainbow(R18n.t.neruda.error.explanation).bold
193
- )
194
- )
195
- end
196
-
197
- def select_throbber_frames
198
- model = Neruda::Config.settings['throbber'] || 'default'
199
- model = 'default' unless Neruda::Utils::THROBBER_FRAMES.has_key?(model)
200
- Neruda::Utils::THROBBER_FRAMES[model]
201
- end
202
-
203
- def run_and_decorate_thread(thread, message, frames)
204
- thread.abort_on_exception = true
205
- current = 0
206
- while thread.alive?
207
- sleep 0.1
208
- print "#{message} #{frames[current % frames.length]}\r"
209
- current += 1
210
- end
211
- end
212
- end
213
- end
214
- end