Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ gem 'redcarpet'
gem 'responders'
gem 'rest-client'
gem 'sass-rails'
gem 'sidekiq-cron'
gem 'simple_form'
gem 'slim-rails'
gem 'uglifier', '>= 2.5.0'
Expand Down
16 changes: 16 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ GEM
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.1.5)
connection_pool (2.2.2)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.4)
Expand All @@ -123,6 +124,8 @@ GEM
railties (>= 3.2, < 6.1)
equalizer (0.0.11)
erubi (1.8.0)
et-orbi (1.2.2)
tzinfo
eventmachine (1.0.9.1)
execjs (2.7.0)
factory_bot (5.0.2)
Expand All @@ -135,6 +138,9 @@ GEM
font-awesome-rails (4.7.0.5)
railties (>= 3.2, < 6.1)
formatador (0.2.5)
fugit (1.3.3)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
guard (2.15.0)
Expand Down Expand Up @@ -245,6 +251,7 @@ GEM
nio4r (~> 2.0)
pundit (2.1.0)
activesupport (>= 3.0.0)
raabro (1.1.6)
rack (2.0.7)
rack-cache (1.9.0)
rack (>= 0.4)
Expand Down Expand Up @@ -360,6 +367,14 @@ GEM
shellany (0.0.1)
shoulda-matchers (4.1.2)
activesupport (>= 4.2.0)
sidekiq (6.0.3)
connection_pool (>= 2.2.2)
rack (>= 2.0.0)
rack-protection (>= 2.0.0)
redis (>= 4.1.0)
sidekiq-cron (1.1.0)
fugit (~> 1.1)
sidekiq (>= 4.2.1)
simple_form (4.1.0)
actionpack (>= 5.0)
activemodel (>= 5.0)
Expand Down Expand Up @@ -476,6 +491,7 @@ DEPENDENCIES
rspec-rails (>= 3.1)
sass-rails
shoulda-matchers
sidekiq-cron
simple_form
simplecov
slim-rails
Expand Down
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
web: jemalloc.sh bundle exec puma -e ${RACK_ENV:-staging} -C config/puma.rb -p ${PORT:-3000}
worker: jemalloc.sh bundle exec sidekiq -q default -q mailers -c 3
34 changes: 6 additions & 28 deletions app/controllers/api/v1/translations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
module API
module V1
class TranslationsController < ApiController

def index_head
stale? etag: index_etag
stale? etag: current_project.translation_cache
head :ok
end

def index
return unless stale? etag: index_etag
cache_key = "#{current_project.id}-#{params[:format]}"

if translation_cache = TranslationCache.find_cache(kind: cache_key, etag: index_etag)
response.headers['CustomCache'] = index_etag.to_json
render status: 200, plain: translation_cache.cache
else
@output = Translation.dump_hash current_project.translations.include_dependencies

TranslationCache.cache(kind: cache_key, etag: index_etag, cache: dump_cache(@output))

respond_with @output
if stale? etag: current_project.translation_cache
respond_to do |format|
format.yaml { render status: 200, plain: current_project.translation_cache.cache_yaml }
format.json { render status: 200, plain: current_project.translation_cache.cache_json }
end
end
end

Expand Down Expand Up @@ -79,20 +71,6 @@ def create

private

def dump_cache(output)
case params[:format]
when 'json' then output.to_json
when 'yaml' then YAML.dump(output).html_safe
else output.to_json
end
end

def index_etag
translation = current_project.translations.unscope(:order).order(:updated_at).last
updated_at = translation ? translation.updated_at : ''
[updated_at]
end

def translation_params(data)
text = data[:text]
{ text: text.is_a?(Array) ? YAML.dump(text).gsub("---\n", '') : text }
Expand Down
3 changes: 3 additions & 0 deletions app/jobs/application_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class ApplicationJob < ActiveJob::Base
queue_as :default
end
7 changes: 7 additions & 0 deletions app/jobs/scheduled/cache_translations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Scheduled
class CacheTranslations < ApplicationJob
def perform
Project.find_each(&:cache_translations!)
end
end
end
15 changes: 15 additions & 0 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,27 @@ class Project < ApplicationRecord
has_many :images, through: :locations

has_one :default_locale, class_name: 'Locale'
has_one :translation_cache
has_and_belongs_to_many :users

before_create :ensure_api_token
validates :api_token, uniqueness: true
validates :name, length: { minimum: 3 }, uniqueness: true

def cache_translations!
cache = translation_cache || build_translation_cache
last_updated_at = translations.maximum(:updated_at)

return if last_updated_at && cache.persisted? &&
cache.updated_at > last_updated_at

output = Translation.dump_hash(translations.include_dependencies)
cache.update(
cache_yaml: YAML.dump(output).html_safe,
cache_json: output.to_json,
)
end

def to_s
name
end
Expand Down
19 changes: 1 addition & 18 deletions app/models/translation_cache.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
require 'digest'

class TranslationCache < ApplicationRecord

def self.find_cache(kind:, etag:)
find_by(kind: kind, etag: build_etag(etag))
end

def self.cache(kind:, etag:, cache:)
if cached = find_by(kind: kind)
cached.update(etag: build_etag(etag), cache: cache)
else
create(kind: kind, etag: build_etag(etag), cache: cache)
end
end

def self.build_etag(etag)
Digest::MD5.hexdigest(etag.to_json)
end
belongs_to :project
end
2 changes: 1 addition & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
# config.action_controller.asset_host = 'http://assets.example.com'

# Use a real queuing backend for Active Job (and separate queues per environment)
# config.active_job.queue_adapter = :resque
config.active_job.queue_adapter = :sidekiq
# config.active_job.queue_name_prefix = "translation_server_#{Rails.env}"

config.action_mailer.perform_caching = false
Expand Down
5 changes: 5 additions & 0 deletions config/initializers/sidekiq.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
schedule_file = "config/schedule.yml"

if File.exist?(schedule_file) && Sidekiq.server?
Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
end
6 changes: 6 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
require 'sidekiq/web'
require 'sidekiq/cron/web'

Rails.application.routes.draw do
authenticate :user, lambda { |user| user.admin? } do
mount Sidekiq::Web => '/sidekiq'
end

resources :projects do
resources :releases, except: [:edit, :update], shallow: true
Expand Down
4 changes: 4 additions & 0 deletions config/schedule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cache_translations:
active_job: true
cron: '* * * * *'
class: 'Scheduled::CacheTranslations'
2 changes: 1 addition & 1 deletion db/migrate/20150227171322_create_locales.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateLocales < ActiveRecord::Migration
class CreateLocales < ActiveRecord::Migration[4.2]
def change
create_table :locales do |t|
t.string :code
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150227171335_create_keys.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateKeys < ActiveRecord::Migration
class CreateKeys < ActiveRecord::Migration[4.2]
def change
create_table :keys do |t|
t.string :key
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150227172303_create_translations.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateTranslations < ActiveRecord::Migration
class CreateTranslations < ActiveRecord::Migration[4.2]
def change
create_table :translations do |t|
t.belongs_to :key, index: true
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150227202414_create_locations.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateLocations < ActiveRecord::Migration
class CreateLocations < ActiveRecord::Migration[4.2]
def change
create_table :locations do |t|
t.string :path
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150227202429_create_images.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateImages < ActiveRecord::Migration
class CreateImages < ActiveRecord::Migration[4.2]
def change
create_table :images do |t|
t.belongs_to :location, index: true
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150227210934_add_array_to_keys.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddArrayToKeys < ActiveRecord::Migration
class AddArrayToKeys < ActiveRecord::Migration[4.2]
def change
change_table :keys do |t|
t.boolean :array, default: false
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150302094322_devise_create_users.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class DeviseCreateUsers < ActiveRecord::Migration
class DeviseCreateUsers < ActiveRecord::Migration[4.2]
def change
create_table(:users) do |t|
## Database authenticatable
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150303060757_add_api_key_to_users.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddAPIKeyToUsers < ActiveRecord::Migration
class AddAPIKeyToUsers < ActiveRecord::Migration[4.2]
def change
add_column :users, :api_key, :string
add_index :users, :api_key
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150303145712_add_float_and_integer_to_keys.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddFloatAndIntegerToKeys < ActiveRecord::Migration
class AddFloatAndIntegerToKeys < ActiveRecord::Migration[4.2]
def change
add_column :keys, :data_type, :string, default: 'string'
remove_column :keys, :array
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150303172656_create_highlights.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateHighlights < ActiveRecord::Migration
class CreateHighlights < ActiveRecord::Migration[4.2]
def change
create_table :highlights do |t|
t.belongs_to :image, index: true
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150309091603_create_releases.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateReleases < ActiveRecord::Migration
class CreateReleases < ActiveRecord::Migration[4.2]
def change
create_table :releases do |t|
t.belongs_to :locale, index: true
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150624115221_add_edited_to_translations.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddEditedToTranslations < ActiveRecord::Migration
class AddEditedToTranslations < ActiveRecord::Migration[4.2]
def change
add_column :translations, :edited, :boolean, default: false
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddLocaleToHighlightsAndImages < ActiveRecord::Migration
class AddLocaleToHighlightsAndImages < ActiveRecord::Migration[4.2]
def change
change_table :highlights do |t|
t.belongs_to :locale, index: true
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150709133711_add_indexes_to_tables.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddIndexesToTables < ActiveRecord::Migration
class AddIndexesToTables < ActiveRecord::Migration[4.2]
def change
add_index :locales, :code
add_index :locations, :path
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150723093015_add_role_to_user.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddRoleToUser < ActiveRecord::Migration
class AddRoleToUser < ActiveRecord::Migration[4.2]
def change
add_column :users, :role, :string

Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20150723093349_add_available_locales_to_user.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddAvailableLocalesToUser < ActiveRecord::Migration
class AddAvailableLocalesToUser < ActiveRecord::Migration[4.2]
def change
add_column :users, :available_locales, :string, array: true
end
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20151023072435_remove_windows_new_lines.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class RemoveWindowsNewLines < ActiveRecord::Migration
class RemoveWindowsNewLines < ActiveRecord::Migration[4.2]
def up
Translation.where('text like ?', '%&#13;%').each do |translation|
translation.update text: translation.text.gsub('&#13;', '')
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20151130092008_create_translation_cache.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateTranslationCache < ActiveRecord::Migration
class CreateTranslationCache < ActiveRecord::Migration[4.2]
def change
create_table :translation_caches do |t|
t.string :etag
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20160912122000_create_projects.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateProjects < ActiveRecord::Migration
class CreateProjects < ActiveRecord::Migration[4.2]
def change
create_table :projects do |t|
t.string :name
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20160912122302_create_default_project.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateDefaultProject < ActiveRecord::Migration
class CreateDefaultProject < ActiveRecord::Migration[4.2]
def up
unless Project.where(id: 1).first
Key.update_all(project_id: 1)
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20160912131046_add_projects_users.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddProjectsUsers < ActiveRecord::Migration
class AddProjectsUsers < ActiveRecord::Migration[4.2]
def change
create_table :projects_users do |t|
t.integer :project_id, index: true
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20160912131153_setup_default_connections.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class SetupDefaultConnections < ActiveRecord::Migration
class SetupDefaultConnections < ActiveRecord::Migration[4.2]
def up
users = User.all.to_a
Project.all.each do |project|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddValidationForKeyInProject < ActiveRecord::Migration
class AddValidationForKeyInProject < ActiveRecord::Migration[4.2]
def change
add_index :keys, [:key, :project_id], unique: true
end
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20161024155634_create_restricted_ips.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateRestrictedIps < ActiveRecord::Migration
class CreateRestrictedIps < ActiveRecord::Migration[4.2]
def change
create_table :restricted_ips do |t|
t.inet :ip
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20161111083528_add_screenshots_to_projects.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AddScreenshotsToProjects < ActiveRecord::Migration
class AddScreenshotsToProjects < ActiveRecord::Migration[4.2]
def change
change_table :projects do |t|
t.boolean :screenshots, default: false
Expand Down
15 changes: 15 additions & 0 deletions db/migrate/20191214163720_add_assocition_project_to_cache.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class AddAssocitionProjectToCache < ActiveRecord::Migration[5.2]
def change
drop_table :translation_caches

create_table :translation_caches do |t|
t.belongs_to :project, index: true, foreign_key: true, null: false
t.text :cache_yaml
t.text :cache_json

t.timestamps
end

Scheduled::CacheTranslations.new.perform
end
end
Loading