robertgauld/OSMExtender

View on GitHub
app/helpers/application_helper.rb

Summary

Maintainability
B
5 hrs
Test Coverage
module ApplicationHelper

  # Interpret a string as markdown
  # @param text the text in markdown format
  # @returns an interpreted html_safe string representation of text
  def markdown(text)
    unless defined?(@@markdown)
      parse_options = {autolink: true, underline: true, hightlight: true, strikethrough: true, tables: true, no_intra_emphasis: true, fenced_code_blocks: true, disable_indented_code_blocks: true}
      renderer_options = {escape_html: true, hard_wrap: true, prettify: true}
      renderer = Redcarpet::Render::HTML.new(renderer_options)
      @@markdown = Redcarpet::Markdown.new(renderer, parse_options)
    end
    @@markdown.render(text).html_safe
  end

  # Display either yes or no highlighted in green or red
  # @param value the boolean value being represented
  # @param positive_value (optional, default true) the value to be considered positive (and displayed in green)
  # @returns an HTML safe string
  def yes_no(value, positive_value=true)
    if positive_value == value
      return "<span style=\"color: green;\">#{value ? 'yes' : 'no'}</span>".html_safe
    else
      return "<span style=\"color: red;\">#{value ? 'YES' : 'NO'}</span>".html_safe
    end
  end

  # Display text highlighted in green or red
  # @param value the boolean value being represented
  # @param positive_value (optional, default true) the value to be considered positive (and displayed in green)
  # @param text the text to display
  # @returns an HTML safe string
  def pos_neg(value, text, positive_value=true, alt_neg_text=nil)
    if positive_value == value
      return "<span style=\"color: green;\">#{text}</span>".html_safe
    else
      return "<span style=\"color: red;\">#{alt_neg_text || text}</span>".html_safe
    end
  end

  # Get the date in the chosen format with the day of the month ordinalized
  # @param date the time to display in the format
  # @param format_string the format string to pass to the strftime methods, after replacing %d with the ordinalized day of the month
  # @returns a string representing the date
  def ordinalized_date(date, format_string)
    return date.strftime(format_string.gsub(/(\%d|%e|%\-d)/, '\1'+date.strftime('%d').to_i.ordinal))
  end

  # Convert a time to duration to finish a sentance fragment starting "do this by"
  # @param time the time to convert to words 
  # @returns a string
  def do_by_time(time)
    if time < Time.now
      return ordinalized_date(time, '%H:%M on %-d %B %Y')
    end
    if time.today?
      return time.strftime('%H:%M today')
    end
    if time.to_date == Date.tomorrow
      return time.strftime('%H:%M tomorrow')
    end
    if time.between?(Date.today,  Date.today+6.days)
      return time.strftime('%H:%M on %A')
    end
    if time.year == Date.today.year
      return ordinalized_date(time, '%H:%M on %A %-d %B')
    end
    return ordinalized_date(time, '%H:%M on %-d %B %Y')
  end

  # Create a link for sorting a table by a given column from the model
  # @param column a string identifying the column to sort by
  # @param title (optional) the column title to use in the link, f not provided the title is generated from column
  # @returns a link generated by the link_to helper
  def sortable_link(column, title=nil)
    css_class = 'sortable'
    title ||= column.titleize
    css_class += (column == sort_column) ? " sortable_current sortable_#{sort_direction}" : ''
    direction = ((column == sort_column) && sort_direction == "asc") ? "desc" : "asc"
    target = params.permit(:sort_column, :sort_direction, :page)
                   .merge({sort_column: column, sort_direction: direction, page: nil})
    link_to title, target, {class: css_class}
  end


  def div_for_password_strength_meter
    %q{<div id="password_strength_meter" style="display: inline-block; min-width: 215px; font-weight: bold; color: black; background-color: #7777ff;">No password!</div>}.html_safe
  end


  # Set title for the page and insert an H1 tag
  def page_title(title)
    provide :title, title
    content_tag 'h1', title
  end


  # Convert an array of (string or array of string) into a set of li tags for display to the user
  def html_from_log_lines(lines)
    content_tag :ol do
      lines.each do |line|
        next line if line.empty?
        if line.is_a?(Array)
          concat html_from_log_lines(line)
        else
          concat content_tag(:li, line)
        end
      end # each line
    end # content_tag :ol
  end

  # Convert an array of (string or array of string) into a set of bulleted lines
  def text_from_log_lines(lines, level=0)
    output = ''
    bullets = "*+>-"
    lines.each do |line|
      next line if line.empty?
      if line.is_a?(Array)
        output += text_from_log_lines(line, level+1)
      else
        output += ' ' * (4 * level)
        output += bullets[level % bullets.size] + ' '
        output += line
        output += "\n"
      end     
    end # each line
    return output.chomp
  end

  def stylesheet_link_tag_if_exists(path, opts = {})
    if asset_exists?("#{path}.css")
      stylesheet_link_tag(path, opts)
    end
  end

  def javascript_include_tag_if_exists(path, opts = {})
    if asset_exists?("#{path}.js")
      javascript_include_tag(path, opts)
    end
  end

  def asset_exists?(path)
    if Rails.application.config.assets.compile
      # Development type environment
      !!Rails.application.assets.find_asset(path)
    else
      # Production type environment
      !!Rails.application.assets_manifest.files.values.find{ |v| v['logical_path'].eql?(path) }
    end
  end

  def seconds_to_time(seconds)
    fail ArgumentError 'time must be a positive number' if !seconds.is_a?(Numeric) || seconds < 0

    parts = []
    remaining = seconds
    {'second' => 60, 'minute' => 60, 'hour' => 24, 'day' => 7, 'week' => nil}.each do |duration, units|
      if units.nil? # Reached the end of the conversions we can do
        parts.push "#{remaining} #{duration.pluralize(remaining)}" if remaining > 0
        break
      end
      this_unit = remaining % units
      remaining = remaining / units
      parts.push "#{this_unit} #{duration.pluralize(this_unit)}" if this_unit > 0
      break if remaining <= 0 # No more time left to split
    end
    parts.reverse.to_sentence
  end

end