slack_pomodoro_timer 0.1.0.pre.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce3b97366999a97518b7cb21bc4c2a51e735d4c2
4
+ data.tar.gz: 95c9b25ecf2a68958cb89acf8aa2e73caab8145f
5
+ SHA512:
6
+ metadata.gz: bc47c95b57e33a6ee38f351c5fd6213c0b247e4034de9ea0bf0868fd0c52d4c7da525a37bafb01ef2fafa5e9b2cf8973615a0113631013c550318ceb2e0a246a
7
+ data.tar.gz: e8e2f41d5c2df2e7d03ca5d24770908aba5d8bcce6255660fb593ac7cf8ec0e1b57871645d9d05d599ce9b13324266484f886962c9b17ad96b1a191f2ada971b
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /tags
11
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in slack_pomodoro_timer.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.("routing/#{m[1]}_routing"),
51
+ rspec.spec.("controllers/#{m[1]}_controller"),
52
+ rspec.spec.("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") }
64
+
65
+ # Turnip features and steps
66
+ watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ end
70
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Bideo Wego
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # SlackPomodoroTimer
2
+
3
+ by [kitlangton](https://github.com/kitlangton) and [Bideo Wego](https://github.com/BideoWego)
4
+
5
+
6
+
7
+ A Ruby powered command line app for sending timed messages to slack channels
8
+
9
+
10
+
11
+
12
+ ## Installation
13
+
14
+ ### Install the gem
15
+ ```shell
16
+ $ gem install slack_pomodoro_timer
17
+ ```
18
+
19
+ ### Configure your Slackbot URL
20
+
21
+ Configure the Slackbot URL:
22
+
23
+ ```shell
24
+ $ slack_pomodoro_timer config --url https://company.slack.com/services/hooks/slackbot?token=YOUR_TOKEN_HERE
25
+ ```
26
+
27
+
28
+
29
+ #### Not sure where to find your Slackbot URL?
30
+
31
+ 1. Make sure you are signed into your Slack team at [https://slack.com/signin](https://slack.com/signin)
32
+
33
+ 1. Then go to this link [https://slack.com/apps/build](https://slack.com/apps/build)
34
+
35
+ 1. Click on the 'Configure' button in the top right
36
+
37
+ 1. Now choose 'Custom Integrations'
38
+
39
+ 1. Choose 'Slackbot'
40
+
41
+ 1. If you do not have any Slackbot integrations you'll have to create one, otherwise skip this step and the next
42
+
43
+ 1. Click 'Add Configuration' then 'Add Slackbot Configuration'
44
+
45
+ 1. You should see an edit button next to your created integration as a pencil icon, click it!
46
+
47
+ 1. Scroll down to 'Setup Instructions' and copy the full URL that you see under 'Your slackbot URL is:'
48
+
49
+ 1. Now paste that URL into the above command to configure the URL for Slack Pomodoro Timer
50
+
51
+ 1. You should now be able to run `$ slack_pomodoro_timer start 1`! See below for changing the channel.
52
+
53
+
54
+ NOTE: Slack Pomodoro Timer is actually able to accept a Webhook URL as well,
55
+ however this functionality is not fully tested at this time.
56
+
57
+
58
+
59
+
60
+ ### Configure the channel
61
+
62
+ Slack Pomodoro Timer is configured to send messages to the 'general' channel by default.
63
+ If you want to send messages to another channel you'll have to configure it will that channel.
64
+
65
+ Configure the channel into which you would like to post (this defaults to the general channel):
66
+
67
+ ```shell
68
+ $ slack_pomodoro_timer config --channel my_channel
69
+ ```
70
+
71
+ You do not need to prepend your channel name with a # symbol, but if you absolutely must, then make sure to wrap your channel name in quotes:
72
+
73
+ ```shell
74
+ $ slack_pomodoro_timer config --channel "#my_channel"
75
+ ```
76
+
77
+
78
+
79
+ ## Usage
80
+
81
+ To run 5 consecutive 25 minute Pomodoros:
82
+
83
+ ```shell
84
+ $ slack_pomodoro_timer start 5
85
+ ```
86
+
87
+ Here's how to use a custom pomodoro time length:
88
+
89
+ ```shell
90
+ $ slack_pomodoro_timer start 5 --minutes 10
91
+ ```
92
+
93
+ For help on command options and usage use the following syntax:
94
+
95
+ ```shell
96
+ $ slack_pomodoro_timer help config
97
+ $ slack_pomodoro_timer help start
98
+ ```
99
+
100
+
101
+ Still a work in progress, however there are minimal passing tests.
102
+ To run the tests you can simply run `$ rspec` or use Guard with `$ bundle exec guard`.
103
+
104
+
105
+
106
+
107
+ ## Development
108
+
109
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
110
+
111
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
112
+
113
+
114
+
115
+
116
+ ## Contributing
117
+
118
+ Bug reports and pull requests are welcome on GitHub [https://github.com/BideoWego/slack_pomodoro_timer](https://github.com/BideoWego/slack_pomodoro_timer)
119
+
120
+
121
+
122
+
123
+
124
+ ## License
125
+
126
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
127
+
128
+
129
+
130
+
131
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "slack_pomodoro_timer"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'slack_pomodoro_timer'
3
+
4
+ SlackPomodoroTimer::CLI.start(ARGV)
5
+
@@ -0,0 +1,9 @@
1
+ require_relative 'slack_pomodoro_timer/version'
2
+ require_relative 'slack_pomodoro_timer/cli'
3
+ require_relative 'slack_pomodoro_timer/timer'
4
+ require_relative 'slack_pomodoro_timer/http'
5
+ require_relative 'slack_pomodoro_timer/config'
6
+ require_relative 'slack_pomodoro_timer/pomodorobot'
7
+
8
+ module SlackPomodoroTimer
9
+ end
@@ -0,0 +1,135 @@
1
+ require 'thor'
2
+
3
+
4
+ module SlackPomodoroTimer
5
+ class CLI < Thor
6
+
7
+ desc 'config [OPTIONS]', 'set the url and channel options with this command'
8
+
9
+
10
+ long_desc %Q;
11
+ 'config' is essential for Slack Pomodoro Timer to run
12
+
13
+
14
+ 'config --url'
15
+
16
+
17
+ You must set a URL for the HTTP service to target.
18
+ It is recommended that you use the Slackbot integration URL for this.
19
+
20
+ For full instructions for how to set this up (you may already have one)
21
+ see the README on the main repository here:
22
+
23
+
24
+ https://github.com/BideoWego/slack_pomodoro_timer
25
+
26
+
27
+ Once you have the URL you may pass it to the config command like so:
28
+
29
+ $ slack_pomodoro_timer config --url https://company.slack.com/services/hooks/slackbot?token=YOUR_TOKEN_HERE
30
+
31
+
32
+ 'config --channel'
33
+
34
+
35
+ Setting a channel is optional, however if you do not wish to post
36
+ to the default channel (general) then you will have to set it here.
37
+
38
+
39
+ To set the channel you may pass it to the config command like so:
40
+
41
+ $ slack_pomodoro_timer config --channel fox29actionnews
42
+
43
+ ;
44
+
45
+
46
+ option :url, aliases: :u
47
+ option :channel, aliases: :c
48
+
49
+
50
+ # Configure the timer URL and channel
51
+ def config
52
+ Config.load
53
+
54
+ if options[:url]
55
+ if HTTP.valid_url?(options[:url])
56
+ Config.add(url: options[:url])
57
+ else
58
+ puts "You have not input a valid slack url."
59
+ end
60
+ end
61
+
62
+ if options[:channel]
63
+ Config.add(channel: options[:channel])
64
+ end
65
+
66
+ Config.save
67
+
68
+ puts "Config updated:" if options[:url] || options[:channel]
69
+ Config.display
70
+ end
71
+
72
+
73
+
74
+
75
+ desc 'start COUNT [OPTIONS]', 'set the number of pomodoros and time interval here'
76
+
77
+ long_desc %Q;
78
+ 'start' is the command that begins the timer and posts to Slack.
79
+
80
+
81
+ Pomodoros
82
+
83
+
84
+ By default, Slack Pomodoro Timer is set to post 1 pomdoro and has a time of 25 minutes.
85
+
86
+ To add more pomdoros simply specify how many pomodoros you'd like to post like so:
87
+
88
+ $ slack_pomodoro_timer start 5
89
+
90
+
91
+ 'start --minutes'
92
+
93
+ The time limit defaults to 25 minutes.
94
+
95
+ Optionally you can provide a time limit in minutes. This will be display to you as the timer
96
+ counts down to zero, at which time the timer will fire again posting another pomodoro.
97
+
98
+ Pass a custom time limit to Slack Pomodoro Timer like so:
99
+
100
+ $ slack_pomodoro_timer start --minutes 10
101
+
102
+
103
+ Stopping the timer
104
+
105
+ At any given time while the timer is running you may stop the timer with CTRL-C.
106
+
107
+
108
+ QUICK TIP!
109
+
110
+ To test the timer out try passing it a short time limit like 0.1
111
+
112
+ $ slack_pomodoro_timer start --minutes 0.1
113
+
114
+ ;
115
+
116
+
117
+ option :minutes, aliases: :m, type: :numeric, default: 25
118
+
119
+
120
+ # Start a timer with a number of pomodoros
121
+ # and optional time limit in minutes
122
+ def start(pomodoros=1)
123
+ if Config.configured?
124
+ interval_in_seconds = options[:minutes] * 60
125
+ Pomodorobot.start_timer(pomodoros, interval_in_seconds)
126
+ else
127
+ puts "Not Configured."
128
+ puts "Run 'slack_pomodoro_timer help config'"
129
+ end
130
+ end
131
+
132
+
133
+ end
134
+ end
135
+
@@ -0,0 +1,104 @@
1
+ require 'yaml'
2
+
3
+ module SlackPomodoroTimer
4
+ class Config
5
+
6
+ FILENAME = '.slack_pomodoro_timer'
7
+ PATH = "#{Dir.home}/#{FILENAME}"
8
+
9
+
10
+ @@config = {}
11
+
12
+
13
+ # Class variable getter
14
+ # returns a hash of config values
15
+ def self.config
16
+ @@config
17
+ end
18
+
19
+
20
+ # Returns true if
21
+ # configured properly
22
+ def self.configured?
23
+ self.load
24
+ if @@config.empty? ||
25
+ @@config.any? { |key, value| value.nil? || value.empty? }
26
+ false
27
+ else
28
+ true
29
+ end
30
+ end
31
+
32
+
33
+ # Add a config option
34
+ # or options
35
+ def self.add(options={})
36
+ add_option(:channel, options[:channel])
37
+ add_option(:url, options[:url])
38
+ end
39
+
40
+
41
+ # Saves the current config
42
+ # hash as YAML to the
43
+ # path
44
+ def self.save
45
+ File.open(PATH, 'w+') do |f|
46
+ f.write(YAML.dump(config))
47
+ end
48
+ end
49
+
50
+
51
+ # Loads the config file if it exists
52
+ # or sets default values
53
+ # if the file does not exist
54
+ def self.load
55
+ file_exists = File.exists?(PATH)
56
+ if File.exists?(PATH)
57
+ value = YAML.load_file(PATH)
58
+ else
59
+ value = defaults
60
+ end
61
+ @@config = value
62
+ end
63
+
64
+
65
+ # Get a config value by key
66
+ def self.get(key)
67
+ config[key]
68
+ end
69
+
70
+
71
+ # Display all config values
72
+ def self.display
73
+ if config.empty?
74
+ puts "No config values set"
75
+ else
76
+ config.each do |key, value|
77
+ puts "#{key.upcase}: #{value}"
78
+ end
79
+ end
80
+ end
81
+
82
+
83
+
84
+
85
+ private
86
+
87
+ # Returns the default config values
88
+ def self.defaults
89
+ {
90
+ :channel => 'general',
91
+ :url => '',
92
+ }
93
+ end
94
+
95
+
96
+ # Sets the key to the given value
97
+ # unless it is nil
98
+ def self.add_option(key, value)
99
+ config[key] = value unless value.nil?
100
+ end
101
+
102
+
103
+ end
104
+ end
@@ -0,0 +1,123 @@
1
+ require 'net/http'
2
+ require 'json'
3
+
4
+ module SlackPomodoroTimer
5
+ class HTTP
6
+
7
+ REGEXES = {
8
+ :slackbot => /\.slack.com\/services\/hooks\/slackbot/,
9
+ :webhook => /hooks\.slack\.com\/services/
10
+ }
11
+
12
+
13
+ attr_accessor :url,
14
+ :data,
15
+ :response
16
+
17
+ attr_reader :integration_type
18
+
19
+
20
+ # Accepts options for url and data
21
+ def initialize(options={})
22
+ @url = options[:url]
23
+ @data = options[:data]
24
+ set_integration_type
25
+ end
26
+
27
+
28
+ # Overrides default setter
29
+ # to allow internally
30
+ # setting the integration type
31
+ # based on the URL
32
+ def url=(value)
33
+ @url = value
34
+ set_integration_type
35
+ @url
36
+ end
37
+
38
+
39
+ # Posts the data to the given URL
40
+ def post
41
+ data = serialized_data
42
+ url = url_for_integration_type
43
+ @response = Net::HTTP.post_form(URI.parse(url), data)
44
+ end
45
+
46
+
47
+ private
48
+ # Returns a hash with a payload key
49
+ # conforming to what Net::HTTP expects
50
+ # in it's data parameter
51
+ def serialized_data
52
+ {
53
+ :payload => serialize_data_by_integration_type
54
+ }
55
+ end
56
+
57
+
58
+ # Returns the data format that
59
+ # Slack expects for the
60
+ # integration type
61
+ # See:
62
+ # https://api.slack.com/slackbot
63
+ # https://api.slack.com/incoming-webhooks
64
+ def serialize_data_by_integration_type
65
+ if @integration_type == 'slackbot'
66
+ serialize_slackbot_data
67
+ else
68
+ serialize_webhook_data
69
+ end
70
+ end
71
+
72
+
73
+ # Returns only the text
74
+ # of the original data
75
+ # as explain here
76
+ # https://api.slack.com/slackbot
77
+ # Slack expects only the raw text
78
+ # for this integration type
79
+ def serialize_slackbot_data
80
+ @data[:text]
81
+ end
82
+
83
+
84
+ # Returns the original data
85
+ # serialized into JSON
86
+ def serialize_webhook_data
87
+ @data.to_json
88
+ end
89
+
90
+
91
+ # Returns the appropriate
92
+ # URL for the integration type
93
+ def url_for_integration_type
94
+ if @integration_type == 'slackbot'
95
+ url = @url
96
+ url += "&channel=#{URI.encode(@data[:channel])}"
97
+ end
98
+ end
99
+
100
+
101
+ # Sets the integration type
102
+ # based on the format of the URL
103
+ def set_integration_type
104
+ if @url.match(REGEXES[:slackbot])
105
+ @integration_type = 'slackbot'
106
+ elsif @url.match(REGEXES[:webhook])
107
+ @integration_type = 'webhook'
108
+ else
109
+ raise ArgumentError, "Slack URL is invalid"
110
+ end
111
+ end
112
+
113
+
114
+ # Validates that the URL fits the expected
115
+ # Slackbot or Webhook URL format
116
+ def self.valid_url?(url)
117
+ REGEXES.any? { |key, regex| regex.match(url) }
118
+ end
119
+
120
+
121
+ end
122
+ end
123
+
@@ -0,0 +1,37 @@
1
+ module SlackPomodoroTimer
2
+ class Pomodorobot
3
+
4
+ # Start a new timer
5
+ # with the given number of pomodoroes
6
+ # that fires at the given interval in seconds
7
+ def self.start_timer(pomodoros, interval_in_seconds)
8
+ Config.load
9
+ timer = Timer.new(pomodoros: pomodoros.to_i, interval: interval_in_seconds)
10
+ timer.start do |current_pomodoro|
11
+ message = '@group :pomodoro:'
12
+ if current_pomodoro == timer.total
13
+ message += ' Last one!'
14
+ elsif current_pomodoro == Timer::DONE
15
+ message += "s are DONE!"
16
+ end
17
+ post message
18
+ end
19
+ end
20
+
21
+
22
+ private
23
+
24
+ # Post the given text message to slack
25
+ def self.post(text)
26
+ http = HTTP.new(url: Config.get(:url))
27
+ data = {
28
+ channel: "##{Config.get(:channel)}",
29
+ text: text
30
+ }
31
+ http.data = data
32
+ http.post
33
+ end
34
+
35
+
36
+ end
37
+ end
@@ -0,0 +1,148 @@
1
+ module SlackPomodoroTimer
2
+ class Timer
3
+
4
+ DONE = :done
5
+
6
+ attr_accessor :pomodoros,
7
+ :interval
8
+
9
+ attr_reader :total
10
+
11
+
12
+ # Accepts options for pomodoros
13
+ # and a time interval in seconds
14
+ def initialize(options={})
15
+ @pomodoros = options[:pomodoros]
16
+ @interval = options[:interval]
17
+ @total = options[:pomodoros]
18
+ end
19
+
20
+ # Starts the timer
21
+ # calls the passed block
22
+ # for each pomodoro
23
+ # displays countdown until next interval
24
+ def start(&block)
25
+ puts start_message if @pomodoros == @total
26
+ begin
27
+ yield(current_pomodoro) if block_given?
28
+ display_countdown
29
+ @pomodoros -= 1
30
+ if stop?
31
+ stop(&block)
32
+ else
33
+ start(&block)
34
+ end
35
+ rescue SystemExit, Interrupt
36
+ puts quit_message
37
+ end
38
+ end
39
+
40
+
41
+ # Sets the number of pomodoros
42
+ # and the resets total
43
+ def pomodoros=(pomodoros)
44
+ @total = pomodoros
45
+ @pomodoros = pomodoros
46
+ end
47
+
48
+
49
+
50
+
51
+ private
52
+
53
+ # Calls the given block passing
54
+ #
55
+ def stop(&block)
56
+ yield(DONE)
57
+ puts stop_message
58
+ end
59
+
60
+ # Displays the timer countdown to next
61
+ # pomodoro in the console
62
+ def display_countdown
63
+ end_time = Time.now + @interval
64
+ until Time.now > end_time
65
+ print "#{time_remaining(end_time)}\r"
66
+ sleep 1
67
+ end
68
+ puts "#{pomodoro_status} -- POSTED at #{current_time}"
69
+ end
70
+
71
+
72
+ # Returns the time remaining until
73
+ # the next timer fire
74
+ def time_remaining(end_time)
75
+ remaining = (end_time - Time.now).ceil
76
+ format_countdown(remaining)
77
+ end
78
+
79
+
80
+ # Formats the countdown timer
81
+ # to display like a digital clock
82
+ # and returns the string
83
+ def format_countdown(seconds)
84
+ minutes = (seconds / 60).to_s.rjust(2,"0")
85
+ while seconds >= 60
86
+ seconds -= 60
87
+ end
88
+ seconds = seconds.to_s.rjust(2,"0")
89
+
90
+ "#{pomodoro_status} -- #{minutes}:#{seconds}"
91
+ end
92
+
93
+
94
+ # Get the current time
95
+ # formatted as an AM/PM digital clock
96
+ def current_time
97
+ Time.now.strftime("%l:%M %p")
98
+ end
99
+
100
+
101
+ # Returns the timer start message
102
+ def start_message
103
+ "Slack Pomodoro Timer started!" +
104
+ "\nStop the timer at any time with CTRL-C"
105
+ end
106
+
107
+
108
+ # Returns the timer stop message
109
+ def stop_message
110
+ "Slack Pomodoro Timer stopped!"
111
+ end
112
+
113
+
114
+ # Returns the timer quit message
115
+ def quit_message
116
+ "\nRemaining pomodoros will not be posted." +
117
+ "\nQuitting slack_pomodoro_timer..."
118
+ end
119
+
120
+
121
+ # Returns the number of the
122
+ # current pomodoro fired in the total
123
+ def pomodoro_status
124
+ "Pomodoro #{current_pomodoro} of #{total}"
125
+ end
126
+
127
+
128
+ # Returns the number of the current
129
+ # pomodoro in ascending increments
130
+ def current_pomodoro
131
+ total - pomodoros + 1
132
+ end
133
+
134
+ # Returns true if stopped
135
+ # manually or if no pomodoros
136
+ # left
137
+ def stop?
138
+ if @pomodoros <= 0
139
+ @pomodoros = total
140
+ true
141
+ else
142
+ false
143
+ end
144
+ end
145
+
146
+
147
+ end
148
+ end
@@ -0,0 +1,3 @@
1
+ module SlackPomodoroTimer
2
+ VERSION = "0.1.0-beta"
3
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'slack_pomodoro_timer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "slack_pomodoro_timer"
8
+ spec.version = SlackPomodoroTimer::VERSION
9
+ spec.authors = ["kitlangton", "Bideo Wego"]
10
+ spec.email = ["kit.langton@gmail.com", "bideowego@gmail.com"]
11
+
12
+ spec.summary = %q{A pomodoro timer for Slack}
13
+ spec.description = %q{Start up a pomodoro timer from your command line that posts to a channel in your Slack team.}
14
+ spec.homepage = "https://github.com/BideoWego/slack_pomodoro_timer"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "thor"
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.10"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "rspec"
35
+ spec.add_development_dependency "guard"
36
+ spec.add_development_dependency "guard-rspec"
37
+ spec.add_development_dependency "webmock"
38
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slack_pomodoro_timer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre.beta
5
+ platform: ruby
6
+ authors:
7
+ - kitlangton
8
+ - Bideo Wego
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2016-01-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.10'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.10'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: guard
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: guard-rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: webmock
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: Start up a pomodoro timer from your command line that posts to a channel
113
+ in your Slack team.
114
+ email:
115
+ - kit.langton@gmail.com
116
+ - bideowego@gmail.com
117
+ executables:
118
+ - slack_pomodoro_timer
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - ".gitignore"
123
+ - ".rspec"
124
+ - ".travis.yml"
125
+ - Gemfile
126
+ - Guardfile
127
+ - LICENSE.txt
128
+ - README.md
129
+ - Rakefile
130
+ - bin/console
131
+ - bin/setup
132
+ - exe/slack_pomodoro_timer
133
+ - lib/slack_pomodoro_timer.rb
134
+ - lib/slack_pomodoro_timer/cli.rb
135
+ - lib/slack_pomodoro_timer/config.rb
136
+ - lib/slack_pomodoro_timer/http.rb
137
+ - lib/slack_pomodoro_timer/pomodorobot.rb
138
+ - lib/slack_pomodoro_timer/timer.rb
139
+ - lib/slack_pomodoro_timer/version.rb
140
+ - slack_pomodoro_timer.gemspec
141
+ homepage: https://github.com/BideoWego/slack_pomodoro_timer
142
+ licenses:
143
+ - MIT
144
+ metadata:
145
+ allowed_push_host: https://rubygems.org
146
+ post_install_message:
147
+ rdoc_options: []
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.3.1
160
+ requirements: []
161
+ rubyforge_project:
162
+ rubygems_version: 2.4.5
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: A pomodoro timer for Slack
166
+ test_files: []
167
+ has_rdoc: