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:
parent
812052a8c7
commit
c6e09f52a1
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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...")
|
||||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user