soryo 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+ gem 'mercenary'
3
+ gem 'premailer'
4
+ gem 'liquid'
5
+ gem 'mail'
6
+ gem 'launchy'
7
+
8
+ group :test do
9
+ gem 'rspec'
10
+ end
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
@@ -0,0 +1,11 @@
1
+ require 'premailer'
2
+
3
+ module Soryo
4
+ class PremailerPlugin < Soryo::Plugin
5
+
6
+ def run(email)
7
+ Premailer.new(email, :with_html_string => true)
8
+ end
9
+
10
+ end
11
+ end
@@ -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