diff --git a/app/liquid_tags/youtube_tag.rb b/app/liquid_tags/youtube_tag.rb index 35aae1131..80716705d 100644 --- a/app/liquid_tags/youtube_tag.rb +++ b/app/liquid_tags/youtube_tag.rb @@ -1,5 +1,10 @@ class YoutubeTag < LiquidTagBase PARTIAL = "liquids/youtube".freeze + MARKER_TO_SECONDS_MAP = { + "h" => 60 * 60, + "m" => 60, + "s" => 1 + }.freeze def initialize(_tag_name, id, _parse_context) super @@ -29,19 +34,23 @@ class YoutubeTag < LiquidTagBase input_no_space end - def translate_start_time(id) - time = id.split("?t=")[-1] - time_hash = { - h: time.scan(/\d+h/)[0]&.delete("h").to_i, - m: time.scan(/\d+m/)[0]&.delete("m").to_i, - s: time.scan(/\d+s/)[0]&.delete("s").to_i - } - time_in_seconds = (time_hash[:h] * 3600) + (time_hash[:m] * 60) + time_hash[:s] - "#{id.split('?t=')[0]}?start=#{time_in_seconds}" + def valid_id?(id) + id.match?(/\A[a-zA-Z0-9_-]{11}((\?t=)?(\d{1,}h?)?(\d{1,2}m)?(\d{1,2}s)?){5,11}?\Z/) end - def valid_id?(id) - id =~ /\A[a-zA-Z0-9_-]{11}((\?t=)?(\d{1}h)?(\d{1,2}m)?(\d{1,2}s)?){5,11}?\Z/ + def translate_start_time(id) + time = id.split("?t=")[-1] + return "#{id.split('?t=')[0]}?start=#{time}" if time.match?(/\A\d+\Z/) + + time_elements = time.split(/[a-z]/) + time_markers = time.split(/\d+/)[1..] + + seconds = 0 + time_markers.each_with_index do |m, i| + seconds += MARKER_TO_SECONDS_MAP.fetch(m, 0) * time_elements[i].to_i + end + + "#{id.split('?t=')[0]}?start=#{seconds}" end end diff --git a/spec/liquid_tags/youtube_tag_spec.rb b/spec/liquid_tags/youtube_tag_spec.rb index 43d63e349..10ac89c54 100644 --- a/spec/liquid_tags/youtube_tag_spec.rb +++ b/spec/liquid_tags/youtube_tag_spec.rb @@ -3,22 +3,9 @@ require "rails_helper" RSpec.describe YoutubeTag, type: :liquid_tag do describe "#id" do let(:valid_id_no_time) { "dQw4w9WgXcQ" } - let(:valid_ids_with_time) { "QASbw8_0meM?t=8h12m26s" } + let(:valid_id_with_time) { "QASbw8_0meM?t=8h12m26s" } let(:invalid_id) { Faker::Lorem.characters(number: rand(12..100)) } - def parsed_id(id) - return id unless id.include?("?t=") - - id_array = id.split("?t=") - time_hash = { - h: id_array[1].scan(/\d+h/)[0]&.delete("h").to_i, - m: id_array[1].scan(/\d+m/)[0]&.delete("m").to_i, - s: id_array[1].scan(/\d+s/)[0]&.delete("s").to_i - } - time_string = ((time_hash[:h] * 3600) + (time_hash[:m] * 60) + time_hash[:s]).to_s - "#{id_array[0]}?start=#{time_string}" - end - def generate_new_liquid(id) Liquid::Template.register_tag("youtube", YoutubeTag) Liquid::Template.parse("{% youtube #{id} %}") @@ -33,7 +20,7 @@ RSpec.describe YoutubeTag, type: :liquid_tag do end it "accepts valid YouTube ID with starting times" do - liquid = generate_new_liquid(valid_ids_with_time).render + liquid = generate_new_liquid(valid_id_with_time).render expect(liquid).to include('