ifocustt 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0dfe2365976e3a78b145968a9fab127547b5ac71
4
- data.tar.gz: baa95c3b6ef52e3ce59fdb2b1dc8c3d3c44a61a3
3
+ metadata.gz: 22f03cae719f85527a009f572e56a83656de450d
4
+ data.tar.gz: 908196a2a331ea2bd9fbfa925ad71cadab6a08d8
5
5
  SHA512:
6
- metadata.gz: c40175f09eb1a141a0e9ed408b65749f619431070a422e5ee1a9bd5be45c1e42867dad4390cbbcdfd8d72992dfd5833e652df197494651a111b0304bdeffc69d
7
- data.tar.gz: 616585264fe4dda64aa48cd16f07a795f17e69dbcaf9ac6137fa517a90c9d195660df4159ff8cb832d3b80d8493f482cca1aa6f03c76a655724bd9e6c4fb3546
6
+ metadata.gz: 38199fdef0d916b4008d57ca34be834f9ece7fe7b5feb720a88c42a28d4a89af4896262a8939fc464abd9f3dca9f853f40d986be7b9c2a8510146c2fcf704d7b
7
+ data.tar.gz: a7619afde1039e458d07b4a2852f1ec61b713471d7bef3cd73316e1b94aac812d418ee4c9cca3a9d6828a4aee2bca016fc2bbd04799450e578582caab9845ef7
data/lib/focus/action.rb CHANGED
@@ -4,9 +4,39 @@ require "interactor"
4
4
  module Focus
5
5
  class FailedActionError < StandardError; end
6
6
 
7
+ # A small wrapper to an Action's context.
8
+ # If an attribute is defined in the context, it will be returned.
9
+ # Otherwise, a lookup within Focus::Config will take place.
10
+ class ContextualConfiguration
11
+ attr_reader :context
12
+
13
+ def initialize(context)
14
+ @context = context
15
+ end
16
+
17
+ def method_missing(m, *args, &block) # rubocop:disable MethodMissing
18
+ context.send(m) || Config.send(m, *args, &block)
19
+ end
20
+ end
21
+
7
22
  class Action
8
23
  include Interactor
9
24
 
25
+ def perform; end
26
+
27
+ def error_message
28
+ "#{self.class.to_s.split('::').last} failed"
29
+ end
30
+
31
+ # This method is used internally and should not be used within actions.
32
+ def call
33
+ perform
34
+ end
35
+
36
+ def config
37
+ ContextualConfiguration.new(context)
38
+ end
39
+
10
40
  private
11
41
 
12
42
  def focus_target
@@ -29,26 +59,27 @@ module Focus
29
59
  focus_seconds * 0.2
30
60
  end
31
61
 
32
- def evaluate_step(klass, args)
62
+ def fail_action!(opts = {})
63
+ raise ArgumentError, "An `:error` key must be provided to fail an action" unless (opts.keys & [:error, "error"]).any?
64
+ context.fail!(opts.merge(action: self.class.to_s.split("::").last))
65
+ end
66
+
67
+ def _evaluate_step(klass, args)
33
68
  action = klass.to_s.gsub(/^.*::/, "")
34
69
  step = "Running #{action}..."
35
70
 
36
71
  Focus::STDOUT.step(step, quiet: context.quiet) do
37
72
  result = klass.call(args)
38
- raise FailedActionError, error_message(result) unless result.success?
73
+ raise FailedActionError, _failed_action_error(result) unless result.success?
39
74
  end
40
75
  end
41
76
 
42
- def error_message(obj)
77
+ def _failed_action_error(obj)
43
78
  "#{obj.action}: #{obj.error}"
44
79
  end
45
80
 
46
81
  def debug_output(*args)
47
82
  Focus::STDOUT.debug_output args
48
83
  end
49
-
50
- def fail_action!(opts = {})
51
- context.fail!(opts.merge(action: self.class.to_s.split("::").last))
52
- end
53
84
  end
54
85
  end
@@ -1,15 +1,9 @@
1
1
  module Focus
2
2
  class ChangeBlinkColor < Action
3
- def call
4
- context.fail! unless perform
5
- end
6
-
7
- private
8
-
9
3
  def perform
10
- url = "#{Config.blink_server}/fadeToRGB?rgb=%#{context.color}"
11
- res = HTTParty.get(url)
12
- res.code == 200
4
+ url = "#{config.blink_server}/fadeToRGB?rgb=%#{context.color}"
5
+ res = Utils::WebClient.get(url)
6
+ fail_action!(error: "Could not change blink(1) color.") unless res.success?
13
7
  end
14
8
  end
15
9
  end
@@ -1,15 +1,12 @@
1
1
  module Focus
2
2
  class ChangeSlackDoNotDisturb < Action
3
- def call
4
- context.fail! unless perform
3
+ def perform
4
+ res = Utils::WebClient.post(url)
5
+ fail_action!(error: res) unless res.success?
5
6
  end
6
7
 
7
8
  private
8
9
 
9
- def perform
10
- Config.slack_token ? HTTParty.post(url) : true
11
- end
12
-
13
10
  def url
14
11
  if context.enabled
15
12
  "#{base_url}&num_minutes=#{focus_minutes}"
@@ -19,7 +16,7 @@ module Focus
19
16
  end
20
17
 
21
18
  def base_url
22
- "#{Config.slack_api_url}/#{action}?token=#{Config.slack_token}"
19
+ "#{config.slack_api_url}/#{action}?token=#{config.slack_token}"
23
20
  end
24
21
 
25
22
  def action
@@ -1,20 +1,18 @@
1
1
  module Focus
2
2
  class ChangeSlackPresence < Action
3
- def call
4
- context.fail! unless perform
3
+ def perform
4
+ res = Utils::WebClient.post url
5
+ fail_action!(error: res) unless res.success?
5
6
  end
6
7
 
7
8
  private
8
9
 
9
- def perform
10
- token = Config.slack_token
11
- if token
12
- url = "#{Config.slack_api_url}/users.setPresence?token=#{token}&presence=#{presence}"
13
- res = HTTParty.post url
14
- res.code == 200
15
- else
16
- true
17
- end
10
+ def token
11
+ config.slack_token
12
+ end
13
+
14
+ def url
15
+ "#{config.slack_api_url}/users.setPresence?token=#{token}&presence=#{presence}"
18
16
  end
19
17
 
20
18
  def presence
@@ -1,14 +1,14 @@
1
1
  require "fileutils"
2
2
  module Focus
3
3
  class LogFocusTime < Action
4
- def call
4
+ def perform
5
5
  update_log
6
6
  end
7
7
 
8
8
  private
9
9
 
10
10
  def update_log
11
- file = File.expand_path Config.focus_history_file
11
+ file = File.expand_path config.focus_history_file
12
12
  new_file = File.exist?(file)
13
13
 
14
14
  File.open(file, "a") do |fo|
@@ -1,14 +1,14 @@
1
1
  module Focus
2
2
  class PostWorkLogToJira < Action
3
- def call
3
+ def perform
4
4
  return unless jira_ticket && seconds_focused >= 60
5
- HTTParty.post(issue_url, options)
5
+ Utils::WebClient.post(issue_url, options)
6
6
  end
7
7
 
8
8
  private
9
9
 
10
10
  def issue_url
11
- "#{Config.jira_url}/issue/#{jira_ticket}/worklog"
11
+ "#{config.jira_url}/issue/#{jira_ticket}/worklog"
12
12
  end
13
13
 
14
14
  def options
@@ -24,7 +24,7 @@ module Focus
24
24
  end
25
25
 
26
26
  def auth
27
- { username: Config.jira_username, password: Config.jira_password }
27
+ { username: config.jira_username, password: config.jira_password }
28
28
  end
29
29
 
30
30
  def headers
@@ -1,6 +1,6 @@
1
1
  module Focus
2
2
  class RunShellCommand < Action
3
- def call
3
+ def perform
4
4
  system(context.command.to_s)
5
5
  end
6
6
  end
@@ -1,8 +1,8 @@
1
1
  module Focus
2
2
  class StartBlinkServer < Action
3
- def call
3
+ def perform
4
4
  verify_blink_server_installed
5
- HTTParty.get(Config.blink_server)
5
+ Utils::WebClient.get(config.blink_server)
6
6
  rescue Errno::ECONNREFUSED
7
7
  start_blink_server
8
8
  end
@@ -13,7 +13,7 @@ module Focus
13
13
  error_msg = \
14
14
  "Blink server not installed. Run `npm install -g node-blink1-server`."
15
15
 
16
- raise ArgumentError, error_msg unless blink_server_installed?
16
+ fail_action!(error: error_msg) unless blink_server_installed?
17
17
  end
18
18
 
19
19
  def blink_server_installed?
@@ -22,7 +22,7 @@ module Focus
22
22
 
23
23
  def start_blink_server
24
24
  fork do
25
- system("blink1-server #{Config.blink_port} &>/dev/null")
25
+ system("blink1-server #{config.blink_port} &>/dev/null")
26
26
  end
27
27
  end
28
28
  end
@@ -7,8 +7,10 @@ module Focus
7
7
 
8
8
  attr_reader :action
9
9
 
10
- def call
10
+ def perform
11
11
  context.actions = ConfigLoader.load("actions")
12
+ parse_jira_ticket
13
+ Focus::STDOUT.puts_line "Starting focus..."
12
14
  context.daemonize ? fork { _actions } : _actions
13
15
  end
14
16
 
@@ -25,6 +27,11 @@ module Focus
25
27
  happy_message
26
28
  end
27
29
 
30
+ def parse_jira_ticket
31
+ context.jira_ticket = Utils::ParseJiraTicketFromGitBranch.call.jira_ticket
32
+ Focus::STDOUT.puts_line "Working on JIRA ticket: '#{context.jira_ticket}'" if context.jira_ticket
33
+ end
34
+
28
35
  def focus
29
36
  @action = :focus
30
37
  perform_actions "OnFocus"
@@ -95,7 +102,7 @@ module Focus
95
102
  klass = constantize(action)
96
103
  args = downcase(keyword_arguments)
97
104
 
98
- evaluate_step klass, with_default_context(args)
105
+ _evaluate_step klass, with_default_context(args)
99
106
  end
100
107
  end
101
108
  end
@@ -1,19 +1,18 @@
1
1
  module Focus
2
2
  class StartRescueTime < Action
3
- def call
4
- context.fail! unless perform
3
+ def perform
4
+ res = Utils::WebClient.post url
5
+ fail_action!(error: res) unless res.success?
5
6
  end
6
7
 
7
8
  private
8
9
 
9
- def perform
10
- token = Config.ifttt_maker_key
11
- if token
12
- url = "https://maker.ifttt.com/trigger/#{event}/with/key/#{token}"
13
- HTTParty.post url
14
- else
15
- true
16
- end
10
+ def token
11
+ config.ifttt_maker_key
12
+ end
13
+
14
+ def url
15
+ "https://maker.ifttt.com/trigger/#{event}/with/key/#{token}"
17
16
  end
18
17
 
19
18
  def event
@@ -1,15 +1,14 @@
1
1
  module Focus
2
2
  class StrobeBlinkColor < Action
3
- def call
4
- context.fail! unless perform
3
+ def perform
4
+ res = Utils::WebClient.get(url)
5
+ fail_action!(error: res) unless res.success?
5
6
  end
6
7
 
7
8
  private
8
9
 
9
- def perform
10
- url = "#{Config.blink_server}/pattern?rgb=%#{context.color}&time=1.5&repeats=0"
11
- res = HTTParty.get(url)
12
- res.code == 200
10
+ def url
11
+ "#{config.blink_server}/pattern?rgb=%#{context.color}&time=1.5&repeats=0"
13
12
  end
14
13
  end
15
14
  end
@@ -1,11 +1,16 @@
1
1
  module Focus
2
2
  class ToggleMacNotificationCenter < Action
3
- def call
4
- toggle if uname == "Darwin"
3
+ def perform
4
+ fail_action!(error: "This action only works on MacOSX") unless mac?
5
+ toggle
5
6
  end
6
7
 
7
8
  private
8
9
 
10
+ def mac?
11
+ uname == "Darwin"
12
+ end
13
+
9
14
  def uname
10
15
  `uname`.chomp
11
16
  end
data/lib/focus/cli.rb CHANGED
@@ -32,6 +32,7 @@ module Focus
32
32
  end
33
33
 
34
34
  opts.on("-t", "--target=TARGET", "Specify what you are focusing on") do |t|
35
+ raise ArgumentError, "#{t} is not a valid target name" if t =~ /^\d+(\.\d)?$/
35
36
  args.target = t
36
37
  end
37
38
 
data/lib/focus/config.rb CHANGED
@@ -6,15 +6,18 @@ module Focus
6
6
  class Config < OpenStruct
7
7
  class << self
8
8
  def method_missing(m, *args, &block) # rubocop:disable MethodMissing
9
- config.env(m) || config.send(m, *args, &block) || raise_undefined_config(m)
9
+ config = new
10
+ config.send(m, *args, &block) || env(m) || raise_undefined_config(m)
10
11
  end
11
12
 
12
- def config
13
- @config ||= new
13
+ private
14
+
15
+ def env(m)
16
+ ENV[m.to_s.upcase]
14
17
  end
15
18
 
16
19
  def raise_undefined_config(m)
17
- error = "(#{m}) neither `ENV['#{m.to_s.upcase}']` or `.focus.yml#config.#{m}` are defined"
20
+ error = "(#{m}) neither `.focus.yml#config.#{m}` or `ENV['#{m.to_s.upcase}']` are defined"
18
21
  raise MissingConfiguration, error
19
22
  end
20
23
  end
@@ -25,10 +28,6 @@ module Focus
25
28
  ingest _hardcoded
26
29
  end
27
30
 
28
- def env(m)
29
- ENV[m.to_s.upcase]
30
- end
31
-
32
31
  private
33
32
 
34
33
  def configurations
@@ -0,0 +1,13 @@
1
+ module Focus
2
+ module Utils
3
+ class WebClient < Util
4
+ class << self
5
+ %i(get post).each do |action|
6
+ define_method(action) do |url, opts = {}|
7
+ HTTParty.send(action, url, opts)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/focus/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Focus
2
- VERSION = "0.0.4".freeze
2
+ VERSION = "0.0.5".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ifocustt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mason
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-15 00:00:00.000000000 Z
11
+ date: 2017-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -92,7 +92,6 @@ files:
92
92
  - LICENSE.txt
93
93
  - assets/focus.jpg
94
94
  - bin/focus
95
- - bin/focus.sh
96
95
  - config/default.yml
97
96
  - lib/focus.rb
98
97
  - lib/focus/action.rb
@@ -117,6 +116,7 @@ files:
117
116
  - lib/focus/util.rb
118
117
  - lib/focus/utils.rb
119
118
  - lib/focus/utils/parse_jira_ticket_from_git_branch.rb
119
+ - lib/focus/utils/web_client.rb
120
120
  - lib/focus/version.rb
121
121
  homepage: http://github.com/binarymason/ifocustt
122
122
  licenses:
data/bin/focus.sh DELETED
@@ -1,136 +0,0 @@
1
- #!/bin/sh
2
- #
3
- # USAGE:
4
- #
5
- # focus [minutes=25] [target=?|JIRA ticket in git branch]
6
-
7
- git_branch_name() { git rev-parse --abbrev-ref HEAD 2>/dev/null; }
8
- jira_ticket() {
9
- local branch=$(git_branch_name)
10
- local ticket=$(echo $branch | sed 's/.*\([a-zA-Z]\{2\}-[0-9]\{2\}\)/\1/') # TODO
11
- if [ "$ticket" == "$branch" ]
12
- then
13
- echo "?"
14
- else
15
- echo "$ticket"
16
- fi
17
- }
18
-
19
- FOCUS_MINUTES="${1-25}"
20
- FOCUS_TARGET="${2-$(jira_ticket)}"
21
- FOCUS_HISTORY_FILE="$HOME/.focus_history"
22
-
23
- info() { printf -- "\033[00;34m..\033[0m %s " "$*"; }
24
- ok() { echo "\033[00;32m✓\033[0m"; }
25
- abort() { echo "!!! $*" >&2; exit 1; }
26
- epoch() { date +%s; }
27
- print_line() { printf "%-15s %-15s %-15s\n" "$1" "$2" "$3"; }
28
- title() { print_line "EPOCH" "FOCUS_TIME" "TARGET"; }
29
- event() { print_line "$(epoch)" "$FOCUS_MINUTES" "$@"; }
30
- add_to_history() { "$@" >> "$FOCUS_HISTORY_FILE"; }
31
-
32
- log_focus() {
33
- info "Updating ~/.focus_history"
34
- if [ ! -f "$FOCUS_HISTORY_FILE" ]; then add_to_history title; fi
35
- add_to_history event "$FOCUS_TARGET"
36
- ok
37
- }
38
-
39
- quietly() {
40
- "$@" &>/dev/null
41
- }
42
-
43
- SLACK_TOKEN=$(cat ~/.secrets/slack-token 2>/dev/null)
44
- SLACK_AWAY="away"
45
- SLACK_AVAILABLE="auto"
46
-
47
- change_slack_presence() {
48
- if [ -n "$SLACK_TOKEN" ]
49
- then
50
- local presence="$1"
51
- info "Changing slack presence to $presence"
52
- local setpresenceurl="https://slack.com/api/users.setPresence?token=$SLACK_TOKEN&presence=$presence&pretty=1"
53
- curl -X POST "$setpresenceurl" &>/dev/null && ok
54
- fi
55
- }
56
-
57
- BLINK_PORT="8754"
58
- BLINK_SERVER="http://localhost:$BLINK_PORT/blink1"
59
- BLINK_RED="23EA5B5B"
60
- BLINK_GREEN="233AF23A"
61
- BLINK_ORANGE="23FFBF00"
62
- start_blink_server() {
63
- if ! command -v blink1-server &> /dev/null
64
- then
65
- abort 'Blink server not installed. Run `npm install -g node-blink1-server`.'
66
- else
67
- quietly curl "$BLINK_SERVER" || blink1-server "$BLINK_PORT" &
68
- fi
69
- }
70
-
71
- change_blink_color() {
72
- local color="$1"
73
- info "Changing blink to $color"
74
- curl "$BLINK_SERVER/fadeToRGB?rgb=%$color" &>/dev/null && ok
75
- }
76
-
77
- strobe_blink_color() {
78
- local color="$1"
79
- local seconds="$2"
80
- local blink_rate="0.5" # both on and off together finishes in one second
81
- curl "$BLINK_SERVER/blink?rgb=%$color&time=$blink_rate&repeats=$seconds" &>/dev/null && ok
82
- }
83
-
84
- IFTTT_MAKER_KEY=$(cat ~/.secrets/ifttt-maker 2>/dev/null)
85
- start_rescue_time() {
86
- if [ -n "$IFTTT_MAKER_KEY" ]
87
- then
88
- local event="rescue_time_focus_start"
89
- info "Firing $event blink(1) event to IFTT"
90
- curl -X POST https://maker.ifttt.com/trigger/${event}/with/key/${IFTTT_MAKER_KEY} &>/dev/null && ok
91
- fi
92
- }
93
-
94
- start_slack_do_not_disturb() {
95
- if [ -n "$SLACK_TOKEN" ]
96
- then
97
- local url="https://slack.com/api/dnd.setSnooze?token=$SLACK_TOKEN&num_minutes=$FOCUS_MINUTES&pretty=1"
98
- info "Changing slack to do not disturb for $FOCUS_MINUTES minutes"
99
- curl -X POST "$url" &>/dev/null && ok
100
- fi
101
- }
102
-
103
- disable_mac_notification_center() {
104
- if [ "$(uname)" == "Darwin" ]
105
- then
106
- info "Disabling Mac OSX notification center"
107
- quietly launchctl unload -w /System/Library/LaunchAgents/com.apple.notificationcenterui.plist
108
- ok
109
- fi
110
- }
111
-
112
- enable_mac_notification_center() {
113
- if [ "$(uname)" == "Darwin" ]
114
- then
115
- launchctl load -w /System/Library/LaunchAgents/com.apple.notificationcenterui.plist
116
- fi
117
- }
118
-
119
- cleanup(){
120
- local focus_seconds=$(echo "$FOCUS_MINUTES * 60" | bc)
121
- local break_seconds=$(echo "$focus_seconds * .2" | bc)
122
- sleep "$focus_seconds" && quietly strobe_blink_color "$BLINK_ORANGE" "$break_seconds"
123
- sleep "$break_seconds" && \
124
- quietly change_slack_presence "$SLACK_AVAILABLE"
125
- quietly enable_mac_notification_center
126
- quietly change_blink_color "$BLINK_GREEN"
127
- }
128
-
129
- disable_mac_notification_center
130
- start_rescue_time
131
- start_blink_server
132
- change_slack_presence "$SLACK_AWAY"
133
- start_slack_do_not_disturb
134
- log_focus
135
- change_blink_color "$BLINK_RED"
136
- cleanup &