idid 0.0.3 → 0.0.4

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.
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.8.7"
4
+ - "1.9.2"
5
+ - "1.9.3"
6
+ - jruby-18mode # JRuby in 1.8 mode
7
+ - jruby-19mode # JRuby in 1.9 mode
8
+ - rbx-18mode
9
+ - rbx-19mode
data/README.md CHANGED
@@ -1,11 +1,15 @@
1
1
  # Idid
2
2
 
3
+ [![Build Status](https://travis-ci.org/foxycoder/idid.png)](https://travis-ci.org/foxycoder/idid)
4
+
3
5
  Ruby CLI to [iDoneThis](http://idonethis.com).
4
6
 
5
7
  ## Usage (easy)
6
8
 
7
9
  $ idid Something awesome that my colleagues should know about.
8
10
 
11
+ See `idid -h` for more available options.
12
+
9
13
  ## Installation
10
14
 
11
15
  $ [sudo] gem install idid
@@ -13,9 +17,8 @@ Ruby CLI to [iDoneThis](http://idonethis.com).
13
17
  ## Todo
14
18
 
15
19
  1. Write some more tests for mail delivery configurations.
16
- 2. Keeping of dones locally for easy review.
17
- 3. Off-line support (queue dones and send later).
18
- 4. Support for iDoneThis personal.
20
+ 2. Off-line support (queue dones and send later).
21
+ 3. Support for iDoneThis personal.
19
22
 
20
23
  ## Contributing
21
24
 
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ desc 'Run all the tests'
4
+ task :default do
5
+ exit system('bundle exec rspec spec --color')
6
+ end
data/bin/idid CHANGED
@@ -1,17 +1,42 @@
1
1
  #!/usr/bin/env ruby
2
-
2
+ require 'optparse'
3
3
  require File.expand_path('../../lib/idid', __FILE__)
4
4
 
5
+ options = {}
6
+
7
+ OptionParser.new do |opts|
8
+ # Show help screen
9
+ opts.on( '-h', '--help', 'Display this screen' ) do
10
+ puts opts
11
+ exit
12
+ end
5
13
 
14
+ # Show list of done items
15
+ list_desc = "Show done log for date. Default: today."
16
+ options[:list] = nil
17
+ opts.on('-l', '--list [YYYY-MM-DD]', list_desc) do |f|
18
+ options[:list] = f || Time.now.strftime('%Y-%m-%d')
19
+ end
20
+ end.parse!
6
21
 
7
- begin
8
- config = Idid::Configuration.new
9
- rescue
10
- config = Idid::Interactive.create_config
11
- config.write
12
- end
22
+ if options[:list]
23
+ puts Idid::Task.list options[:list]
24
+ else
25
+ begin
26
+ config = Idid::Configuration.new
27
+ rescue
28
+ config = Idid::Interactive.create_config
29
+ config.write
30
+ Idid::Interactive.status "Got your settings. Let's record your progress!"
31
+ end
13
32
 
14
- Idid.configuration = config
15
- Idid.send ARGV
33
+ if ARGV.any?
34
+ task = Idid::Task.new ARGV.join " "
35
+ task.save
16
36
 
17
- puts 'done'
37
+ Idid::Delivery.new(config).email task.to_s
38
+ Idid::Interactive.status "Got it! Let's get some more done!"
39
+ else
40
+ Idid::Interactive.fail "Shoot! An empty message cannot be send!"
41
+ end
42
+ end
data/idid.gemspec CHANGED
@@ -17,7 +17,10 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
+ gem.add_development_dependency 'rake'
20
21
  gem.add_development_dependency 'rspec', '~> 2.12.0'
22
+ gem.add_development_dependency 'travis-lint'
21
23
 
22
24
  gem.add_runtime_dependency 'mail', '~> 2.5.3'
25
+ gem.add_runtime_dependency 'json', '~> 1.7.5'
23
26
  end
@@ -1,7 +1,7 @@
1
1
  module Idid
2
2
  class Configuration
3
3
 
4
- SMTP_DEFAULTS = {
4
+ SMTP_DEFAULTS = {
5
5
  :address => 'smtp.gmail.com',
6
6
  :port => '587',
7
7
  :user_name => ENV['GMAIL_SMTP_USER'],
@@ -22,26 +22,26 @@ module Idid
22
22
  attr_accessor :delivery
23
23
 
24
24
  # Public: configuration to use with iDoneThis
25
- #
25
+ #
26
26
  # options - Hash with configuration options
27
27
  # project - Name of the project to post to (e.g.
28
28
  # project.idonethis.com)
29
29
  # email - Email address to use when sending mail.
30
- # delivery - Email delivery configuration Hash:
30
+ # delivery - Email delivery configuration Hash:
31
31
  # method - Symbol (:smtp|:sendmail|:exim)
32
32
  # options - Configuration Hash for the
33
33
  # delivery method (see:
34
34
  # https://github.com/mikel/mail).
35
35
  #
36
36
  # Returns a new Idid::Configuration instance
37
- def initialize options = {}
38
- options = options.merge(read_config) if read_config
39
- raise ArgumentError.new("Provide a project to use.") unless options['project']
40
- raise ArgumentError.new("Provide an email address.") unless options['email']
41
- raise ArgumentError.new("Provide a delivery method.") unless options['delivery']
37
+ def initialize(options = {})
38
+ options = read_config.merge options if read_config
39
+ raise ArgumentError.new "Provide a project to use." unless options['project']
40
+ raise ArgumentError.new "Provide an email address." unless options['email']
41
+ raise ArgumentError.new "Provide a delivery method." unless options['delivery']
42
42
 
43
- @project = options['project']
44
- @email = options['email']
43
+ @project = options['project']
44
+ @email = options['email']
45
45
  @delivery = options['delivery']
46
46
  end
47
47
 
@@ -68,7 +68,7 @@ module Idid
68
68
  end
69
69
 
70
70
  def self.config_file
71
- File.join( ENV['HOME'], '.idid.yml' )
71
+ File.join ENV['HOME'], '.idid.yml'
72
72
  end
73
73
  end
74
74
  end
@@ -0,0 +1,60 @@
1
+ module Idid
2
+ class Delivery
3
+
4
+ attr_accessor :config
5
+
6
+ # Public: Initialize a new Delivery. It will automatically set the correct
7
+ # delivery options
8
+ #
9
+ # config - The Hash options to use when sending the email to iDoneThis
10
+ #
11
+ # Returns a new instance of Delivery
12
+ def initialize(config)
13
+ @config = config
14
+ setup_delivery
15
+ end
16
+
17
+ # Public: Send email to iDoneThis for logging
18
+ #
19
+ # message - The String with the actual activity you want to log
20
+ #
21
+ # Returns Mail::Message object
22
+ def email(message)
23
+ config = @config # Needed because @config is not in the block scope below
24
+
25
+ Mail.deliver do
26
+ from config.email
27
+ to "#{config.project}@team.idonethis.com"
28
+ subject "I did this"
29
+ body message
30
+ end
31
+ end
32
+
33
+ private
34
+ # Private: Set the right delivery options for Mail to use, based on the
35
+ # settings in the configuration file. Defaults to sending mail via SMTP, if
36
+ # no or unknown delivery method is specified.
37
+ #
38
+ # Returns nothing
39
+ def setup_delivery
40
+ method = @config.delivery['method'] || :smtp
41
+ options = @config.delivery['options'] || {}
42
+
43
+ options.keys.each do |key|
44
+ options[(key.to_sym rescue key) || key] = options.delete(key)
45
+ end
46
+
47
+ options = Idid::Configuration::SMTP_DEFAULTS.merge options if method == :smtp
48
+ options = Idid::Configuration::EXIM_DEFAULTS.merge options if method == :exim
49
+
50
+ mail_defaults_for method, options
51
+ end
52
+
53
+ def mail_defaults_for(method, options = {})
54
+ Mail.defaults do
55
+ delivery_method method, options
56
+ end
57
+ end
58
+
59
+ end
60
+ end
@@ -6,8 +6,7 @@ module Idid
6
6
  status "Please take a moment to create a new configuration.."
7
7
  config = user_config
8
8
  config['delivery'] ||= {}
9
- user_config_from_key 'project',
10
- "What is the name of your iDoneThis project (look at the url: <project>.idonethis.com)", nil, config
9
+ user_config_from_key 'project', "What is the name of your iDoneThis project (look at the url: <project>.idonethis.com)", nil, config
11
10
  user_config_from_key 'email', "What is your associated email address for this iDoneThis project?", nil, config
12
11
  user_config_from_key 'method', "How do you want to send emails to iDoneThis? (smtp, sendmail, exim)", 'smtp', config['delivery']
13
12
 
@@ -25,7 +24,7 @@ module Idid
25
24
  user_config_from_key key, key.to_s, default, config['delivery']['options']
26
25
  end
27
26
 
28
- Idid::Configuration.new(config)
27
+ Idid::Configuration.new config
29
28
  end
30
29
 
31
30
  def user_config_from_key(key, text, default, config = nil)
@@ -46,7 +45,7 @@ module Idid
46
45
  puts "\e[36m#{text}\e[0m"
47
46
  end
48
47
 
49
- def fail(text='Failed!')
48
+ def fail(text = 'Failed!')
50
49
  puts "\e[31m#{text}\e[0m"
51
50
  end
52
51
 
data/lib/idid/task.rb ADDED
@@ -0,0 +1,90 @@
1
+ require 'date'
2
+ require 'json'
3
+
4
+ module Idid
5
+ class Task
6
+ attr_accessor :contents, :log, :logdate
7
+
8
+ # Public: Initialize a new Task
9
+ #
10
+ # contents - The String containing the task that has been done
11
+ #
12
+ # Returns an instance of Task
13
+ def initialize(contents, logdate = nil)
14
+ @contents = contents
15
+ @log = Task.read_log
16
+ @logdate = logdate || Date.today
17
+ end
18
+
19
+ # Public: Save a task to the log file. If there were tasks for this day
20
+ # already, it's appended to that days log. Otherwise, a new day is added to
21
+ # the log.
22
+ #
23
+ # Returns boolean
24
+ def save
25
+ logdate = @logdate.strftime '%Y-%m-%d'
26
+
27
+ if @log.has_key? logdate
28
+ @log[logdate].push @contents
29
+ else
30
+ @log[logdate] = [@contents]
31
+ end
32
+
33
+ Task.write_log @log
34
+ end
35
+
36
+ # Public: Transform Task into a String
37
+ #
38
+ # Returns the String with the contents of the task
39
+ def to_s
40
+ @contents
41
+ end
42
+
43
+ # Public: Lists all activities for a given date.
44
+ #
45
+ # date - The String date you wish to show the entries of, in the format
46
+ # YYYY-MM-DD
47
+ #
48
+ # Returns the String showing the logged activities
49
+ def self.list(date)
50
+ formatted_date = Date.parse(date).strftime '%e %B %Y'
51
+ list = read_log[date]
52
+
53
+ if list.nil?
54
+ "Could not find any activity for#{formatted_date}"
55
+ else
56
+ formatted_log = list.map{|l| '* ' + l }.join "\n"
57
+ "Log for#{formatted_date}:\n#{formatted_log}"
58
+ end
59
+ end
60
+
61
+ private
62
+ # Private: Location of the log file (~/.idid)
63
+ #
64
+ # Returns the String with the location of the log file
65
+ def self.logfile
66
+ logfile = File.join ENV['HOME'], '.idid'
67
+ end
68
+
69
+ # Private: Reads the log file into memory.
70
+ #
71
+ # Returns the Hash containing all log entries, or an empty hash if no
72
+ # entries were found
73
+ def self.read_log
74
+ if File.exists? logfile
75
+ JSON.load open(logfile) rescue {}
76
+ else
77
+ {}
78
+ end
79
+ end
80
+
81
+ # Private: Writes the log file to disk in JSON format
82
+ #
83
+ # log - The Hash containing the done log
84
+ #
85
+ # Returns boolean
86
+ def self.write_log(log)
87
+ File.open(logfile, 'w') { |f| f.write log.to_json }
88
+ end
89
+ end
90
+ end
data/lib/idid/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Idid
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/idid.rb CHANGED
@@ -4,53 +4,4 @@ require 'yaml'
4
4
  Dir[File.expand_path("../idid/**/*.rb", __FILE__)].each {|f| require f}
5
5
 
6
6
  module Idid
7
- class << self
8
- attr_accessor :configuration
9
-
10
- def send *words
11
- setup_delivery
12
- Mail.deliver do
13
- from Idid.configuration.email
14
- to "#{Idid.configuration.project}@team.idonethis.com"
15
- subject "I did this"
16
- body words.flatten.join(" ")
17
- end
18
- end
19
-
20
- def setup_delivery
21
- method = Idid.configuration.delivery['method']
22
- options = Idid.configuration.delivery['options'] || {}
23
-
24
- options.keys.each do |key|
25
- options[(key.to_sym rescue key) || key] = options.delete(key)
26
- end
27
-
28
- case method
29
- when 'smtp'
30
- setup_smtp options
31
- when 'sendmail'
32
- setup_sendmail
33
- when 'exim'
34
- setup_exim options
35
- end
36
- end
37
-
38
- def setup_smtp options = {}
39
- Mail.defaults do
40
- delivery_method :smtp, Idid::Configuration::SMTP_DEFAULTS.merge(options)
41
- end
42
- end
43
-
44
- def setup_sendmail
45
- Mail.defaults do
46
- delivery_method :sendmail
47
- end
48
- end
49
-
50
- def setup_exim options={}
51
- Mail.defaults do
52
- delivery_method :exim, Idid::Configuration::EXIM_DEFAULTS.merge(options)
53
- end
54
- end
55
- end
56
7
  end
@@ -6,23 +6,27 @@ describe Idid::Configuration do
6
6
  let(:project) { 'foobar' }
7
7
  let(:delivery) { {:method => :sendmail} }
8
8
 
9
- before { Idid::Configuration.any_instance.stub(:read_config) { nil } }
10
-
11
9
  its('project') { should eq project }
12
10
  its('email') { should eq email }
13
11
 
14
- it 'raises ArgumentError if no email option is passed' do
15
- expect { Idid::Configuration.new('project' => project, 'delivery' => delivery) }.
16
- to raise_error(ArgumentError, /email/)
17
- end
12
+ context "when any of the options are missing" do
13
+ before do
14
+ Idid::Configuration.any_instance.stub(:read_config) { nil }
15
+ end
18
16
 
19
- it 'raises ArgumentError if no project option is passed' do
20
- expect { Idid::Configuration.new('email' => email, 'delivery' => delivery) }.
21
- to raise_error(ArgumentError, /project/)
22
- end
17
+ it 'raises ArgumentError if no email option is passed' do
18
+ expect { Idid::Configuration.new('project' => project, 'delivery' => delivery) }.
19
+ to raise_error(ArgumentError, /email/)
20
+ end
21
+
22
+ it 'raises ArgumentError if no project option is passed' do
23
+ expect { Idid::Configuration.new('email' => email, 'delivery' => delivery) }.
24
+ to raise_error(ArgumentError, /project/)
25
+ end
23
26
 
24
- it 'raises ArgumentError if no delivery option is passed' do
25
- expect { Idid::Configuration.new('email' => email, 'project' => project) }.
26
- to raise_error(ArgumentError, /delivery/)
27
+ it 'raises ArgumentError if no delivery option is passed' do
28
+ expect { Idid::Configuration.new('email' => email, 'project' => project) }.
29
+ to raise_error(ArgumentError, /delivery/)
30
+ end
27
31
  end
28
32
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Idid::Delivery do
4
+
5
+ subject { delivery }
6
+
7
+ let(:delivery) { Idid::Delivery.new config }
8
+ let(:config) do
9
+ Idid::Configuration.new(
10
+ 'project' => 'foo',
11
+ 'email' => 'john@example.com',
12
+ 'delivery' => { 'method' => :test }
13
+ )
14
+ end
15
+
16
+ its('config') { should eq config }
17
+
18
+ describe "#email" do
19
+ subject { delivery.email 'Tested Idid::Deliver.email' }
20
+ its(:to) { should eq ['foo@team.idonethis.com'] }
21
+ its(:from) { should eq ['john@example.com'] }
22
+ its(:body) { should eq 'Tested Idid::Deliver.email' }
23
+ end
24
+
25
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe Idid::Task do
4
+ subject { task }
5
+
6
+ let(:task) { Idid::Task.new contents, logdate }
7
+ let(:contents) { 'Bar' }
8
+ let(:logdate) { Date.new 2013,1,1 }
9
+
10
+ its(:contents) { should eq contents }
11
+ its(:log) { should be_a_kind_of Hash }
12
+ its(:logdate) { should eq Date.new(2013,1,1) }
13
+
14
+ describe "#save" do
15
+ before do
16
+ Idid::Task.stub(:read_log).and_return log_file
17
+ Idid::Task.stub(:write_log).and_return true
18
+ task.save
19
+ end
20
+
21
+ subject { task.log }
22
+
23
+ context "date has no logged items yet" do
24
+ let(:log_file) { {"2013-02-01" => ["Foo"]} }
25
+ it { should eq({"2013-02-01" => ["Foo"], "2013-01-01" => ["Bar"]}) }
26
+ end
27
+
28
+ context "date has already logged items" do
29
+ let(:log_file) { {"2013-01-01" => ["Foo"]} }
30
+ it { should eq({"2013-01-01" => ["Foo", "Bar"]}) }
31
+ end
32
+ end
33
+
34
+ describe "#to_s" do
35
+ subject { task.to_s }
36
+ it { should eq contents }
37
+ end
38
+
39
+ describe ".list" do
40
+ before do
41
+ Idid::Task.stub(:read_log).and_return({"2013-01-01" => ["Foo", "Bar"]})
42
+ end
43
+
44
+ subject { Idid::Task.list date }
45
+
46
+ context "logged items exist" do
47
+ let(:date) { '2013-01-01' }
48
+ it { should match /Log for 1 January 2013/ }
49
+ it { should match /\* Foo/ }
50
+ it { should match /\* Bar/ }
51
+ end
52
+
53
+ context "no logged items" do
54
+ let(:date) { '2013-01-02' }
55
+ it { should match /Could not find any activity for 2 January 2013/ }
56
+ end
57
+ end
58
+
59
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,3 +2,9 @@ require 'bundler'
2
2
  Bundler.require
3
3
 
4
4
  Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
5
+
6
+ RSpec.configure do |config|
7
+ config.color_enabled = true
8
+ config.tty = true
9
+ config.formatter = :progress
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: idid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-04 00:00:00.000000000 Z
12
+ date: 2013-01-08 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: rspec
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -27,6 +43,22 @@ dependencies:
27
43
  - - ~>
28
44
  - !ruby/object:Gem::Version
29
45
  version: 2.12.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: travis-lint
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
30
62
  - !ruby/object:Gem::Dependency
31
63
  name: mail
32
64
  requirement: !ruby/object:Gem::Requirement
@@ -43,6 +75,22 @@ dependencies:
43
75
  - - ~>
44
76
  - !ruby/object:Gem::Version
45
77
  version: 2.5.3
78
+ - !ruby/object:Gem::Dependency
79
+ name: json
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 1.7.5
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.7.5
46
94
  description: A Ruby CLI for iDoneThis
47
95
  email:
48
96
  - wrdevos@gmail.com
@@ -52,6 +100,7 @@ extensions: []
52
100
  extra_rdoc_files: []
53
101
  files:
54
102
  - .gitignore
103
+ - .travis.yml
55
104
  - Gemfile
56
105
  - LICENSE.txt
57
106
  - README.md
@@ -60,9 +109,13 @@ files:
60
109
  - idid.gemspec
61
110
  - lib/idid.rb
62
111
  - lib/idid/configuration.rb
112
+ - lib/idid/delivery.rb
63
113
  - lib/idid/interactive.rb
114
+ - lib/idid/task.rb
64
115
  - lib/idid/version.rb
65
116
  - spec/idid/configuration_spec.rb
117
+ - spec/idid/delivery_spec.rb
118
+ - spec/idid/task_spec.rb
66
119
  - spec/spec_helper.rb
67
120
  homepage: https://github.com/foxycoder/idid
68
121
  licenses: []
@@ -90,4 +143,6 @@ specification_version: 3
90
143
  summary: Post to iDoneThis from your command line.
91
144
  test_files:
92
145
  - spec/idid/configuration_spec.rb
146
+ - spec/idid/delivery_spec.rb
147
+ - spec/idid/task_spec.rb
93
148
  - spec/spec_helper.rb