ghost_in_the_post 0.0.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +24 -0
- data/lib/ghost_in_the_post.rb +47 -0
- data/lib/ghost_in_the_post/automatic.rb +19 -0
- data/lib/ghost_in_the_post/ghost_on_command.rb +10 -0
- data/lib/ghost_in_the_post/ghost_on_delivery.rb +12 -0
- data/lib/ghost_in_the_post/mail_ghost.rb +30 -0
- data/lib/ghost_in_the_post/mailer.rb +18 -0
- data/lib/ghost_in_the_post/phantom/staticize.js +27 -0
- data/lib/ghost_in_the_post/phantom_transform.rb +91 -0
- data/lib/ghost_in_the_post/version.rb +3 -0
- data/spec/dummy/Gemfile +3 -0
- data/spec/dummy/Gemfile.lock +115 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/javascripts/test.js +1 -0
- data/spec/dummy/app/mailers/auto_mailer.rb +13 -0
- data/spec/dummy/app/mailers/mailer.rb +13 -0
- data/spec/dummy/app/views/auto_mailer/normal_email.html.erb +13 -0
- data/spec/dummy/app/views/auto_mailer/normal_email.text +1 -0
- data/spec/dummy/app/views/mailer/normal_email.html.erb +12 -0
- data/spec/dummy/app/views/mailer/normal_email.text +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +13 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +11 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/ghost_in_the_post.rb +5 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/log/development.log +216 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/1hVihiFdBkDBsuCvA1I2vuFa9N6p-5zQ-qKvf4vz7jA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/23mzeUAO-pIzGJ1n84Dbg25udWeSiBcd6e_QsDihWQc.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6544SZAu2zCeDrdro4h3izdKNXVvHzstwz12UxeiJoA.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/BMI0IB92xLhvUPcr_K0JuSk8zczmrEEbJCd3qwHauhQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/GtqgDsC0JMsKfj0x5uQrbPcSS3QIPIzLKrq2fGJDBf0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/IFLV6zTaBXU1ccodbD3QJ4xUIOEix_Fbb7j8wsxrHw8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Lc8lcXR-AibSZCIbx_imdfIOmD-zbZ_pwSNMs0o0Dos.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/O9gjtBITAGlfzUwc2DT5N0GW2bo2b2yQ64gnQljLogM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/OQXwnC5z5STtd87Tr2dz1QBt4iZ8PoZTH8KBtBlUGnE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/OZ04c215C4Euu3scfhmxmte0o_tZOVWTqrv61cpy7H4.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_Bn81xMZj4dS_W5s9uSDhtEdpRZtsc21rcKEYAPCsZY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_Cw52w24AWZEbxLmduyWBMA6Y1OmJiEm1VNn7pY4rtk.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_HO5Nyj_TzTxVwa4OOf_0UJfBCmjgkv7NsRU29AD5Oo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/eN_ueL7m-D9xkEZpaLKwCxdrNzyz-MW9jcdJ5TdF9j8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/efKfhZKxLC7ERXlMb5CQMqYwbvWS-A--pH-0fqzvRiQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/goEv0RKoifagsjFSdEHY-23E9ybQn_t1HHEZq7PlKQI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/n6_6RjvPX2rCv5dytbSnnDrGwAj1ZcPfninuNUeP_iE.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/nXo-w2o4zQBM_uSUnniuP53t5erBbSZPecMED9YnzQI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oB1njyQ78MOMRf_5TvuYzHleeI8eke5-FDIIVl7qas0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qxbw0jMkxTNeM5T2QovOD9vTyvjHVjBN5tZdwBf519A.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y98HqYF9nxOk8t_j3BKv9Nc4LuSAEzhER7rCCvOM6xI.cache +1 -0
- data/spec/lib/ghost_in_the_post/automatic_spec.rb +42 -0
- data/spec/lib/ghost_in_the_post/ghost_on_command_spec.rb +26 -0
- data/spec/lib/ghost_in_the_post/mail_ghost_spec.rb +73 -0
- data/spec/lib/ghost_in_the_post/mailer_spec.rb +38 -0
- data/spec/lib/ghost_in_the_post/phantom_transform_spec.rb +134 -0
- data/spec/lib/ghost_in_the_post_spec.rb +60 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/mailer_support.rb +23 -0
- data/spec/support/quiet_load.rb +6 -0
- metadata +238 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: d5264602db0f4c3dff7764e85b40b297046a9a55
|
|
4
|
+
data.tar.gz: 289c490672985941a51227c4a9133ec1ba9e175c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c7b6aca158ff83c738d9cb85d01d7011d9cae5d8e47a8f5ed6650dc394086a216217ab2e7c557796fbe02583b0c6489d959caa90c00e3ff1376bc3c38aa20f75
|
|
7
|
+
data.tar.gz: 40ae64bdf2f34875db66564f55de75b23563ed87595fe10102fc894e78ea091abf67e0d0c9572106c65fc1e358a74f0be406d1a19bf9d44737eb481f1ddc9fb2
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2016 Tim Anema
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
5
|
+
end
|
|
6
|
+
require 'rdoc/task'
|
|
7
|
+
require "bundler/gem_tasks"
|
|
8
|
+
|
|
9
|
+
desc "Run specs"
|
|
10
|
+
task :spec do
|
|
11
|
+
sh "bundle exec rspec -f progress"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
15
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
16
|
+
rdoc.title = 'GhostInThePost'
|
|
17
|
+
rdoc.options << '--line-numbers'
|
|
18
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
19
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
Bundler::GemHelper.install_tasks
|
|
23
|
+
|
|
24
|
+
task :default => :spec
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'rails'
|
|
2
|
+
module GhostInThePost
|
|
3
|
+
ATTRIBUTE_NAMES = [
|
|
4
|
+
:phantomjs_path,
|
|
5
|
+
:includes,
|
|
6
|
+
:remove_js_tags,
|
|
7
|
+
]
|
|
8
|
+
private_constant :ATTRIBUTE_NAMES
|
|
9
|
+
cattr_reader(*ATTRIBUTE_NAMES)
|
|
10
|
+
|
|
11
|
+
@@phantomjs_path = nil #setting this to nil helps testing
|
|
12
|
+
@@includes = []
|
|
13
|
+
@@remove_js_tags = true
|
|
14
|
+
|
|
15
|
+
def self.config=(new_config={})
|
|
16
|
+
self.complain_about_unknown_keys(new_config.keys)
|
|
17
|
+
@@phantomjs_path = new_config[:phantomjs_path]
|
|
18
|
+
@@includes = Array(new_config[:includes])
|
|
19
|
+
@@remove_js_tags = new_config[:remove_js_tags].nil? ? true : new_config[:remove_js_tags]
|
|
20
|
+
raise ArgumentError, "GhostInThePost.config.phantomjs_path is not set" if self.phantomjs_path.nil?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.phantomjs_path
|
|
24
|
+
@@phantomjs_path or raise ArgumentError, "GhostInThePost.config.phantomjs_path is not set"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def self.complain_about_unknown_keys(keys)
|
|
30
|
+
invalid_keys = keys - ATTRIBUTE_NAMES
|
|
31
|
+
if invalid_keys.size > 0
|
|
32
|
+
raise ArgumentError, "Unknown configuration parameters: #{invalid_keys}", caller(1)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
require "ghost_in_the_post/version"
|
|
39
|
+
|
|
40
|
+
require "ghost_in_the_post/phantom_transform"
|
|
41
|
+
require "ghost_in_the_post/mail_ghost"
|
|
42
|
+
|
|
43
|
+
require "ghost_in_the_post/ghost_on_command"
|
|
44
|
+
require "ghost_in_the_post/ghost_on_delivery"
|
|
45
|
+
|
|
46
|
+
require "ghost_in_the_post/mailer"
|
|
47
|
+
require "ghost_in_the_post/automatic"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module GhostInThePost
|
|
2
|
+
module Automatic
|
|
3
|
+
attr_accessor :included_scripts
|
|
4
|
+
|
|
5
|
+
def include_script(*paths)
|
|
6
|
+
@included_scripts ||= []
|
|
7
|
+
@included_scripts += paths
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def mail(*args, &block)
|
|
11
|
+
super.tap do |email|
|
|
12
|
+
email.extend GhostOnCommand
|
|
13
|
+
email.extend GhostOnDelivery
|
|
14
|
+
email.included_scripts = @included_scripts
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module GhostInThePost
|
|
2
|
+
class MailGhost
|
|
3
|
+
attr_reader :email, :included_scripts
|
|
4
|
+
|
|
5
|
+
def initialize(email, included_scripts)
|
|
6
|
+
@email = email
|
|
7
|
+
@included_scripts = Array(included_scripts).compact
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def execute
|
|
11
|
+
improve_body if email.content_type =~ /^text\/html/
|
|
12
|
+
improve_html_part(email.html_part) if email.html_part
|
|
13
|
+
email
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def improve_body
|
|
19
|
+
email.body = ghost_html(email.body.decoded)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def improve_html_part(html_part)
|
|
23
|
+
html_part.body = ghost_html(html_part.body.decoded)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def ghost_html(old_html)
|
|
27
|
+
PhantomTransform.new(old_html, included_scripts).transform
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module GhostInThePost
|
|
2
|
+
module Mailer
|
|
3
|
+
attr_accessor :included_scripts
|
|
4
|
+
|
|
5
|
+
def include_script(*paths)
|
|
6
|
+
@included_scripts ||= []
|
|
7
|
+
@included_scripts += paths
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def mail(*args, &block)
|
|
11
|
+
super.tap do |email|
|
|
12
|
+
email.extend GhostOnCommand
|
|
13
|
+
email.included_scripts = included_scripts
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var system = require('system'),
|
|
3
|
+
page = require('webpage').create(),
|
|
4
|
+
html = system.args[1], //the email to be processed
|
|
5
|
+
no_script = system.args[2] == "true",
|
|
6
|
+
include = system.args[3]; //the injected js file
|
|
7
|
+
|
|
8
|
+
page.onLoadFinished = function(status) {
|
|
9
|
+
//load included scripts to be loaded on the dom
|
|
10
|
+
if(!!include){
|
|
11
|
+
page.injectJs(include);
|
|
12
|
+
}
|
|
13
|
+
if(no_script) {
|
|
14
|
+
page.evaluate(function(){
|
|
15
|
+
var script_tags = document.getElementsByTagName("script");
|
|
16
|
+
for(var i = 0; i < script_tags.length; i++) {
|
|
17
|
+
script_tags[i].parentNode.removeChild(script_tags[i]);
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
//write out to console to export contents
|
|
22
|
+
console.log(page.content);
|
|
23
|
+
phantom.exit(); //get out of here
|
|
24
|
+
};
|
|
25
|
+
//load html content
|
|
26
|
+
page.setContent(html, 'http://www.whatever.com');
|
|
27
|
+
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module GhostInThePost
|
|
2
|
+
class PhantomTransform
|
|
3
|
+
PHANTOMJS_SCRIPT = File.expand_path('../phantom/staticize.js', __FILE__)
|
|
4
|
+
|
|
5
|
+
def initialize(html, included_scripts=[])
|
|
6
|
+
@html = html
|
|
7
|
+
@included_scripts = Array(included_scripts).compact
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def transform
|
|
11
|
+
injectable_scripts.any? ? transform_with_injections : simple_transform
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def command
|
|
17
|
+
[
|
|
18
|
+
GhostInThePost.phantomjs_path,
|
|
19
|
+
PHANTOMJS_SCRIPT,
|
|
20
|
+
@html,
|
|
21
|
+
GhostInThePost.remove_js_tags
|
|
22
|
+
]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#there is scripts to inject so create a tmp file to put them all in
|
|
26
|
+
def transform_with_injections
|
|
27
|
+
#set output to just html so that if there is an error that is caught it will
|
|
28
|
+
#at least return valid html
|
|
29
|
+
output = @html
|
|
30
|
+
begin
|
|
31
|
+
#generate a tempfile with all the js that we need so that phantom can inject
|
|
32
|
+
#easily and not have to max out a single command
|
|
33
|
+
file = Tempfile.new(['inject', '.js'])
|
|
34
|
+
injectable_scripts.map do |script|
|
|
35
|
+
asset = find_asset_in_pipeline(script)
|
|
36
|
+
file.write(asset.to_s) unless asset.nil?
|
|
37
|
+
end.compact
|
|
38
|
+
file.close #closing the file makes it accessible by phantom
|
|
39
|
+
|
|
40
|
+
#generate the html with the javascript
|
|
41
|
+
output = IO.popen(command + [file.path]){|io| io.read}
|
|
42
|
+
|
|
43
|
+
file.unlink
|
|
44
|
+
rescue => e
|
|
45
|
+
#clean up the temp file
|
|
46
|
+
file.unlink
|
|
47
|
+
end
|
|
48
|
+
output
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#no scripts to inject so just run the command
|
|
52
|
+
def simple_transform
|
|
53
|
+
IO.popen(command){|io| io.read}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def injectable_scripts
|
|
57
|
+
@injectable_scripts ||= (GhostInThePost.includes + @included_scripts)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def find_asset_in_pipeline(name)
|
|
61
|
+
normalized_name = normalize_asset_name(name)
|
|
62
|
+
Rails.application.assets[normalized_name] || Rails.application.assets[remove_asset_digest(normalized_name)]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def normalize_asset_name(href)
|
|
66
|
+
remove_asset_prefix(href.split('?').first)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
DIGEST_PATTERN = /
|
|
70
|
+
- # Digest comes after a dash
|
|
71
|
+
(?:
|
|
72
|
+
[a-z0-9]{32} | # Old style is 32 character hash
|
|
73
|
+
[a-z0-9]{64} # New style is 64 characters
|
|
74
|
+
)
|
|
75
|
+
\. # Dot for the file extension
|
|
76
|
+
/x.freeze
|
|
77
|
+
|
|
78
|
+
def remove_asset_digest(path)
|
|
79
|
+
path.gsub(DIGEST_PATTERN, '.')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def remove_asset_prefix(path)
|
|
83
|
+
path.sub(Regexp.new("^#{Regexp.quote(asset_prefix)}/?"), "")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def asset_prefix
|
|
87
|
+
::Rails.application.try(:config).try(:assets).try(:prefix) || "/assets"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
end
|
data/spec/dummy/Gemfile
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: ../..
|
|
3
|
+
specs:
|
|
4
|
+
ghost_in_the_post (0.0.1)
|
|
5
|
+
rails (~> 4.2.3)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
actionmailer (4.2.3)
|
|
11
|
+
actionpack (= 4.2.3)
|
|
12
|
+
actionview (= 4.2.3)
|
|
13
|
+
activejob (= 4.2.3)
|
|
14
|
+
mail (~> 2.5, >= 2.5.4)
|
|
15
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
16
|
+
actionpack (4.2.3)
|
|
17
|
+
actionview (= 4.2.3)
|
|
18
|
+
activesupport (= 4.2.3)
|
|
19
|
+
rack (~> 1.6)
|
|
20
|
+
rack-test (~> 0.6.2)
|
|
21
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
22
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
23
|
+
actionview (4.2.3)
|
|
24
|
+
activesupport (= 4.2.3)
|
|
25
|
+
builder (~> 3.1)
|
|
26
|
+
erubis (~> 2.7.0)
|
|
27
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
28
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
29
|
+
activejob (4.2.3)
|
|
30
|
+
activesupport (= 4.2.3)
|
|
31
|
+
globalid (>= 0.3.0)
|
|
32
|
+
activemodel (4.2.3)
|
|
33
|
+
activesupport (= 4.2.3)
|
|
34
|
+
builder (~> 3.1)
|
|
35
|
+
activerecord (4.2.3)
|
|
36
|
+
activemodel (= 4.2.3)
|
|
37
|
+
activesupport (= 4.2.3)
|
|
38
|
+
arel (~> 6.0)
|
|
39
|
+
activesupport (4.2.3)
|
|
40
|
+
i18n (~> 0.7)
|
|
41
|
+
json (~> 1.7, >= 1.7.7)
|
|
42
|
+
minitest (~> 5.1)
|
|
43
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
|
44
|
+
tzinfo (~> 1.1)
|
|
45
|
+
arel (6.0.3)
|
|
46
|
+
builder (3.2.2)
|
|
47
|
+
concurrent-ruby (1.0.0)
|
|
48
|
+
concurrent-ruby (1.0.0-java)
|
|
49
|
+
erubis (2.7.0)
|
|
50
|
+
globalid (0.3.6)
|
|
51
|
+
activesupport (>= 4.1.0)
|
|
52
|
+
i18n (0.7.0)
|
|
53
|
+
json (1.8.3)
|
|
54
|
+
json (1.8.3-java)
|
|
55
|
+
loofah (2.0.3)
|
|
56
|
+
nokogiri (>= 1.5.9)
|
|
57
|
+
mail (2.6.3)
|
|
58
|
+
mime-types (>= 1.16, < 3)
|
|
59
|
+
mime-types (2.99)
|
|
60
|
+
mini_portile2 (2.0.0)
|
|
61
|
+
minitest (5.8.4)
|
|
62
|
+
nokogiri (1.6.7.2)
|
|
63
|
+
mini_portile2 (~> 2.0.0.rc2)
|
|
64
|
+
nokogiri (1.6.7.2-java)
|
|
65
|
+
rack (1.6.4)
|
|
66
|
+
rack-test (0.6.3)
|
|
67
|
+
rack (>= 1.0)
|
|
68
|
+
rails (4.2.3)
|
|
69
|
+
actionmailer (= 4.2.3)
|
|
70
|
+
actionpack (= 4.2.3)
|
|
71
|
+
actionview (= 4.2.3)
|
|
72
|
+
activejob (= 4.2.3)
|
|
73
|
+
activemodel (= 4.2.3)
|
|
74
|
+
activerecord (= 4.2.3)
|
|
75
|
+
activesupport (= 4.2.3)
|
|
76
|
+
bundler (>= 1.3.0, < 2.0)
|
|
77
|
+
railties (= 4.2.3)
|
|
78
|
+
sprockets-rails
|
|
79
|
+
rails-deprecated_sanitizer (1.0.3)
|
|
80
|
+
activesupport (>= 4.2.0.alpha)
|
|
81
|
+
rails-dom-testing (1.0.7)
|
|
82
|
+
activesupport (>= 4.2.0.beta, < 5.0)
|
|
83
|
+
nokogiri (~> 1.6.0)
|
|
84
|
+
rails-deprecated_sanitizer (>= 1.0.1)
|
|
85
|
+
rails-html-sanitizer (1.0.3)
|
|
86
|
+
loofah (~> 2.0)
|
|
87
|
+
railties (4.2.3)
|
|
88
|
+
actionpack (= 4.2.3)
|
|
89
|
+
activesupport (= 4.2.3)
|
|
90
|
+
rake (>= 0.8.7)
|
|
91
|
+
thor (>= 0.18.1, < 2.0)
|
|
92
|
+
rake (10.5.0)
|
|
93
|
+
sprockets (3.5.2)
|
|
94
|
+
concurrent-ruby (~> 1.0)
|
|
95
|
+
rack (> 1, < 3)
|
|
96
|
+
sprockets-rails (3.0.1)
|
|
97
|
+
actionpack (>= 4.0)
|
|
98
|
+
activesupport (>= 4.0)
|
|
99
|
+
sprockets (>= 3.0.0)
|
|
100
|
+
thor (0.19.1)
|
|
101
|
+
thread_safe (0.3.5)
|
|
102
|
+
thread_safe (0.3.5-java)
|
|
103
|
+
tzinfo (1.2.2)
|
|
104
|
+
thread_safe (~> 0.1)
|
|
105
|
+
|
|
106
|
+
PLATFORMS
|
|
107
|
+
java
|
|
108
|
+
ruby
|
|
109
|
+
|
|
110
|
+
DEPENDENCIES
|
|
111
|
+
ghost_in_the_post!
|
|
112
|
+
rails (= 4.2.3)
|
|
113
|
+
|
|
114
|
+
BUNDLED WITH
|
|
115
|
+
1.10.6
|