soryo 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/Gemfile +10 -0
- data/bin/soryo +18 -0
- data/lib/classes/config.rb +48 -0
- data/lib/classes/fileinstance.rb +60 -0
- data/lib/classes/plugin.rb +19 -0
- data/lib/classes/template.rb +25 -0
- data/lib/commands/buildcommand.rb +43 -0
- data/lib/commands/command.rb +43 -0
- data/lib/commands/sendcommand.rb +49 -0
- data/lib/commands/testcommand.rb +48 -0
- data/lib/plugins/premailer.rb +11 -0
- data/lib/senders/mail.rb +1 -0
- data/lib/soryo.rb +18 -0
- data/lib/testers/preview.rb +25 -0
- data/lib/testers/tester.rb +24 -0
- data/soryo.gemspec +28 -0
- data/test/command_spec.rb +31 -0
- data/test/config_spec.rb +47 -0
- data/test/fileinstance_spec.rb +80 -0
- data/test/files/file.file +0 -0
- data/test/files/json.json +4 -0
- data/test/files/yaml.yaml +2 -0
- data/test/template_spec.rb +19 -0
- data/test_files/advanced.json +12 -0
- data/test_files/advanced.liquid +4 -0
- data/test_files/basic.json +3 -0
- data/test_files/basic.liquid +1 -0
- data/test_files/email.html +963 -0
- data/test_files/email.json +15 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b242fd3f70f5af9854d288ec5435165ddae6bbc9
|
4
|
+
data.tar.gz: 3ffc2b1b3f12e33127d1835c45cf28eec7451499
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cbcade7f9542ad649a555f7bcadb84b975f761107bde5553160b1d26ac1f1e95323883e05bf844bec8d6db5e657c10caaf58779be6c0023007a103c197b1ecc9
|
7
|
+
data.tar.gz: 19d1c78db96a1170be6d601612c5364c2688f05730675730d089c4dc20f5db772bb11fc1b044fe00cb159aca5ca536c1e14250b20537350a37abf90d710d7c6a
|
data/.gitignore
ADDED
@@ -0,0 +1,35 @@
|
|
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
|
35
|
+
|
data/Gemfile
ADDED
data/bin/soryo
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
|
4
|
+
|
5
|
+
require 'mercenary'
|
6
|
+
require 'soryo'
|
7
|
+
|
8
|
+
Mercenary.program(:soryo) do |p|
|
9
|
+
p.version '0.1'
|
10
|
+
p.description 'This will be a program to generate emails Jekyll style'
|
11
|
+
p.syntax "soryo <subcommand> [options]"
|
12
|
+
|
13
|
+
Soryo::Command.descendants.each do |c|
|
14
|
+
c.add_command(p)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Soryo
|
4
|
+
DEFAULTS = {
|
5
|
+
# Output
|
6
|
+
'output_location' => Dir.pwd,
|
7
|
+
'output_name' => nil,
|
8
|
+
|
9
|
+
# Testing
|
10
|
+
'test_type' => 'preview',
|
11
|
+
'test_apikey' => nil,
|
12
|
+
'test_username' => nil,
|
13
|
+
'test_password' => nil,
|
14
|
+
|
15
|
+
# Sending
|
16
|
+
'mail_send' => 'local',
|
17
|
+
'mail_smtpserver' => nil,
|
18
|
+
'mail_username' => nil,
|
19
|
+
'mail_password' => nil,
|
20
|
+
'mail_fromaddress' => nil,
|
21
|
+
'mail_subject' => nil
|
22
|
+
}
|
23
|
+
|
24
|
+
class Config < Hash
|
25
|
+
def initialize
|
26
|
+
super()
|
27
|
+
merge_with(DEFAULTS)
|
28
|
+
end
|
29
|
+
|
30
|
+
def merge_with(config)
|
31
|
+
new_self = self.merge(config)
|
32
|
+
new_self.each do |k,v|
|
33
|
+
self[k] = v
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Takes in settings file path, merges yaml with settings
|
38
|
+
def read_yaml(settings)
|
39
|
+
settings_instance = Soryo::FileInstance.new(settings)
|
40
|
+
if settings_instance.existance?
|
41
|
+
self.merge_with(settings_instance.to_hash)
|
42
|
+
else
|
43
|
+
raise 'NoFileFound'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'yaml'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
module Soryo
|
6
|
+
class FileInstance
|
7
|
+
|
8
|
+
attr_reader :file_path
|
9
|
+
|
10
|
+
def initialize(file_path)
|
11
|
+
@file_path = Pathname.new(file_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
if self.existance?
|
16
|
+
file = File.open(@file_path, 'r')
|
17
|
+
file_text = file.read
|
18
|
+
file.close
|
19
|
+
file_text
|
20
|
+
else
|
21
|
+
raise 'NoFileFound'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def existance?
|
26
|
+
File.exists?(file_path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def write(file_contents)
|
30
|
+
file = File.open(@file_path, 'w')
|
31
|
+
file.write(file_contents)
|
32
|
+
file.close
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_hash
|
36
|
+
if self.existance?
|
37
|
+
if File.extname(@file_path) == '.json'
|
38
|
+
json_hash = JSON.parse(self.to_s)
|
39
|
+
elsif ['.yaml', '.yml'].include? File.extname(@file_path)
|
40
|
+
yaml_hash = YAML.load(self.to_s)
|
41
|
+
else
|
42
|
+
raise 'Must be a JSON or YAML file'
|
43
|
+
end
|
44
|
+
else
|
45
|
+
raise 'NoFileFound'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def _symbolize(obj)
|
50
|
+
return obj.inject({}){|memo,(k,v)| memo[k.to_sym] = _symbolize(v); memo} if obj.is_a? Hash
|
51
|
+
return obj.inject([]){|memo,v | memo << _symbolize(v); memo} if obj.is_a? Array
|
52
|
+
return obj
|
53
|
+
end
|
54
|
+
|
55
|
+
def shortname
|
56
|
+
File.basename(@file_path, '.*')
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Soryo
|
2
|
+
class Plugin
|
3
|
+
|
4
|
+
# Used for finding all necessary plugins
|
5
|
+
def self.descendants
|
6
|
+
descendants = []
|
7
|
+
ObjectSpace.each_object(singleton_class) do |k|
|
8
|
+
descendants.unshift k unless k == self
|
9
|
+
end
|
10
|
+
descendants
|
11
|
+
end
|
12
|
+
|
13
|
+
def run(contents)
|
14
|
+
abort_string = '#{self.class} does not have a run method'
|
15
|
+
abort(abort_string)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'liquid'
|
2
|
+
module Soryo
|
3
|
+
class Template
|
4
|
+
attr_reader :template, :hash
|
5
|
+
|
6
|
+
def initialize(template, hash)
|
7
|
+
@template = template
|
8
|
+
@hash = hash
|
9
|
+
end
|
10
|
+
|
11
|
+
def compile
|
12
|
+
compiled_template = Liquid::Template.parse(@template)
|
13
|
+
email = compiled_template.render(@hash)
|
14
|
+
run_plugins email
|
15
|
+
end
|
16
|
+
|
17
|
+
def run_plugins(email)
|
18
|
+
Soryo::Plugin.descendants.each do |c|
|
19
|
+
c.new.run(email)
|
20
|
+
end
|
21
|
+
email
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'mercenary'
|
2
|
+
module Soryo
|
3
|
+
class BuildCommand < Soryo::Command
|
4
|
+
|
5
|
+
def initialize(template, email, options)
|
6
|
+
super(options)
|
7
|
+
@template = Soryo::FileInstance.new template
|
8
|
+
@email = Soryo::FileInstance.new email
|
9
|
+
end
|
10
|
+
|
11
|
+
def build
|
12
|
+
template_builder = Soryo::Template.new(@template.to_s, @email.to_hash)
|
13
|
+
final_email = template_builder.compile
|
14
|
+
# Run the plugins
|
15
|
+
save final_email
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def save(email)
|
20
|
+
filename = @email.shortname + '.html'
|
21
|
+
final_email = Soryo::FileInstance.new(filename)
|
22
|
+
final_email.write(email)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.add_command(program)
|
26
|
+
program.command(:build) do |c|
|
27
|
+
c.syntax "build <template> <email> <json> [options]"
|
28
|
+
c.description "Build an email using a template"
|
29
|
+
|
30
|
+
c.action do |args, options|
|
31
|
+
if args.length != 2
|
32
|
+
abort('Please enter both a template and email')
|
33
|
+
end
|
34
|
+
command = Soryo::BuildCommand.new(args[0], args[1], options)
|
35
|
+
command.build
|
36
|
+
end
|
37
|
+
|
38
|
+
self.add_options(c)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Soryo
|
5
|
+
class Command
|
6
|
+
|
7
|
+
attr_reader :config
|
8
|
+
|
9
|
+
def self.descendants
|
10
|
+
descendants = []
|
11
|
+
ObjectSpace.each_object(singleton_class) do |k|
|
12
|
+
descendants.unshift k unless k == self
|
13
|
+
end
|
14
|
+
descendants
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(options)
|
18
|
+
@config = Soryo::Config.new
|
19
|
+
unless options.nil?
|
20
|
+
@config.merge_with(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
get_settings_file
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_settings_file
|
27
|
+
if @config[:settings_file]
|
28
|
+
@config.read_yaml(@config[:settings_file])
|
29
|
+
elsif Pathname.new('settings.yaml').exist?
|
30
|
+
@config.read_yaml('settings.yaml')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.add_options(c)
|
35
|
+
c.option 'config_file', '--config', 'choose a different config file'
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.add_command(program)
|
39
|
+
abort('Command.self.add_command should not be called on their own')
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'mercenary'
|
2
|
+
module Soryo
|
3
|
+
class SendCommand < Soryo::Command
|
4
|
+
|
5
|
+
def initialize(template, email, options, instructions)
|
6
|
+
super(options)
|
7
|
+
@template = Soryo::FileInstance.new template
|
8
|
+
@email = Soryo::FileInstance.new email
|
9
|
+
@instructions = Soryo::FileInstance.new instructions
|
10
|
+
end
|
11
|
+
|
12
|
+
def build
|
13
|
+
template_builder = Soryo::Template.new(@template.to_s, @email.to_hash)
|
14
|
+
final_email = template_builder.compile
|
15
|
+
# Run the plugins
|
16
|
+
send final_email
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def send(email)
|
21
|
+
Soryo::Sender.descendants.each do |c|
|
22
|
+
if c.sender_name == @config["send_type"]
|
23
|
+
sender = c.new
|
24
|
+
sender.run(email, @config)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.add_command(program)
|
30
|
+
program.command(:send) do |c|
|
31
|
+
c.syntax "send <template> <json> <email instructions> [options]"
|
32
|
+
c.description "Build an email using a template and send it to the world"
|
33
|
+
|
34
|
+
c.option "test_type", "--test_type", "choose the type of testing you want"
|
35
|
+
|
36
|
+
c.action do |args, options|
|
37
|
+
if args.length != 3
|
38
|
+
abort('Please enter a template, email, and instructions')
|
39
|
+
end
|
40
|
+
command = Soryo::SendCommand.new(args[0], args[1], options, args[2])
|
41
|
+
command.build
|
42
|
+
end
|
43
|
+
|
44
|
+
self.add_options(c)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'mercenary'
|
2
|
+
module Soryo
|
3
|
+
class TestCommand < Soryo::Command
|
4
|
+
|
5
|
+
def initialize(template, email, options)
|
6
|
+
super(options)
|
7
|
+
@template = Soryo::FileInstance.new template
|
8
|
+
@email = Soryo::FileInstance.new email
|
9
|
+
end
|
10
|
+
|
11
|
+
def build
|
12
|
+
template_builder = Soryo::Template.new(@template.to_s, @email.to_hash)
|
13
|
+
final_email = template_builder.compile
|
14
|
+
# Run the plugins
|
15
|
+
test final_email
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def test(email)
|
20
|
+
Soryo::Tester.descendants.each do |c|
|
21
|
+
if c.tester_name == @config["test_type"]
|
22
|
+
tester = c.new
|
23
|
+
tester.run(email, @config)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.add_command(program)
|
29
|
+
program.command(:test) do |c|
|
30
|
+
c.syntax "test <template> <json> [options]"
|
31
|
+
c.description "Build an email using a template"
|
32
|
+
|
33
|
+
c.option "test_type", "--test_type", "choose the type of testing you want"
|
34
|
+
|
35
|
+
c.action do |args, options|
|
36
|
+
if args.length != 2
|
37
|
+
abort('Please enter both a template and email')
|
38
|
+
end
|
39
|
+
command = Soryo::TestCommand.new(args[0], args[1], options)
|
40
|
+
command.build
|
41
|
+
end
|
42
|
+
|
43
|
+
self.add_options(c)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
data/lib/senders/mail.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/lib/soryo.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Soryo
|
2
|
+
require 'classes/fileinstance'
|
3
|
+
require 'classes/template'
|
4
|
+
require 'classes/config'
|
5
|
+
|
6
|
+
# Commands
|
7
|
+
require 'commands/command'
|
8
|
+
require 'commands/buildcommand'
|
9
|
+
require 'commands/testcommand'
|
10
|
+
|
11
|
+
# Plugins
|
12
|
+
require 'classes/plugin'
|
13
|
+
require 'plugins/premailer'
|
14
|
+
|
15
|
+
# Testers
|
16
|
+
require 'testers/tester'
|
17
|
+
require 'testers/preview'
|
18
|
+
end
|