RaP Caption inbox: read uploaded caption json file

Some additional validation/normalization is added for the language tag,
and some cleanup has been done for logging.
This commit is contained in:
Calvin Walton 2019-05-10 14:06:23 -04:00
parent 812052a8c7
commit c6e09f52a1
4 changed files with 97 additions and 24 deletions

View File

@ -19,16 +19,18 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "redis"
gem "nokogiri"
gem "loofah"
gem "rubyzip"
gem "builder"
gem "trollop", "2.1.3"
gem "open4"
gem "fastimage"
gem "absolute_time" gem "absolute_time"
gem "jwt" gem "builder"
gem "java_properties" gem "fastimage"
gem "fnv" gem "fnv"
gem "java_properties"
gem "journald-logger"
gem "jwt"
gem "locale"
gem "loofah"
gem "nokogiri"
gem "open4"
gem "rb-inotify" gem "rb-inotify"
gem "redis"
gem "rubyzip"
gem "trollop", "2.1.3"

View File

@ -8,7 +8,11 @@ GEM
ffi (1.10.0) ffi (1.10.0)
fnv (0.2.0) fnv (0.2.0)
java_properties (0.0.4) java_properties (0.0.4)
journald-logger (2.0.4)
journald-native (~> 1.0)
journald-native (1.0.11)
jwt (2.1.0) jwt (2.1.0)
locale (2.1.2)
loofah (2.2.3) loofah (2.2.3)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
@ -31,7 +35,9 @@ DEPENDENCIES
fastimage fastimage
fnv fnv
java_properties java_properties
journald-logger
jwt jwt
locale
loofah loofah
nokogiri nokogiri
open4 open4

View File

@ -18,24 +18,22 @@
# along with BigBlueButton. If not, see <http://www.gnu.org/licenses/>. # along with BigBlueButton. If not, see <http://www.gnu.org/licenses/>.
require "rubygems" require "rubygems"
require "bundler/setup"
require File.expand_path("../../lib/recordandplayback", __FILE__)
require "journald-logger"
require "locale"
require "rb-inotify" require "rb-inotify"
require "yaml" require "yaml"
require "logger"
props = YAML::load(File.open("bigbluebutton.yml")) # Read configuration and set up logger
props = YAML::load(File.open(File.expand_path("../bigbluebutton.yml", __FILE__)))
log_dir = props["log_dir"] log_dir = props["log_dir"]
logger = Logger.new(STDERR) logger = Journald::Logger.new("bbb-rap-caption-inbox")
logger.level = Logger::INFO BigBlueButton.logger = logger
# TODO: I need to set the Bigbluebutton logger here if I load the other rap code
def handle_caption_file(filename)
# There's a possible race condition where we can be notified twice for a new
# file. That's fine, just do nothing the second time.
return unless File.exist?(filename)
logger.info("Found new caption index file #{filename}")
end
captions_dir = props["captions_dir"] captions_dir = props["captions_dir"]
unless captions_dir unless captions_dir
@ -44,6 +42,64 @@ unless captions_dir
end end
captions_inbox_dir = File.join(captions_dir, "inbox") captions_inbox_dir = File.join(captions_dir, "inbox")
# Internal error classes
# Base class for internal errors
class CaptionError < StandardError
end
# Indicates that uploaded caption files are invalid (unrecoverable)
class InvalidCaptionError < CaptionError
end
# Implementation
def caption_file_notify(json_filename)
# There's a possible race condition where we can be notified twice for a new
# file. That's fine, just do nothing the second time.
return unless File.exist?(json_filename)
logger.info("Found new caption index file #{json_filename}")
# TODO: Rather than do anything directly in this script, it should create a
# queue job (resque?) that does the actual work.
new_caption_info = File.open(json_filename) { |file| JSON.parse(file) }
logger.tag(record_id: new_caption_info["record_id"]) do
# TODO: This is racy if multiple tools are editing the captions.json file
captions_info = begin
File.open(
File.join(captions_dir, new_caption_info["record_id"], "captions.json")
) do |file|
JSON.parse(file)
end
rescue
# No captions file or cannot be read, assume none present
[]
end
langtag = Locale::Tag::Rfc.parse(new_caption_info["lang"])
raise InvalidCaptionError, "Language tag is not well-formed" unless langtag
# Remove the info for an existing matching track
captions_info.delete_if do |caption_info|
caption_info["lang"] == new_caption_info["lang"] &&
caption_info["kind"] == new_caption_info["kind"]
end
captions_info << {
"kind" => new_caption_info["kind"],
"label" => new_caption_info["label"],
"lang" => langtag.to_s,
"source" => "upload",
}
dest_filename = "#{captions_info["kind"]}_#{captions_info["lang"]}.vtt"
end
end
logger.info("Setting up inotify watch on #{captions_inbox_dir}") logger.info("Setting up inotify watch on #{captions_inbox_dir}")
notifier = INotify::Notifier.new notifier = INotify::Notifier.new
notifier.watch(captions_inbox_dir, :moved_to, :create) do |event| notifier.watch(captions_inbox_dir, :moved_to, :create) do |event|
@ -54,7 +110,7 @@ end
logger.info("Checking for missed/skipped caption files") logger.info("Checking for missed/skipped caption files")
Dir.glob(File.join(captions_inbox_dir, "*-track.json")).each do |filename| Dir.glob(File.join(captions_inbox_dir, "*-track.json")).each do |filename|
handle_caption_file(filename) caption_file_notify(filename)
end end
logger.info("Waiting for new caption files...") logger.info("Waiting for new caption files...")

View File

@ -0,0 +1,9 @@
[Unit]
Description=BigBlueButton recording caption upload handler
[Service]
Type=simple
ExecStart=/usr/local/bigbluebutton/core/scripts/rap-caption-inbox.rb
User=bigbluebutton
Slice=bbb_record_core.slice
Restart=on-failure