cloudfuji 0.0.37
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.
- data/.gitignore +7 -0
- data/.rspec +4 -0
- data/Gemfile +17 -0
- data/README.md +3 -0
- data/Rakefile +36 -0
- data/app/controllers/cloudfuji/data_controller.rb +33 -0
- data/app/controllers/cloudfuji/envs_controller.rb +31 -0
- data/app/controllers/cloudfuji/mail_controller.rb +37 -0
- data/bin/cloudfuji +86 -0
- data/cloudfuji.gemspec +26 -0
- data/config/routes.rb +1 -0
- data/lib/cloudfuji.rb +53 -0
- data/lib/cloudfuji/action_mailer.rb +35 -0
- data/lib/cloudfuji/app.rb +202 -0
- data/lib/cloudfuji/bar.rb +19 -0
- data/lib/cloudfuji/base.rb +23 -0
- data/lib/cloudfuji/command.rb +110 -0
- data/lib/cloudfuji/config.rb +12 -0
- data/lib/cloudfuji/data.rb +52 -0
- data/lib/cloudfuji/data_helper.rb +1 -0
- data/lib/cloudfuji/dns.rb +195 -0
- data/lib/cloudfuji/engine.rb +21 -0
- data/lib/cloudfuji/envs.rb +6 -0
- data/lib/cloudfuji/envs_helper.rb +1 -0
- data/lib/cloudfuji/event.rb +63 -0
- data/lib/cloudfuji/event_observer.rb +20 -0
- data/lib/cloudfuji/mail_helper.rb +1 -0
- data/lib/cloudfuji/mail_route.rb +186 -0
- data/lib/cloudfuji/middleware.rb +42 -0
- data/lib/cloudfuji/models.rb +59 -0
- data/lib/cloudfuji/notification.rb +0 -0
- data/lib/cloudfuji/orm/active_record.rb +44 -0
- data/lib/cloudfuji/orm/mongoid.rb +31 -0
- data/lib/cloudfuji/platform.rb +47 -0
- data/lib/cloudfuji/schema.rb +42 -0
- data/lib/cloudfuji/smtp.rb +24 -0
- data/lib/cloudfuji/user.rb +59 -0
- data/lib/cloudfuji/user_helper.rb +7 -0
- data/lib/cloudfuji/utils.rb +53 -0
- data/lib/cloudfuji/version.rb +4 -0
- data/lib/generators/active_record/cloudfuji_generator.rb +28 -0
- data/lib/generators/active_record/templates/migration.rb +20 -0
- data/lib/generators/cloudfuji/auth_migration_generator.rb +46 -0
- data/lib/generators/cloudfuji/cloudfuji_generator.rb +14 -0
- data/lib/generators/cloudfuji/hooks_generator.rb +43 -0
- data/lib/generators/cloudfuji/install_generator.rb +24 -0
- data/lib/generators/cloudfuji/mail_routes_generator.rb +45 -0
- data/lib/generators/cloudfuji/orm_helpers.rb +21 -0
- data/lib/generators/cloudfuji/routes_generator.rb +22 -0
- data/lib/generators/mongoid/cloudfuji_generator.rb +17 -0
- data/lib/generators/templates/README +5 -0
- data/lib/generators/templates/cloudfuji.rb +10 -0
- data/lib/hooks.rb +36 -0
- data/lib/rails/routes.rb +42 -0
- data/lib/tasks/cloudfuji.rake +6 -0
- data/spec/app_spec/controllers/envs_controller_spec.rb +25 -0
- data/spec/app_spec/controllers/mail_controller_spec.rb +28 -0
- data/spec/app_spec/integration/app_claim_spec.rb +16 -0
- data/spec/gem_spec/base_spec.rb +24 -0
- data/spec/gem_spec/command_spec.rb +181 -0
- data/spec/gem_spec/config_spec.rb +9 -0
- data/spec/gem_spec/data_spec.rb +13 -0
- data/spec/gem_spec/hooks_spec.rb +5 -0
- data/spec/gem_spec/mail_route_spec.rb +168 -0
- data/spec/gem_spec/platform_spec.rb +9 -0
- data/spec/gem_spec/user_spec.rb +45 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/test_apps/rails-2.3/.gitignore +13 -0
- data/spec/test_apps/rails-2.3/Gemfile +13 -0
- data/spec/test_apps/rails-2.3/README +243 -0
- data/spec/test_apps/rails-2.3/Rakefile +10 -0
- data/spec/test_apps/rails-2.3/app/controllers/application_controller.rb +10 -0
- data/spec/test_apps/rails-2.3/app/helpers/application_helper.rb +3 -0
- data/spec/test_apps/rails-2.3/config/boot.rb +114 -0
- data/spec/test_apps/rails-2.3/config/environment.rb +41 -0
- data/spec/test_apps/rails-2.3/config/environments/development.rb +17 -0
- data/spec/test_apps/rails-2.3/config/environments/production.rb +28 -0
- data/spec/test_apps/rails-2.3/config/environments/test.rb +30 -0
- data/spec/test_apps/rails-2.3/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_apps/rails-2.3/config/initializers/cookie_verification_secret.rb +7 -0
- data/spec/test_apps/rails-2.3/config/initializers/inflections.rb +10 -0
- data/spec/test_apps/rails-2.3/config/initializers/mime_types.rb +5 -0
- data/spec/test_apps/rails-2.3/config/initializers/new_rails_defaults.rb +21 -0
- data/spec/test_apps/rails-2.3/config/initializers/session_store.rb +15 -0
- data/spec/test_apps/rails-2.3/config/locales/en.yml +5 -0
- data/spec/test_apps/rails-2.3/config/routes.rb +43 -0
- data/spec/test_apps/rails-2.3/db/seeds.rb +7 -0
- data/spec/test_apps/rails-2.3/doc/README_FOR_APP +2 -0
- data/spec/test_apps/rails-2.3/lib/tasks/rspec.rake +144 -0
- data/spec/test_apps/rails-2.3/public/404.html +30 -0
- data/spec/test_apps/rails-2.3/public/422.html +30 -0
- data/spec/test_apps/rails-2.3/public/500.html +30 -0
- data/spec/test_apps/rails-2.3/public/favicon.ico +0 -0
- data/spec/test_apps/rails-2.3/public/images/rails.png +0 -0
- data/spec/test_apps/rails-2.3/public/javascripts/application.js +2 -0
- data/spec/test_apps/rails-2.3/public/javascripts/controls.js +963 -0
- data/spec/test_apps/rails-2.3/public/javascripts/dragdrop.js +973 -0
- data/spec/test_apps/rails-2.3/public/javascripts/effects.js +1128 -0
- data/spec/test_apps/rails-2.3/public/javascripts/prototype.js +4320 -0
- data/spec/test_apps/rails-2.3/public/robots.txt +5 -0
- data/spec/test_apps/rails-2.3/script/about +4 -0
- data/spec/test_apps/rails-2.3/script/autospec +6 -0
- data/spec/test_apps/rails-2.3/script/console +3 -0
- data/spec/test_apps/rails-2.3/script/dbconsole +3 -0
- data/spec/test_apps/rails-2.3/script/destroy +3 -0
- data/spec/test_apps/rails-2.3/script/generate +3 -0
- data/spec/test_apps/rails-2.3/script/performance/benchmarker +3 -0
- data/spec/test_apps/rails-2.3/script/performance/profiler +3 -0
- data/spec/test_apps/rails-2.3/script/plugin +3 -0
- data/spec/test_apps/rails-2.3/script/runner +3 -0
- data/spec/test_apps/rails-2.3/script/server +3 -0
- data/spec/test_apps/rails-2.3/script/spec +10 -0
- data/spec/test_apps/rails-2.3/spec/all_spec.rb +5 -0
- data/spec/test_apps/rails-2.3/spec/rcov.opts +2 -0
- data/spec/test_apps/rails-2.3/spec/spec.opts +4 -0
- data/spec/test_apps/rails-2.3/spec/spec_helper.rb +83 -0
- data/spec/test_apps/rails-2.3/test/performance/browsing_test.rb +9 -0
- data/spec/test_apps/rails-2.3/test/test_helper.rb +38 -0
- data/spec/test_apps/rails-3.0/.gitignore +4 -0
- data/spec/test_apps/rails-3.0/.rspec +2 -0
- data/spec/test_apps/rails-3.0/Gemfile +10 -0
- data/spec/test_apps/rails-3.0/README +256 -0
- data/spec/test_apps/rails-3.0/Rakefile +7 -0
- data/spec/test_apps/rails-3.0/app/controllers/application_controller.rb +3 -0
- data/spec/test_apps/rails-3.0/app/controllers/static_controller.rb +4 -0
- data/spec/test_apps/rails-3.0/app/helpers/application_helper.rb +2 -0
- data/spec/test_apps/rails-3.0/app/helpers/static_helper.rb +2 -0
- data/spec/test_apps/rails-3.0/app/views/layouts/application.html.erb +14 -0
- data/spec/test_apps/rails-3.0/app/views/static/home.html.erb +1 -0
- data/spec/test_apps/rails-3.0/config.ru +4 -0
- data/spec/test_apps/rails-3.0/config/application.rb +46 -0
- data/spec/test_apps/rails-3.0/config/boot.rb +6 -0
- data/spec/test_apps/rails-3.0/config/environment.rb +5 -0
- data/spec/test_apps/rails-3.0/config/environments/development.rb +26 -0
- data/spec/test_apps/rails-3.0/config/environments/production.rb +49 -0
- data/spec/test_apps/rails-3.0/config/environments/test.rb +35 -0
- data/spec/test_apps/rails-3.0/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_apps/rails-3.0/config/initializers/inflections.rb +10 -0
- data/spec/test_apps/rails-3.0/config/initializers/mime_types.rb +5 -0
- data/spec/test_apps/rails-3.0/config/initializers/secret_token.rb +7 -0
- data/spec/test_apps/rails-3.0/config/initializers/session_store.rb +8 -0
- data/spec/test_apps/rails-3.0/config/locales/en.yml +5 -0
- data/spec/test_apps/rails-3.0/config/routes.rb +62 -0
- data/spec/test_apps/rails-3.0/db/schema.rb +15 -0
- data/spec/test_apps/rails-3.0/db/seeds.rb +7 -0
- data/spec/test_apps/rails-3.0/doc/README_FOR_APP +2 -0
- data/spec/test_apps/rails-3.0/lib/tasks/.gitkeep +0 -0
- data/spec/test_apps/rails-3.0/public/404.html +26 -0
- data/spec/test_apps/rails-3.0/public/422.html +26 -0
- data/spec/test_apps/rails-3.0/public/500.html +26 -0
- data/spec/test_apps/rails-3.0/public/favicon.ico +0 -0
- data/spec/test_apps/rails-3.0/public/images/rails.png +0 -0
- data/spec/test_apps/rails-3.0/public/index.html +239 -0
- data/spec/test_apps/rails-3.0/public/javascripts/application.js +2 -0
- data/spec/test_apps/rails-3.0/public/javascripts/controls.js +965 -0
- data/spec/test_apps/rails-3.0/public/javascripts/dragdrop.js +974 -0
- data/spec/test_apps/rails-3.0/public/javascripts/effects.js +1123 -0
- data/spec/test_apps/rails-3.0/public/javascripts/prototype.js +6001 -0
- data/spec/test_apps/rails-3.0/public/javascripts/rails.js +191 -0
- data/spec/test_apps/rails-3.0/public/robots.txt +5 -0
- data/spec/test_apps/rails-3.0/public/stylesheets/.gitkeep +0 -0
- data/spec/test_apps/rails-3.0/script/rails +6 -0
- data/spec/test_apps/rails-3.0/spec/all_spec.rb +5 -0
- data/spec/test_apps/rails-3.0/spec/spec_helper.rb +78 -0
- data/spec/test_apps/rails-3.0/test/performance/browsing_test.rb +9 -0
- data/spec/test_apps/rails-3.0/test/test_helper.rb +13 -0
- data/spec/test_apps/rails-3.0/vendor/plugins/.gitkeep +0 -0
- data/tasks/cover_me.rake +11 -0
- data/test_app/spec/views/home.html.erb_spec.rb +15 -0
- metadata +261 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Automatically required by the envs_controller
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Cloudfuji
|
|
2
|
+
# Cloudfuji::Event lists all the events from the Cloudfuji server. All events
|
|
3
|
+
# are hashes with the following keys:
|
|
4
|
+
# * category
|
|
5
|
+
# * name
|
|
6
|
+
# * data
|
|
7
|
+
# Data will hold the arbitrary data for the type of event signalled
|
|
8
|
+
class Event
|
|
9
|
+
begin
|
|
10
|
+
@@events = JSON.parse(ENV["CLOUDFUJI_EVENTS"]) #:nodoc:
|
|
11
|
+
rescue
|
|
12
|
+
@@events = []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_reader :category, :name, :data
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
def events_url
|
|
19
|
+
"#{Cloudfuji::Platform.host}/apps/#{Cloudfuji::Platform.name}/events.json"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Lists all events
|
|
23
|
+
def all
|
|
24
|
+
@@events.collect{ |e| Event.new(e) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Lists the first (oldest) event
|
|
28
|
+
def first
|
|
29
|
+
Event.new(@@events.first)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Lists the last (newest) event
|
|
33
|
+
def last
|
|
34
|
+
Event.new(@@events.last)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# NOOP right now
|
|
38
|
+
def refresh
|
|
39
|
+
@@events = Cloudfuji::Command.get_command(events_url)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def publish(options={})
|
|
43
|
+
# Enforce standard format on client side so that any errors
|
|
44
|
+
# can be more quickly caught for the developer
|
|
45
|
+
return StandardError("Cloudfuji::Event format incorrect, please make sure you're using the correct structure for sending events") unless !options[:name].nil? && !options[:category].nil? && !options[:data].nil?
|
|
46
|
+
|
|
47
|
+
payload = {}
|
|
48
|
+
payload[:category] = options[:category]
|
|
49
|
+
payload[:name] = options[:name]
|
|
50
|
+
payload[:data] = options[:data]
|
|
51
|
+
|
|
52
|
+
Cloudfuji::Command.post_command(events_url, payload)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def initialize(options={})
|
|
57
|
+
@category = options["category"]
|
|
58
|
+
@name = options["name"]
|
|
59
|
+
@data = options["data"]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Cloudfuji
|
|
2
|
+
class EventObserver
|
|
3
|
+
attr_accessor :params
|
|
4
|
+
|
|
5
|
+
def self.inherited(klass)
|
|
6
|
+
if Cloudfuji::Platform.on_cloudfuji?
|
|
7
|
+
Cloudfuji::Data.add_observer(klass.new)
|
|
8
|
+
else
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@params ||= {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def params
|
|
17
|
+
@params
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Automatically required by the mail_controller
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
module Cloudfuji
|
|
2
|
+
class Mailroute
|
|
3
|
+
def self.map(&block)
|
|
4
|
+
raise StandardError.new("Mailroute only supported in Ruby >= 1.9.1") if RUBY_VERSION < "1.9.1"
|
|
5
|
+
|
|
6
|
+
@@routes ||= self.new
|
|
7
|
+
yield @@routes
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.routes
|
|
11
|
+
@@routes
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.clear_routes!
|
|
15
|
+
@@routes = self.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.pretty_print_routes
|
|
19
|
+
@@routes.routes.each_pair do |route_name, definition|
|
|
20
|
+
puts "#{route_name} => "
|
|
21
|
+
definition[:rules].each do |rule|
|
|
22
|
+
pretty_print_rule(rule, "\t\t")
|
|
23
|
+
end
|
|
24
|
+
definition[:constraints].each do |constraint|
|
|
25
|
+
pretty_print_contraint(constraint, "\t\t")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.pretty_print_rule(rule, prefix="")
|
|
31
|
+
output = "#{prefix}#{rule.first} => #{string_to_regex(rule[1]).inspect}, required? #{rule.last == true}"
|
|
32
|
+
puts output
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.pretty_print_contraint(constraint, prefix="")
|
|
36
|
+
output = "#{prefix}Constraint: #{constraint.inspect}"
|
|
37
|
+
puts output
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Taken from somewhere on stackoverflow, props to the author!
|
|
41
|
+
def self.string_to_regex(string)
|
|
42
|
+
return nil unless string.strip.match(/\A\/(.*)\/(.*)\Z/mx)
|
|
43
|
+
regexp , flags = $1 , $2
|
|
44
|
+
return nil if !regexp || flags =~ /[^xim]/m
|
|
45
|
+
|
|
46
|
+
x = /x/.match(flags) && Regexp::EXTENDED
|
|
47
|
+
i = /i/.match(flags) && Regexp::IGNORECASE
|
|
48
|
+
m = /m/.match(flags) && Regexp::MULTILINE
|
|
49
|
+
|
|
50
|
+
Regexp.new regexp , [x,i,m].inject(0){|a,f| f ? a+f : a }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.field_matcher(*field_names)
|
|
54
|
+
self.class_eval do
|
|
55
|
+
field_names.each do |field_name|
|
|
56
|
+
define_method field_name do |line, *args|
|
|
57
|
+
constraints = args.first || {}
|
|
58
|
+
required = args[1]
|
|
59
|
+
|
|
60
|
+
add_route_rule(field_name.to_s, build_matcher(line, constraints), required)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
attr_accessor :params, :constraints, :routes, :current_target, :reply
|
|
67
|
+
field_matcher :from, :sender, :subject, :body
|
|
68
|
+
|
|
69
|
+
# Regex shortcuts
|
|
70
|
+
def ampm
|
|
71
|
+
/\d+[apmAPM]{2}/
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def word
|
|
75
|
+
/\w+/
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def number
|
|
79
|
+
/\d+/
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def words_and_spaces
|
|
83
|
+
/[\w|\s]+/
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def month
|
|
87
|
+
/((?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Sept|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?))/
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def year
|
|
91
|
+
/((?:(?:[1]{1}\\d{1}\\d{1}\\d{1})|(?:[2]{1}\\d{3})))(?![\\d])/
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def initialize
|
|
95
|
+
@routes ||= ActiveSupport::OrderedHash.new
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def route(target, &block)
|
|
99
|
+
@routes[@current_target = target] = {:rules => [], :constraints => []}
|
|
100
|
+
yield self
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Maybe add_requirement is better?
|
|
104
|
+
# Constraint procs must return true if the mail should be allowed
|
|
105
|
+
def add_constraint(params_field_name, requirement_type)
|
|
106
|
+
checkers = {
|
|
107
|
+
:not_allowed => Proc.new { |params| params[params_field_name.to_s].nil? },
|
|
108
|
+
:required => Proc.new { |params| not params[params_field_name.to_s].nil? },
|
|
109
|
+
:custom => Proc.new { |params| requirement_type.call(params[params_field_name.to_s]) }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
checker = requirement_type.is_a?(Proc) ? checkers[:custom] : checkers[requirement_type]
|
|
113
|
+
|
|
114
|
+
raise StandardError if checker.nil?
|
|
115
|
+
|
|
116
|
+
@routes[@current_target][:constraints] << checker
|
|
117
|
+
@routes[@current_target][:constraints].flatten! # In case we've added a nil
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def process(mail)
|
|
121
|
+
@params = preprocess_mail(mail)
|
|
122
|
+
|
|
123
|
+
# Iterate through the routes and test each rule for each route against current mail
|
|
124
|
+
@routes.each_pair do |route_name, definition|
|
|
125
|
+
_matches = true
|
|
126
|
+
|
|
127
|
+
# route: {'name-of-route' => {:rules => [[:field, matcher]], :constraints => []}}
|
|
128
|
+
definition[:rules].each do |matcher|
|
|
129
|
+
result = self.class.string_to_regex(matcher[1]).match(mail[matcher.first])
|
|
130
|
+
if result.nil?
|
|
131
|
+
_matches = false
|
|
132
|
+
break
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Only Ruby 1.9 support named capture groups
|
|
136
|
+
result.names.each { |key| @params[key] = result[key] }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Run param-based constraints
|
|
140
|
+
if _matches and constraints_pass?(definition[:constraints], params)
|
|
141
|
+
@params['mail'] = mail
|
|
142
|
+
puts "Firing: #{@params.inspect}, #{route_name}"
|
|
143
|
+
return Cloudfuji::Data.fire(params, "mail_#{route_name.gsub('.', '_')}")
|
|
144
|
+
break
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
private
|
|
151
|
+
|
|
152
|
+
def preprocess_mail(mail)
|
|
153
|
+
params = {}
|
|
154
|
+
# Remove Re:'s from the subject and set reply => true if present
|
|
155
|
+
if mail["subject"].match(/^(Re: ){1,}/i)
|
|
156
|
+
params['reply'] = true
|
|
157
|
+
until !mail["subject"].match(/^(Re: ){1,}/i)
|
|
158
|
+
mail["subject"] = mail["subject"][4..-1]
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
if from_details = mail['from'].try(:match, /^([\w|\s]*) <(.*)>/)
|
|
163
|
+
params['from_name'] = from_details[1]
|
|
164
|
+
params['from_email'] = from_details[2]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
return params
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def add_route_rule(field, matcher, required=true)
|
|
171
|
+
route = @routes[@current_target]
|
|
172
|
+
route[route.keys.first] << [field, matcher, required]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def build_matcher(line, constraints)
|
|
176
|
+
temp = "/#{line}/"
|
|
177
|
+
constraints.keys.each { |key| temp.gsub!("{:#{key}}", "(?<#{key}>#{constraints[key].inspect[1..-2]})") }
|
|
178
|
+
temp
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def constraints_pass?(constraints, params)
|
|
182
|
+
constraints.nil? or constraints.select{ |proc| proc.call(params) != true }.empty?
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#require 'rack/utils'
|
|
2
|
+
|
|
3
|
+
module Cloudfuji
|
|
4
|
+
class Middleware
|
|
5
|
+
include Rack::Utils
|
|
6
|
+
|
|
7
|
+
def initialize(app, opts = {})
|
|
8
|
+
@app = app
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call(env)
|
|
12
|
+
if Cloudfuji::Platform.on_cloudfuji? and Cloudfuji::Bar.in_bar_display_path?(env)
|
|
13
|
+
status, headers, response = @app.call(env)
|
|
14
|
+
|
|
15
|
+
content = ""
|
|
16
|
+
response.each { |part| content += part }
|
|
17
|
+
|
|
18
|
+
# "claiming" bar + stats ?
|
|
19
|
+
content.gsub!(/<\/body>/i, <<-STR
|
|
20
|
+
<script type="text/javascript">
|
|
21
|
+
var _cloudfuji_app = '#{Cloudfuji::Platform.name}';
|
|
22
|
+
var _cloudfuji_claimed = #{Cloudfuji::Platform.claimed?.to_s};
|
|
23
|
+
var _cloudfuji_metrics_token = '#{Cloudfuji::Platform.metrics_token}';
|
|
24
|
+
(function() {
|
|
25
|
+
var cloudfuji = document.createElement('script'); cloudfuji.type = 'text/javascript'; cloudfuji.async = true;
|
|
26
|
+
cloudfuji.src = '#{Cloudfuji::Platform.cloudfuji_js_source}?t=#{::Cloudfuji::VERSION.gsub('.', '')}';
|
|
27
|
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(cloudfuji, s);
|
|
28
|
+
})();
|
|
29
|
+
</script>
|
|
30
|
+
</body>
|
|
31
|
+
STR
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
headers['content-length'] = bytesize(content).to_s
|
|
35
|
+
[status, headers, [content]]
|
|
36
|
+
else
|
|
37
|
+
@app.call(env)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Cloudfuji
|
|
2
|
+
module Models
|
|
3
|
+
def self.included(base)
|
|
4
|
+
base.extend ClassMethods
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def cloudfuji_save
|
|
8
|
+
# It's possible we're saving an item just handed to us by Cloudfuji, so we
|
|
9
|
+
# don't want to re-publish it. We can detect it using the version.
|
|
10
|
+
|
|
11
|
+
puts "what"
|
|
12
|
+
# cloudfuji_id.nil? This is new, it's from us (otherwise cloudfuji would have given it an id), we should publish it.
|
|
13
|
+
# cloudfuji_version == self.find(self.id).cloudfuji_version The version hasn't changed, our data has, we should publish it
|
|
14
|
+
puts "new_record? #{self.new_record?}"
|
|
15
|
+
puts "self.id = #{self.id}"
|
|
16
|
+
puts "ido_id.nil? #{ido_id.nil?}"
|
|
17
|
+
puts "ido_version == self.class.find(self.id).ido_version ? #{ido_version == self.class.find(self.id).ido_version}" unless self.new_record?
|
|
18
|
+
if self.ido_id.nil? or (not self.new_record? and self.ido_version == self.class.find(self.id).ido_version)
|
|
19
|
+
puts "Local change, publishing to Cloudfuji databus"
|
|
20
|
+
|
|
21
|
+
data = self.to_cloudfuji
|
|
22
|
+
|
|
23
|
+
begin
|
|
24
|
+
response = Cloudfuji::Data.publish(self.class.class_variable_get("@@ido_model"), data)
|
|
25
|
+
rescue => e
|
|
26
|
+
puts e.inspect
|
|
27
|
+
# TODO: Catch specific exceptions and bubble up errors (e.g. 'cloudfuji is down', 'model is malformed', etc.)
|
|
28
|
+
return false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
self.ido_version = response["ido_version"]
|
|
32
|
+
self.ido_id ||= response["ido_id"]
|
|
33
|
+
|
|
34
|
+
puts response.inspect
|
|
35
|
+
else
|
|
36
|
+
puts "Remote change, not publishing to Cloudfuji databus"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
return true
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module ClassMethods
|
|
43
|
+
def cloudfuji model
|
|
44
|
+
self.class_variable_set("@@ido_model", model)
|
|
45
|
+
|
|
46
|
+
[:create, :update, :destroy].each do |event|
|
|
47
|
+
puts "Hooking into #{model}.#{event}..."
|
|
48
|
+
|
|
49
|
+
Cloudfuji::Data.listen("#{model}.#{event}") do |data, hook|
|
|
50
|
+
puts "#{hook}.) Firing off #{model}.#{event} now with data: #{data}"
|
|
51
|
+
self.send("on_cloudfuji_#{event}".to_sym, self.from_cloudfuji(data))
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
before_save :cloudfuji_save
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'orm_adapter/adapters/active_record'
|
|
2
|
+
|
|
3
|
+
module Cloudfuji
|
|
4
|
+
module Orm
|
|
5
|
+
# This module contains some helpers and handle schema (migrations):
|
|
6
|
+
#
|
|
7
|
+
# create_table :accounts do |t|
|
|
8
|
+
# t.database_authenticatable
|
|
9
|
+
# t.confirmable
|
|
10
|
+
# t.recoverable
|
|
11
|
+
# t.rememberable
|
|
12
|
+
# t.trackable
|
|
13
|
+
# t.lockable
|
|
14
|
+
# t.timestamps
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# However this method does not add indexes. If you need them, here is the declaration:
|
|
18
|
+
#
|
|
19
|
+
# add_index "accounts", ["email"], :name => "email", :unique => true
|
|
20
|
+
# add_index "accounts", ["confirmation_token"], :name => "confirmation_token", :unique => true
|
|
21
|
+
# add_index "accounts", ["reset_password_token"], :name => "reset_password_token", :unique => true
|
|
22
|
+
#
|
|
23
|
+
module ActiveRecord
|
|
24
|
+
module Schema
|
|
25
|
+
include Cloudfuji::Schema
|
|
26
|
+
|
|
27
|
+
# Tell how to apply schema methods.
|
|
28
|
+
def apply_cloudfuji_schema(name, type, options={})
|
|
29
|
+
column name, type.to_s.downcase.to_sym, options
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
module ActiveRecord
|
|
37
|
+
class Base
|
|
38
|
+
include Cloudfuji::Models
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
ActiveRecord::ConnectionAdapters::Table.send :include, Cloudfuji::Orm::ActiveRecord::Schema
|
|
43
|
+
ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Cloudfuji::Orm::ActiveRecord::Schema
|
|
44
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'orm_adapter/adapters/mongoid'
|
|
2
|
+
|
|
3
|
+
module Cloudfuji
|
|
4
|
+
module Orm
|
|
5
|
+
module Mongoid
|
|
6
|
+
module Hook
|
|
7
|
+
def cloudfuji_modules_hook!
|
|
8
|
+
extend Schema
|
|
9
|
+
yield
|
|
10
|
+
return unless Devise.apply_schema
|
|
11
|
+
devise_modules.each { |m| send(m) if respond_to?(m, true) }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Schema
|
|
16
|
+
include Cloudfuji::Schema
|
|
17
|
+
|
|
18
|
+
# Tell how to apply schema methods
|
|
19
|
+
def apply_cloudfuji_schema(name, type, options={})
|
|
20
|
+
type = Time if type == DateTime
|
|
21
|
+
field name, { :type => type }.merge!(options)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Mongoid::Document::ClassMethods.class_eval do
|
|
29
|
+
include Cloudfuji::Models
|
|
30
|
+
include Cloudfuji::Orm::Mongoid::Hook
|
|
31
|
+
end
|