motivator 1.0.0

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: 28d28fe55e12ee6b8dde44c811f73475f7841694
4
+ data.tar.gz: 05c34927fe66fb370b6ef1a07863d69facbe2c1f
5
+ SHA512:
6
+ metadata.gz: dca6b4b698d905a159e6564e36f2468769ed6fd540b518de7d3256dc55eacf3674b90370deccfe383451426ff827c8ff022130c5eaae0bb00e1b084249d3cfca
7
+ data.tar.gz: d871ef1de34588e2f31ce1ec32257f0a63b88aa26d28014b6619b0cc76b162ff78030e4db7bcd69cb77bd118b99a365e9fa9e39aed5f67a58a29b00f4419877a
data/bin/motivator ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'motivator'
4
+ require 'yaml'
5
+ require 'colour_output'
6
+ require 'optparse'
7
+ require 'command_parser'
8
+ require 'file_watcher'
9
+
10
+ # load the quotes from the yaml file
11
+ quotes = YAML.load_file('./lib/quote.yml')
12
+ # initialise the motivation class
13
+ motivator = Motivator.new(quotes['quotes'], ColourOutput.new, FileWatcher.new)
14
+
15
+ # get arguments from the command line
16
+ parser = CommandParser.new(quotes)
17
+ options = parser.collect(ARGV)
18
+
19
+ # send the arguments to the motivation object and print the output
20
+ # to the console
21
+ puts motivator.send(options[:method], options[:arguments])
@@ -0,0 +1,33 @@
1
+ class ColourOutput
2
+ attr_accessor :colours, :default
3
+
4
+ # initialize and yield self in order to give a hook to modify class
5
+ def initialize
6
+ @colours = default_colours
7
+ @default = "\033[92m"
8
+
9
+ yield self if block_given?
10
+ end
11
+
12
+ # default colors hash
13
+ def default_colours
14
+ {primary: "\033[95m", blue: "\033[94m", green: "\033[92m", warning: "\033[93m", }
15
+ end
16
+
17
+ # print out a random color
18
+ def random(string)
19
+ random_key = @colours.keys.sample
20
+
21
+ self.send(random_key, string)
22
+ end
23
+
24
+ # if the method is missing we need to wrap the argument in a
25
+ # color from the method call
26
+ def method_missing(name, *args)
27
+ if @colours.include? name
28
+ "#{@colours[name]}#{args[0]}\033[0m"
29
+ else
30
+ "#{@default}#{args[0]}\033[0m"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,70 @@
1
+ require 'optparse'
2
+
3
+ # wrapper class for options parser
4
+ class CommandParser
5
+ # pass the config so we can access
6
+ def initialize config
7
+ @config = config
8
+ @options = options
9
+ end
10
+
11
+ # default options
12
+ def options
13
+ { method: nil, arguments: nil}
14
+ end
15
+
16
+ # collect the command arguments via the option parser class
17
+ def collect(arguments)
18
+ # build the class options from options parser instance
19
+ parser = OptionParser.new do |opts|
20
+ opts.banner = "Options for output grasshopper"
21
+ opts.separator "\n"
22
+ opts.separator "Specifics:"
23
+
24
+ opts.on('-m [name]', '--motivate [name]', String, "# Output a motivational quote") do |m|
25
+ @options[:method] = 'motivate'
26
+ @options[:arguments] = { author: m }
27
+ end
28
+
29
+ opts.on('-w [glob1,glob2] ', '--watch [glob1,glob2]', Array, '# Watch files & output a message on file/folder change event') do |w|
30
+ @options[:method] = 'watch'
31
+ @options[:arguments] = { files: w }
32
+ end
33
+
34
+ opts.on_tail('-h', '--help', '# Output command line help options') do
35
+ puts opts
36
+ exit
37
+ end
38
+ end
39
+
40
+ # set the options from calling the parser if there are any exceptions
41
+ # we need to catch them and output the help message
42
+ begin
43
+ parser.parse!(arguments)
44
+ rescue Exception => e
45
+ puts parser
46
+ exit(1)
47
+ end
48
+
49
+ # if no valid methods were set we can't execute and therefore we exit and
50
+ # put the parser message to the console
51
+ if @options[:method].nil?
52
+ puts parser
53
+ exit(1)
54
+ end
55
+
56
+ #return the options
57
+ @options
58
+ end
59
+
60
+ #output a prett list of authors
61
+ def output_authors
62
+ authors = []
63
+
64
+ @config['quotes'].each do |author|
65
+ authors << author[0]
66
+ end
67
+
68
+ authors.join(', ')
69
+ end
70
+ end
@@ -0,0 +1,79 @@
1
+ class FileWatcher
2
+ attr_reader :snapshot, :changed, :event
3
+
4
+ def initialize(files = nil, options = {})
5
+ @files = files || ['./**/*']
6
+ @changed = nil
7
+ @event = nil
8
+ if not @files.empty?
9
+ @snapshot = snapshot_filesystem
10
+ end
11
+ @options = options
12
+ end
13
+
14
+ def set_files(files)
15
+ @files = files
16
+ @snapshot = snapshot_filesystem
17
+ end
18
+
19
+ # take a snapshot of the given files so we can compare at a given date
20
+ def snapshot_filesystem
21
+ mtimes = {}
22
+
23
+ files = @files.map { |file| Dir[file] }.flatten.uniq
24
+
25
+ files.each do |file|
26
+ if File.exists? file
27
+ mtimes[file] = File.stat(file).mtime
28
+ end
29
+ end
30
+
31
+ mtimes
32
+ end
33
+
34
+ # have the given files changed if they have then
35
+ # set the changed file and return true
36
+ def files_changed?
37
+ # initialise variables for the
38
+ new_snapshot = snapshot_filesystem
39
+ has_changed = false
40
+
41
+ # take a new snapshot and subtract this from the old snapshot in order to get forward changes
42
+ # then add the snapshot to the oposite subtraction to get backward changes
43
+ changes = (@snapshot.to_a - new_snapshot.to_a) + (new_snapshot.to_a - @snapshot.to_a)
44
+
45
+ # determine the event for each change
46
+ changes.each do |change|
47
+ if @snapshot.keys.include? change[0]
48
+ @changed = {change[0] => change[1]}
49
+ @event = (new_snapshot.keys.include? change[0]) ? :change : :delete
50
+ has_changed = true
51
+ else
52
+ @changed = {change[0] => change[1]}
53
+ @event = :new
54
+ has_changed = true
55
+ end
56
+ end
57
+
58
+ # lets reset the snapshot so that we don't create a forever loop
59
+ @snapshot = new_snapshot
60
+
61
+ return has_changed
62
+ end
63
+
64
+ # watching the files given in initialize if the files change call the proc
65
+ def watch(have_changed, waiting = nil)
66
+ @watching = true
67
+
68
+ while @watching
69
+ if files_changed?
70
+ @watching = have_changed.call(@changed, @event)
71
+ end
72
+
73
+ sleep(1)
74
+
75
+ waiting.call if waiting
76
+ end
77
+ end
78
+
79
+ end
data/lib/motivator.rb ADDED
@@ -0,0 +1,47 @@
1
+ class Motivator
2
+ attr_accessor :quotes
3
+
4
+ def initialize(quotes, colourer, watcher)
5
+ @quotes = quotes
6
+ @colourer = colourer
7
+ @watcher = watcher
8
+ end
9
+
10
+ # output a string of motivation to the console prepended by the
11
+ # quotes author and coloured with ansi character codes
12
+ def motivate(opts = {})
13
+ author = (opts[:author].nil?) ? @quotes.keys.sample : opts[:author]
14
+
15
+ readable(author) + @colourer.random(" ~ " + get_quote(author, opts[:id]))
16
+ end
17
+
18
+ # watch the files in the system and call the files changed method as a
19
+ # proc when there is an event that we need to hook into
20
+ def watch(opts)
21
+ @watcher.set_files(opts[:files]) if opts[:files]
22
+ @watcher.watch(method(:files_changed))
23
+ end
24
+
25
+ # the callable method which contains the logic once files are changed
26
+ def files_changed(file, event)
27
+ puts motivate
28
+ # return true so that the watch loop keeps running
29
+ return true
30
+ end
31
+
32
+ # get a quote, either from random or from specified author or index
33
+ def get_quote(author, index = nil)
34
+ if index.nil?
35
+ quote_length = (@quotes[author].length) - 1
36
+ index = Random.rand(0..quote_length)
37
+ end
38
+
39
+ @quotes[author][index]
40
+ end
41
+
42
+ # convert from underscores to spaces and capitalise
43
+ # so the name is readable in the console
44
+ def readable(string)
45
+ string.gsub('_', ' ').split.map(&:capitalize).join(' ')
46
+ end
47
+ end
data/lib/quote.yml ADDED
@@ -0,0 +1,42 @@
1
+ #main quotes
2
+ quotes:
3
+ bruce_lee:
4
+ - "Mistakes are always forgivable, if one has the courage to admit them"
5
+ - "If you spend too much time thinking about a thing, you'll never get it done"
6
+ - "A wise man can learn more from a foolish question than a fool can learn from a wise answer"
7
+ steve_jobs:
8
+ - "Design is not just what it looks like and feels like. Design is how it works"
9
+ - "Sometimes when you innovate, you make mistakes. It is best to admit them quickly, and get on with improving your other innovations"
10
+ - "Innovation distinguishes between a leader and a follower"
11
+ abraham_licoln:
12
+ - "Nearly all men can stand adversity, but if you want to test a man's character, give him power"
13
+ - "Whatever you are, be a good one"
14
+ - "Always bear in mind that your own resolution to succeed is more important than any other"
15
+ c_s_lewis:
16
+ - "I have found a desire within myself that no experience in this world can satisfy; the most probable explanation is that I was made for another world"
17
+ - "Friendship is born at that moment when one person says to another: What! You too? I thought I was the only one"
18
+ - "You are never too old to set another goal or to dream a new dream"
19
+ thomas_edison:
20
+ - "I have not failed. I've just found 10,000 ways that won't work"
21
+ - "Many of life's failures are people who did not realize how close they were to success when they gave up"
22
+ - "Our greatest weakness lies in giving up. The most certain way to succeed is always to try just one more time"
23
+ eleanor_roosevelt:
24
+ - "No one can make you feel inferior without your consent"
25
+ - "Great minds discuss ideas; average minds discuss events; small minds discuss people"
26
+ - "The future belongs to those who believe in the beauty of their dreams"
27
+ mark_twain:
28
+ - "Don't go around saying the world owes you a living. The world owes you nothing. It was here first"
29
+ - "I have never let my schooling interfere with my education"
30
+ - "If you tell the truth, you don't have to remember anything"
31
+ albert_einstein:
32
+ - "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe"
33
+ - "The important thing is not to stop questioning. Curiosity has its own reason for existing"
34
+ - "Science without religion is lame, religion without science is blind"
35
+ winston_churchill:
36
+ - "Success consists of going from failure to failure without loss of enthusiasm"
37
+ - "If you're going through hell, keep going"
38
+ - "You have enemies? Good. That means you've stood up for something, sometime in your life"
39
+ walt_disney:
40
+ - "All our dreams can come true, if we have the courage to pursue them"
41
+ - "It's kind of fun to do the impossible"
42
+ - "We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths"
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motivator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Hugo Rut
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mocha
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.1.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 5.8.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 5.8.3
41
+ description: Quotes to motivate from the command line
42
+ email: hugorut@gmail.com
43
+ executables:
44
+ - motivator
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ./lib/colour_output.rb
49
+ - ./lib/command_parser.rb
50
+ - ./lib/file_watcher.rb
51
+ - ./lib/motivator.rb
52
+ - ./lib/quote.yml
53
+ - bin/motivator
54
+ homepage:
55
+ licenses:
56
+ - MIT
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.0.14
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Command line motivator
78
+ test_files: []