module Devlog

The devlog module with all the mumbo

Constants

DATETIME_FORMAT

Parsing datetime

DEVLOG_FILE

The default is the current folder with devlog.markdown in it.

Public Class Methods

display_version() click to toggle source
# File lib/devlog.rb, line 62
def self.display_version
  "\n#{'Devlog'.green} v#{Devlog.version}\n"
end
libpath(*args) click to toggle source

Returns the library path for the module. If any arguments are given, they will be joined to the end of the libray path using File.join.

# File lib/devlog.rb, line 36
def self.libpath(*args)
  args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
end
log(txt) click to toggle source

Write simple console log

# File lib/devlog.rb, line 67
def self.log(txt)
  puts "#{txt}"
end
path(*args) click to toggle source

Returns the lpath for the module. If any arguments are given, they will be joined to the end of the path using File.join.

# File lib/devlog.rb, line 44
def self.path(*args)
  args.empty? ? PATH : ::File.join(PATH, args.flatten)
end
require_all_libs_relative_to(fname, dir = nil) click to toggle source

Utility method used to require all files ending in .rb that lie in the directory below this file that has the same name as the filename passed in. Optionally, a specific directory name can be passed in such that the filename does not have to be equivalent to the directory.

# File lib/devlog.rb, line 53
def self.require_all_libs_relative_to(fname, dir = nil)
  dir ||= ::File.basename(fname, '.*')
  search_me = ::File.expand_path(
    ::File.join(::File.dirname(fname), dir, '**', '*.rb')
  )

  Dir.glob(search_me).sort.each { |rb| require rb }
end
version() click to toggle source

Returns the version string for the library.

# File lib/devlog.rb, line 28
def self.version
  VERSION
end

Public Instance Methods

devlog_file_setting() click to toggle source

Calculate a devlog_file path.

# File lib/devlog_settings.rb, line 43
def devlog_file_setting
  return DEVLOG_FILE unless settings
  devlog_file_setting = settings['devlog_file']
  if devlog_file_setting && File.exist?(File.join(Dir.pwd, devlog_file_setting))
    devlog_file_setting
  else
    DEVLOG_FILE
  end
end
devlog_session_entry(session_type = 'Coding', begin_end = 'BEGIN') click to toggle source

Helper for the time entries

# File lib/devlog.rb, line 194
def devlog_session_entry(session_type = 'Coding', begin_end = 'BEGIN')
  "\n##{Time.now.strftime(DATETIME_FORMAT)} #{session_type}Session::#{begin_end}\n"
end
export_devlog_now(devlog_file = 'devlog.markdown') click to toggle source
# File lib/devlog.rb, line 258
def export_devlog_now(devlog_file = 'devlog.markdown')
  devlog_export_file = File.join(File.dirname(devlog_file), 'devlog_book.markdown')
  # `sed -n '1!G;h;$p' #{devlog_file} > #{devlog_export_file}` #not what we want! , we want just the sessions upside down, but text intact
  # so need to parse all sessions and print them out in reverse!

  sessionEnd = ''
  sessionMidd = ''
  sessionBegin = ''
  in_session = false

  # The ends are the begins, the begins are the ends

  File.new(devlog_export_file, 'wb')

  File.open(devlog_file, 'r').each do |line|
    if line =~ /-NOCHARGE/
      in_session = false #do not export nocharge sessions
    elsif line =~ /\A#/ && (line =~ /CodingSession::END/ || line =~ /ComSession::END/ )
      in_session = true
      sessionEnd = line
    elsif line =~ /\A#/ && ( line =~ /CodingSession::BEGIN/ || line =~ /ComSession::BEGIN/ )
      if in_session
        in_session = false
        sessionBegin = line
        s = sessionBegin + sessionMidd + sessionEnd
        # system "echo '#{s}' | cat - #{devlog_export_file} > #{devlog_export_file}.tmp && mv #{devlog_export_file}.tmp #{devlog_export_file}"
        prepend_string(devlog_export_file, s)
        sessionEnd = ''
        sessionMidd = ''
        sessionBegin = ''
      end
    else
      sessionMidd << line
    end
  end

  devlog_export_file
end
is_session_open(devlog_file = 'devlog.markdown') click to toggle source

If the first non empty line is not and END entry then session is open (or malformed file)

# File lib/devlog.rb, line 240
def is_session_open(devlog_file = 'devlog.markdown')
  is_open = true
  File.open(devlog_file, 'r') do |f|
    loop do
      break if not line = f.gets # exit on end of file, read line
      if (line.strip.size>0) # non empty line
        if (line =~ /Session::END/)
          is_open = false
          break
        else
          break
        end
      end
    end
  end
  is_open
end
load_settings(file) click to toggle source
# File lib/devlog_settings.rb, line 26
def load_settings(file)
  begin
    yaml = YAML.load_file(file)
  rescue
    yaml = nil
  end
  @settings = yaml ? Settings[yaml] : Settings.new
end
parse_datetime(line) click to toggle source
# File lib/devlog.rb, line 73
def parse_datetime(line)
  parts = line[1..-1].split
  DateTime.strptime("#{parts[0]} #{parts[1]}", DATETIME_FORMAT)
rescue StandardError
  abort "\nError\nCan not parse line with invalid date:\n\n#{line}".to_s.blue
end
parse_devlog_now(devlog = nil) click to toggle source
# File lib/devlog.rb, line 80
def parse_devlog_now(devlog = nil)
  t = Parsing.new
  t.devlog_file = devlog

  return t unless devlog
  return t unless File.exist?(devlog)

  timeEnd = nil
  timeBegin = nil
  timeEnd_line_number = nil
  timeBegin_line_number = nil
  in_session = false
  temp_zezzion = nil

  line_number = 0
  File.open(devlog, 'r').each do |line|
    line_number += 1

    if line =~ /-NOCHARGE/
      in_session = false # do not count nocharge sessions, this is a secret feature
    elsif line =~ /\A#/ && line =~ /CodingSession::END/
      in_session = true
      timeEnd = parse_datetime(line)
      timeEnd_line_number = line_number

      # zezzion
      temp_zezzion = Zezzion.new
      temp_zezzion.zzend = timeEnd
      temp_zezzion.zzend_line_number = timeEnd_line_number

    elsif line =~ /\A#/ && line =~ /CodingSession::BEGIN/
      if in_session
        in_session = false
        timeBegin = parse_datetime(line)
        timeBegin_line_number = line_number

        # cs_time += (timeEnd - timeBegin).to_f * 24 #hours *60 #minutes *60 #seconds
        delta = (timeEnd - timeBegin).to_f * 24 #hours *60 #minutes *60 #seconds
        t.coding_session_time += delta

        # zezzion
        temp_zezzion.coding_session_time += delta
        temp_zezzion.zzbegin = timeBegin
        temp_zezzion.zzbegin_line_number = timeBegin_line_number
        t.add_zezzion temp_zezzion
        temp_zezzion = nil

      end
    elsif line =~ /\A#/ && line =~ /ComSession::END/
      in_session = true
      timeEnd = parse_datetime(line)
      timeEnd_line_number = line_number

      # zezzion
      temp_zezzion = Zezzion.new(Zezzion::COM)
      temp_zezzion.zzend = timeEnd
      temp_zezzion.zzend_line_number = timeEnd_line_number

    elsif line =~ /\A#/ && line =~ /ComSession::BEGIN/
      if in_session
        in_session = false
        timeBegin = parse_datetime(line)
        timeBegin_line_number = line_number

        delta = (timeEnd - timeBegin).to_f * 24
        t.com_session_time += delta

        # zezzion
        temp_zezzion.coding_session_time += delta
        temp_zezzion.zzbegin = timeBegin
        temp_zezzion.zzbegin_line_number = timeBegin_line_number
        t.add_zezzion temp_zezzion
        temp_zezzion = nil

      end
    elsif line =~ /\A\+[0-9]+[h]/
      delta = line.to_f
      t.com_session_time += delta

      # zezzion
      if temp_zezzion
        temp_zezzion.com_session_time += delta
      else
        puts "error adding temp_zezzion com_session_time at line: #{line}"
      end
    elsif line =~ /\A\+[0-9]+[m]/
      delta = (line.to_f / 60)
      t.com_session_time += delta

      # zezzion
      if temp_zezzion
        temp_zezzion.com_session_time += delta
      else
        puts "error adding temp_zezzion com_session_time at line: #{line}"
      end
    elsif line =~ /\A\-[0-9]+[h]/
      delta = (line.to_f)
      t.payed_time += delta

      # zezzion
      if temp_zezzion
        temp_zezzion.payed_time += delta
      else
        puts "error adding temp_zezzion delta time at line: #{line}"
      end
    end
  end
  # return the Parsing object
  t
end
prepend_string(path, string = "\n") click to toggle source
# File lib/devlog.rb, line 204
def prepend_string(path, string = "\n")
  Tempfile.open File.basename(path) do |tempfile|
    tempfile << string
    File.open(path, 'r+') do |file|
      tempfile << file.read
      file.pos = tempfile.pos = 0
      file << tempfile.read
    end
  end
end
save_info(devlog_file = 'devlog.markdown', info_file = 'info.markdown') click to toggle source
# File lib/devlog.rb, line 226
def save_info(devlog_file = 'devlog.markdown', info_file = 'info.markdown')
  info = parse_devlog_now(devlog_file)
  if info.has_info?
    File.open(File.join(File.dirname(devlog_file), info_file), 'w') {|f| f.write(info.to_info_string(true)) }
  else
    puts "No info present.".red
  end
end
save_to_readme(devlog_file = 'devlog.markdown') click to toggle source
# File lib/devlog.rb, line 235
def save_to_readme(devlog_file = 'devlog.markdown')
  `cp #{devlog_file} #{File.join(File.dirname(devlog_file), 'README.markdown')}`
end
settings() click to toggle source
# File lib/devlog_settings.rb, line 35
def settings
  @settings ||= Settings.new
end
start_coding_session(devlog_file = 'devlog.markdown') click to toggle source

insert a new session

# File lib/devlog.rb, line 216
def start_coding_session(devlog_file = 'devlog.markdown')
  prepend_string(devlog_file, devlog_session_entry('Coding', 'BEGIN'))
end
stop_coding_session(devlog_file = 'devlog.markdown') click to toggle source

close the current session, if any

# File lib/devlog.rb, line 221
def stop_coding_session(devlog_file = 'devlog.markdown')
  prepend_string(devlog_file, devlog_session_entry('Coding', 'END'))
  save_info(devlog_file)
end
weekly_pdf(tajm, weeks_from_now = 0, devlog_file = 'devlog.markdown') click to toggle source
# File lib/devlog.rb, line 297
def weekly_pdf(tajm, weeks_from_now = 0, devlog_file = 'devlog.markdown')
  require 'erb'
  devlog_file = settings.devlog_file || devlog_file
  template = settings.has?(:weekly_timesheet_template) ? settings.weekly_timesheet_template : File.join(Devlog.path, 'templates', 'weekly_timesheet.erb.html')
  convert_command = settings.has?(:convert_to_pdf_command) ? settings.convert_to_pdf_command : 'wkhtmltopdf'
  puts "Using weekly template: #{template} #{settings.has?(:weekly_timesheet_template)}".green

  zezzions = tajm.zezzions_for_week(weeks_from_now, DateTime.current)

  if zezzions.any?
    file_id = zezzions.last.zzbegin.strftime("%Y-%m-%d")
    pdf = File.join(File.dirname(devlog_file), "sevendays-#{file_id}.pdf")
    html = File.join(File.dirname(devlog_file), "sevendays-#{file_id}.html")
    @sevendays = Sevendays.new(zezzions)

    renderer = ERB.new(File.read(template))

    File.open(html,'w') {|f| f.write(renderer.result()) }

    `#{convert_command} #{html} #{pdf}`
  else
    'No sessions to render.'.red
  end
end