Skip to content

Commit

Permalink
Add language column to Talk (#140)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoroth committed Aug 19, 2024
1 parent 170e6f1 commit b27b7b9
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ gem "bootsnap", require: false
# All sorts of useful information about every country packaged as convenient little country objects
gem "countries"

# ISO 639-1 and ISO 639-2 language code entries and convenience methods
gem "iso-639"

group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[mri windows]
Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ GEM
irb (1.14.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
iso-639 (0.3.6)
jbuilder (2.12.0)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
Expand Down Expand Up @@ -532,6 +533,7 @@ DEPENDENCIES
google-protobuf
groupdate (~> 6.2)
inline_svg (~> 1.9)
iso-639
jbuilder
json-repair (~> 0.2.0)
litestream (~> 0.10.1)
Expand Down
19 changes: 19 additions & 0 deletions app/avo/filters/language.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Avo::Filters::Language < Avo::Filters::SelectFilter
self.name = "Language"

# self.visible = -> do
# true
# end

def apply(request, query, language)
if language
query.where(language: language)
else
query
end
end

def options
Language.used
end
end
2 changes: 2 additions & 0 deletions app/avo/resources/talk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def fields
record.summary.present?
end
field :description, as: :textarea, hide_on: :index
field :language, hide_on: :index
field :slug, as: :text, hide_on: :index
field :video_id, as: :text, hide_on: :index
field :video_provider, as: :text, hide_on: :index
Expand Down Expand Up @@ -64,5 +65,6 @@ def filters
filter Avo::Filters::Topics
filter Avo::Filters::Title
filter Avo::Filters::Slug
filter Avo::Filters::Language
end
end
30 changes: 30 additions & 0 deletions app/models/language.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class Language
ALL_ALPHA2_CODES = ISO_639::ISO_639_1.map(&:alpha2).freeze
ALL_ENGLISH_NAMES = ISO_639::ISO_639_1.map { |language| language.english_name.split(";").first }.freeze
ALL_LANGUAGES = ALL_ALPHA2_CODES.zip(ALL_ENGLISH_NAMES).to_h.freeze

def self.find(term)
ISO_639
.search(term)
.reject { |result| result.alpha2.blank? }
.first
end

def self.alpha2_codes
ALL_ALPHA2_CODES
end

def self.english_names
ALL_ENGLISH_NAMES
end

def self.all
ALL_LANGUAGES
end

def self.used
assigned_languages = Talk.distinct.pluck(:language)

Language.all.dup.keep_if { |key, value| assigned_languages.include?(key) }
end
end
9 changes: 9 additions & 0 deletions app/models/talk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,21 @@ class Talk < ApplicationRecord

# validations
validates :title, presence: true
validates :language, presence: true,
inclusion: {in: Language.alpha2_codes, message: "%{value} is not a valid IS0-639 alpha2 code"}

# delegates
delegate :name, to: :event, prefix: true, allow_nil: true

# jobs
performs :update_from_yml_metadata!, queue_as: :low

# attributes
attribute :language, default: "en"

# normalization
normalizes :language, with: ->(language) { Language.find(language)&.alpha2 }

# TODO convert to performs
def analyze_talk_topics!
AnalyzeTalkTopicsJob.perform_now(self)
Expand Down Expand Up @@ -151,6 +159,7 @@ def transcript
def update_from_yml_metadata!
self.title = static_metadata.title
self.description = static_metadata.description
self.language = static_metadata.language
self.date = static_metadata.try(:date) || static_metadata.published_at
save
end
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20240818212042_add_language_to_talk.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddLanguageToTalk < ActiveRecord::Migration[7.2]
def change
add_column :talks, :language, :string, null: false, default: "en"
end
end
3 changes: 2 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
tlk.video_id = talk_data["video_id"]
tlk.video_provider = :youtube
tlk.date = talk_data["published_at"]
tlk.language = talk_data["language"]
tlk.thumbnail_xs = talk_data["thumbnail_xs"] || ""
tlk.thumbnail_sm = talk_data["thumbnail_sm"] || ""
tlk.thumbnail_md = talk_data["thumbnail_md"] || ""
Expand Down
Empty file removed test/models/.keep
Empty file.
66 changes: 66 additions & 0 deletions test/models/langauge_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
require "test_helper"

class LanguageTest < ActiveSupport::TestCase
test "all" do
assert_equal Hash, Language.all.class
assert_equal 184, Language.all.length
end

test "all lookup" do
assert_equal "English", Language.all["en"]
assert_equal "French", Language.all["fr"]
assert_equal "German", Language.all["de"]
assert_equal "Japanese", Language.all["ja"]
assert_equal "Portuguese", Language.all["pt"]
assert_equal "Spanish", Language.all["es"]
end

test "alpha2_codes" do
assert_equal Array, Language.alpha2_codes.class
assert_equal 184, Language.alpha2_codes.length
end

test "english_names" do
assert_equal Array, Language.english_names.class
assert_equal 184, Language.english_names.length
end

test "find by full name" do
assert_equal "en", Language.find("English").alpha2
assert_equal "en", Language.find("english").alpha2

assert_equal "ja", Language.find("Japanese").alpha2
assert_equal "ja", Language.find("japanese").alpha2

assert_nil Language.find("random")
assert_nil Language.find("nonexistent")
end

test "find by alpha2 code" do
assert_equal "English", Language.find("en").english_name
assert_equal "English", Language.find("en").english_name

assert_equal "Japanese", Language.find("ja").english_name
assert_equal "Japanese", Language.find("ja").english_name
end

test "find by alpha3 code" do
assert_equal "English", Language.find("eng").english_name
assert_equal "English", Language.find("eng").english_name

assert_equal "Japanese", Language.find("jpn").english_name
assert_equal "Japanese", Language.find("jpn").english_name
end

test "used" do
assert_equal 1, Language.used.length
assert_equal ["en"], Language.used.keys

talk = talks(:two)
talk.language = "Spanish"
talk.save

assert_equal 2, Language.used.length
assert_equal ["en", "es"], Language.used.keys
end
end
27 changes: 27 additions & 0 deletions test/models/talk_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,31 @@ class TalkTest < ActiveSupport::TestCase
@talk.update_from_yml_metadata!
assert_equal "Hotwire Cookbook: Common Uses, Essential Patterns & Best Practices", @talk.title
end

test "language is english by default" do
assert_equal "en", Talk.new.language
end

test "language is normalized to alpha2 code" do
assert_equal "en", Talk.new(language: "English").language
assert_equal "en", Talk.new(language: "english").language
assert_equal "en", Talk.new(language: "en").language

assert_equal "ja", Talk.new(language: "Japanese").language
assert_equal "ja", Talk.new(language: "japanese").language
assert_equal "ja", Talk.new(language: "ja").language

assert_nil Talk.new(language: "doesntexist").language
assert_nil Talk.new(language: "random").language
end

test "language must be valid and present" do
talk = talks(:one)
talk.language = "random"
talk.valid?

assert_equal 2, talk.errors.size
assert_equal ["Language can't be blank", "Language is not a valid IS0-639 alpha2 code"],
talk.errors.map(&:full_message)
end
end

0 comments on commit b27b7b9

Please sign in to comment.