Module: Sidekiq::WebHelpers
- Defined in:
- lib/sidekiq/web/helpers.rb
Overview
These methods are available to pages within the Web UI and UI extensions. They are not public APIs for applications to use.
Constant Summary collapse
- SAFE_QPARAMS =
%w[page direction]
- RETRY_JOB_KEYS =
Set.new(%w[ queue class args retry_count retried_at failed_at jid error_message error_class backtrace error_backtrace enqueued_at retry wrapped created_at tags display_class ])
Instance Method Summary collapse
-
#add_to_head ⇒ Object
This view helper provide ability display you html code in to head of page.
- #available_locales ⇒ Object
- #busy_weights(capsule_weights) ⇒ Object
- #clear_caches ⇒ Object
- #csp_nonce ⇒ Object
- #csrf_tag ⇒ Object
- #current_path ⇒ Object
- #current_status ⇒ Object
- #delete_or_add_queue(job, params) ⇒ Object
- #display_args(args, truncate_after_chars = 2000) ⇒ Object
- #display_custom_head ⇒ Object
- #display_tags(job, within = "retries") ⇒ Object
- #environment_title_prefix ⇒ Object
- #filter_link(jid, within = "retries") ⇒ Object
- #filtering(which) ⇒ Object
- #find_locale_files(lang) ⇒ Object
- #format_memory(rss_kb) ⇒ Object
- #get_locale ⇒ Object
- #h(text) ⇒ Object
- #job_params(job, score) ⇒ Object
- #language_name(locale) ⇒ Object
-
#locale ⇒ Object
Given an Accept-Language header like “fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2” this method will try to best match the available locales to the user’s preferred languages.
- #locale_files ⇒ Object
- #number_with_delimiter(number, options = {}) ⇒ Object
- #parse_key(key) ⇒ Object
- #pollable? ⇒ Boolean
- #processes ⇒ Object
- #product_version ⇒ Object
-
#qparams(options) ⇒ Object
Merge options with current params, filter safe params, and stringify to query string.
-
#redirect_with_query(url) ⇒ Object
Any paginated list that performs an action needs to redirect back to the proper page after performing that action.
- #redis_info ⇒ Object
- #redis_url ⇒ Object
- #relative_time(time) ⇒ Object
- #retry_extra_items(retry_job) ⇒ Object
- #retry_or_delete_or_kill(job, params) ⇒ Object
- #root_path ⇒ Object
- #rtl? ⇒ Boolean
- #script_tag(location, **kwargs) ⇒ Object
- #search(jobset, substr) ⇒ Object
- #server_utc_time ⇒ Object
- #singularize(str, count) ⇒ Object
- #sort_direction_label ⇒ Object
-
#sorted_processes ⇒ Object
Sorts processes by hostname following the natural sort order.
- #stats ⇒ Object
- #store_name ⇒ Object
- #store_version ⇒ Object
- #strings(lang) ⇒ Object
- #style_tag(location, **kwargs) ⇒ Object
- #t(msg, options = {}) ⇒ Object
- #text_direction ⇒ Object
- #to_display(arg) ⇒ Object
- #to_json(x) ⇒ Object
- #to_query_string(hash) ⇒ Object
- #truncate(text, truncate_after_chars = 2000) ⇒ Object
-
#unfiltered? ⇒ Boolean
sidekiq/sidekiq#3243.
-
#user_preferred_languages ⇒ Object
See www.rfc-editor.org/rfc/rfc9110.html#section-12.5.4 Returns an array of language tags ordered by their quality value.
- #workset ⇒ Object
Instance Method Details
#add_to_head ⇒ Object
This view helper provide ability display you html code in to head of page. Example:
<% add_to_head do %>
<link rel="stylesheet" .../>
<meta .../>
<% end %>
151 152 153 154 |
# File 'lib/sidekiq/web/helpers.rb', line 151 def add_to_head @head_html ||= [] @head_html << yield.dup if block_given? end |
#available_locales ⇒ Object
106 107 108 |
# File 'lib/sidekiq/web/helpers.rb', line 106 def available_locales @@available_locales ||= Set.new(locale_files.map { |path| File.basename(path, ".yml") }) end |
#busy_weights(capsule_weights) ⇒ Object
259 260 261 262 263 264 265 |
# File 'lib/sidekiq/web/helpers.rb', line 259 def busy_weights(capsule_weights) # backwards compat with 7.0.0, remove in 7.1 cw = [capsule_weights].flatten cw.map { |hash| hash.map { |name, weight| (weight > 0) ? +name << ": " << weight.to_s : name }.join(", ") }.join("; ") end |
#clear_caches ⇒ Object
94 95 96 97 98 |
# File 'lib/sidekiq/web/helpers.rb', line 94 def clear_caches @@strings = nil @@locale_files = nil @@available_locales = nil end |
#csp_nonce ⇒ Object
343 344 345 |
# File 'lib/sidekiq/web/helpers.rb', line 343 def csp_nonce env[:csp_nonce] end |
#csrf_tag ⇒ Object
339 340 341 |
# File 'lib/sidekiq/web/helpers.rb', line 339 def csrf_tag "<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>" end |
#current_path ⇒ Object
285 286 287 |
# File 'lib/sidekiq/web/helpers.rb', line 285 def current_path @current_path ||= request.path_info.gsub(/^\//, "") end |
#current_status ⇒ Object
289 290 291 |
# File 'lib/sidekiq/web/helpers.rb', line 289 def current_status (workset.size == 0) ? "idle" : "active" end |
#delete_or_add_queue(job, params) ⇒ Object
438 439 440 441 442 443 444 |
# File 'lib/sidekiq/web/helpers.rb', line 438 def delete_or_add_queue(job, params) if params["delete"] job.delete elsif params["add_to_queue"] job.add_to_queue end end |
#display_args(args, truncate_after_chars = 2000) ⇒ Object
326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/sidekiq/web/helpers.rb', line 326 def display_args(args, truncate_after_chars = 2000) return "Invalid job payload, args is nil" if args.nil? return "Invalid job payload, args must be an Array, not #{args.class.name}" unless args.is_a?(Array) begin args.map { |arg| h(truncate(to_display(arg), truncate_after_chars)) }.join(", ") rescue "Illegal job arguments: #{h args.inspect}" end end |
#display_custom_head ⇒ Object
156 157 158 |
# File 'lib/sidekiq/web/helpers.rb', line 156 def display_custom_head @head_html.join if defined?(@head_html) end |
#display_tags(job, within = "retries") ⇒ Object
137 138 139 140 141 |
# File 'lib/sidekiq/web/helpers.rb', line 137 def (job, within = "retries") job..map { |tag| "<span class='label label-info jobtag jobtag-#{Rack::Utils.escape_html(tag)}'>#{filter_link(tag, within)}</span>" }.join(" ") end |
#environment_title_prefix ⇒ Object
409 410 411 412 413 |
# File 'lib/sidekiq/web/helpers.rb', line 409 def environment_title_prefix environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development" "[#{environment.upcase}] " unless environment == "production" end |
#filter_link(jid, within = "retries") ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/sidekiq/web/helpers.rb', line 129 def filter_link(jid, within = "retries") if within.nil? ::Rack::Utils.escape_html(jid) else "<a href='#{root_path}#{within}?substr=#{jid}'>#{::Rack::Utils.escape_html(jid)}</a>" end end |
#filtering(which) ⇒ Object
125 126 127 |
# File 'lib/sidekiq/web/helpers.rb', line 125 def filtering(which) erb(:filtering, locals: {which: which}) end |
#find_locale_files(lang) ⇒ Object
110 111 112 |
# File 'lib/sidekiq/web/helpers.rb', line 110 def find_locale_files(lang) locale_files.select { |file| file =~ /\/#{lang}\.yml$/ } end |
#format_memory(rss_kb) ⇒ Object
372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/sidekiq/web/helpers.rb', line 372 def format_memory(rss_kb) return "0" if rss_kb.nil? || rss_kb == 0 if rss_kb < 100_000 "#{number_with_delimiter(rss_kb)} KB" elsif rss_kb < 10_000_000 "#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB" else "#{number_with_delimiter(rss_kb / (1024.0 * 1024.0), precision: 1)} GB" end end |
#get_locale ⇒ Object
221 222 223 |
# File 'lib/sidekiq/web/helpers.rb', line 221 def get_locale strings(locale) end |
#h(text) ⇒ Object
389 390 391 392 393 394 395 |
# File 'lib/sidekiq/web/helpers.rb', line 389 def h(text) ::Rack::Utils.escape_html(text.to_s) rescue ArgumentError => e raise unless e..eql?("invalid byte sequence in UTF-8") text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16") retry end |
#job_params(job, score) ⇒ Object
298 299 300 |
# File 'lib/sidekiq/web/helpers.rb', line 298 def job_params(job, score) "#{score}-#{job["jid"]}" end |
#language_name(locale) ⇒ Object
114 115 116 |
# File 'lib/sidekiq/web/helpers.rb', line 114 def language_name(locale) strings(locale).fetch("LanguageName", locale) end |
#locale ⇒ Object
Given an Accept-Language header like “fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2” this method will try to best match the available locales to the user’s preferred languages.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/sidekiq/web/helpers.rb', line 186 def locale # session[:locale] is set via the locale selector from the footer @locale ||= if (l = session&.fetch(:locale, nil)) && available_locales.include?(l) l else matched_locale = nil # Attempt to find a case-insensitive exact match first user_preferred_languages.each do |preferred| # We only care about the language and primary subtag # "en-GB-oxendict" becomes "en-GB" language_tag = preferred.split("-")[0..1].join("-") matched_locale = available_locales.find { |available_locale| available_locale.casecmp?(language_tag) } break if matched_locale end return matched_locale if matched_locale # Find the first base language match # "en-US,es-MX;q=0.9" matches "en" user_preferred_languages.each do |preferred| base_language = preferred.split("-", 2).first matched_locale = available_locales.find { |available_locale| available_locale.casecmp?(base_language) } break if matched_locale end matched_locale || "en" end end |
#locale_files ⇒ Object
100 101 102 103 104 |
# File 'lib/sidekiq/web/helpers.rb', line 100 def locale_files @@locale_files ||= config.locales.flat_map { |path| Dir["#{path}/*.yml"] } end |
#number_with_delimiter(number, options = {}) ⇒ Object
384 385 386 387 |
# File 'lib/sidekiq/web/helpers.rb', line 384 def number_with_delimiter(number, = {}) precision = [:precision] || 0 %(<span data-nwp="#{precision}">#{number.round(precision)}</span>) end |
#parse_key(key) ⇒ Object
302 303 304 305 |
# File 'lib/sidekiq/web/helpers.rb', line 302 def parse_key(key) score, jid = key.split("-", 2) [score.to_f, jid] end |
#pollable? ⇒ Boolean
423 424 425 426 |
# File 'lib/sidekiq/web/helpers.rb', line 423 def pollable? # there's no point to refreshing the metrics pages every N seconds !(current_path == "" || current_path.index("metrics")) end |
#processes ⇒ Object
242 243 244 |
# File 'lib/sidekiq/web/helpers.rb', line 242 def processes @processes ||= Sidekiq::ProcessSet.new end |
#product_version ⇒ Object
415 416 417 |
# File 'lib/sidekiq/web/helpers.rb', line 415 def product_version "Sidekiq v#{Sidekiq::VERSION}" end |
#qparams(options) ⇒ Object
Merge options with current params, filter safe params, and stringify to query string
310 311 312 313 314 |
# File 'lib/sidekiq/web/helpers.rb', line 310 def qparams() = .transform_keys(&:to_s) to_query_string(request.params.merge()) end |
#redirect_with_query(url) ⇒ Object
Any paginated list that performs an action needs to redirect back to the proper page after performing that action.
399 400 401 402 403 404 405 406 407 |
# File 'lib/sidekiq/web/helpers.rb', line 399 def redirect_with_query(url) r = request.referer if r && r =~ /\?/ ref = URI(r) redirect("#{url}?#{ref.query}") else redirect url end end |
#redis_info ⇒ Object
277 278 279 |
# File 'lib/sidekiq/web/helpers.rb', line 277 def redis_info @info ||= Sidekiq.default_configuration.redis_info end |
#redis_url ⇒ Object
271 272 273 274 275 |
# File 'lib/sidekiq/web/helpers.rb', line 271 def redis_url Sidekiq.redis do |conn| conn.config.server_url end end |
#relative_time(time) ⇒ Object
293 294 295 296 |
# File 'lib/sidekiq/web/helpers.rb', line 293 def relative_time(time) stamp = time.getutc.iso8601 %(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>) end |
#retry_extra_items(retry_job) ⇒ Object
364 365 366 367 368 369 370 |
# File 'lib/sidekiq/web/helpers.rb', line 364 def retry_extra_items(retry_job) @retry_extra_items ||= {}.tap do |extra| retry_job.item.each do |key, value| extra[key] = value unless RETRY_JOB_KEYS.include?(key) end end end |
#retry_or_delete_or_kill(job, params) ⇒ Object
428 429 430 431 432 433 434 435 436 |
# File 'lib/sidekiq/web/helpers.rb', line 428 def retry_or_delete_or_kill(job, params) if params["retry"] job.retry elsif params["delete"] job.delete elsif params["kill"] job.kill end end |
#root_path ⇒ Object
281 282 283 |
# File 'lib/sidekiq/web/helpers.rb', line 281 def root_path "#{env["SCRIPT_NAME"]}/" end |
#rtl? ⇒ Boolean
164 165 166 |
# File 'lib/sidekiq/web/helpers.rb', line 164 def rtl? text_direction == "rtl" end |
#script_tag(location, **kwargs) ⇒ Object
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/sidekiq/web/helpers.rb', line 40 def script_tag(location, **kwargs) global = location.match?(/:\/\//) location = root_path + location if !global && !location.start_with?(root_path) attrs = { type: "text/javascript", nonce: csp_nonce, src: location } html_tag(:script, attrs.merge(kwargs)) {} end |
#search(jobset, substr) ⇒ Object
118 119 120 121 122 123 |
# File 'lib/sidekiq/web/helpers.rb', line 118 def search(jobset, substr) resultset = jobset.scan(substr).to_a @current_page = 1 @count = @total_size = resultset.size resultset end |
#server_utc_time ⇒ Object
419 420 421 |
# File 'lib/sidekiq/web/helpers.rb', line 419 def server_utc_time Time.now.utc.strftime("%H:%M:%S UTC") end |
#singularize(str, count) ⇒ Object
86 87 88 89 90 91 92 |
# File 'lib/sidekiq/web/helpers.rb', line 86 def singularize(str, count) if count == 1 && str.respond_to?(:singularize) # rails str.singularize else str end end |
#sort_direction_label ⇒ Object
234 235 236 |
# File 'lib/sidekiq/web/helpers.rb', line 234 def sort_direction_label (url_params("direction") == "asc") ? "↑" : "↓" end |
#sorted_processes ⇒ Object
Sorts processes by hostname following the natural sort order
247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/sidekiq/web/helpers.rb', line 247 def sorted_processes @sorted_processes ||= begin return processes unless processes.all? { |p| p["hostname"] } processes.to_a.sort_by do |process| # Kudos to `shurikk` on StackOverflow # https://stackoverflow.com/a/15170063/575547 process["hostname"].split(/(\d+)/).map { |a| /\d+/.match?(a) ? a.to_i : a } end end end |
#stats ⇒ Object
267 268 269 |
# File 'lib/sidekiq/web/helpers.rb', line 267 def stats @stats ||= Sidekiq::Stats.new end |
#store_name ⇒ Object
11 12 13 14 15 16 |
# File 'lib/sidekiq/web/helpers.rb', line 11 def store_name hash = redis_info return "Dragonfly" if hash.has_key?("dragonfly_version") return "Valkey" if hash.has_key?("valkey_version") "Redis" end |
#store_version ⇒ Object
18 19 20 21 22 23 |
# File 'lib/sidekiq/web/helpers.rb', line 18 def store_version hash = redis_info return hash["dragonfly_version"] if hash.has_key?("dragonfly_version") return hash["valkey_version"] if hash.has_key?("valkey_version") hash["redis_version"] end |
#strings(lang) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/sidekiq/web/helpers.rb', line 69 def strings(lang) @@strings ||= {} # Allow sidekiq-web extensions to add locale paths # so extensions can be localized @@strings[lang] ||= config.locales.each_with_object({}) do |path, global| find_locale_files(lang).each do |file| strs = YAML.safe_load_file(file) global.merge!(strs[lang]) end end end |
#style_tag(location, **kwargs) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/sidekiq/web/helpers.rb', line 25 def style_tag(location, **kwargs) global = location.match?(/:\/\//) location = root_path + location if !global && !location.start_with?(root_path) attrs = { type: "text/css", media: "screen", rel: "stylesheet", nonce: csp_nonce, href: location } add_to_head do html_tag(:link, attrs.merge(kwargs)) end end |
#t(msg, options = {}) ⇒ Object
225 226 227 228 229 230 231 232 |
# File 'lib/sidekiq/web/helpers.rb', line 225 def t(msg, = {}) string = get_locale[msg] || strings("en")[msg] || msg if .empty? string else string % end end |
#text_direction ⇒ Object
160 161 162 |
# File 'lib/sidekiq/web/helpers.rb', line 160 def text_direction get_locale["TextDirection"] || "ltr" end |
#to_display(arg) ⇒ Object
347 348 349 350 351 352 353 354 355 |
# File 'lib/sidekiq/web/helpers.rb', line 347 def to_display(arg) arg.inspect rescue begin arg.to_s rescue => ex "Cannot display argument: [#{ex.class.name}] #{ex.}" end end |
#to_json(x) ⇒ Object
82 83 84 |
# File 'lib/sidekiq/web/helpers.rb', line 82 def to_json(x) Sidekiq.dump_json(x) end |
#to_query_string(hash) ⇒ Object
316 317 318 319 320 |
# File 'lib/sidekiq/web/helpers.rb', line 316 def to_query_string(hash) hash.map { |key, value| SAFE_QPARAMS.include?(key) ? "#{key}=#{CGI.escape(value.to_s)}" : next }.compact.join("&") end |
#truncate(text, truncate_after_chars = 2000) ⇒ Object
322 323 324 |
# File 'lib/sidekiq/web/helpers.rb', line 322 def truncate(text, truncate_after_chars = 2000) (truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text end |
#unfiltered? ⇒ Boolean
sidekiq/sidekiq#3243
216 217 218 219 |
# File 'lib/sidekiq/web/helpers.rb', line 216 def unfiltered? s = url_params("substr") yield unless s && s.size > 0 end |
#user_preferred_languages ⇒ Object
See www.rfc-editor.org/rfc/rfc9110.html#section-12.5.4 Returns an array of language tags ordered by their quality value
Inspiration taken from github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/sidekiq/web/helpers.rb', line 172 def user_preferred_languages languages = env["HTTP_ACCEPT_LANGUAGE"] languages.to_s.gsub(/\s+/, "").split(",").map { |language| locale, quality = language.split(";q=", 2) locale = nil if locale == "*" # Ignore wildcards quality = quality ? quality.to_f : 1.0 [locale, quality] }.sort { |(_, left), (_, right)| right <=> left }.map(&:first).compact end |