kratos 1.0.0

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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +21 -0
  7. data/README.md +24 -0
  8. data/bin/kratos +18 -0
  9. data/bin/rake +16 -0
  10. data/bin/rspec +16 -0
  11. data/bin/setup +14 -0
  12. data/kratos.gemspec +30 -0
  13. data/lib/kratos/actions.rb +31 -0
  14. data/lib/kratos/app_builder.rb +468 -0
  15. data/lib/kratos/generators/app_generator.rb +164 -0
  16. data/lib/kratos/version.rb +6 -0
  17. data/lib/kratos.rb +4 -0
  18. data/templates/Capfile +15 -0
  19. data/templates/Gemfile.erb +67 -0
  20. data/templates/Procfile +2 -0
  21. data/templates/README.md.erb +29 -0
  22. data/templates/_javascript.html.erb +10 -0
  23. data/templates/acceptance_helpers_rspec.rb +18 -0
  24. data/templates/action_mailer.rb +5 -0
  25. data/templates/application.scss +4 -0
  26. data/templates/bin_setup +25 -0
  27. data/templates/brakeman.rake +9 -0
  28. data/templates/bundler_audit.rake +12 -0
  29. data/templates/cap_environment.rb +1 -0
  30. data/templates/capybara_poltergeist.rb +17 -0
  31. data/templates/circle.yml.erb +9 -0
  32. data/templates/config_locales_en_datetime.yml +107 -0
  33. data/templates/config_locales_en_messages.yml.erb +3 -0
  34. data/templates/config_locales_pt-BR_datetime.yml +108 -0
  35. data/templates/config_locales_pt-BR_messages.yml.erb +4 -0
  36. data/templates/database_cleaner_rspec.rb +21 -0
  37. data/templates/deploy.rake +28 -0
  38. data/templates/deploy_config.rb.erb +33 -0
  39. data/templates/dev.rake +12 -0
  40. data/templates/disable_xml_params.rb +1 -0
  41. data/templates/dotfiles/.ctags +2 -0
  42. data/templates/dotfiles/.gitignore +14 -0
  43. data/templates/dotfiles/.sample.application.yml +15 -0
  44. data/templates/errors.rb +34 -0
  45. data/templates/factory_girl_rspec.rb +3 -0
  46. data/templates/foreman.rake +39 -0
  47. data/templates/i18n-tasks.yml +22 -0
  48. data/templates/i18n.rb +3 -0
  49. data/templates/i18n_rspec.rb +19 -0
  50. data/templates/json_encoding.rb +1 -0
  51. data/templates/kratos_layout.html.erb.erb +20 -0
  52. data/templates/lograge.rb +14 -0
  53. data/templates/postgresql_database.yml.erb +22 -0
  54. data/templates/puma.rb +28 -0
  55. data/templates/rails_helper.rb +28 -0
  56. data/templates/redis.rb +10 -0
  57. data/templates/rspec_api_documentation_rspec.rb.erb +33 -0
  58. data/templates/rubocop.rake +4 -0
  59. data/templates/rubocop.yml +40 -0
  60. data/templates/schedule.rb +8 -0
  61. data/templates/secrets.yml +14 -0
  62. data/templates/shoulda_matchers_config_rspec.rb +6 -0
  63. data/templates/sidekiq.yml +4 -0
  64. data/templates/sidekiq_rspec.yml +10 -0
  65. data/templates/sidekiq_security.rb +6 -0
  66. data/templates/smtp.rb +9 -0
  67. data/templates/spec_helper.rb +31 -0
  68. data/templates/staging.rb +5 -0
  69. data/templates/timezones.rb +26 -0
  70. metadata +145 -0
@@ -0,0 +1,28 @@
1
+ namespace :deploy do
2
+ task :setup_env do
3
+ on roles(:web) do
4
+ within release_path do
5
+ execute(:cp, "~/.#{fetch(:application)}.yml config/application.yml")
6
+ execute(:cp, "~/.#{fetch(:application)}.env .env")
7
+ execute(:cp, "~/.#{fetch(:application)}.foreman .foreman")
8
+ end
9
+ end
10
+ end
11
+ before :updated, :setup_env
12
+
13
+ task :restart do
14
+ invoke 'foreman:export'
15
+ invoke 'foreman:restart'
16
+ end
17
+
18
+ desc 'reload the database with seed data'
19
+ task :seed do
20
+ on primary :db do
21
+ within current_path do
22
+ with rails_env: fetch(:stage) do
23
+ execute(:rake, 'db:seed')
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+ # config valid only for current version of Capistrano
2
+ lock '3.4.0'
3
+
4
+ set :application, '<%= app_name.dasherize %>'
5
+ set :user, 'deploy'
6
+ # set :repo_url, 'git@github.com:organization/repository.git'
7
+
8
+ set :rbenv_ruby, File.read('.ruby-version').strip
9
+ set :rbenv_type, :user
10
+ set :rbenv_bin_path, '/home/deploy/.rbenv/shims'
11
+
12
+ # Always deploy the current branch.
13
+ set :branch, `git rev-parse --abbrev-ref HEAD`.chomp
14
+
15
+ set :deploy_to, '/home/deploy/<%= app_name.dasherize %>'
16
+ set :log_level, :info
17
+
18
+ set :linked_dirs, fetch(:linked_dirs, []).push('log',
19
+ 'tmp/pids',
20
+ 'tmp/cache')
21
+
22
+ set :default_env, path: '/home/deploy/.rbenv/shims:$PATH'
23
+
24
+ namespace :deploy do
25
+ after :restart, :clear_cache do
26
+ on roles(:web), in: :groups, limit: 3, wait: 10 do
27
+ # Here we can do anything such as:
28
+ # within release_path do
29
+ # execute :rake, 'cache:clear'
30
+ # end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ if Rails.env.development? || Rails.env.test?
2
+ require 'factory_girl'
3
+
4
+ namespace :dev do
5
+ desc 'Sample data for local development environment'
6
+ task prime: 'db:setup' do
7
+ include FactoryGirl::Syntax::Methods
8
+
9
+ # create(:user, email: "user@example.com", password: "password")
10
+ end
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)
@@ -0,0 +1,2 @@
1
+ --recurse=yes
2
+ --exclude=vendor
@@ -0,0 +1,14 @@
1
+ !.keep
2
+ *.DS_Store
3
+ *.swo
4
+ *.swp
5
+ /.bundle
6
+ /.env.local
7
+ /coverage/*
8
+ /db/*.sqlite3
9
+ /log/*
10
+ /public/system
11
+ /public/assets
12
+ /tags
13
+ /tmp/*
14
+ /config/application.yml
@@ -0,0 +1,15 @@
1
+ ASSET_HOST: localhost:3000
2
+ APPLICATION_HOST: localhost:3000
3
+ PORT: 3000
4
+ RACK_ENV: development
5
+ REDIS_URL: redis://127.0.0.1:6379
6
+ SECRET_KEY_BASE: development_secret
7
+ EXECJS_RUNTIME: Node
8
+ SMTP_ADDRESS: smtp.example.com
9
+ SMTP_DOMAIN: example.com
10
+ SMTP_PASSWORD: password
11
+ SMTP_USERNAME: username
12
+ WEB_CONCURRENCY: 1
13
+ AWS_REGION: us-east-1
14
+ AWS_ACCESS_KEY_ID: <put-your-key-here>
15
+ AWS_SECRET_ACCESS_KEY: <put-your-secret-here>
@@ -0,0 +1,34 @@
1
+ require 'net/http'
2
+ require 'net/smtp'
3
+
4
+ # Example:
5
+ # begin
6
+ # some http call
7
+ # rescue *HTTP_ERRORS => error
8
+ # notify_hoptoad error
9
+ # end
10
+
11
+ HTTP_ERRORS = [
12
+ EOFError,
13
+ Errno::ECONNRESET,
14
+ Errno::EINVAL,
15
+ Net::HTTPBadResponse,
16
+ Net::HTTPHeaderSyntaxError,
17
+ Net::ProtocolError,
18
+ Timeout::Error
19
+ ].freeze
20
+
21
+ SMTP_SERVER_ERRORS = [
22
+ IOError,
23
+ Net::SMTPAuthenticationError,
24
+ Net::SMTPServerBusy,
25
+ Net::SMTPUnknownError,
26
+ Timeout::Error
27
+ ].freeze
28
+
29
+ SMTP_CLIENT_ERRORS = [
30
+ Net::SMTPFatalError,
31
+ Net::SMTPSyntaxError
32
+ ].freeze
33
+
34
+ SMTP_ERRORS = SMTP_SERVER_ERRORS + SMTP_CLIENT_ERRORS
@@ -0,0 +1,3 @@
1
+ RSpec.configure do |config|
2
+ config.include FactoryGirl::Syntax::Methods
3
+ end
@@ -0,0 +1,39 @@
1
+ namespace :foreman do
2
+ desc "Export the Procfile to Ubuntu's upstart scripts"
3
+ task :export do
4
+ on roles(:app) do
5
+ within current_path do
6
+ # Add path to .env.
7
+ # Needed for rbenv to work properly.
8
+ execute(:echo, "\"PATH=#{fetch(:rbenv_bin_path)}:$PATH\" >> .env")
9
+ # Create the upstart script
10
+ execute(:sudo, "#{fetch(:rbenv_prefix)} " \
11
+ 'foreman export upstart /etc/init ' \
12
+ "-a #{fetch(:application)} " \
13
+ "-u #{fetch(:user)} ")
14
+ end
15
+ end
16
+ end
17
+
18
+ desc 'Start the application services'
19
+ task :start do
20
+ on roles(:app) do
21
+ execute("sudo service #{fetch(:application)} start")
22
+ end
23
+ end
24
+
25
+ desc 'Stop the application services'
26
+ task :stop do
27
+ on roles(:app) do
28
+ execute("sudo service #{fetch(:application)} stop")
29
+ end
30
+ end
31
+
32
+ desc 'Restart the application services'
33
+ task :restart do
34
+ on roles(:app), in: :sequence, wait: 15 do
35
+ execute("sudo service #{fetch(:application)} start || " \
36
+ "sudo service #{fetch(:application)} restart")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ locales:
2
+ - en
3
+ - pt-BR
4
+ data:
5
+ read:
6
+ - config/locales/%{locale}.*.yml
7
+ write:
8
+ - config/locales/%{locale}.auto.yml
9
+
10
+ search:
11
+ paths:
12
+ - "app/controllers"
13
+ - "app/models"
14
+ - "app/views"
15
+ - "spec"
16
+ ignore_unused:
17
+ - activerecord.*
18
+ - date.*
19
+ - datetime.*
20
+ - number.*
21
+ - time.*
22
+ - titles.*
data/templates/i18n.rb ADDED
@@ -0,0 +1,3 @@
1
+ RSpec.configure do |config|
2
+ config.include ActionView::Helpers::TranslationHelper
3
+ end
@@ -0,0 +1,19 @@
1
+ require 'i18n/tasks'
2
+
3
+ RSpec.describe 'I18n' do
4
+ let(:i18n) { I18n::Tasks::BaseTask.new }
5
+ let(:missing_keys) { i18n.missing_keys }
6
+ let(:unused_keys) { i18n.unused_keys }
7
+
8
+ it 'does not have missing keys' do
9
+ expect(missing_keys)
10
+ .to be_empty, "Missing #{missing_keys.leaves.count} i18n keys, run " \
11
+ 'i18n-tasks missing to show them'
12
+ end
13
+
14
+ it 'does not have unused keys' do
15
+ expect(unused_keys)
16
+ .to be_empty, "#{unused_keys.leaves.count} unused i18n keys, run "\
17
+ "'i18n-tasks unused' to show them"
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ ActiveSupport::JSON::Encoding.time_precision = 0
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <html lang="<%= I18n.locale %>">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="ROBOTS" content="NOODP" />
6
+ <meta name="viewport" content="initial-scale=1" />
7
+ <%%#
8
+ Configure default and controller-, and view-specific titles in
9
+ config/locales/en.yml. For more see:
10
+ https://github.com/calebthompson/title#usage
11
+ %>
12
+ <title><%%= title %></title>
13
+ <%%= stylesheet_link_tag :application, media: "all" %>
14
+ <%%= csrf_meta_tags %>
15
+ </head>
16
+ <body class="<%%= body_class %>">
17
+ <%%= yield %>
18
+ <%%= render "javascript" %>
19
+ </body>
20
+ </html>
@@ -0,0 +1,14 @@
1
+ Rails.application.configure do
2
+ if Rails.env.production?
3
+ config.lograge.enabled = true
4
+ config.log_tags = [:uuid]
5
+
6
+ config.lograge.custom_options = lambda do |event|
7
+ params = event.payload[:params].reject do |k|
8
+ %w(controller action).include? k
9
+ end
10
+
11
+ { 'params' => params }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ development: &default
2
+ adapter: postgresql
3
+ database: <%= app_name %>_development
4
+ encoding: utf8
5
+ host: localhost
6
+ min_messages: warning
7
+ pool: <%%= Integer(ENV.fetch("DB_POOL", 5)) %>
8
+ reaping_frequency: <%%= Integer(ENV.fetch("DB_REAPING_FREQUENCY", 10)) %>
9
+ timeout: 5000
10
+
11
+ test:
12
+ <<: *default
13
+ database: <%= app_name %>_test
14
+
15
+ production: &deploy
16
+ encoding: utf8
17
+ min_messages: warning
18
+ pool: <%%= [Integer(ENV.fetch("MAX_THREADS", 5)), Integer(ENV.fetch("DB_POOL", 5))].max %>
19
+ timeout: 5000
20
+ url: <%%= ENV.fetch("DATABASE_URL", "") %>
21
+
22
+ staging: *deploy
data/templates/puma.rb ADDED
@@ -0,0 +1,28 @@
1
+ # https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server
2
+
3
+ # The environment variable WEB_CONCURRENCY may be set to a default value based
4
+ # on dyno size. To manually configure this value use heroku config:set
5
+ # WEB_CONCURRENCY.
6
+ #
7
+ # Increasing the number of workers will increase the amount of resting memory
8
+ # your dynos use. Increasing the number of threads will increase the amount of
9
+ # potential bloat added to your dynos when they are responding to heavy
10
+ # requests.
11
+ #
12
+ # Starting with a low number of workers and threads provides adequate
13
+ # performance for most applications, even under load, while maintaining a low
14
+ # risk of overusing memory.
15
+ workers Integer(ENV.fetch('WEB_CONCURRENCY', 2))
16
+ threads_count = Integer(ENV.fetch('MAX_THREADS', 2))
17
+ threads(threads_count, threads_count)
18
+
19
+ preload_app!
20
+
21
+ rackup DefaultRackup
22
+ environment ENV.fetch('RACK_ENV', 'development')
23
+
24
+ on_worker_boot do
25
+ # Worker specific setup for Rails 4.1+
26
+ # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
27
+ ActiveRecord::Base.establish_connection
28
+ end
@@ -0,0 +1,28 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+
3
+ require File.expand_path('../../config/environment', __FILE__)
4
+ abort('DATABASE_URL environment variable is set') if ENV['DATABASE_URL']
5
+
6
+ require 'rspec/rails'
7
+ require 'ffaker'
8
+
9
+ Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |file| require file }
10
+
11
+ # Define the feature Dsl
12
+ module Features
13
+ # Extend this module in spec/support/features/*.rb
14
+ include Formulaic::Dsl
15
+ end
16
+
17
+ RSpec.configure do |config|
18
+ config.include Features, type: :feature
19
+ config.infer_base_class_for_anonymous_controllers = false
20
+ config.infer_spec_type_from_file_location!
21
+ config.use_transactional_fixtures = false
22
+
23
+ config.before(:all) do
24
+ Rails.cache.clear
25
+ end
26
+ end
27
+
28
+ ActiveRecord::Migration.maintain_test_schema!
@@ -0,0 +1,10 @@
1
+ url = URI.parse(ENV['REDIS_URL'] ||
2
+ 'redis://127.0.0.1:6379')
3
+
4
+ if Rails.env.test?
5
+ Redis.current = Redis.new(host: url.host, port: url.port,
6
+ password: url.password, thread_safe: true, db: '15')
7
+ else
8
+ Redis.current = Redis.new(host: url.host, port: url.port,
9
+ password: url.password, thread_safe: true)
10
+ end
@@ -0,0 +1,33 @@
1
+ require 'rspec_api_documentation'
2
+ require 'rspec_api_documentation/dsl'
3
+
4
+ RspecApiDocumentation.configure do |config|
5
+ config.format = [:json, :html]
6
+ config.api_name = '<%= app_name %>'
7
+ config.curl_headers_to_filter = %w('Cookie')
8
+ config.post_body_formatter = 'json'
9
+ config.keep_source_order = true
10
+ config.request_headers_to_include = ['Accept',
11
+ 'Content-Type',
12
+ 'Authorization',
13
+ 'Host']
14
+
15
+ # Removes the DSL method `status`,
16
+ # this is required if you have a parameter named status
17
+ # response_status is an alias to status
18
+ # because status is commonly a parameter.
19
+ config.disable_dsl_status!
20
+
21
+ if ENV['CIRCLE_ARTIFACTS']
22
+ config.docs_dir = Pathname.new("#{ENV['CIRCLE_ARTIFACTS']}/api-docs")
23
+ end
24
+ end
25
+
26
+ RSpec.configure do |config|
27
+ config.before(:each) do |example|
28
+ if example.metadata[:document]
29
+ header 'Accept', 'application/json'
30
+ header 'Content-Type', 'application/json'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ if Rails.env.development? || Rails.env.test?
2
+ require 'rubocop/rake_task'
3
+ RuboCop::RakeTask.new
4
+ end
@@ -0,0 +1,40 @@
1
+ AllCops:
2
+ Exclude:
3
+ - "Gemfile"
4
+ - "db/**/*"
5
+ - "vendor/**/*"
6
+ - "tmp/**/*"
7
+ - "config/**/*"
8
+ - "bin/**/*"
9
+ - "log/**/*"
10
+ - "Guardfile"
11
+ - "spec/factories/*"
12
+ RunRailsCops: true
13
+
14
+ Metrics/MethodLength:
15
+ Enabled: false
16
+
17
+ Metrics/ClassLength:
18
+ Enabled: false
19
+
20
+ Metrics/AbcSize:
21
+ Enabled: false
22
+
23
+ Metrics/CyclomaticComplexity:
24
+ Max: 10
25
+
26
+ Metrics/PerceivedComplexity:
27
+ Max: 10
28
+
29
+ Style/PredicateName:
30
+ Description: Check the names of predicate methods.
31
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
32
+ Enabled: true
33
+ NamePrefix:
34
+ - is_
35
+ - has_
36
+ - have_
37
+ NamePrefixBlacklist:
38
+ - is_
39
+ Exclude:
40
+ - spec/**/*
@@ -0,0 +1,8 @@
1
+ # Use this file to easily define all of your cron jobs.
2
+ #
3
+ # It's helpful, but not entirely necessary to understand cron before proceeding.
4
+ # http://en.wikipedia.org/wiki/Cron
5
+
6
+ # every 1.day, at: '1:00 am' do
7
+ # rake ...
8
+ # end
@@ -0,0 +1,14 @@
1
+ default: &default
2
+ secret_key_base: <%%= ENV["SECRET_KEY_BASE"] %>
3
+
4
+ development:
5
+ <<: *default
6
+
7
+ test:
8
+ <<: *default
9
+
10
+ staging:
11
+ <<: *default
12
+
13
+ production:
14
+ <<: *default
@@ -0,0 +1,6 @@
1
+ Shoulda::Matchers.configure do |config|
2
+ config.integrate do |with|
3
+ with.test_framework :rspec
4
+ with.library :rails
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ :concurrency: <%= ENV.fetch("MAX_THREADS", 5) %>
2
+ :pidfile: tmp/pids/sidekiq.pid
3
+ :queues:
4
+ - default
@@ -0,0 +1,10 @@
1
+ require 'sidekiq/testing'
2
+
3
+ RSpec.configure do |config|
4
+ config.before(:each) do
5
+ Sidekiq::Worker.clear_all
6
+ end
7
+ config.after(:each) do
8
+ Sidekiq::Testing.fake!
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ require 'sidekiq'
2
+ require 'sidekiq/web'
3
+
4
+ Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
5
+ [user, password] == %w(admin sidekiq)
6
+ end
data/templates/smtp.rb ADDED
@@ -0,0 +1,9 @@
1
+ SMTP_SETTINGS = {
2
+ address: ENV.fetch('SMTP_ADDRESS'), # example: "smtp.sendgrid.net"
3
+ authentication: :plain,
4
+ domain: ENV.fetch('SMTP_DOMAIN'), # example: "heroku.com"
5
+ enable_starttls_auto: true,
6
+ password: ENV.fetch('SMTP_PASSWORD'),
7
+ port: '587',
8
+ user_name: ENV.fetch('SMTP_USERNAME')
9
+ }.freeze
@@ -0,0 +1,31 @@
1
+ if ENV.fetch('COVERAGE', false)
2
+ require 'simplecov'
3
+ SimpleCov.start 'rails' do
4
+ add_filter '/lib/'
5
+ minimum_coverage 95
6
+
7
+ if ENV['CIRCLE_ARTIFACTS']
8
+ coverage_dir File.join(
9
+ '..', '..', '..', ENV['CIRCLE_ARTIFACTS'], 'coverage')
10
+ end
11
+ end
12
+ end
13
+
14
+ require 'webmock/rspec'
15
+
16
+ # http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
+ RSpec.configure do |config|
18
+ config.expect_with :rspec do |expectations|
19
+ expectations.syntax = :expect
20
+ end
21
+
22
+ config.mock_with :rspec do |mocks|
23
+ mocks.syntax = :expect
24
+ mocks.verify_partial_doubles = true
25
+ end
26
+
27
+ config.example_status_persistence_file_path = 'tmp/rspec_examples.txt'
28
+ config.order = :random
29
+ end
30
+
31
+ WebMock.disable_net_connect!(allow_localhost: true)
@@ -0,0 +1,5 @@
1
+ require_relative 'production'
2
+
3
+ Mail.register_interceptor(
4
+ RecipientInterceptor.new(ENV.fetch('EMAIL_RECIPIENTS'))
5
+ )
@@ -0,0 +1,26 @@
1
+ module ActiveSupport
2
+ class TimeZone
3
+ MAPPING.merge!('Noronha' => 'America/Noronha',
4
+ 'Belém' => 'America/Belem',
5
+ 'Fortaleza' => 'America/Fortaleza',
6
+ 'Recife' => 'America/Recife',
7
+ 'Araguaina' => 'America/Araguaina',
8
+ 'Maceió' => 'America/Maceio',
9
+ 'Campo Grande' => 'America/Campo_Grande',
10
+ 'Cuiabá' => 'America/Cuiaba',
11
+ 'Santarém' => 'America/Santarem',
12
+ 'Porto Velho' => 'America/Porto_Velho',
13
+ 'Boa Vista' => 'America/Boa_Vista',
14
+ 'Manaus' => 'America/Manaus',
15
+ 'Eirunepé' => 'America/Eirunepe',
16
+ 'Rio Branco' => 'America/Rio_Branco')
17
+
18
+ def self.br_zones
19
+ @br_zones ||= all.find_all do |z|
20
+ ['Noronha', 'Belém', 'Fortaleza', 'Recife', 'Araguaina', 'Maceió',
21
+ 'Campo Grande', 'Cuiabá', 'Santarém', 'Porto Velho', 'Boa Vista',
22
+ 'Manaus', 'Eirunepé', 'Rio Branco', 'Brasilia'].include?(z.name)
23
+ end
24
+ end
25
+ end
26
+ end