Module: WebUtils
- Extended by:
- Rack::Utils
- Defined in:
- lib/web_utils.rb
Constant Summary collapse
- VERSION =
'0.1.5'.freeze
- EMPTY_STRING =
Global string constants
''.freeze
- IES_STRING =
'ies'.freeze
- E_STRING =
'e'.freeze
- S_STRING =
's'.freeze
- Y_STRING =
'y'.freeze
- X_STRING =
'x'.freeze
- XES_STRING =
'xes'.freeze
- SPACE =
' '.freeze
- DASH =
'-'.freeze
- UNDERSCORE =
'_'.freeze
- AMPERSAND =
'&'.freeze
- PERCENT =
'%'.freeze
- PIPE =
'|'
- DOT =
'.'.freeze
- COMMA =
','.freeze
- CONST_SEP =
'::'.freeze
- ELLIPSIS =
'...'
- AND_STRING =
'and'.freeze
- SPACE_PERCENT_STRING =
' percent'.freeze
- TRUE_STRING =
'true'.freeze
- FALSE_STRING =
'false'.freeze
- BR_TAG =
'<br>'.freeze
- ARG1_SUB =
'\1'.freeze
- BLANK_RE =
From then on, constants preceed the methods they are used on.
/\A[[:space:]]*\z/.freeze
- PLURAL_RE =
/([b-df-hj-np-tv-z])ys\z/.freeze
- PLURAL_SUB =
'\1ies'.freeze
- SINGULAR_RE =
/ies\z/.freeze
- UPPER_OR_NUM_RE =
/([A-Z]|\d+)/.freeze
- DASH_LOWER_OR_NUM_RE =
/\-([a-z0-9])/.freeze
- START_UPPER_RE =
/^[A-Z]/.freeze
- START_LOWER_RE =
/^[a-z]/.freeze
- ACCENTS =
"ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž".freeze
- WITHOUT_ACCENTS =
"AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz".freeze
- DASHIFY_RE =
/(\-|[^0-9a-zA-Z])+/.freeze
- EDGE_DASH_RE =
/(\A-|-\z)/.freeze
- ALPHA_NUM_RE =
/[a-zA-Z0-9]+/.freeze
- EACH_STUB_ERR_MSG =
'WebUtils.each_stub expects an object which respond to each_with_index.'
- TYPECASTABLE =
[:bool, :boolean, :nil, :int, :integer, :float].freeze
- INT_RE =
/\A-?\d+\z/.freeze
- FLOAT_RE =
/\A-?\d*\.\d+\z/.freeze
- ID_CHARS =
(('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a).freeze.map(&:freeze)
- ID_SIZE =
16
- DEPRECATED_RANDOM_ID_STRING =
'WebUtils::generate_random_id is deprecated. Use standard SecureRandom instead.'.freeze
- RN_RE =
/\r?\n/.freeze
- COMPLETE_LINK_RE =
/^(\/|[a-z]*:)/.freeze
- EXTERNAL_LINK_RE =
/\A[a-z]*:?\/\//.freeze
- EMAIL_REGEX =
/([^\s]+@[^\s]*[a-zA-Z])/.freeze
- LINK_REGEX =
/\b((https?:\/\/|ftps?:\/\/|www\.)([A-Za-z0-9\-_=%&@\?\.\/]+))\b/.freeze
- TAG_REGEX =
/<[^>]*>/.freeze
- NL_RE =
/\n/.freeze
- QUERY_SPLITTER =
/[^a-zA-Z0-9\&]+/.freeze
- PRICE_ERR_MSG =
'The price needs to be the price in cents/pence as an integer'.freeze
- PRICE_FMT =
'%.2f'.freeze
- NO_CENTS_RE =
/\.00/.freeze
- THOUSANDS_RE =
/(\d{3})(?=\d)/.freeze
- THOUSANDS_SUB =
'\1,'.freeze
- PRICE_PARSE_ERR_MSG =
'The price needs to be parsed from a String'.freeze
- SWITCH_DOT_COMMA_TR =
['.,'.freeze, ',.'.freeze].freeze
- COMMA_BASED_PRICE_RE =
/(\.\d\d\d|,\d\d?)\z/.freeze
- NON_PRICE_CHARS_RE =
/[^\d\.\-,]/.freeze
- DEFAULT_BRAND =
self.name
- START_DOT_SLASH_RE =
/\A\.\//.freeze
- BOT_REGEX =
/bot|crawl|slurp|spider/i.freeze
Class Method Summary collapse
- .automatic_html(s, br = BR_TAG) ⇒ Object
- .automatic_typecast(str, casted = TYPECASTABLE) ⇒ Object
- .being_crawled?(request) ⇒ Boolean
- .blank?(s) ⇒ Boolean
- .branded_filename(path, brand = DEFAULT_BRAND) ⇒ Object
- .complete_link(link) ⇒ Object
- .dasherize_class_name(s) ⇒ Object
- .deep_copy(original) ⇒ Object
- .display_price(int) ⇒ Object
- .each_stub(obj, &block) ⇒ Object
- .ensure_key(h, k, v) ⇒ Object
- .ensure_key!(h, k, v) ⇒ Object
- .external_link?(link) ⇒ Boolean
- .filename_variation(path, variation, ext) ⇒ Object
- .generate_random_id(size = ID_SIZE) ⇒ Object
- .get_value(raw, context = Kernel) ⇒ Object
- .google_maps_link(address) ⇒ Object
- .guess_related_class_name(context, clue) ⇒ Object
- .h(text) ⇒ Object
- .initial_request?(request) ⇒ Boolean
- .label_for_field(field_name) ⇒ Object
- .nl2br(s, br = BR_TAG) ⇒ Object
- .parse_price(string) ⇒ Object
- .pluralize(s) ⇒ Object
- .regex_for_query(query, exhaustive = true) ⇒ Object
- .resolve_class_name(s, context = Kernel) ⇒ Object
- .resolve_dasherized_class_name(s) ⇒ Object
- .singularize(s) ⇒ Object
- .slugify(s, force_lower = true) ⇒ Object
- .truncate(s, c = 320, ellipsis = ELLIPSIS) ⇒ Object
- .u(text) ⇒ Object
- .undasherize_class_name(s) ⇒ Object
Class Method Details
.automatic_html(s, br = BR_TAG) ⇒ Object
267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/web_utils.rb', line 267 def automatic_html s, br=BR_TAG replaced = s.to_s. gsub(LINK_REGEX) do |str| url = complete_link $1 "<a href='#{url}' target='_blank'>#{$1}</a>" end. gsub(EMAIL_REGEX) do |str| "<a href='mailto:#{$1.downcase}'>#{$1}</a>" end nl2br(replaced,br) end |
.automatic_typecast(str, casted = TYPECASTABLE) ⇒ Object
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/web_utils.rb', line 199 def automatic_typecast str, casted=TYPECASTABLE return str unless str.is_a?(String) casted = casted.map do |sym| case sym when :int :integer when :bool :boolean else sym end end if casted.include?(:boolean) and str == TRUE_STRING true elsif casted.include?(:boolean) and str == FALSE_STRING false elsif casted.include?(:nil) and str == EMPTY_STRING nil elsif casted.include?(:integer) and str =~ INT_RE str.to_i elsif casted.include?(:float) and str =~ FLOAT_RE str.to_f else str end end |
.being_crawled?(request) ⇒ Boolean
361 362 363 |
# File 'lib/web_utils.rb', line 361 def being_crawled? request request.user_agent =~ BOT_REGEX end |
.blank?(s) ⇒ Boolean
47 48 49 50 51 52 53 54 55 |
# File 'lib/web_utils.rb', line 47 def blank? s return true if s.nil? # Not much difference with strip on benchmarks # return (s.empty? or BLANK_RE.match?(s)) if s.is_a?(String) return (s.strip.empty?) if s.is_a?(String) return s.empty? if s.respond_to?(:empty?) return true if s==false false end |
.branded_filename(path, brand = DEFAULT_BRAND) ⇒ Object
340 341 342 343 |
# File 'lib/web_utils.rb', line 340 def branded_filename path, brand=DEFAULT_BRAND "#{File.dirname(path)}/#{brand}-#{File.basename(path)}" .sub(START_DOT_SLASH_RE, EMPTY_STRING) end |
.complete_link(link) ⇒ Object
248 249 250 251 252 253 254 |
# File 'lib/web_utils.rb', line 248 def complete_link link if blank?(link) or link =~ COMPLETE_LINK_RE link else "//#{link}" end end |
.dasherize_class_name(s) ⇒ Object
86 87 88 |
# File 'lib/web_utils.rb', line 86 def dasherize_class_name s s.gsub(UPPER_OR_NUM_RE) {|str| "-#{str.downcase}" }[1..-1].gsub(CONST_SEP, DASH) end |
.deep_copy(original) ⇒ Object
141 142 143 |
# File 'lib/web_utils.rb', line 141 def deep_copy original Marshal.load(Marshal.dump(original)) end |
.display_price(int) ⇒ Object
307 308 309 310 311 312 313 314 315 316 |
# File 'lib/web_utils.rb', line 307 def display_price int unless int.is_a?(Integer) raise(TypeError, PRICE_ERR_MSG) end (PRICE_FMT % (int/100.0)) .sub(NO_CENTS_RE, EMPTY_STRING) .reverse .gsub(THOUSANDS_RE, THOUSANDS_SUB) .reverse end |
.each_stub(obj, &block) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/web_utils.rb', line 182 def each_stub obj, &block raise TypeError, EACH_STUB_ERR_MSG unless obj.respond_to?(:each_with_index) obj.each_with_index do |(k,v),i| value = v || k if value.is_a?(Hash) || value.is_a?(Array) each_stub(value,&block) else block.call(obj, (v.nil? ? i : k), value) end end end |
.ensure_key(h, k, v) ⇒ Object
151 152 153 |
# File 'lib/web_utils.rb', line 151 def ensure_key h, k, v {k=>v}.merge h end |
.ensure_key!(h, k, v) ⇒ Object
146 147 148 |
# File 'lib/web_utils.rb', line 146 def ensure_key! h, k, v h.fetch(k) {|k| h.store(k, v) } end |
.external_link?(link) ⇒ Boolean
259 260 261 |
# File 'lib/web_utils.rb', line 259 def external_link? link !!(link =~ EXTERNAL_LINK_RE) end |
.filename_variation(path, variation, ext) ⇒ Object
346 347 348 349 |
# File 'lib/web_utils.rb', line 346 def filename_variation path, variation, ext old_ext = File.extname(path) path.sub(/#{Regexp.escape old_ext}$/, ".#{variation}.#{ext}") end |
.generate_random_id(size = ID_SIZE) ⇒ Object
231 232 233 234 235 236 |
# File 'lib/web_utils.rb', line 231 def generate_random_id size=ID_SIZE warn DEPRECATED_RANDOM_ID_STRING id = String.new size.times{id << ID_CHARS[rand(ID_CHARS.size)]} id end |
.get_value(raw, context = Kernel) ⇒ Object
130 131 132 133 134 135 136 137 138 |
# File 'lib/web_utils.rb', line 130 def get_value raw, context=Kernel if raw.is_a? Proc raw.call elsif raw.is_a? Symbol context.__send__ raw else raw end end |
.google_maps_link(address) ⇒ Object
376 377 378 |
# File 'lib/web_utils.rb', line 376 def google_maps_link address "https://www.google.com/maps/search/?api=1&query=#{u address}" end |
.guess_related_class_name(context, clue) ⇒ Object
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/web_utils.rb', line 118 def context, clue context.respond_to?(:name) ? context.name : context.to_s clue = clue.to_s return clue if clue =~ START_UPPER_RE if clue =~ START_LOWER_RE clue = undasherize_class_name singularize(clue).gsub(UNDERSCORE, DASH) clue = "::#{clue}" end "#{context}#{clue}" end |
.h(text) ⇒ Object
366 367 368 |
# File 'lib/web_utils.rb', line 366 def h text escape_html text end |
.initial_request?(request) ⇒ Boolean
352 353 354 355 356 |
# File 'lib/web_utils.rb', line 352 def initial_request? request URI.parse(request.referer).host!=request.host rescue URI::InvalidURIError return true end |
.label_for_field(field_name) ⇒ Object
175 176 177 |
# File 'lib/web_utils.rb', line 175 def label_for_field field_name field_name.to_s.scan(ALPHA_NUM_RE).map(&:capitalize).join(SPACE) end |
.nl2br(s, br = BR_TAG) ⇒ Object
241 242 243 |
# File 'lib/web_utils.rb', line 241 def nl2br s, br=BR_TAG s.to_s.gsub(RN_RE, br) end |
.parse_price(string) ⇒ Object
324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/web_utils.rb', line 324 def parse_price string unless string.is_a?(String) raise(TypeError, PRICE_PARSE_ERR_MSG) end string = string.gsub(NON_PRICE_CHARS_RE, EMPTY_STRING) if string[COMMA_BASED_PRICE_RE] # comma-based price string = string.tr(*SWITCH_DOT_COMMA_TR) end (PRICE_FMT % string.gsub(COMMA, EMPTY_STRING)).gsub(DOT, EMPTY_STRING).to_i end |
.pluralize(s) ⇒ Object
61 62 63 64 65 66 |
# File 'lib/web_utils.rb', line 61 def pluralize s s = s.dup s<<E_STRING if s[-1,1]==X_STRING s<<S_STRING s.sub PLURAL_RE, PLURAL_SUB end |
.regex_for_query(query, exhaustive = true) ⇒ Object
293 294 295 296 297 298 |
# File 'lib/web_utils.rb', line 293 def regex_for_query query, exhaustive=true atoms = query.split(QUERY_SPLITTER) atom_patterns = atoms.map{|a| "(?=.*\\b#{a})" } sep = exhaustive ? EMPTY_STRING : PIPE /#{atom_patterns.join(sep)}/i.freeze end |
.resolve_class_name(s, context = Kernel) ⇒ Object
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/web_utils.rb', line 98 def resolve_class_name s, context=Kernel current, *payload = s.to_s.split(CONST_SEP) raise(NameError) if current.nil? const = context.const_get(current) if payload.empty? const else resolve_class_name(payload.join(CONST_SEP),const) end end |
.resolve_dasherized_class_name(s) ⇒ Object
110 111 112 |
# File 'lib/web_utils.rb', line 110 def resolve_dasherized_class_name s resolve_class_name(undasherize_class_name(s.to_s)) end |
.singularize(s) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/web_utils.rb', line 71 def singularize s if s.end_with? XES_STRING s[0..-3] elsif s.end_with? IES_STRING s.sub(SINGULAR_RE, Y_STRING) elsif s.end_with? S_STRING s[0..-2] else s.dup end end |
.slugify(s, force_lower = true) ⇒ Object
161 162 163 164 165 166 167 168 169 170 |
# File 'lib/web_utils.rb', line 161 def slugify s, force_lower=true s = s.to_s .tr(ACCENTS, WITHOUT_ACCENTS) .gsub(AMPERSAND, AND_STRING) .gsub(PERCENT, SPACE_PERCENT_STRING) .gsub(DASHIFY_RE, DASH) .gsub(EDGE_DASH_RE, EMPTY_STRING) s = s.downcase if force_lower escape(s) end |
.truncate(s, c = 320, ellipsis = ELLIPSIS) ⇒ Object
283 284 285 286 287 288 |
# File 'lib/web_utils.rb', line 283 def truncate s, c=320, ellipsis=ELLIPSIS s.to_s .gsub(TAG_REGEX, EMPTY_STRING) .gsub(NL_RE, SPACE) .sub(/^(.{#{c}}\w*).*$/m, ARG1_SUB+ellipsis) end |
.u(text) ⇒ Object
371 372 373 |
# File 'lib/web_utils.rb', line 371 def u text escape text end |
.undasherize_class_name(s) ⇒ Object
93 94 95 |
# File 'lib/web_utils.rb', line 93 def undasherize_class_name s s.capitalize.gsub(DASH_LOWER_OR_NUM_RE) {|str| $1.upcase }.gsub(DASH, CONST_SEP) end |