fc-reminder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b5ce7bf3d6d953a9e54908ae34a2bd2396baf817
4
+ data.tar.gz: bcdc3d656757ae1435d8d0ffe91ef6994727cc0b
5
+ SHA512:
6
+ metadata.gz: 534d323b3629151c2f241ce61db8bd44df904192f587023dfcbf654f23f3fb21a7eafc872ebefb77a808ab4813e83039c0996e409ea40c4c17c0a6fe2c8ead6d
7
+ data.tar.gz: 41f6f401684ace0fae51de6e0aa4b7bb53cb188a9293447cbc481e26dd9c88f86a246db0d4962c80d13b752de5c8d3ea86c198241710008abe38c2d4571c3992
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2013, Kamil Kieliszczyk
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice, this
11
+ list of conditions and the following disclaimer in the documentation and/or
12
+ other materials provided with the distribution.
13
+
14
+ * Neither the name of the {organization} nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,10 @@
1
+ fc-reminder
2
+ ===========
3
+
4
+ Football Continuous Reminder
5
+
6
+ ## Copyright and License
7
+
8
+ Copyright (c) 2013, Kamil Kieliszczyk and Contributors. All Rights Reserved.
9
+
10
+ This project is licenced under the [BSD 3-Clause License](LICENSE).
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler/gem_tasks'
3
+
4
+ Bundler.setup(:default, :development)
5
+
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
8
+
9
+ RSpec::Core::RakeTask.new(:spec) do |spec|
10
+ spec.pattern = FileList['spec/**/*_spec.rb']
11
+ end
12
+
13
+ task default: :spec
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'mixlib/cli'
5
+ require 'fc-reminder'
6
+
7
+ class FCReminderCLI
8
+ include Mixlib::CLI
9
+
10
+ BIN_BASENAME = File.basename(__FILE__)
11
+ HOME_DIR = '~/fcreminder'
12
+
13
+ banner "Usage: #{BIN_BASENAME} [options] start|stop|restart|run"
14
+
15
+ option :team,
16
+ short: '-t STRING',
17
+ long: '--team STRING',
18
+ required: true,
19
+ on: :head,
20
+ description: 'Team name'
21
+
22
+ option :recipient,
23
+ short: '-r STRING',
24
+ long: '--recipient STRING',
25
+ required: true,
26
+ on: :head,
27
+ description: 'Recipient data'
28
+
29
+ option :check,
30
+ short: '-c HH:MM',
31
+ long: '--check HH:MM',
32
+ default: '12:00',
33
+ description: 'Time at which presence of a match will be checked (default: 12:00)'
34
+
35
+ option :daemon,
36
+ short: '-D',
37
+ long: '--daemon',
38
+ default: false,
39
+ boolean: true,
40
+ description: 'Daemonize process (default: false)'
41
+
42
+ option :dir,
43
+ short: '-d',
44
+ long: '--dir DIR',
45
+ default: File.expand_path(HOME_DIR),
46
+ description: "Directory to change to once the process starts (default: #{File.expand_path(HOME_DIR)})",
47
+ proc: lambda { |dir| File.expand_path(dir) }
48
+
49
+ option :monitor,
50
+ short: '-m',
51
+ long: '--monitor',
52
+ default: false,
53
+ boolean: true,
54
+ description: 'Start monitor process (default: false)'
55
+
56
+ option :identifier,
57
+ short: '-i STRING',
58
+ long: '--identifier STRING',
59
+ description: 'An identifier for the process (default: value of --team)'
60
+
61
+ option :log,
62
+ short: '-l',
63
+ long: '--log',
64
+ default: false,
65
+ boolean: true,
66
+ description: 'Redirect both STDOUT and STDERR to a logfile named FCReminder.<team>.output in the directory defined in --log-dir (default: false)'
67
+
68
+ option :logdir,
69
+ long: '--log-dir DIR',
70
+ default: File.expand_path("#{HOME_DIR}/log"),
71
+ description: "A specific directory to put the log files into (default: #{File.expand_path("#{HOME_DIR}/log")}",
72
+ proc: lambda { |dir| File.expand_path(dir) }
73
+
74
+ def run
75
+ parse_options
76
+ config[:argv] = opt_parser.parse!(ARGV)
77
+ create_dir(config[:dir])
78
+ create_dir(config[:logdir])
79
+ config
80
+ end
81
+
82
+ private
83
+
84
+ def create_dir(dir)
85
+ Dir.mkdir(dir) unless File.exists?(dir)
86
+ end
87
+ end
88
+
89
+ FCReminder::Runner.new(FCReminderCLI.new.run).start
90
+
@@ -0,0 +1,31 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'fc-reminder/version'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = 'fc-reminder'
6
+ spec.version = FCReminder::VERSION
7
+ spec.authors = ['Kamil Kieliszczyk']
8
+ spec.email = ['kamil@kieliszczyk.net']
9
+ spec.description = 'Simple reminder about an upcoming football game'
10
+ spec.summary = 'Simple reminder about an upcoming football game'
11
+ spec.homepage = 'https://github.com/kiela/fc-reminder'
12
+
13
+ spec.platform = Gem::Platform::RUBY
14
+ spec.required_rubygems_version = '>= 1.3.6'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'mechanize', '~> 2.7.3'
22
+ spec.add_dependency 'twilio-ruby', '~> 3.11.4'
23
+ spec.add_dependency 'mixlib-cli', '~> 1.3.0'
24
+ spec.add_dependency 'daemons', '~> 1.1.9'
25
+ spec.add_dependency 'clockwork', '~> 0.7.0'
26
+
27
+ spec.add_development_dependency 'bundler', '~> 1.3'
28
+ spec.add_development_dependency 'rake'
29
+ spec.add_development_dependency 'rspec', '~> 3.0.0.beta1'
30
+ spec.add_development_dependency 'fakeweb'
31
+ end
@@ -0,0 +1,13 @@
1
+ require 'fc-reminder/version'
2
+ require 'fc-reminder/reminder'
3
+ require 'fc-reminder/gateways/base'
4
+ require 'fc-reminder/gateways/twilio'
5
+ require 'fc-reminder/providers/base'
6
+ require 'fc-reminder/providers/livescore'
7
+ require 'fc-reminder/runner'
8
+
9
+ module FCReminder
10
+ def self.build(&customization_block)
11
+ Reminder.new(&customization_block)
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module FCReminder
2
+ module Gateways
3
+ class Base
4
+ attr_accessor :config
5
+
6
+ def send(recipient:, data:)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,30 @@
1
+ require 'twilio-ruby'
2
+
3
+ module FCReminder
4
+ module Gateways
5
+ class Twilio < Base
6
+ def send(recipient:, data:)
7
+ client = ::Twilio::REST::Client.new(
8
+ config[:account_sid],
9
+ config[:auth_token]
10
+ )
11
+ client.account.messages.create(
12
+ from: config[:phone_number],
13
+ to: recipient,
14
+ body: message(data)
15
+ )
16
+ end
17
+
18
+ private
19
+
20
+ def message(data)
21
+ if data.empty?
22
+ "No match for today"
23
+ else
24
+ "Reminder of today's match in #{data[:country]} (#{data[:league]})"\
25
+ " between #{data[:team1]} and #{data[:team2]} at #{data[:time]}"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ require 'mechanize'
2
+
3
+ module FCReminder
4
+ module Providers
5
+ class Base
6
+ attr_reader :client
7
+
8
+ def initialize
9
+ @client = Mechanize.new do |agent|
10
+ agent.user_agent_alias = "Linux Firefox"
11
+ end
12
+ end
13
+
14
+ def url
15
+ ""
16
+ end
17
+
18
+ def run(team_name:)
19
+ Hash.new
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,59 @@
1
+ module FCReminder
2
+ module Providers
3
+ class LiveScore < Base
4
+ BASE_URL = "http://www.livescore.com"
5
+
6
+ def url
7
+ "#{BASE_URL}/soccer/#{Time.now.strftime("%Y-%m-%d")}"
8
+ end
9
+
10
+ def run(team_name:)
11
+ cell = search(page: client.get(url), team_name: team_name.downcase)
12
+ cell.nil? ? super : prepare_output_from(cell)
13
+ end
14
+
15
+ private
16
+
17
+ def search(page:, team_name:)
18
+ page.search(".content table.league-table td").find do |td|
19
+ has_team?(td) and team_match?(td, team_name)
20
+ end
21
+ end
22
+
23
+ def has_team?(cell)
24
+ %w(fh fa).include? cell.attributes["class"].value
25
+ end
26
+
27
+ def team_match?(cell, team_name)
28
+ cell.text.strip.downcase == team_name
29
+ end
30
+
31
+ def prepare_output_from(cell)
32
+ r = Hash.new
33
+ r.merge!(fetch(attrs: league_attrs, source: cell.parent.parent))
34
+ r.merge!(fetch(attrs: match_attrs, source: cell.parent))
35
+ r
36
+ end
37
+
38
+ def fetch(attrs:, source:)
39
+ attrs.inject({}) { |h,(k,v)| h[k] = source.search(v).text.strip; h }
40
+ end
41
+
42
+ def league_attrs
43
+ {
44
+ country: 'span.league > a',
45
+ league: 'span.league > span > a',
46
+ }
47
+ end
48
+
49
+ def match_attrs
50
+ {
51
+ time: 'td.fd',
52
+ team1: 'td.fh',
53
+ team2: 'td.fa'
54
+ }
55
+ end
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,41 @@
1
+ module FCReminder
2
+ class Reminder
3
+ attr_reader :provider, :gateway
4
+ attr_accessor :team_name, :recipient
5
+
6
+ def initialize(&customization_block)
7
+ @provider = Providers::LiveScore.new
8
+ @gateway = Gateways::Twilio.new
9
+ eval_block &customization_block
10
+ end
11
+
12
+ def provider=(obj)
13
+ if obj.kind_of? Providers::Base
14
+ @provider = obj
15
+ else
16
+ raise 'Provider should inherits from FCReminder::Providers::Base'
17
+ end
18
+ end
19
+
20
+ def gateway=(obj)
21
+ if obj.kind_of? Gateways::Base
22
+ @gateway = obj
23
+ else
24
+ raise 'Gateway should inherits from FCReminder::Gateways::Base'
25
+ end
26
+ end
27
+
28
+ def run(&customization_block)
29
+ eval_block &customization_block
30
+ result = provider.run(team_name: team_name)
31
+ gateway.send(recipient: recipient, data: result) unless result.empty?
32
+ end
33
+
34
+ private
35
+
36
+ def eval_block(&block)
37
+ instance_eval &block if block_given?
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,68 @@
1
+ require 'daemons'
2
+ require 'clockwork'
3
+
4
+ module FCReminder
5
+ class Runner
6
+ PROCESS_NAME = 'FCReminder'
7
+ attr_reader :options, :reminder
8
+
9
+ def initialize(options)
10
+ @options = options
11
+ @reminder = initialize_reminder
12
+ end
13
+
14
+ def start
15
+ set_reminder(@reminder, @options)
16
+ @options[:daemon] ? daemonize(@options) : run
17
+ end
18
+
19
+ private
20
+
21
+ def initialize_reminder
22
+ FCReminder.build do |config|
23
+ config.gateway.config = {
24
+ account_sid: ENV['TWILIO_ACCOUNT_SID'],
25
+ auth_token: ENV['TWILIO_AUTH_TOKEN'],
26
+ phone_number: ENV['TWILIO_PHONE_NUMBER']
27
+ }
28
+ end
29
+ end
30
+
31
+ def set_reminder(reminer, options)
32
+ Clockwork.every(1.day, 'fc-reminder.check', at: options[:check]) do
33
+ reminder.run do |conf|
34
+ conf.team_name = options[:team]
35
+ conf.recipient = options[:recipient]
36
+ end
37
+ end
38
+ end
39
+
40
+ def run
41
+ Clockwork::run
42
+ end
43
+
44
+ def daemonize(options)
45
+ name = process_name(options)
46
+ opts = daemonize_options(options)
47
+ Daemons.run_proc(name, opts) { run }
48
+ end
49
+
50
+ def process_name(options)
51
+ arr = [PROCESS_NAME]
52
+ arr.push(options[:identifier] ? options[:identifier] : options[:team])
53
+ arr.join('.')
54
+ end
55
+
56
+ def daemonize_options(options)
57
+ {
58
+ ARGV: options[:argv],
59
+ dir_mode: :normal,
60
+ dir: options[:dir],
61
+ monitor: options[:monitor],
62
+ log_dir: options[:logdir],
63
+ log_output: options[:log]
64
+ }
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,3 @@
1
+ module FCReminder
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe FCReminder::Gateways::Base do
4
+ subject(:gateway) { FCReminder::Gateways::Base.new }
5
+
6
+ context "setters" do
7
+ it "allows to set config attribute" do
8
+ config = {foo: 'bar'}
9
+ expect(gateway.config).to be_nil
10
+ gateway.config = config
11
+ expect(gateway.config).to eq(config)
12
+ end
13
+ end
14
+
15
+ context "#send" do
16
+ it "responds to send method" do
17
+ expect(gateway).to respond_to(:send)
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe FCReminder::Gateways::Twilio do
4
+ subject(:gateway) { FCReminder::Gateways::Twilio.new }
5
+
6
+ context "#initialize" do
7
+ it "should be instance of FCReminder::Gateways::Base" do
8
+ expect(gateway).to be_kind_of(FCReminder::Gateways::Base)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe FCReminder::Providers::Base do
4
+ subject(:provider) { FCReminder::Providers::Base.new }
5
+ let(:team_name) { "Barcelona" }
6
+
7
+ context "#initialize" do
8
+ it "initializes HTTP client" do
9
+ expect(provider.client).not_to be_nil
10
+ end
11
+
12
+ it "disallows to change client" do
13
+ expect(provider).not_to respond_to(:client=)
14
+ end
15
+ end
16
+
17
+ context "#url" do
18
+ it "returns empty string" do
19
+ expect(provider.url).to be_empty
20
+ end
21
+ end
22
+
23
+ context "#run" do
24
+ it "returns empty instance of Hash" do
25
+ expect(provider.run(team_name: team_name)).to be_instance_of(Hash)
26
+ expect(provider.run(team_name: team_name)).to be_empty
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe FCReminder::Providers::LiveScore do
4
+ subject(:provider) { FCReminder::Providers::LiveScore.new }
5
+ let(:team_name) { "Barcelona" }
6
+
7
+ context "#initialize" do
8
+ it "should be instance of FCReminder::Providers::Base" do
9
+ expect(provider).to be_kind_of(FCReminder::Providers::Base)
10
+ end
11
+ end
12
+
13
+ context "#url" do
14
+ it "returns valid url" do
15
+ expect(provider.url).to match(/^#{URI::regexp}$/)
16
+ end
17
+ end
18
+
19
+ context "#run" do
20
+ context "there is no match that day" do
21
+ before(:each) { fake_page_without_match(provider.url) }
22
+
23
+ it "returns default value" do
24
+ default_value = FCReminder::Providers::Base.new.run(team_name: team_name)
25
+ expect(provider.run(team_name: team_name)).to eq(default_value)
26
+ end
27
+ end
28
+
29
+ context "there is a match that day" do
30
+ before(:each) { fake_page_with_match(provider.url) }
31
+
32
+ it "returns non-empty instance of Hash" do
33
+ expect(provider.run(team_name: team_name)).to be_an_instance_of(Hash)
34
+ expect(provider.run(team_name: team_name)).not_to be_empty
35
+ end
36
+
37
+ %w(country league time team1 team2).each do |attr|
38
+ it "has return value which includes #{attr}" do
39
+ expect(provider.run(team_name: team_name)).to have_key(attr.to_sym)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ class TestProvider < FCReminder::Providers::Base
4
+ end
5
+
6
+ class TestGateway < FCReminder::Gateways::Base
7
+ end
8
+
9
+ describe FCReminder::Reminder do
10
+ let(:team_name) { "Team Name" }
11
+ let(:recipient) { "+1234567890" }
12
+
13
+ context "#initialize" do
14
+ it "sets default values" do
15
+ reminder = FCReminder.build
16
+ expect(reminder.provider).to be_kind_of(FCReminder::Providers::Base)
17
+ expect(reminder.gateway).to be_kind_of(FCReminder::Gateways::Base)
18
+ end
19
+
20
+ it "allows to configure attributes by using a block" do
21
+ team, receiver = team_name, recipient
22
+
23
+ reminder = FCReminder.build do |config|
24
+ config.team_name = team
25
+ config.recipient = receiver
26
+ end
27
+
28
+ expect(reminder.team_name).to eq(team)
29
+ expect(reminder.recipient).to eq(receiver)
30
+ end
31
+ end
32
+
33
+ context "setters" do
34
+ subject(:reminder) { FCReminder.build }
35
+
36
+ it "allows to set team_name attribute" do
37
+ expect(reminder.team_name).to be_nil
38
+ reminder.team_name = team_name
39
+ expect(reminder.team_name).to eq(team_name)
40
+ end
41
+
42
+ it "allows to set recipient attribute" do
43
+ expect(reminder.recipient).to be_nil
44
+ reminder.recipient = recipient
45
+ expect(reminder.recipient).to eq(recipient)
46
+ end
47
+
48
+ context "provider" do
49
+ it "disallows to set when instance doesn't inherit from FCReminder::Providers::Base" do
50
+ expect{ reminder.provider = Object.new }.to raise_error
51
+ end
52
+
53
+ it "allows to set when instance inherits from FCReminder::Providers::Base" do
54
+ obj = TestProvider.new
55
+ expect(reminder.provider).not_to eq(obj)
56
+ reminder.provider = obj
57
+ expect(reminder.provider).to eq(obj)
58
+ end
59
+ end
60
+
61
+ context "gateway" do
62
+ it "disallows to set when instance doesn't inherit from FCReminder::Gateways::Base" do
63
+ expect{ reminder.gateway = Object.new }.to raise_error
64
+ end
65
+
66
+ it "allows to set when instance inherits from FCReminder::Gateways::Base" do
67
+ obj = TestGateway.new
68
+ expect(reminder.gateway).not_to eq(obj)
69
+ reminder.gateway = obj
70
+ expect(reminder.gateway).to eq(obj)
71
+ end
72
+ end
73
+ end
74
+
75
+ context "#run" do
76
+ subject(:reminder) { FCReminder.build }
77
+ before(:each) { fake_page_with_match(reminder.provider.url) }
78
+ before(:each) { reminder.gateway.stub(:send) {} }
79
+
80
+ it "allows to set consumer data by using a block" do
81
+ expect(reminder.team_name).to be_nil
82
+ expect(reminder.recipient).to be_nil
83
+
84
+ team, receiver = team_name, recipient
85
+ reminder.run do |config|
86
+ config.team_name = team
87
+ config.recipient = receiver
88
+ end
89
+
90
+ expect(reminder.team_name).to eq(team)
91
+ expect(reminder.recipient).to eq(receiver)
92
+ end
93
+
94
+ it "calls provider for data" do
95
+ reminder.provider.stub(:run) { Hash.new }
96
+ expect(reminder.provider).to receive(:run).with(team_name: team_name)
97
+
98
+ reminder.team_name = team_name
99
+ reminder.recipient = recipient
100
+ reminder.run
101
+ end
102
+
103
+ it "calls gateway for sending message" do
104
+ result = {foo: 'bar'}
105
+ reminder.provider.stub(:run) { result }
106
+ expect(reminder.gateway).to receive(:send).with(
107
+ recipient: recipient,
108
+ data: result
109
+ )
110
+
111
+ reminder.team_name = team_name
112
+ reminder.recipient = recipient
113
+ reminder.run
114
+ end
115
+ end
116
+ end
117
+
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe FCReminder::Runner do
4
+ let(:options) { {foo: "bar"} }
5
+
6
+ context "#initialize" do
7
+ subject(:runner) { FCReminder::Runner.new(options) }
8
+
9
+ it "sets options" do
10
+ expect(runner.options).to eq(options)
11
+ end
12
+
13
+ it "initializes reminder" do
14
+ expect(runner.reminder).to be_an_instance_of(FCReminder::Reminder)
15
+ end
16
+ end
17
+
18
+ context "setters" do
19
+ subject(:runner) { FCReminder::Runner.new(options) }
20
+
21
+ it "disallows to change options after initializing" do
22
+ expect(runner).not_to respond_to(:options=)
23
+ end
24
+
25
+ it "disallows to change reminder after initializing" do
26
+ expect(runner).not_to respond_to(:reminder=)
27
+ end
28
+ end
29
+
30
+ context "#start" do
31
+ it "sets reminder" do
32
+ options = {daemon: false}
33
+ runner = FCReminder::Runner.new(options)
34
+
35
+ Clockwork.stub(:every) { |&block| block.call }
36
+ runner.reminder.stub(:run) {}
37
+ runner.stub(:run) {}
38
+
39
+ expect(runner.reminder).to receive(:run)
40
+ runner.start
41
+ end
42
+
43
+ it "starts normal process" do
44
+ options = {daemon: false}
45
+ runner = FCReminder::Runner.new(options)
46
+
47
+ runner.stub(:run) {}
48
+
49
+ expect(runner).to receive(:run)
50
+ runner.start
51
+ end
52
+
53
+ it "starts daemon process" do
54
+ options = {daemon: true}
55
+ runner = FCReminder::Runner.new(options)
56
+
57
+ runner.stub(:daemonize) {}
58
+
59
+ expect(runner).to receive(:daemonize)
60
+ runner.start
61
+ end
62
+ end
63
+ end
64
+
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe FCReminder do
4
+ it 'has a version number' do
5
+ expect(FCReminder::VERSION).not_to be_nil
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe FCReminder do
4
+ context "#build" do
5
+ it "returns an instance of FCReminder::Reminder" do
6
+ expect(FCReminder.build).to be_instance_of(FCReminder::Reminder)
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,6 @@
1
+ GEM_ROOT = File.expand_path("../../", __FILE__)
2
+ $:.unshift File.join(GEM_ROOT, "lib")
3
+
4
+ require 'fc-reminder'
5
+ Dir[File.join(GEM_ROOT, "spec", "support", "**/*.rb")].each { |f| require f }
6
+
@@ -0,0 +1,41 @@
1
+ <div class="content">
2
+ <table class="league-table">
3
+ <colgroup><col class="cold">
4
+ <col class="colh">
5
+ <col class="cols">
6
+ <col class="cola">
7
+ </colgroup><tbody><tr>
8
+ <th colspan="4">
9
+ <span class="league">
10
+ <a href="/soccer/spain/"><strong>Spain</strong></a> - <span><a href="/soccer/spain/primera-division/">Liga BBVA</a></span>
11
+ </span>
12
+ <span class="date">December 1</span>
13
+ </th>
14
+ </tr>
15
+ <tr class="even">
16
+ <td class="fd"> 12:00 </td>
17
+ <td class="fh"> Real Betis </td>
18
+ <td class="fs"> ? - ? </td>
19
+ <td class="fa"> Rayo Vallecano </td>
20
+ </tr>
21
+ <tr>
22
+ <td class="fd"> 17:00 </td>
23
+ <td class="fh"> Granada </td>
24
+ <td class="fs"> ? - ? </td>
25
+ <td class="fa"> Sevilla </td>
26
+ </tr>
27
+ <tr class="even">
28
+ <td class="fd"> 19:00 </td>
29
+ <td class="fh"> Valencia </td>
30
+ <td class="fs"> ? - ? </td>
31
+ <td class="fa"> Osasuna </td>
32
+ </tr>
33
+ <tr>
34
+ <td class="fd"> 21:00 </td>
35
+ <td class="fh"> Athletic Bilbao </td>
36
+ <td class="fs"> ? - ? </td>
37
+ <td class="fa"> Barcelona </td>
38
+ </tr>
39
+ </tbody></table>
40
+ </div>
41
+
@@ -0,0 +1,52 @@
1
+ <div class="content">
2
+ <table class="league-table">
3
+ <colgroup><col class="cold">
4
+ <col class="colh">
5
+ <col class="cols">
6
+ <col class="cola">
7
+ </colgroup><tbody><tr>
8
+ <th colspan="4">
9
+ <span class="league">
10
+ <a href="/soccer/england/"><strong>England</strong></a> - <span><a href="/soccer/england/premier-league/">Premier League</a></span>
11
+ </span>
12
+ <span class="date">November 30</span>
13
+ </th>
14
+ </tr>
15
+ <tr class="even">
16
+ <td class="fd"> 16:00 </td>
17
+ <td class="fh"> Aston Villa </td>
18
+ <td class="fs"> ? - ? </td>
19
+ <td class="fa"> Sunderland </td>
20
+ </tr>
21
+ <tr>
22
+ <td class="fd"> 16:00 </td>
23
+ <td class="fh"> Cardiff City </td>
24
+ <td class="fs"> ? - ? </td>
25
+ <td class="fa"> Arsenal </td>
26
+ </tr>
27
+ <tr class="even">
28
+ <td class="fd"> 16:00 </td>
29
+ <td class="fh"> Everton </td>
30
+ <td class="fs"> ? - ? </td>
31
+ <td class="fa"> Stoke City </td>
32
+ </tr>
33
+ <tr>
34
+ <td class="fd"> 16:00 </td>
35
+ <td class="fh"> Norwich City </td>
36
+ <td class="fs"> ? - ? </td>
37
+ <td class="fa"> Crystal Palace </td>
38
+ </tr>
39
+ <tr class="even">
40
+ <td class="fd"> 16:00 </td>
41
+ <td class="fh"> West Ham United </td>
42
+ <td class="fs"> ? - ? </td>
43
+ <td class="fa"> Fulham </td>
44
+ </tr>
45
+ <tr>
46
+ <td class="fd"> 18:30 </td>
47
+ <td class="fh"> Newcastle United </td>
48
+ <td class="fs"> ? - ? </td>
49
+ <td class="fa"> West Bromwich Albion </td>
50
+ </tr>
51
+ </tbody></table>
52
+ </div>
@@ -0,0 +1,18 @@
1
+ require 'fakeweb'
2
+
3
+ FakeWeb.allow_net_connect = false
4
+
5
+ def fake_page_without_match(url)
6
+ file = File.join(GEM_ROOT, "spec", "support", "fakeweb", "fake_page_without_match.html")
7
+ fake_html_page url, File.read(file)
8
+ end
9
+
10
+ def fake_page_with_match(url)
11
+ file = File.join(GEM_ROOT, "spec", "support", "fakeweb", "fake_page_with_match.html")
12
+ fake_html_page url, File.read(file)
13
+ end
14
+
15
+ def fake_html_page(url, body)
16
+ FakeWeb.register_uri(:get, url, body: body, content_type: "text/html")
17
+ end
18
+
metadata ADDED
@@ -0,0 +1,210 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fc-reminder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kamil Kieliszczyk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mechanize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.7.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.7.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: twilio-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.11.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.11.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: mixlib-cli
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: daemons
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.9
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.9
69
+ - !ruby/object:Gem::Dependency
70
+ name: clockwork
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.7.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.7.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 3.0.0.beta1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 3.0.0.beta1
125
+ - !ruby/object:Gem::Dependency
126
+ name: fakeweb
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Simple reminder about an upcoming football game
140
+ email:
141
+ - kamil@kieliszczyk.net
142
+ executables:
143
+ - fc-reminder
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitignore"
148
+ - ".rspec"
149
+ - Gemfile
150
+ - LICENSE
151
+ - README.md
152
+ - Rakefile
153
+ - bin/fc-reminder
154
+ - fc-reminder.gemspec
155
+ - lib/fc-reminder.rb
156
+ - lib/fc-reminder/gateways/base.rb
157
+ - lib/fc-reminder/gateways/twilio.rb
158
+ - lib/fc-reminder/providers/base.rb
159
+ - lib/fc-reminder/providers/livescore.rb
160
+ - lib/fc-reminder/reminder.rb
161
+ - lib/fc-reminder/runner.rb
162
+ - lib/fc-reminder/version.rb
163
+ - spec/fc-reminder/gateways/base_spec.rb
164
+ - spec/fc-reminder/gateways/twilio_spec.rb
165
+ - spec/fc-reminder/providers/base_spec.rb
166
+ - spec/fc-reminder/providers/livescore_spec.rb
167
+ - spec/fc-reminder/reminder_spec.rb
168
+ - spec/fc-reminder/runner_spec.rb
169
+ - spec/fc-reminder/version_spec.rb
170
+ - spec/fc-reminder_spec.rb
171
+ - spec/spec_helper.rb
172
+ - spec/support/fakeweb/fake_page_with_match.html
173
+ - spec/support/fakeweb/fake_page_without_match.html
174
+ - spec/support/helpers.rb
175
+ homepage: https://github.com/kiela/fc-reminder
176
+ licenses: []
177
+ metadata: {}
178
+ post_install_message:
179
+ rdoc_options: []
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: 1.3.6
192
+ requirements: []
193
+ rubyforge_project:
194
+ rubygems_version: 2.1.11
195
+ signing_key:
196
+ specification_version: 4
197
+ summary: Simple reminder about an upcoming football game
198
+ test_files:
199
+ - spec/fc-reminder/gateways/base_spec.rb
200
+ - spec/fc-reminder/gateways/twilio_spec.rb
201
+ - spec/fc-reminder/providers/base_spec.rb
202
+ - spec/fc-reminder/providers/livescore_spec.rb
203
+ - spec/fc-reminder/reminder_spec.rb
204
+ - spec/fc-reminder/runner_spec.rb
205
+ - spec/fc-reminder/version_spec.rb
206
+ - spec/fc-reminder_spec.rb
207
+ - spec/spec_helper.rb
208
+ - spec/support/fakeweb/fake_page_with_match.html
209
+ - spec/support/fakeweb/fake_page_without_match.html
210
+ - spec/support/helpers.rb