actiontexter 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: c07c70abba49ae94efaf917157560d5875da1a33
4
+ data.tar.gz: 47ed0798483fcb979995ee767d85b7267f344094
5
+ SHA512:
6
+ metadata.gz: 26b22ffcbd88a798bc69f9d598ab17ef59613c1f5afe4fe69ada7cf80a84fddd02b6a3cf155b7f2e989db1b165cfce920538cf18baa8a6e88b06caae6690f988
7
+ data.tar.gz: 1d05bcc3498f847f4978c025a7d3c766b4bdcf056ae2a74fe256fb3010563452f955471e4cd9f978d8d9985b976ac72628a1aeefd045c1daa6af565084eef0dd
@@ -0,0 +1,7 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ test/dummy/db/*.sqlite3
5
+ test/dummy/log/*.log
6
+ test/dummy/tmp/
7
+ *.swp
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) {{year}} {{fullname}}
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ 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, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,27 @@
1
+ = ActionTexter
2
+
3
+ Allows you to build text messages similar to ActionMailer
4
+
5
+ == Installation
6
+
7
+ In your Gemfile add:
8
+
9
+ gem 'action_texter'
10
+
11
+ Install your gems:
12
+
13
+ bundle install
14
+
15
+ That's it!
16
+
17
+ == Configuration
18
+
19
+ In your environments/[RAILS_ENV].rb file, add:
20
+
21
+ config.action_texter.delivery_method = :file
22
+ config.action_texter.file_settings = {}
23
+
24
+ == Contributing
25
+
26
+ If you'd like to contribute to this project, please fork and send me a pull
27
+ request.
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../lib/action_texter/version', __FILE__)
2
+ Gem::Specification.new do |s|
3
+ s.name = "actiontexter"
4
+ s.version = ActionTexter::VERSION::STRING
5
+ s.description = 'Allows you to build text messages similar to ActionMailer'
6
+ s.summary = 'Allows you to build text messages similar to ActionMailer'
7
+ s.add_dependency "activesupport", ">= 3.0.0"
8
+
9
+ s.author = "Jeff Ching"
10
+ s.email = "jeff@chingr.com"
11
+ s.homepage = "http://github.com/chingor13/action_texter"
12
+ s.extra_rdoc_files = ['README.rdoc']
13
+ s.has_rdoc = true
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = Dir.glob('test/*_test.rb')
17
+ end
18
+
@@ -0,0 +1,22 @@
1
+ actionpack_path = File.expand_path('../../../actionpack/lib', __FILE__)
2
+ $:.unshift(actionpack_path) if File.directory?(actionpack_path) && !$:.include?(actionpack_path)
3
+
4
+ require 'abstract_controller'
5
+ require 'action_view'
6
+ require 'action_texter/version'
7
+
8
+ module ActionTexter
9
+ extend ::ActiveSupport::Autoload
10
+
11
+ autoload :Base
12
+ autoload :Message
13
+ autoload :DeliveryMethods
14
+ autoload :FileDelivery
15
+ autoload :TestDelivery
16
+ autoload :TwilioDelivery
17
+ autoload :WhitelistProxyDelivery
18
+ end
19
+
20
+ if defined?(Rails)
21
+ require 'action_texter/railtie'
22
+ end
@@ -0,0 +1,115 @@
1
+ module ActionTexter
2
+ class Base < AbstractController::Base
3
+ include DeliveryMethods
4
+ abstract!
5
+
6
+ include AbstractController::Logger
7
+ include AbstractController::Rendering
8
+ include AbstractController::Layouts
9
+ include AbstractController::Helpers
10
+ include AbstractController::Translation
11
+ include AbstractController::AssetPaths
12
+
13
+ self.protected_instance_variables = %w(@_action_has_layout)
14
+
15
+ class_attribute :default_params
16
+ self.default_params = {}.freeze
17
+
18
+ class << self
19
+ # Register one or more Observers which will be notified when mail is delivered.
20
+ def register_observers(*observers)
21
+ observers.flatten.compact.each { |observer| register_observer(observer) }
22
+ end
23
+
24
+ # Register one or more Interceptors which will be called before mail is sent.
25
+ def register_interceptors(*interceptors)
26
+ interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
27
+ end
28
+
29
+ # Register an Observer which will be notified when mail is delivered.
30
+ # Either a class or a string can be passed in as the Observer. If a string is passed in
31
+ # it will be <tt>constantize</tt>d.
32
+ def register_observer(observer)
33
+ delivery_observer = (observer.is_a?(String) ? observer.constantize : observer)
34
+ Mail.register_observer(delivery_observer)
35
+ end
36
+
37
+ # Register an Interceptor which will be called before mail is sent.
38
+ # Either a class or a string can be passed in as the Interceptor. If a string is passed in
39
+ # it will be <tt>constantize</tt>d.
40
+ def register_interceptor(interceptor)
41
+ delivery_interceptor = (interceptor.is_a?(String) ? interceptor.constantize : interceptor)
42
+ Mail.register_interceptor(delivery_interceptor)
43
+ end
44
+
45
+ def texter_name
46
+ @texter_name ||= name.underscore
47
+ end
48
+ attr_writer :texter_name
49
+ alias :controller_path :texter_name
50
+
51
+ def default(value = nil)
52
+ self.default_params = default_params.merge(value).freeze if value
53
+ default_params
54
+ end
55
+
56
+ def respond_to?(method, include_private = false)
57
+ super || action_methods.include?(method.to_s)
58
+ end
59
+
60
+ protected
61
+
62
+ def method_missing(method, *args)
63
+ return super unless respond_to?(method)
64
+ new(method, *args).message
65
+ end
66
+ end
67
+
68
+ attr_internal :message
69
+
70
+ def initialize(method_name = nil, *args)
71
+ super()
72
+ @_message = Message.new
73
+ process(method_name, *args) if method_name
74
+ end
75
+
76
+ def process(*args)
77
+ lookup_context.skip_default_locale!
78
+ super
79
+ end
80
+
81
+ def texter_name
82
+ self.class.texter_name
83
+ end
84
+
85
+ def text(headers={}, &block)
86
+ m = @_message
87
+
88
+ wrap_delivery_behavior!(headers.delete(:delivery_method))
89
+
90
+ # Call all the procs (if any)
91
+ default_values = self.class.default.merge(self.class.default) do |k,v|
92
+ v.respond_to?(:call) ? v.bind(self).call : v
93
+ end
94
+ headers = headers.reverse_merge(default_values)
95
+ headers.each do |k, v|
96
+ m[k] = v
97
+ end
98
+
99
+ templates_path = self.class.texter_name
100
+ templates_name = action_name
101
+
102
+ each_template(templates_path, templates_name) do |template|
103
+ m.body ||= render(:template => template)
104
+ end
105
+ m
106
+ end
107
+
108
+ def each_template(paths, name, &block)
109
+ templates = lookup_context.find_all(name, Array.wrap(paths))
110
+ templates.uniq { |t| t.formats }.each(&block)
111
+ end
112
+
113
+ ActiveSupport.run_load_hooks(:action_texter, self)
114
+ end
115
+ end
@@ -0,0 +1,74 @@
1
+ require 'tmpdir'
2
+
3
+ module ActionTexter
4
+ # This module handles everything related to mail delivery, from registering new
5
+ # delivery methods to configuring the mail object to be sent.
6
+ module DeliveryMethods
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ class_attribute :delivery_methods, :delivery_method
11
+
12
+ # Do not make this inheritable, because we always want it to propagate
13
+ cattr_accessor :raise_delivery_errors
14
+ self.raise_delivery_errors = true
15
+
16
+ cattr_accessor :perform_deliveries
17
+ self.perform_deliveries = true
18
+
19
+ self.delivery_methods = {}.freeze
20
+ self.delivery_method = :file
21
+
22
+ add_delivery_method :file, ActionTexter::FileDelivery,
23
+ :location => defined?(Rails.root) ? "#{Rails.root}/tmp/texts" : "#{Dir.tmpdir}/texts"
24
+ add_delivery_method :test, ActionTexter::TestDelivery
25
+ add_delivery_method :twilio, ActionTexter::TwilioDelivery
26
+ add_delivery_method :whitelist_proxy, ActionTexter::WhitelistProxyDelivery
27
+ end
28
+
29
+ module ClassMethods
30
+ # Provides a list of SMS messages that have been delivered by ActionTexter::TestDelivery
31
+ delegate :deliveries, :deliveries=, :to => ActionTexter::TestDelivery
32
+
33
+ # Adds a new delivery method through the given class using the given symbol
34
+ # as alias and the default options supplied:
35
+ #
36
+ # Example:
37
+ #
38
+ # add_delivery_method :sendmail, Mail::Sendmail,
39
+ # :location => '/usr/sbin/sendmail',
40
+ # :arguments => '-i -t'
41
+ #
42
+ def add_delivery_method(symbol, klass, default_options={})
43
+ class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
44
+ send(:"#{symbol}_settings=", default_options)
45
+ self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
46
+ end
47
+
48
+ def wrap_delivery_behavior(message, method=nil) #:nodoc:
49
+ method ||= self.delivery_method
50
+ message.delivery_handler = self
51
+
52
+ case method
53
+ when NilClass
54
+ raise "Delivery method cannot be nil"
55
+ when Symbol
56
+ if klass = delivery_methods[method.to_sym]
57
+ message.delivery_method(klass, send(:"#{method}_settings"))
58
+ else
59
+ raise "Invalid delivery method #{method.inspect}"
60
+ end
61
+ else
62
+ message.delivery_method(method)
63
+ end
64
+
65
+ message.perform_deliveries = perform_deliveries
66
+ message.raise_delivery_errors = raise_delivery_errors
67
+ end
68
+ end
69
+
70
+ def wrap_delivery_behavior!(*args) #:nodoc:
71
+ self.class.wrap_delivery_behavior(@_message, *args)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,19 @@
1
+ module ActionTexter
2
+ class FileDelivery
3
+ attr_reader :location
4
+ def initialize(config = {})
5
+ @location = config[:location]
6
+ raise ArgumentError, "you must specify config.action_texter.file_settings to contain a :location" unless @location
7
+ Dir.mkdir(@location) unless Dir.exists?(@location)
8
+ end
9
+
10
+ def deliver(message)
11
+ File.open(File.join(location, "#{message.to}.txt"), "a") do |file|
12
+ file.puts("FROM: #{message.from}")
13
+ file.puts(message.body)
14
+ file.puts("-"*40)
15
+ end
16
+ true
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ module ActionTexter
2
+ class Message
3
+ attr_accessor :to, :from, :body
4
+
5
+ attr_accessor :delivery_handler, :perform_deliveries, :raise_delivery_errors
6
+ attr_reader :delivery_method, :delivery_options
7
+
8
+ def initialize(attrs = {})
9
+ attrs.each do |k, v|
10
+ self.send("#{k}=", v) if self.respond_to?("#{k}=")
11
+ end
12
+ end
13
+
14
+ def []=(k, v)
15
+ self.send("#{k}=", v) if self.respond_to?("#{k}=")
16
+ end
17
+
18
+ def [](k)
19
+ self.send(k) if self.respond_to?(k)
20
+ end
21
+
22
+ def deliver
23
+ return false unless perform_deliveries
24
+ begin
25
+ @delivery_method.deliver(self)
26
+ rescue => e
27
+ raise e if raise_delivery_errors
28
+ end
29
+ end
30
+
31
+ def delivery_method(method = nil, opts = {})
32
+ unless method
33
+ @delivery_method
34
+ else
35
+ @delivery_method = method.new(opts)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,45 @@
1
+ require "action_texter"
2
+ require "rails"
3
+ require "abstract_controller/railties/routes_helpers"
4
+
5
+ module ActionTexter
6
+ class Railtie < Rails::Railtie
7
+ config.action_texter = ActiveSupport::OrderedOptions.new
8
+
9
+ initializer "action_texter.logger" do
10
+ ActiveSupport.on_load(:action_texter) { self.logger ||= Rails.logger }
11
+ end
12
+
13
+ initializer "action_texter.set_configs" do |app|
14
+ paths = app.config.paths
15
+ options = app.config.action_texter
16
+
17
+ options.assets_dir ||= paths["public"].first
18
+ options.javascripts_dir ||= paths["public/javascripts"].first
19
+ options.stylesheets_dir ||= paths["public/stylesheets"].first
20
+
21
+ # make sure readers methods get compiled
22
+ #options.asset_path ||= app.config.asset_path
23
+ options.asset_host ||= app.config.asset_host
24
+ options.relative_url_root ||= app.config.relative_url_root
25
+
26
+ ActiveSupport.on_load(:action_texter) do
27
+ include AbstractController::UrlFor
28
+ extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
29
+ include app.routes.mounted_helpers
30
+
31
+ register_interceptors(options.delete(:interceptors))
32
+ register_observers(options.delete(:observers))
33
+
34
+ options.each { |k,v| send("#{k}=", v) }
35
+ prepend_view_path(Rails.configuration.paths["app/views"])
36
+ end
37
+ end
38
+
39
+ initializer "action_texter.compile_config_methods" do
40
+ ActiveSupport.on_load(:action_texter) do
41
+ config.compile_methods! if config.respond_to?(:compile_methods!)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,14 @@
1
+ module ActionTexter
2
+ class TestDelivery
3
+ cattr_accessor :deliveries
4
+ self.deliveries = []
5
+
6
+ def initialize(config = {})
7
+ end
8
+
9
+ def deliver(message)
10
+ self.class.deliveries << message
11
+ true
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ module ActionTexter
2
+ class TwilioDelivery
3
+ attr_reader :client
4
+
5
+ def initialize(config = {})
6
+ @sid = config[:sid]
7
+ @token = config[:token]
8
+ @subaccount = config[:subaccount]
9
+ raise ArgumentError, "you must specify config.action_texter.twilio_settings to contain a :sid" unless @sid
10
+ raise ArgumentError, "you must specify config.action_texter.twilio_settings to contain a :token" unless @token
11
+ @client = Twilio::REST::Client.new(@sid, @token)
12
+ @client = client.accounts.find(@subaccount) if @subaccount
13
+ end
14
+
15
+ def deliver(message)
16
+ client.sms.messages.create(
17
+ :from => message.from,
18
+ :to => message.to,
19
+ :body => message.body.strip
20
+ )
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ module ActionTexter
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ TINY = 0
6
+ PRE = nil
7
+
8
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ module ActionTexter
2
+ class WhitelistProxyDelivery
3
+ class BlockedDelivery < StandardError; end
4
+ attr_reader :delivery_method, :whitelist
5
+
6
+ def initialize(config = {})
7
+ @delivery_method = config[:delivery_method]
8
+ @whitelist = config[:whitelist]
9
+ raise ArgumentError, "you must specify config.action_texter.whitelist_proxy_settings to contain a :delivery_method" unless @delivery_method
10
+ raise ArgumentError, "you must specify config.action_texter.whitelist_proxy_settings to contain a :whitelist" unless @whitelist
11
+ end
12
+
13
+ def deliver(message)
14
+ raise BlockedDelivery if blocked?(message.to)
15
+
16
+ real_delivery_method.deliver(message)
17
+ end
18
+
19
+ protected
20
+
21
+ def blocked?(to)
22
+ !whitelist.include?(to.to_s)
23
+ end
24
+
25
+ def real_delivery_method
26
+ @real_delivery_method ||= begin
27
+ settings = ActionTexter::Base.send(:"#{self.delivery_method}_settings")
28
+ ActionTexter::Base.delivery_methods[self.delivery_method].new(settings)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1 @@
1
+ require 'action_texter'
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: actiontexter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeff Ching
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
27
+ description: Allows you to build text messages similar to ActionMailer
28
+ email: jeff@chingr.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ files:
34
+ - .gitignore
35
+ - LICENSE
36
+ - README.rdoc
37
+ - actiontexter.gemspec
38
+ - lib/action_texter.rb
39
+ - lib/action_texter/base.rb
40
+ - lib/action_texter/delivery_methods.rb
41
+ - lib/action_texter/file_delivery.rb
42
+ - lib/action_texter/message.rb
43
+ - lib/action_texter/railtie.rb
44
+ - lib/action_texter/test_delivery.rb
45
+ - lib/action_texter/twilio_delivery.rb
46
+ - lib/action_texter/version.rb
47
+ - lib/action_texter/whitelist_proxy_delivery.rb
48
+ - lib/actiontexter.rb
49
+ homepage: http://github.com/chingor13/action_texter
50
+ licenses: []
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.0.3
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Allows you to build text messages similar to ActionMailer
72
+ test_files: []