grass 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.sass-cache/e3d4c2039fc7a8446e752aad5ac08f85d7457f92/(__TEMPLATE__)c +0 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +10 -0
  9. data/bin/grass +89 -0
  10. data/config/grass.rb +27 -0
  11. data/db/migrate/1_create_grass_sources.rb +24 -0
  12. data/grass.gemspec +43 -0
  13. data/lib/grass.rb +68 -0
  14. data/lib/grass/cache.rb +52 -0
  15. data/lib/grass/core_ext/kernel.rb +8 -0
  16. data/lib/grass/endpoints/api.rb +70 -0
  17. data/lib/grass/endpoints/front.rb +122 -0
  18. data/lib/grass/file_sync.rb +70 -0
  19. data/lib/grass/goliath/rack/auth_barrier.rb +109 -0
  20. data/lib/grass/goliath/rack/cache.rb +37 -0
  21. data/lib/grass/goliath/rack/cors.rb +45 -0
  22. data/lib/grass/goliath/rack/secure_headers.rb +20 -0
  23. data/lib/grass/goliath/rack/validator.rb +52 -0
  24. data/lib/grass/helpers/i18n_helper.rb +91 -0
  25. data/lib/grass/helpers/render_helper.rb +35 -0
  26. data/lib/grass/key.rb +137 -0
  27. data/lib/grass/render.rb +27 -0
  28. data/lib/grass/render/layout.rb +11 -0
  29. data/lib/grass/render/page.rb +31 -0
  30. data/lib/grass/render/renderer.rb +35 -0
  31. data/lib/grass/render/script.rb +27 -0
  32. data/lib/grass/render/stylesheet.rb +13 -0
  33. data/lib/grass/render/text.rb +11 -0
  34. data/lib/grass/render/view.rb +34 -0
  35. data/lib/grass/render/yui_renderer.rb +27 -0
  36. data/lib/grass/source.rb +107 -0
  37. data/lib/grass/tasks/db.rake +67 -0
  38. data/lib/grass/version.rb +3 -0
  39. data/lib/templates/app/Gemfile +9 -0
  40. data/lib/templates/app/Procfile +3 -0
  41. data/lib/templates/app/Rakefile +7 -0
  42. data/lib/templates/app/app/assets/scripts/application.en.js.coffee +1 -0
  43. data/lib/templates/app/app/assets/stylesheets/application.en.css.scss +4 -0
  44. data/lib/templates/app/app/content/pages/about.en.html.erb +3 -0
  45. data/lib/templates/app/app/content/pages/index.en.md.erb +5 -0
  46. data/lib/templates/app/app/views/layouts/application.en.html.erb +14 -0
  47. data/lib/templates/app/app/views/pages/show.en.html.erb +4 -0
  48. data/lib/templates/app/app/views/shared.en.html.erb +9 -0
  49. data/lib/templates/app/config/cache.yml +20 -0
  50. data/lib/templates/app/config/database.yml +35 -0
  51. data/lib/templates/app/config/grass.rb +27 -0
  52. data/lib/templates/app/db/migrate/1_create_grass_sources.rb +24 -0
  53. data/lib/templates/app/haproxy.cfg +43 -0
  54. data/lib/templates/app/public/favicon.ico +0 -0
  55. data/lib/templates/app/public/robots.txt +2 -0
  56. data/lib/templates/app/server.rb +7 -0
  57. data/test/dummy/app/content/texts/testapi.en.txt +1 -0
  58. data/test/dummy/config/cache.yml +23 -0
  59. data/test/dummy/config/database.yml +35 -0
  60. data/test/dummy/config/dummy.rb +1 -0
  61. data/test/dummy/config/haproxy.cfg +37 -0
  62. data/test/dummy/public/favicon.ico +0 -0
  63. data/test/dummy/public/robots.txt +2 -0
  64. data/test/minitest_helper.rb +38 -0
  65. data/test/support/grass.rb +21 -0
  66. data/test/support/test.jpg +0 -0
  67. data/test/test_api.rb +74 -0
  68. data/test/test_front.rb +52 -0
  69. data/test/test_key.rb +118 -0
  70. data/test/test_source.rb +51 -0
  71. data/test/test_source_file.rb +47 -0
  72. data/test/test_source_render.rb +54 -0
  73. data/vendor/yuicompressor-2.4.8.jar +0 -0
  74. metadata +399 -0
@@ -0,0 +1,27 @@
1
+ require "yui/compressor"
2
+ require 'grass/render/renderer'
3
+ module Grass
4
+ module Render
5
+ module YuiRenderer
6
+
7
+ include Renderer
8
+
9
+ YUI_JAR_FILE = "#{Grass.gem_root}/vendor/yuicompressor-2.4.8.jar"
10
+ CSS = YUI::CssCompressor.new({jar_file: YUI_JAR_FILE})
11
+ JS = YUI::JavaScriptCompressor.new({jar_file: YUI_JAR_FILE, munge: true})
12
+
13
+ def render
14
+ compress(super)
15
+ end
16
+
17
+ def compress source
18
+ compressor.compress(source)
19
+ end
20
+
21
+ def compressor
22
+ raise NotImplementedError
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,107 @@
1
+ require 'active_record'
2
+ require 'grass/key'
3
+ require 'grass/file_sync'
4
+ require 'grass/render'
5
+ require 'grass/cache'
6
+ require 'mime/types'
7
+
8
+ module Grass
9
+
10
+
11
+ ##
12
+ # Source is smallest data object
13
+
14
+ class Source < ActiveRecord::Base
15
+
16
+ MIMES = {
17
+ 'text' => 'text/plain',
18
+ 'view' => 'text/html',
19
+ 'layout' => 'text/html',
20
+ 'page' => 'text/html',
21
+ 'script' => 'application/javascript',
22
+ 'stylesheet' => 'text/css'
23
+ }
24
+
25
+ cattr_accessor :fallback
26
+
27
+ self.fallback = true
28
+ self.primary_key = :keyid
29
+ self.table_name = :grass_sources
30
+
31
+ attr_accessor :key
32
+
33
+ after_initialize :convert_key
34
+
35
+ def self.[](*keys)
36
+ keys.flatten.map{|key|
37
+
38
+ key = Key.new(id: key.dup)
39
+
40
+ file = self.find_by(locale: key.locale, dir: key.dir, path: key.path)
41
+ if file.nil? && self.fallback
42
+ file = self.find_by(locale: I18n.default_locale, dir: key.dir, path: key.path)
43
+ end
44
+ file
45
+
46
+ }.compact
47
+ end
48
+
49
+ scope :locale, -> (locale) { unscoped.where(locale: locale.to_s) }
50
+ default_scope -> { where(hidden: false) }
51
+
52
+ include FileSync
53
+ include Render
54
+ include Cache
55
+
56
+ attr_reader :data
57
+
58
+ serialize :pairs, Array
59
+
60
+ after_initialize :set_mime_type
61
+ before_save :set_mime_type
62
+
63
+ def read
64
+ self.binary || self.result || self.raw
65
+ end
66
+
67
+ def write value
68
+ # self.file.write(value)
69
+ self.update(raw: value)
70
+ end
71
+
72
+ def type
73
+ @type ||= self.key.dir.split("/").last.singularize
74
+ end
75
+
76
+ def hide!
77
+ self.update!(hidden: true)
78
+ end
79
+
80
+ def show!
81
+ self.update!(hidden: false)
82
+ end
83
+
84
+ private
85
+
86
+ def set_mime_type
87
+ self.mime_type ||= MIMES[self.type] || MIME::Types.type_for(self.binary.nil? ? self.format : self.filepath).first.to_s
88
+ end
89
+
90
+ def convert_key
91
+ if self.key.nil?
92
+ self.key = self.filepath ? Key.new(filepath: self.filepath) : Key.new(id: self.keyid)
93
+ elsif self.key.is_a? String
94
+ self.key = Key.new(id: self.key)
95
+ end
96
+
97
+ Key::ATTR_TYPES.each do |attr|
98
+ unless attr == :id
99
+ write_attribute(attr,self.key.public_send(attr))
100
+ end
101
+ end
102
+ self.keyid = self.key.id
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,67 @@
1
+ require 'pg'
2
+ require 'erb'
3
+ require 'active_record'
4
+ require 'yaml'
5
+ require 'active_support/core_ext/hash'
6
+
7
+ namespace :db do
8
+
9
+ desc "erases and rewinds all dbs"
10
+ task :rewind do
11
+ %w(development test).each do |env|
12
+ ENV['RACK_ENV']=env
13
+ Rake::Task["db:drop"].reenable
14
+ Rake::Task["db:create"].reenable
15
+ Rake::Task["db:migrate"].reenable
16
+ Rake::Task["db:drop"].invoke
17
+ Rake::Task["db:create"].invoke
18
+ Rake::Task["db:migrate"].invoke
19
+ end
20
+ end
21
+
22
+ desc "loads database configuration in for other tasks to run"
23
+ task :load_config do
24
+
25
+ # ActiveRecord::Base.configurations = db_conf
26
+
27
+ # drop and create need to be performed with a connection to the 'postgres' (system) database
28
+ ActiveRecord::Base.establish_connection db_conf.merge('database' => 'postgres',
29
+ 'schema_search_path' => 'public')
30
+ end
31
+
32
+ desc "creates and migrates your database"
33
+ task :setup => :load_config do
34
+ Rake::Task["db:create"].invoke
35
+ Rake::Task["db:migrate"].invoke
36
+ end
37
+
38
+ desc "migrate your database"
39
+ task :migrate do
40
+ ActiveRecord::Base.establish_connection db_conf
41
+
42
+ ActiveRecord::Migrator.migrate(
43
+ ActiveRecord::Migrator.migrations_paths,
44
+ ENV["VERSION"] ? ENV["VERSION"].to_i : nil
45
+ )
46
+ end
47
+
48
+ desc 'Drops the database'
49
+ task :drop => :load_config do
50
+ ActiveRecord::Base.connection.drop_database db_conf['database']
51
+ end
52
+
53
+ desc 'Creates the database'
54
+ task :create => :load_config do
55
+ ActiveRecord::Base.connection.create_database db_conf['database']
56
+ end
57
+
58
+
59
+ def db_conf
60
+ config = YAML.load(ERB.new(File.read("config/database.yml")).result)[env]
61
+ end
62
+
63
+ def env
64
+ ENV['RACK_ENV'] ||= "development"
65
+ end
66
+
67
+ end
@@ -0,0 +1,3 @@
1
+ module Grass
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ ruby '2.0.0'
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'grass', path: '../../../grass'
6
+ gem 'rake'
7
+ group :development, :test do
8
+ gem 'foreman'
9
+ end
@@ -0,0 +1,3 @@
1
+ e_front: bundle exec ruby server.rb front -c ./config/grass.rb -p 4000 -e ${ENV:-development} -sv
2
+ e_api: bundle exec ruby server.rb api -c ./config/grass.rb -p 4001 -e ${ENV:-development} -sv
3
+ haproxy: haproxy -f ./haproxy.cfg
@@ -0,0 +1,7 @@
1
+ $LOAD_PATH.unshift File.expand_path('../', __FILE__)
2
+ load "grass/tasks/db.rake"
3
+ desc "pushes deployed file changes"
4
+ task :deploy do
5
+ system 'bundle exec grass push'
6
+ end
7
+ task :default => :deploy
@@ -0,0 +1 @@
1
+ console.log "hello from Grass!"
@@ -0,0 +1,4 @@
1
+ body{
2
+ background: #f0f0f0;
3
+ color: #333;
4
+ }
@@ -0,0 +1,3 @@
1
+ <!-- START/pages/about.erb.html -->
2
+ <h2> About Page </h2>
3
+ <!-- END/pages/about.erb.html -->
@@ -0,0 +1,5 @@
1
+ <!-- START/pages/index.md.erb.html -->
2
+ # Hello World!
3
+
4
+ Welcome to Grass App!
5
+ <!-- END/pages/index.md.erb.html -->
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Grass</title>
5
+ <link rel="stylesheet" href="/stylesheets/application.css" type="text/css" media="screen" title="no title" charset="utf-8">
6
+ </head>
7
+ <body>
8
+
9
+ <!-- START/layouts/application.erb.html -->
10
+ <%= yield %>
11
+ <!-- END/layouts/application.erb.html -->
12
+
13
+ <script type="text/javascript" charset="utf-8" src="/scripts/application.js"></script>
14
+ </body>
@@ -0,0 +1,4 @@
1
+ <!-- START/views/pages.erb.html -->
2
+ <%= render_content %>
3
+ <%= render_partial('/views/shared') %>
4
+ <!-- END/views/pages.erb.html -->
@@ -0,0 +1,9 @@
1
+ <!-- START/views/shared.erb.html -->
2
+ <pre>
3
+ country_info: <%= country_info %>
4
+ language_info: <%= language_info %>
5
+ http_host: <%= http_host %>
6
+ request_path: <%= request_path %>
7
+ params: <%= params %>
8
+ </pre>
9
+ <!-- END/views/shared.erb.html -->
@@ -0,0 +1,20 @@
1
+ development:
2
+ compress: true
3
+ threadsafe: true
4
+ namespace: grass:$app_development
5
+ servers: localhost:11211
6
+ async: true
7
+ test:
8
+ compress: true
9
+ threadsafe: true
10
+ namespace: grass:$app_test
11
+ servers: localhost:11211
12
+ async: true
13
+ production:
14
+ compress: true
15
+ threadsafe: true
16
+ namespace: grass:$app
17
+ servers: <%= ENV['MEMCACHIER_SERVERS'] %>
18
+ password: <%= ENV['MEMCACHIER_PASSWORD'] %>
19
+ username: <%= ENV['MEMCACHIER_USERNAME'] %>
20
+ async: true
@@ -0,0 +1,35 @@
1
+ development:
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ database: $app_development
5
+ username: $username
6
+ password:
7
+ host: localhost
8
+ port: 5432
9
+ # pool: 5
10
+ # connections: 20
11
+
12
+ test:
13
+ adapter: postgresql
14
+ encoding: unicode
15
+ database: $app_test
16
+ username: $username
17
+ password:
18
+ host: localhost
19
+ port: 5432
20
+ # pool: 5
21
+ # connections: 20
22
+
23
+ production:
24
+ <% if db = URI.parse(ENV['DATABASE_URL']) rescue nil %>
25
+ adapter: <%= db.scheme == "postgres" ? "postgresql" : db.scheme %>
26
+ encoding: unicode
27
+ database: <%= db.path[1..-1] %>
28
+ username: <%= db.user %>
29
+ password: <%= db.password %>
30
+ host: <%= db.host %>
31
+ port: <%= db.port %>
32
+ pool: <%= ENV['DB_POOL'] || 5 %>
33
+ connections: <%= ENV['DB_CONNECTIONS'] || 20 %>
34
+ reaping_frequency: <%= ENV['DB_REAP_FREQ'] || 10 %>
35
+ <% end %>
@@ -0,0 +1,27 @@
1
+ require 'i18n'
2
+ require 'grass'
3
+ require 'ip_country'
4
+ require 'active_record'
5
+
6
+ Time.zone = ENV['TIME_ZONE'] || "London"
7
+ I18n.load_path << Dir.glob("#{Grass.root}/config/locales/**/*.yml")
8
+ I18n.enforce_available_locales = false
9
+ I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
10
+ I18n.default_locale = ENV['DEFAULT_LOCALE'] ? ENV['DEFAULT_LOCALE'].to_sym : :en
11
+ I18n.available_locales = ENV['AVAILABLE_LOCALES'] ? ENV['AVAILABLE_LOCALES'].split(",").map(&:to_sym) : [:en]
12
+
13
+ ActiveRecord::Base.establish_connection Grass.load_config('database')
14
+
15
+ if respond_to?(:config)
16
+
17
+ # config['enable_cache_for_development'] = true
18
+
19
+ ENV['GEOIP_FILE'] ||= "#{Grass.root}/db/geo_ip.dat"
20
+ if ::File.exists?(ENV['GEOIP_FILE'])
21
+ IPCountry.init ENV['GEOIP_FILE']
22
+ config['ip_country'] = IPCountry
23
+ end
24
+
25
+ config['dalli'] = Grass.cache
26
+
27
+ end
@@ -0,0 +1,24 @@
1
+ class CreateGrassSources < ActiveRecord::Migration
2
+ def change
3
+ create_table :grass_sources, id: false do |t|
4
+ t.column :keyid, :string, null: false, index: true, primary: true
5
+ t.column :dir, :string
6
+ t.column :path, :string
7
+ t.column :locale, :string
8
+ t.column :format, :string
9
+ t.column :handler, :string
10
+ t.column :filepath, :string
11
+
12
+ t.column :raw, :text
13
+ t.column :result, :text
14
+ t.column :binary, :oid, limit: 2147483648 #:binary
15
+
16
+ t.column :pairs, :string, default: []
17
+ t.column :hidden, :boolean, default: false
18
+ t.column :mime_type, :string
19
+
20
+ t.timestamps
21
+ end
22
+ add_index :grass_sources, [:locale,:dir,:path], unique: true
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ global
2
+ pidfile /var/run/haproxy.pid
3
+ log 127.0.0.1 local0 info
4
+ user root
5
+
6
+ defaults
7
+ mode http
8
+
9
+ clitimeout 600000 # maximum inactivity time on the client side
10
+ srvtimeout 600000 # maximum inactivity time on the server side
11
+ timeout connect 8000 # maximum time to wait for a connection attempt to a server to succeed
12
+
13
+ stats enable
14
+ stats auth admin:password
15
+ stats uri /monitor
16
+ stats refresh 5s
17
+ retries 5
18
+ option httpchk GET /status
19
+ option redispatch
20
+ option httpclose
21
+ option abortonclose
22
+ option forwardfor
23
+
24
+ balance roundrobin # each server is used in turns, according to assigned weight
25
+
26
+ frontend http
27
+ bind :5000
28
+ monitor-uri /haproxy # end point to monitor HAProxy status (returns 200)
29
+
30
+ acl acl_api hdr_beg(host) -i api
31
+ use_backend backend_api if acl_api
32
+
33
+ acl acl_front path_reg ^/?
34
+ use_backend backend_front if acl_front
35
+
36
+ default_backend backend_front
37
+
38
+ backend backend_front
39
+ server srv_index 127.0.0.1:4000
40
+
41
+ backend backend_api
42
+ server srv_donors 127.0.0.1:4001
43
+
@@ -0,0 +1,2 @@
1
+ User-agent: *
2
+ Disallow: /