diff --git a/bigbluebutton-config/bin/bbb-record b/bigbluebutton-config/bin/bbb-record index 3d862af135a1b3b3dfebac544a4b2aeff4d159b2..1a6d71dd0b6ab4af7d4de87878b652c084bb03e1 100755 --- a/bigbluebutton-config/bin/bbb-record +++ b/bigbluebutton-config/bin/bbb-record @@ -336,8 +336,8 @@ if [ $LIST ]; then # A -- Archiving # -echo "MeetingID Time APVD APVDE RA Slides Processed Published Description" -echo "------------------------------------------------------ ---------------------------- ---- ----- -- ------ -------------------- -------------------- -----------------------------" +echo "MeetingID Time APVD APVDE RAS Slides Processed Published Description" +echo "------------------------------------------------------ ---------------------------- ---- ----- --- ------ -------------------- -------------------- -----------------------------" if [ -z $HEAD ]; then # If we're not called with --list20, show all recordings @@ -430,7 +430,7 @@ for meeting in $(ls -t /var/bigbluebutton | grep "[0-9]\{13\}$" | head -n $HEAD) # echo -n " " STATUS_DIR=$RAW_PRESENTATION_SRC/recording/status - DIRS="recorded archived" + DIRS="recorded archived sanity" for dir in $DIRS; do if [ -f $STATUS_DIR/$dir/$meeting.done ]; then echo -n "X" diff --git a/record-and-playback/core/lib/recordandplayback/events_archiver.rb b/record-and-playback/core/lib/recordandplayback/events_archiver.rb index 776574db16af14a4fad5761b29e8e5aa228f013f..649b1a66263b1c8e670a93705fa5bbd0c6429d2e 100755 --- a/record-and-playback/core/lib/recordandplayback/events_archiver.rb +++ b/record-and-playback/core/lib/recordandplayback/events_archiver.rb @@ -40,6 +40,18 @@ module BigBlueButton def event_info_for(meeting_id, event) @redis.hgetall("recording:#{meeting_id}:#{event}") + end + + def delete_event_info_for(meeting_id,event) + @redis.del("recording:#{meeting_id}:#{event}") + end + + def delete_events_for(meeting_id) + @redis.del("meeting:#{meeting_id}:recordings") + end + + def delete_metadata_for(meeting_id) + @redis.del("meeting:info:#{meeting_id}") end end @@ -89,6 +101,18 @@ module BigBlueButton end xml.target! end + + def delete_events(meeting_id) + meeting_metadata = @redis.metadata_for(meeting_id) + if (meeting_metadata != nil) + msgs = @redis.events_for(meeting_id) + msgs.each do |msg| + @redis.delete_event_info_for(meeting_id, msg) + end + @redis.delete_events_for(meeting_id) + end + @redis.delete_metadata_for(meeting_id) + end def save_events_to_file(directory, result) File.open("#{directory}/events.xml", 'w') do |f2| diff --git a/record-and-playback/core/scripts/rap-worker.rb b/record-and-playback/core/scripts/rap-worker.rb index 0572cb2588d868322a834efaf7e51355419df109..aa1fd5c2530c85c6be1bfd31a449bc7c65b2689c 100755 --- a/record-and-playback/core/scripts/rap-worker.rb +++ b/record-and-playback/core/scripts/rap-worker.rb @@ -28,10 +28,34 @@ def archive_recorded_meeting(recording_dir) end -def process_archived_meeting(recording_dir) +def sanity_archived_meeting(recording_dir) archived_done_files = Dir.glob("#{recording_dir}/status/archived/*.done") - + sanity_done_files = Dir.glob("#{recording_dir}/status/sanity/*.done") + sanity_failed_files = Dir.glob("#{recording_dir}/status/sanity/*.fail") + archived_done_files.each do |df| + match = /(.*).done/.match df.sub(/.+\//, "") + meeting_id = match[1] + + has_failed = sanity_failed_files.any? { |s| s.include?(meeting_id) } + if(has_failed) + BigBlueButton.logger.info("it has failed sanity check... skipping meeting: #{meeting_id}") + next + end + + is_sanity_check_completed = sanity_done_files.any? { |s| s.include?(meeting_id) } + if(!is_sanity_check_completed) + command = "ruby sanity/sanity.rb -m #{meeting_id}" + BigBlueButton.execute(command) + end + end + +end + +def process_archived_meeting(recording_dir) + sanity_done_files = Dir.glob("#{recording_dir}/status/sanity/*.done") + + sanity_done_files.each do |df| match = /(.*).done/.match df.sub(/.+\//, "") meeting_id = match[1] @@ -101,6 +125,7 @@ end props = YAML::load(File.open('bigbluebutton.yml')) recording_dir = props['recording_dir'] archive_recorded_meeting(recording_dir) +sanity_archived_meeting(recording_dir) process_archived_meeting(recording_dir) publish_processed_meeting(recording_dir) diff --git a/record-and-playback/core/scripts/sanity/sanity.rb b/record-and-playback/core/scripts/sanity/sanity.rb new file mode 100755 index 0000000000000000000000000000000000000000..f3a01a8d270b3eb5cb65d0bf474d833bedaf41db --- /dev/null +++ b/record-and-playback/core/scripts/sanity/sanity.rb @@ -0,0 +1,76 @@ +require '../lib/recordandplayback' +require 'logger' +require 'trollop' +require 'yaml' +require "nokogiri" +require "redis" +require "fileutils" + +def check_events_xml(raw_dir,meeting_id) + filepath = "#{raw_dir}/#{meeting_id}/events.xml" + raise Exception, "Events file doesn't exists." if not File.exists?(filepath) + bad_doc = Nokogiri::XML(File.open(filepath)) { |config| config.options = Nokogiri::XML::ParseOptions::STRICT } +end + +def check_audio_files(raw_dir,meeting_id) + #check every file that is in events.xml, it's in audio dir + doc = Nokogiri::XML(File.open("#{raw_dir}/#{meeting_id}/events.xml")) + + doc.xpath("//event[@eventname='StartRecordingEvent']/filename/text()").each { |fs_audio_file| + audioname = fs_audio_file.content.split("/").last + raw_audio_file = "#{raw_dir}/#{meeting_id}/audio/#{audioname}" + #checking that the audio file exists in raw directory + raise Exception, "Audio file doesn't exists in raw directory." if not File.exists?(raw_audio_file) + + #checking length + raise Exception, "Audio file length is zero." if BigBlueButton::AudioEvents.determine_length_of_audio_from_file(raw_audio_file) <= 0 + } + +end + +BigBlueButton.logger = Logger.new('/var/log/bigbluebutton/sanity.log', 'daily' ) + +opts = Trollop::options do + opt :meeting_id, "Meeting id to archive", :default => '58f4a6b3-cd07-444d-8564-59116cb53974', :type => String +end + +meeting_id = opts[:meeting_id] + +# This script lives in scripts/archive/steps while bigbluebutton.yml lives in scripts/ +props = YAML::load(File.open('bigbluebutton.yml')) + +audio_dir = props['raw_audio_src'] +recording_dir = props['recording_dir'] +raw_archive_dir = "#{recording_dir}/raw" +redis_host = props['redis_host'] +redis_port = props['redis_port'] + +begin + BigBlueButton.logger.info("checking events.xml") + check_events_xml(raw_archive_dir,meeting_id) + BigBlueButton.logger.info("checking audio") + check_audio_files(raw_archive_dir,meeting_id) + #delete keys + BigBlueButton.logger.info("deleting keys") + redis = BigBlueButton::RedisWrapper.new(redis_host, redis_port) + events_archiver = BigBlueButton::RedisEventsArchiver.new redis + events_archiver.delete_events(meeting_id) + + #delete audio + #Dir.glob("#{audio_dir}/#{meeting_id}*.wav").each{ |audio_meeting| + # FileUtils.rm( + #} + + #create done files for sanity + BigBlueButton.logger.info("creating sanity done files") + sanity_done = File.new("#{recording_dir}/status/sanity/#{meeting_id}.done", "w") + sanity_done.write("sanity check #{meeting_id}") + sanity_done.close +rescue Exception => e + BigBlueButton.logger.error("error in sanity check: " + e.message) + sanity_done = File.new("#{recording_dir}/status/sanity/#{meeting_id}.fail", "w") + sanity_done.write("error: " + e.message) + sanity_done.close +end + +