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,7 @@
1
+ $LOAD_PATH.unshift File.expand_path('../', __FILE__)
2
+
3
+ $stdout.sync = true
4
+
5
+ require 'goliath'
6
+ require 'grass'
7
+ require "grass/endpoints/#{ARGV.shift}"
@@ -0,0 +1 @@
1
+ simple text
@@ -0,0 +1,23 @@
1
+ development:
2
+ compress: true
3
+ threadsafe: true
4
+ namespace: grass:dummy_development
5
+ servers: localhost:11211
6
+ async: true
7
+ test:
8
+ compress: true
9
+ threadsafe: true
10
+ namespace: grass:dummy_test
11
+ servers: localhost:11211
12
+ async: true
13
+ production:
14
+ compress: true
15
+ threadsafe: true
16
+ namespace: grass:dummy_nukleer
17
+ servers: <%= ENV['MEMCACHIER_SERVERS'] %>
18
+ password: <%= ENV['MEMCACHIER_PASSWORD'] %>
19
+ username: <%= ENV['MEMCACHIER_USERNAME'] %>
20
+ async: true
21
+ down_retry_delay: 1
22
+ socket_timeout: 0.5
23
+ socket_max_failures: 20
@@ -0,0 +1,35 @@
1
+ development:
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ database: grass_dummy_development
5
+ username: onuruyar
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: grass_dummy_test
16
+ username: onuruyar
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 @@
1
+ import('grass')
@@ -0,0 +1,37 @@
1
+ global
2
+ user root
3
+ log 127.0.0.1 local0 info
4
+
5
+ defaults
6
+ mode http
7
+
8
+ clitimeout 600000 # maximum inactivity time on the client side
9
+ srvtimeout 600000 # maximum inactivity time on the server side
10
+ timeout connect 8000 # maximum time to wait for a connection attempt to a server to succeed
11
+
12
+ stats enable
13
+ stats auth admin:password
14
+ stats uri /monitor
15
+ stats refresh 5s
16
+ retries 5
17
+ option redispatch
18
+
19
+ balance roundrobin # each server is used in turns, according to assigned weight
20
+
21
+ frontend http
22
+ bind :8000
23
+ monitor-uri /haproxy # end point to monitor HAProxy status (returns 200)
24
+
25
+ acl users path_reg ^/users/?
26
+
27
+ use_backend users if users
28
+
29
+ default_backend front
30
+
31
+ backend front
32
+ option httpclose
33
+ server srv01 127.0.0.1:5000
34
+
35
+ backend users
36
+ option httpclose
37
+ server srv0 127.0.0.1:5001
@@ -0,0 +1,2 @@
1
+ User-agent: *
2
+ Disallow: /
@@ -0,0 +1,38 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'grass'
4
+ require 'dalli'
5
+ require 'minitest/autorun'
6
+ require 'minitest/pride'
7
+ require 'i18n'
8
+ require 'em-synchrony/em-http'
9
+ require 'goliath/test_helper'
10
+
11
+ I18n.enforce_available_locales = false
12
+
13
+ require 'active_record'
14
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ":memory:")
15
+
16
+ require "#{Grass.gem_root}/db/migrate/1_create_grass_sources"
17
+ ActiveRecord::Schema.define do
18
+ CreateGrassSources.new.change
19
+ end
20
+
21
+ cache_conf = {
22
+ "compress" => true,
23
+ "threadsafe" => true,
24
+ "namespace" => "grass:test",
25
+ "servers" => "localhost:11211",
26
+ "async" => true
27
+ }
28
+ Grass.cache = Dalli::Client.new cache_conf.delete("servers").split(","), cache_conf
29
+
30
+ class MiniTest::Spec
31
+ include Goliath::TestHelper
32
+ def teardown
33
+ Grass.cache.flush
34
+ end
35
+ def setup
36
+ Grass.root = File.expand_path('../../test/dummy', __FILE__)
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ require 'i18n'
2
+ require 'grass'
3
+ require "ip_country"
4
+
5
+ I18n.enforce_available_locales = false
6
+ I18n.default_locale = ENV['DEFAULT_LOCALE'] ? ENV['DEFAULT_LOCALE'].to_sym : :en
7
+ I18n.available_locales = ENV['AVAILABLE_LOCALES'] ? ENV['AVAILABLE_LOCALES'].split(",").map(&:to_sym) : [:en]
8
+
9
+ # config = YAML.load(ERB.new(File.read('config/database.yml')).result)[Goliath.env.to_s]
10
+ # ActiveRecord::Base.establish_connection config
11
+
12
+ Time.zone = ENV['TIME_ZONE'] || "London"
13
+
14
+ ENV['GEOIP_FILE'] ||= "#{Grass.root}/db/geo_ip.dat"
15
+
16
+ if ::File.exists?(ENV['GEOIP_FILE'])
17
+ IPCountry.init ENV['GEOIP_FILE']
18
+ config['ip_country'] = IPCountry
19
+ end
20
+
21
+ config['dalli'] = Grass.cache
Binary file
@@ -0,0 +1,74 @@
1
+ require 'minitest_helper'
2
+ require 'goliath'
3
+
4
+ Grass.root = File.expand_path('../../test/dummy', __FILE__)
5
+
6
+ require 'grass/endpoints/api'
7
+
8
+ module Grass
9
+ describe :"grass/endpoints/api" do
10
+
11
+ before do
12
+ I18n.default_locale = :en
13
+ I18n.available_locales = [:en,:es]
14
+ @layout = Source.create!(key: "/views/layouts/pages/apihome", raw: "HEADER <%= yield %> FOOTER")
15
+ @layout.commit!
16
+ @page = Source.create!(key: "/pages/apihome", raw: "PAGE CONTENT")
17
+ @page.commit!
18
+ end
19
+
20
+ after do
21
+ @layout.destroy!
22
+ @page.destroy!
23
+ end
24
+
25
+ let(:api_options) { {:verbose => true, :log_stdout => true, :config => "#{Grass.gem_root}/test/support/grass.rb" } }
26
+
27
+ it 'returns file json rep' do
28
+ with_api(API, api_options) do
29
+ get_request(:path => '/en/pages/apihome') do |c|
30
+ file = JSON.load(c.response)
31
+ assert_equal file['keyid'], @page.keyid
32
+ assert_equal file['raw'], @page.raw
33
+ end
34
+ end
35
+ end
36
+
37
+ it 'creates file' do
38
+ with_api(API, api_options) do
39
+ post_request(:path => '/en/texts/testapi', :body => {"raw" => "simple text"}) do |c|
40
+ file = JSON.load(c.response)
41
+ assert_equal file['raw'], "simple text"
42
+ end
43
+ end
44
+ end
45
+
46
+ it 'updates file' do
47
+ with_api(API, api_options) do
48
+ put_request(:path => '/en/views/layouts/pages/apihome', :body => {"raw" => "HEADER UPDATED <%= yield %> FOOTER"}) do |c|
49
+ file = JSON.load(c.response)
50
+ assert_equal file['keyid'], @layout.keyid
51
+ assert_equal file['raw'], @layout.reload.raw
52
+ end
53
+ end
54
+ end
55
+
56
+ it 'commit file' do
57
+ with_api(API, api_options) do
58
+ put_request(:path => '/en/views/layouts/pages/apihome', :body => {"raw" => "HEADER UPDATED PUB <%= yield %> FOOTER", "commit" => true}) do |c|
59
+ file = JSON.load(c.response)
60
+ assert_equal file['raw'], "HEADER UPDATED PUB <%= yield %> FOOTER"
61
+ end
62
+ end
63
+ end
64
+
65
+ it 'deletes file' do
66
+ with_api(API, api_options) do
67
+ delete_request(:path => '/en/pages/apihome') do |c|
68
+ assert_equal JSON.load(c.response), true
69
+ end
70
+ end
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,52 @@
1
+ require 'minitest_helper'
2
+ require 'goliath'
3
+ require 'grass/endpoints/front'
4
+
5
+ module Grass
6
+ describe :"grass/endpoints/front" do
7
+
8
+ before do
9
+ I18n.available_locales = [:en,:es]
10
+ Source.fallback = true
11
+ @layout = Source.create!(key: "/views/layouts/pages/frontpage", raw: "HEADER <%= yield %> FOOTER")
12
+ @view = Source.create!(key: "/views/pages/frontpage", raw: "<%= render_content %>")
13
+ @page = Source.create!(key: "/pages/frontpage", raw: "PAGE CONTENT")
14
+ @page2 = Source.create!(key: "/es/pages/frontpage", raw: "PAGE CONTENT ES")
15
+ end
16
+
17
+ after do
18
+ @page2.destroy
19
+ @page.destroy
20
+ @layout.destroy
21
+ @view.destroy
22
+ end
23
+
24
+ let(:api_options) { {:verbose => true, :log_stdout => true, :config => "#{Grass.gem_root}/test/support/grass.rb" } }
25
+
26
+ # it 'renders any object based on path' do
27
+ # with_api(Front, api_options) do
28
+ # get_request(:path => '/pages/frontpage') do |c|
29
+ # assert_equal c.response, "HEADER PAGE CONTENT FOOTER"
30
+ # end
31
+ # end
32
+ # end
33
+ #
34
+ # it 'renders index default' do
35
+ # with_api(Front, api_options) do
36
+ # get_request(:path => '/frontpage') do |c|
37
+ # assert_equal c.response, "HEADER PAGE CONTENT FOOTER"
38
+ # end
39
+ # end
40
+ # end
41
+
42
+ it 'renders localised pages' do
43
+ with_api(Front, api_options) do
44
+ get_request(:path => '/es/frontpage') do |c|
45
+ assert_equal c.response, "HEADER PAGE CONTENT ES FOOTER"
46
+ end
47
+ end
48
+ end
49
+
50
+
51
+ end
52
+ end
@@ -0,0 +1,118 @@
1
+ require 'minitest_helper'
2
+ require 'grass/key'
3
+ module Grass
4
+
5
+ class TestKey < Minitest::Test
6
+
7
+ def setup
8
+ I18n.default_locale = :en
9
+ I18n.available_locales = [:en,:es]
10
+ end
11
+
12
+ ##
13
+ # Template Keys
14
+
15
+ def test_new_with_locale
16
+ key = Key.new(id: "/es/views/test" )
17
+ assert key.valid?
18
+ assert_equal "/views/test", key.id
19
+ assert_equal "es", key.locale
20
+ assert_equal "views", key.dir
21
+ assert_equal "test", key.path
22
+ assert_equal "html", key.format
23
+ assert_equal nil, key.handler
24
+ assert_equal "#{Grass.app_root}/views/test.es.html", key.filepath
25
+ end
26
+
27
+ def test_new_layout
28
+ key = Key.new(id: "/en/views/layouts/application.html.erb" )
29
+ assert key.valid?
30
+ assert_equal "/views/layouts/application", key.id
31
+ assert_equal "en", key.locale
32
+ assert_equal "views/layouts", key.dir
33
+ assert_equal "application", key.path
34
+ assert_equal "html", key.format
35
+ assert_equal "erb", key.handler
36
+ assert_equal "#{Grass.app_root}/views/layouts/application.en.html.erb", key.filepath
37
+ end
38
+
39
+ ##
40
+ # Asset Keys
41
+
42
+ def test_assets
43
+ key = Key.new(id: "/es/stylesheets/app.css" )
44
+ assert key.valid?
45
+ assert_equal "/stylesheets/app", key.id
46
+ assert_equal 'es', key.locale
47
+ assert_equal "stylesheets", key.dir
48
+ assert_equal "app", key.path
49
+ assert_equal "css", key.format
50
+ assert_equal nil, key.handler
51
+ assert_equal "#{Grass.app_root}/assets/stylesheets/app.es.css", key.filepath
52
+ end
53
+
54
+ def test_assets_js
55
+ key = Key.new(id: "/scripts/app.js.coffee.erb" )
56
+ assert key.valid?
57
+ assert_equal "/scripts/app", key.id
58
+ assert_equal 'en', key.locale
59
+ assert_equal "scripts", key.dir
60
+ assert_equal "app", key.path
61
+ assert_equal "js", key.format
62
+ assert_equal "coffee.erb", key.handler
63
+ assert_equal "#{Grass.app_root}/assets/scripts/app.en.js.coffee.erb", key.filepath
64
+ end
65
+
66
+ def test_assets_with_filepath
67
+ key = Key.new(filepath: "#{Grass.app_root}/scripts/app.en.js.coffee.erb" )
68
+ assert key.valid?
69
+ assert_equal "/scripts/app", key.id
70
+ assert_equal 'en', key.locale
71
+ assert_equal "scripts", key.dir
72
+ assert_equal "app", key.path
73
+ assert_equal "js", key.format
74
+ assert_equal "coffee.erb", key.handler
75
+ assert_equal "#{Grass.app_root}/assets/scripts/app.en.js.coffee.erb", key.filepath
76
+ end
77
+
78
+ ##
79
+ #Content Keys
80
+
81
+ def test_with_external_filepath
82
+ key = Key.new(filepath: "/var/www/grosartik/app/content/pages/test.es.htm.haml" )
83
+ assert key.valid?
84
+ assert_equal "/pages/test", key.id
85
+ assert_equal "es", key.locale
86
+ assert_equal "pages", key.dir
87
+ assert_equal "test", key.path
88
+ assert_equal "htm", key.format
89
+ assert_equal "haml", key.handler
90
+ assert_equal "#{Grass.app_root}/content/pages/test.es.htm.haml", key.filepath
91
+ end
92
+
93
+ def test_new
94
+ key = Key.new(id: "/texts/test.txt.str" )
95
+ assert key.valid?
96
+ assert_equal "/texts/test", key.id
97
+ assert_equal "en", key.locale
98
+ assert_equal "texts", key.dir
99
+ assert_equal "test", key.path
100
+ assert_equal "txt", key.format
101
+ assert_equal 'str', key.handler
102
+ assert_equal "#{Grass.app_root}/content/texts/test.en.txt.str", key.filepath
103
+ end
104
+
105
+ def test_new_with_handler_and_format
106
+ key = Key.new(id: "/es/pages/test.htm.haml" )
107
+ assert key.valid?
108
+ assert_equal "/pages/test", key.id
109
+ assert_equal "es", key.locale
110
+ assert_equal "pages", key.dir
111
+ assert_equal "test", key.path
112
+ assert_equal "htm", key.format
113
+ assert_equal "haml", key.handler
114
+ assert_equal "#{Grass.app_root}/content/pages/test.es.htm.haml", key.filepath
115
+ end
116
+
117
+ end
118
+ end
@@ -0,0 +1,51 @@
1
+ require 'minitest_helper'
2
+ require 'grass/source'
3
+
4
+ module Grass
5
+
6
+ class TestSource < Minitest::Test
7
+
8
+ def setup
9
+ I18n.default_locale = :en
10
+ I18n.available_locales = [:en,:es]
11
+
12
+ @source = Source.create!(key: Key.new(id: "/texts/sourcekey_#{Time.now.to_f.to_s.gsub('.','_')}"), raw: "Hello")
13
+
14
+ end
15
+
16
+ def teardown
17
+ @source.destroy!
18
+ end
19
+
20
+ def test_persisted?
21
+ assert @source.persisted?
22
+ end
23
+
24
+ def test_find
25
+ source = Source.find_by(keyid: @source.keyid)
26
+ assert_equal source.as_json, @source.as_json
27
+
28
+ source = Source[@source.keyid].first
29
+
30
+ assert_equal source.as_json, @source.as_json
31
+ end
32
+
33
+ def test_read
34
+ assert_equal "Hello", @source.read
35
+ end
36
+
37
+ def test_write
38
+ @source.write("Hello World")
39
+ assert_equal "Hello World", @source.read
40
+ end
41
+
42
+ def test_binary
43
+ file = Source.create!(key: "/images/test.jpg", binary: IO.binread("#{Grass.gem_root}/test/support/test.jpg"))
44
+ refute_nil file.binary
45
+ assert_equal file.read, file.binary
46
+ assert_equal file.mime_type, "image/jpeg"
47
+ file.destroy!
48
+ end
49
+
50
+ end
51
+ end