daf 0.3.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: 7fda2ec5348bcba315e6b234fe2d074ebdff16f1
4
+ data.tar.gz: 6c59a79b72716fedf16e9724a3c9dcd73ed7a07e
5
+ SHA512:
6
+ metadata.gz: d2d94f5e13286e1f9be111612bcdd687ad91231d6060b997ffd9383ad88d529804953241c983673faa558680731efb1f84455e2006dde905513ab8c06e97e6bd
7
+ data.tar.gz: 4bcf8c5103e21bcafb9dc39a98083d251cfae11afe2a12fe667c3a0045d2744a81a9bc0dd1062255805237df81a3665ac97c621eadc709d8de4e5ae6da0be007
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1
5
+ install:
6
+ - bundle install
7
+ script:
8
+ - bundle exec rake validate
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in daf.gemspec
4
+ gemspec
@@ -0,0 +1,71 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ daf (0.3.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.0.0)
10
+ astrolabe (1.3.0)
11
+ parser (>= 2.2.0.pre.3, < 3.0)
12
+ builder (3.2.2)
13
+ diff-lcs (1.2.5)
14
+ docile (1.1.5)
15
+ faraday (0.9.1)
16
+ multipart-post (>= 1.2, < 3)
17
+ jwt (1.5.0)
18
+ mime-types (2.6.1)
19
+ multi_json (1.10.1)
20
+ multipart-post (2.0.0)
21
+ parser (2.2.0.pre.8)
22
+ ast (>= 1.1, < 3.0)
23
+ slop (~> 3.4, >= 3.4.5)
24
+ powerpack (0.0.9)
25
+ rainbow (2.0.0)
26
+ rake (10.3.2)
27
+ rspec (3.1.0)
28
+ rspec-core (~> 3.1.0)
29
+ rspec-expectations (~> 3.1.0)
30
+ rspec-mocks (~> 3.1.0)
31
+ rspec-core (3.1.7)
32
+ rspec-support (~> 3.1.0)
33
+ rspec-expectations (3.1.2)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.1.0)
36
+ rspec-mocks (3.1.3)
37
+ rspec-support (~> 3.1.0)
38
+ rspec-support (3.1.2)
39
+ rubocop (0.27.1)
40
+ astrolabe (~> 1.3)
41
+ parser (>= 2.2.0.pre.7, < 3.0)
42
+ powerpack (~> 0.0.6)
43
+ rainbow (>= 1.99.1, < 3.0)
44
+ ruby-progressbar (~> 1.4)
45
+ ruby-progressbar (1.7.0)
46
+ simplecov (0.9.1)
47
+ docile (~> 1.1.0)
48
+ multi_json (~> 1.0)
49
+ simplecov-html (~> 0.8.0)
50
+ simplecov-html (0.8.0)
51
+ slop (3.6.0)
52
+ twilio-ruby (4.2.0)
53
+ builder (>= 2.1.2)
54
+ jwt (~> 1.0)
55
+ multi_json (>= 1.3.0)
56
+ washbullet (0.4.0)
57
+ faraday (~> 0.9.0)
58
+ mime-types
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ bundler (>= 1.6)
65
+ daf!
66
+ rake
67
+ rspec
68
+ rubocop
69
+ simplecov
70
+ twilio-ruby
71
+ washbullet
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Kayla McArthur
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,37 @@
1
+ ## Dynamic Action Framework
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/daf.svg)](http://badge.fury.io/rb/daf) [![Build Status](https://kayla-ci.org/klmcarthur/DAF.svg?branch=master)](https://kayla-ci.org/klmcarthur/DAF) [![Inline docs](http://inch-ci.org/github/klmcarthur/DAF.svg?branch=master)](http://inch-ci.org/github/klmcarthur/DAF) [![Code Climate](https://codeclimate.com/github/klmcarthur/DAF/badges/gpa.svg)](https://codeclimate.com/github/klmcarthur/DAF)
4
+
5
+
6
+ https://rubygems.org/gems/daf
7
+
8
+ Dynamic Action Framework, or DAF, is a flexible, extensible system to let a user trigger actions based on events, either on a system or through anything else you can write in Ruby. Some examples of things you can automate using DAF:
9
+
10
+ * When my bus is 10 minutes away, text me
11
+ * When I get an email from my mother, text me the contents
12
+ * When I'm five minutes away from a meeting, send me the agenda
13
+ * Automatically create a blog entry based on my tweets
14
+ * Automatically download any picture from facebook that has me tagged
15
+ * Alert me when the weather changes via text message
16
+
17
+ In addition, you could use it as a library to develop other action systems, including things like:
18
+
19
+ * Server monitoring systems
20
+ * Email filtering systems
21
+
22
+ DAF integrates with other action systems such as IFTTT in numerous ways, the easiest probably being through use of Dropbox and monitoring file modification times. Using DAF with these services permits an even greater level of integration and customizability.
23
+
24
+ ### Planned Features
25
+
26
+ * Additional plugins for input/output
27
+ * A robust Erlang daemon that uses Ruby framework to provide high availability monitor
28
+ * Additional input sources (SQL, Socket/Listening API, etc)
29
+ * REST API layer
30
+
31
+ ## Contributing
32
+
33
+ If you're interested in contributing custom actions or monitors you've written, please just submit a pull request - http://github.com/klmcarthur/DAF - and I'll happily have a look.
34
+
35
+ If you're interested in using DAF in something else, or have a different front-end experience, please let me know as well, for front-ends, I'd love to bring it into the core if it's interesting or useful, and for third party projects I'd love to link to you.
36
+
37
+ Thanks!
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'bundler/gem_tasks'
4
+ Bundler.setup(:default, :development)
5
+ require 'rspec/core'
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ task default: :validate
9
+
10
+ desc 'Validate Package'
11
+ task validate: [:rubocop, :spec]
12
+
13
+ desc 'Run RuboCop'
14
+ task :rubocop do
15
+ require 'rubocop/rake_task'
16
+ RuboCop::RakeTask.new
17
+ end
18
+
19
+ desc 'Build Documentation'
20
+ task :yard do
21
+ require 'yard'
22
+ YARD::Rake::YardocTask.new
23
+ end
data/bin/dad ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'daf'
4
+ include DAF
5
+ start_dad
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'daf/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'daf'
8
+ spec.version = DAF::VERSION
9
+ spec.authors = ['Kayla McArthur']
10
+ spec.email = ['kayla@kayla.is']
11
+ spec.summary = 'A daemon and framework for monitoring events, '\
12
+ 'and triggering actions'
13
+ spec.description = 'A library and corresponding daemon based on that '\
14
+ 'library to monitor a number of sources for events '\
15
+ 'and trigger actions based on those events. '\
16
+ 'Includes a default set of monitors and actions '\
17
+ 'and tools to create more'
18
+ spec.homepage = 'http://github.com/klmcarthur/DAF'
19
+ spec.license = 'MIT'
20
+
21
+ spec.files = `git ls-files -z`.split("\x0")
22
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
23
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
24
+ spec.require_paths = ['lib']
25
+ spec.required_ruby_version = '>= 2.0.0'
26
+
27
+ spec.add_development_dependency 'bundler', '>= 1.6'
28
+ spec.add_development_dependency 'rake'
29
+ spec.add_development_dependency 'rubocop'
30
+ spec.add_development_dependency 'simplecov'
31
+ spec.add_development_dependency 'rspec'
32
+ spec.add_development_dependency 'twilio-ruby'
33
+ spec.add_development_dependency 'washbullet'
34
+
35
+ end
@@ -0,0 +1,16 @@
1
+ ---
2
+ Monitor:
3
+ Type: FileUpdateMonitor
4
+ Options:
5
+ path: /tmp/test1
6
+ frequency: 2
7
+
8
+ Action:
9
+ Type: EmailAction
10
+ Options:
11
+ to: test@example.com
12
+ from: test@example.com
13
+ subject: "File updated at {{time}}"
14
+ body: "Contents of File: {{contentts}}"
15
+ server: localhost
16
+ ---
@@ -0,0 +1,50 @@
1
+ require 'daf/datasources/yaml_data_source'
2
+
3
+ # Starts the DAF daemon (DAD) - takes a directory
4
+ # containing the YAML files for monitor/action pairs
5
+ # After parsing configuration, will daemonize and continue
6
+ # monitoring until SIGTERM is received
7
+ #
8
+ # @author Kayla McArthur (mailto:kayla@kayla.is)
9
+ # @icense MIT License
10
+ module DAF
11
+ def start_dad
12
+ if ARGV[0] && File.directory?(ARGV[0])
13
+ commands = []
14
+
15
+ Dir[ARGV[0] + '/*.yaml'].each do |file|
16
+ commands << Command.new(YAMLDataSource.new(file))
17
+ end
18
+
19
+ dad = DynamicActionDaemon.new(commands)
20
+ dad.start
21
+ else
22
+ print_usage
23
+ end
24
+ end
25
+
26
+ def print_usage
27
+ puts 'DAF not started - please see below'
28
+ puts 'Usage: daf [path to config folder]'
29
+ puts 'Directory must contain one or more config'
30
+ puts 'files with a .yaml extension'
31
+ end
32
+
33
+ # This class represents the Dynamic Action Daemon
34
+ # it requires a set of commands to be passed in
35
+ class DynamicActionDaemon
36
+ # Initializes DAD with a given command set
37
+ #
38
+ # @param commands [Array] Array containing Command objects
39
+ def initialize(commands)
40
+ @commands = commands
41
+ end
42
+
43
+ # Starts the daemon - this method will block for duration
44
+ # of execution of program
45
+ def start
46
+ @commands.each(&:execute)
47
+ sleep
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,25 @@
1
+ require 'daf/configurable'
2
+
3
+ module DAF
4
+ # Stores information related to actions that can
5
+ # be taken as a result of a Monitor firing
6
+ # Exposes only one method, and is a Configurable
7
+ class Action
8
+ include Configurable
9
+
10
+ # Activate this action using given options - takes an optional
11
+ # block parameter that will be invoked when action
12
+ # is complete, with a parameter of if the action was successful
13
+ # and also returns if action was successful
14
+ #
15
+ # @param options [Hash] A hash of options with name/value pairs, must
16
+ # match types expected for each option or will raise an exception
17
+ # @yield If successful, will execute the optional block passed in
18
+ def activate(options)
19
+ process_options(options)
20
+ success = invoke
21
+ yield success if block_given?
22
+ success
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ require 'daf/action'
2
+ require 'net/smtp'
3
+
4
+ module DAF
5
+ # An action that sends an email based on parameters
6
+ class EmailAction < Action
7
+ attr_option :to, String, :required
8
+ attr_option :from, String, :required
9
+ attr_option :subject, String, :required
10
+ attr_option :body, String, :required
11
+ attr_option :server, String, :required
12
+ attr_option :port, Integer
13
+
14
+ def invoke
15
+ message = format_email(@to.value, @from.value,
16
+ @subject.value, @body.value)
17
+ port = self.port.valid? ? self.port.value : 25
18
+ Net::SMTP.start(@server.value, port) do |smtp|
19
+ smtp.send_message(message, @from.value, @to.value)
20
+ end
21
+ true
22
+ end
23
+
24
+ def format_email(to, from, subject, body)
25
+ <<TEXT
26
+ From: #{from}
27
+ To: #{to}
28
+ Subject: #{subject}
29
+
30
+ #{body}
31
+ TEXT
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,26 @@
1
+ require 'daf/action'
2
+ require 'washbullet'
3
+
4
+ module DAF
5
+ # An action that sends an sms using twilio based on parameters
6
+ class PushbulletAction < Action
7
+ attr_option :key, String, :required
8
+ attr_option :identifier, String, :required
9
+ attr_option :title, String, :required
10
+ attr_option :message, String, :required
11
+
12
+ def client
13
+ @client ||= Washbullet::Client.new(@key)
14
+ end
15
+
16
+ def invoke
17
+ client.push_note(receiver: :device,
18
+ identifier: @identifier,
19
+ params: {
20
+ title: @title,
21
+ body: @message
22
+ }
23
+ )
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ require 'daf/action'
2
+ require 'English'
3
+
4
+ module DAF
5
+ # An action that executes a shell script
6
+ class ShellAction < Action
7
+ attr_option :path, String, :required do |value|
8
+ File.executable?(value)
9
+ end
10
+
11
+ attr_option :arguments, String
12
+
13
+ attr_output :results, String
14
+
15
+ def invoke
16
+ arguments = self.arguments.value ? " #{self.arguments.value}" : ''
17
+ @results = `#{path.value}#{arguments}`
18
+ $CHILD_STATUS.exitstatus
19
+ end
20
+ end
21
+ end