Module: TimeLogRobot

Defined in:
lib/time_log_robot.rb,
lib/time_log_robot/entry.rb,
lib/time_log_robot/tagger.rb,
lib/time_log_robot/version.rb,
lib/time_log_robot/reporter.rb,
lib/time_log_robot/toggl/entry.rb,
lib/time_log_robot/toggl/report.rb,
lib/time_log_robot/toggl/tagger.rb,
lib/time_log_robot/jira/work_logger.rb,
lib/time_log_robot/jira/payload_builder.rb,
lib/time_log_robot/jira/issue_key_parser.rb

Defined Under Namespace

Modules: JIRA, Toggl Classes: Entry, Reporter, Tagger

Constant Summary collapse

VERSION =
'0.4.0'

Class Method Summary collapse

Class Method Details

.create_settings_file_if_nonexistentObject



137
138
139
# File 'lib/time_log_robot.rb', line 137

def create_settings_file_if_nonexistent
  File.new(settings_file_path, "w+") unless File.file?(settings_file_path)
end

.envarsObject



172
173
174
# File 'lib/time_log_robot.rb', line 172

def envars
  envars_help.keys
end

.envars_helpObject



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/time_log_robot.rb', line 176

def envars_help
  {
    'MAPPING_FILE_PATH' =>
      "This is the path to your mapping file. By default, this file is named `.time_log_robot_mapping.yml` and lives in your home directory.\n\n",

    'TOGGL_TOKEN' =>
      "In your Toggl account, go to your profile page and look for the API token at the bottom.\n\n",

    'TOGGL_WORKSPACE_ID' =>
      "This is a little trickier. Your workspaces usually only show a human-readable name to you in Toggl's UI, and here you need the workspace machine ID. But you can do a curl request to find it like this (replacing TOGGL_TOKEN with your token from above):

      \tcurl -v -u TOGGL_TOKEN:api_token \ -X GET https://www.toggl.com/api/v8/workspaces

      Look at the result and find the id given for the workspace you want to use.\n\n",

    'TOGGL_USER_AGENT' =>
      "This is your Toggl username, usually your email.\n\n",

    'TOGGL_DEFAULT_LOG_TAG' =>
      "This is the tag name you would like to use for tagging your Toggl time entries as they are logged to JIRA.\n\n",

    'JIRA_USERNAME' =>
      "This is your JIRA username, which can be found in your JIRA user profile.\n\n",

    'JIRA_PASSWORD' =>
      "I know there's a lot of jargon, but some of these are pretty self-explanatory\n"
  }
end

.fetch_envars_from_configObject



114
115
116
117
118
119
120
# File 'lib/time_log_robot.rb', line 114

def fetch_envars_from_config
  return unless envars = YAML.load_file(settings_file_path)
  envars.each_pair do |key, value|
    value.strip! unless should_not_strip?(key)
    ENV[key.upcase] = value
  end
end

.fetch_time_report(since) ⇒ Object



164
165
166
167
168
169
170
# File 'lib/time_log_robot.rb', line 164

def fetch_time_report(since)
  if since.nil?
    Toggl::Report.fetch
  else
    Toggl::Report.fetch(since: since)
  end
end

.get_envar(key) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/time_log_robot.rb', line 98

def get_envar(key)
  print "Enter your #{key}: "
  env_value = gets.chomp
  env_value.strip! unless should_not_strip?(key)
  ENV[key] = env_value
  if ENV[key].length == 0
    puts 'Invalid input. This is a required field.'
    exit
  end
  ENV[key]
end

.get_missing_envarsObject



87
88
89
90
91
92
93
94
95
96
# File 'lib/time_log_robot.rb', line 87

def get_missing_envars
  missing_envars = {}

  TimeLogRobot.envars.each do |key|
    next if key == 'MAPPING_FILE_PATH' || ENV[key]
    missing_envars[key] = get_envar(key)
  end

  return missing_envars
end

.parse(args) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/time_log_robot.rb', line 28

def parse(args)
  options = OpenStruct.new
  options.mapping   = nil
  options.overwrite = false
  options.since     = nil

  opt_parser = OptionParser.new do |opts|
    opts.separator ''
    opts.banner = 'Usage: time_log_robot [options]'

    opts.separator ''
    opts.separator 'Specific options:'

    opts.separator ''
    opts.on('-m', '--mapping PATH', String,
            'Description to JIRA key mapping file is located by default at',
            '`~/.time_log_robot_mapping.yml`. Use this flag if you have a', 'mapping file elsewhere and would like to define the path to', 'point to your file instead.') do |mapping|
      options.mapping = mapping
    end

    opts.separator ''
    opts.on('-o', '--overwrite',
            'Your settings are automatically written to a file -',
            '`~/.time_log_robot_settings.yml` - to be used again the next', 'time you invoke the robot. Use this flag if you need to', 'overwrite those settings.') do |overwrite|
      options.overwrite = overwrite
    end

    opts.separator ''
    opts.on('-s', '--since DATE', Date,
            'The date from which to log time entries.',
            'Must be in YYYY-MM-DD format.',
            'Default is the previous Saturday.') do |date|
      options.since = date
    end

    opts.separator ''
    opts.separator 'Common options:'

    opts.on_tail('-i', '--inputs_help',
                 'Learn how and where to find the inputs you need to get', 'this working') do
      print_inputs_help
      exit
    end

    opts.on_tail('-h', '--help', 'Show this message') do
      puts opts
      exit
    end

    opts.on_tail('-v', '--version', 'Show version') do
      puts TimeLogRobot::VERSION
      exit
    end
  end

  opt_parser.parse!(args)
  options
end


145
146
147
148
149
150
# File 'lib/time_log_robot.rb', line 145

def print_inputs_help
  TimeLogRobot.envars_help.each_pair do |envar, help_text|
    puts envar
    puts help_text
  end
end

.rootObject



152
153
154
# File 'lib/time_log_robot.rb', line 152

def root
  File.dirname __dir__
end

.run(args) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/time_log_robot.rb', line 9

def run(args)
  options = TimeLogRobot.parse(args)

  create_settings_file_if_nonexistent

  fetch_envars_from_config unless options.overwrite

  missing_envars = get_missing_envars
  if options.mapping
    missing_envars['MAPPING_FILE_PATH'] = get_envar('MAPPING_FILE_PATH')
  end

  since = options.since.to_time unless options.since.nil?

  TimeLogRobot.start(since)

  write_missing_envars(missing_envars) if missing_envars.any?
end

.settings_file_pathObject



141
142
143
# File 'lib/time_log_robot.rb', line 141

def settings_file_path
  File.join(ENV['HOME'], '.time_log_robot_settings.yml')
end

.should_not_strip?(key) ⇒ Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/time_log_robot.rb', line 110

def should_not_strip?(key)
  %w(JIRA_PASSWORD).include? key
end

.start(since) ⇒ Object



156
157
158
159
160
161
162
# File 'lib/time_log_robot.rb', line 156

def start(since)
  report = fetch_time_report(since)
  JIRA::WorkLogger.log_all(
    service: report[:service],
    time_entries: report[:entries]
  )
end

.write_missing_envars(missing_envars = {}) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/time_log_robot.rb', line 122

def write_missing_envars(missing_envars={})
  puts "\nTo avoid entering setup information each time, the following configuration has been stored in `#{settings_file_path}`:"
  missing_envars.each_pair do |key, value|
    if key =~ /password|token/i
      puts "\t#{key}=[FILTERED]"
    else
      puts "\t#{key}=#{value}"
    end

    data = YAML.load_file(settings_file_path) || {}
    data[key.downcase] = value
    File.open(settings_file_path, 'w') { |f| YAML.dump(data, f) }
  end
end