4
\$\begingroup\$

Unfortunately due to my job I will have to leave out some of the information that is created by this generator, however I will be replacing it with another string of information.

I have created an email generator for work, that will user a template and add the information provided into the email, I would like some critique on what I've done so far I will not be able to add a GitHub repository for this program, so I understand if you do not want to take the time to look through the code, thank you ahead of time.

Main file:

#!/usr/local/bin/env ruby

require 'date'
require 'etc'

require_relative 'lib/clipboard'
require_relative 'lib/date'
require_relative 'lib/format'
require_relative 'lib/time'
require_relative 'lib/email/version'
require_relative 'lib/log_email'

include Format
include DateCheck
include TimeCheck
include ClipBrd
include Email
include LogEmail

def help_page
  #-<summary>
  # Basic help for the program 
  #</summary>-#

  puts
  "\e[44mruby gen_email.rb -[t] <type-of-email> --[example|version|dev-mode]\e[0m"
end

def examples_page
  #-<summary>
  # Shows an example of a generic email that was created by the program 
  #</summary>-#

  <<-_END_

REMOVED FOR SECURITY

V/R,
#{get_user}
          _END_
end

def developer_mode
  message = <<-_END_

  Launching development..

  Feel free to play around with your own ideas
  if you make anything awesome let the creator
  know so he can add it.\e[0m
          _END_
  puts "\e[32m#{message}\e[0m"
  #-<summary> 
  # If the user has a PATH that is used as their editor
  # The program will open the source file in that editor
  # other wise it opens the source file in notepad
  #</summary>-#

  ENV['editor'].nil? ? system('notepad.exe gen_email.rb') : system(ENV['editor'])
end

def header
  TimeCheck.check_time
end

def name
  Format.prompt('Enter users full name')
end

def summary
  Format.prompt('Enter summary of issue')
end

def num
  Format.prompt('Enter ticket number')
end

def body
  Format.prompt('Enter what will happen or what you did')
end

def check_date
  DateCheck.date
end

def account
  Format.prompt('Enter users account')
end

def get_user
  #-<summary>
  # Get the name by using the Etc library,
  # basically just pull the login name and
  # grab the first word along with the first
  # letter of the last word 
  #</summary>-#

  user = Etc.getlogin
  @esd_user = user.split('_').first.capitalize + ' ' + user.split('_').last[0].upcase
end

def pend
  #-<summary>
  # Pending emails template this was taken
  # from the docs website, if it gets updated 
  # I will be sending out and updated version
  # of this program with the updated templates 
  #</summary>-#

  email = <<-_END_
#{header} #{name},

In regard to your request #{summary}; Ticket# INC00000#{num} was created.

#{body}

**Please respond before #{check_date}, or your ticket will automatically close.**

V/R,
#{get_user}

  _END_
  copy(email)
end

def generic
  #-<summary>
  # Generic email/default email template
  # taken from that same place as the pending
  # template 
  #</summary>-#

  email = <<-_END_
#{header} #{name},

 #{summary}; Ticket# INC00000#{num}.

#{body}


V/R,
#{get_user}

  _END_
  copy(email)
end

def sixty_day
  #-<summary>
  # Sixty day hold email for account deletions 
  # once again taken from the docs 
  #</summary>-#

  email = <<-_END_
#{header} #{name},

Thank you for contacting the Service Desk, in regard to your request for account #{account}; Ticket# INC00000#{num};

**You will have until #{check_date} to respond. After this date, your ticket will automatically close.**


V/R,
#{get_user}

  _END_

  copy(email)
end

def osha_reg
  #-<summary> 
  # 
  # this was also taken 
  # from the docs 
  #</summary>-#

  email = <<-_END_
#{header} #{name},
Thank you for contacting the Service Desk. In regard to your request #{summary}; Ticket# INC00000#{num} 


V/R,
#{get_user}

  _END_
  copy(email)
end

def copy(email)
  #-<summary> 
  # Copy the email so that we can use that copy
  # as a template to copy to the clipboard 
  #</summary>-#

  File.open('./lib/tools/tmp/email_to_copy', 'w') { |s| s.puts(email) }
  LogEmail.log(email)
  clipbrd
end

def clipbrd
  ClipBrd.copy_to_clipbrd
  Format.info('Copied to clipboard press CNTRL-V to paste')
end

def gather_intel
  #-<summary>
  #These are the options available and how they
  # will be invoked, if the ARGV argument contains
  # any of the words that are here it will send you 
  # to that email template 
  #</summary>-#

  case
    when ARGV[1] == nil
      Format.warning('No email type given defaulting to generic..')
      generic
    when ARGV[1].include?('osha')
      Format.info('Creating OSHA email..')
      osha_reg
    when ARGV[1].include?('pend')
      Format.info('Creating 6 day hold pending email..')
      pend
    when ARGV[1].include?('60') || ARGV[1].include?('account deletion')
      Format.info('Creating 60 day hold account deletion email..')
      sixty_day
    when ARGV[1].include?('generic')
      Format.info('Creating generic email..')
      generic
    else
      raise ArgumentError.new(Format.warning("Invalid email type: #{ARGV[1]}")) 
  end
end

#-<summary> 
# ARGV options or the flags that are available
# as of right now these are the only flags,
# dev mode will give you the access to play with the 
# flags, alternatively you can ask me for a forked
# clone of the git repo (it's a private repo so 
# looking for it on GitHub or BitBucket won't work)
# and I'll send you a forked copy so that you can 
# add some features or take some away. Once you are
# done with the forked clone, send it back to me and
# I'll let you know whether it will be implemented or
# not. DO NOT TRY TO ADD BUTTONS. I HATE BUTTONS.
# If you ned my information it's in the gemspec file
# or the email.gemspec.rb file in the main directory
# of the program 
#</summary>-#

case ARGV[0]
  when '-h' then puts help_page
  when '-t' then gather_intel
  when '--example' then puts "\e[36m#{examples_page}\e[0m"
  when '--version' then puts Email.version
  when '--dev-mode' then developer_mode
  when nil then puts help_page
  else
    puts help_page
end

Lib files:

time.rb:

module TimeCheck

  def check_time
    #-<summary>
    # Check the to see if it's morning or afternoon 
    # if it;s afternoon the program will say Good afternoon
    # to the user in the beginning of the email, and if
    # it's morning the program will say Good morning 
    #</summary>-#

    if Time.now.strftime('%P') == 'pm'
      'Good afternoon'
    else
      'Good morning'
    end
  end

end

log_email.rb:

module LogEmail
  #-<summary>
  # Basically this creates a log of all emails
  # that are sent through this program, this is
  # useful because if you need to find something
  # it will be there for you. It will also have the
  # time that the email was sent. Eventually this 
  # will be encypted with a private decryption key
  # that only I will have, that way if someone needs 
  # to be audited or something, I can request the file,
  # and decrypt the file, then send it to the requestor
  # this will prevent people from tampering with the 
  # file to make themselves look better, or something.
  #</summary>-#

  def log(email)
    separator = "[#{Time.now.strftime('%T')}] ----------"
    File.open('./log/email_log.LOG', 'a+') { |s| s.puts(separator, email) }
  end
end

format.rb:

module Format
  #-<summary>
  # Create a colored format for the output
  # just use the ANSI color options for the 
  # output without the need of an external
  # gem. Mostly because we can't gem install
  # stuff on these laptops, I'd have to manually
  # go around and local install this gem on every
  # computer around me.. That's a lot of work..
  #</summary>-#

  def info(input)
    puts "[\e[35m#{Time.now.strftime('%T')}\e[0m]\e[36m#{input}\e[0m"
  end

  def warning(input)
    puts "[\e[35m#{Time.now.strftime('%T')}\e[0m]\e[47m#{input}\e[0m"
  end  

  def prompt(input)
    print "\e[36m#{input}:\e[0m "
    STDIN.gets.chomp
  end

end

date.rb:

module DateCheck

  def date
  #-<summary>
  # Create date and skip over Saturday and Sunday
  # if the date lands on either of them, so for
  # example of the day is Friday, and you pend and
  # you pend a ticket for 6 days, it will skip
  # to the Monday after the next Friday
  #</summary>-#

  p today = Date.today
  p (1..Float::INFINITY)
        .lazy
        .map { |offset| today + offset }
        .reject { |date| date.saturday? || date.sunday? }
        .drop(5)
        .next

  end
end

clipboard.rb

module ClipBrd
  #-<summay>
  # Copy the information to the users clipboard 
  #</summary>-#

  def copy_to_clipbrd
    `lib/tools/cliptext.exe from lib/tools/tmp/email_to_copy`
  end

end

tools

You will need to install cliptext.exe and put it in the tools directory

email directory

module Email
  def version
    puts
    "\e[36mThis program is currently in version number: 1.0.0\e[0m"
  end
end
\$\endgroup\$
3
\$\begingroup\$

Have you considered using OptionParser or GLI? Both provide utilities to easily make a command line application.

I'd suggest moving the email templates out to separate files, perhaps with ERb. That way, the presentation is separated from the business logic of this tool.

Instead of having everything in modules and #includeing them into the main global Object, I would consider moving this functionality to one or more classes that can be instantiated in this script. This will make it easier to test your code.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I like the idea about the classes, would you suggest putting all the modules into their own separate classes, the emails separated is a good idea also, I have used OptParse before and I really don't like it, idk why but it seems a little over complicated to me \$\endgroup\$ – 13aal May 12 '16 at 11:50
  • \$\begingroup\$ Sure, putting the modules into their own classes would be good start. You can always refactor when you discover a good abstraction. If you don't have any already, I would add some tests. \$\endgroup\$ – Kenrick Chien May 13 '16 at 0:44
  • \$\begingroup\$ Well I took your advice and as of right now I've kept the modules how they are, but I implemented optparse into it. I'll probably mess around with the classes today. \$\endgroup\$ – 13aal May 13 '16 at 12:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.