Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

akonhilas/APPEALS-31620 #20788

Merged
merged 13 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/jobs/hearings/download_transcription_file_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def hearing
def parse_hearing
identifiers = file_name.split(".").first
hearing_id = identifiers.split("_")[1]
hearing_type = identifiers.split("_")[2]
hearing_type = identifiers.split("_").last.split("-").first
hearing_type.constantize.find(hearing_id)
rescue StandardError => error
raise FileNameError, "Encountered error #{error} when attempting to parse hearing from file name '#{file_name}'"
Expand All @@ -130,7 +130,7 @@ def docket_number
#
# Returns: TranscriptionFile object
def find_or_create_transcription_file(file_name_arg = file_name)
Hearings::TranscriptionFile.find_or_create_by(
TranscriptionFile.find_or_create_by(
file_name: file_name_arg,
hearing_id: hearing.id,
hearing_type: hearing.class.name,
Expand Down
68 changes: 68 additions & 0 deletions app/jobs/hearings/get_webex_recordings_details_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

# This job will retrieve a list of webex hearing recording detail links
# and download the information from the links

class Hearings::GetWebexRecordingsDetailsJob < CaseflowJob
include Hearings::EnsureCurrentUserIsSet

queue_with_priority :low_priority
application_attr :hearing_schedule
attr_reader :id

retry_on(Caseflow::Error::WebexApiError, wait: :exponentially_longer) do |job, exception|
# TO IMPLEMENT: SEND EMAIL TO VA OPS TEAM
job.log_error(exception)
end

def perform(id:)
konhilas-ariana marked this conversation as resolved.
Show resolved Hide resolved
ensure_current_user_is_set
data = get_recording_details(id)
topic = data.topic

mp4_link = data.mp4_link
send_file(topic, "mp4", mp4_link)

vtt_link = data.vtt_link
send_file(topic, "vtt", vtt_link)

mp3_link = data.mp3_link
send_file(topic, "mp3", mp3_link)
end

def log_error(error)
Rails.logger.error("Retrying #{self.class.name} because failed with error: #{error}")
extra = {
application: self.class.name,
job_id: job_id
}
Raven.capture_exception(error, extra: extra)
end

private

def get_recording_details(id)
query = { "id": id }

WebexService.new(
host: ENV["WEBEX_HOST_MAIN"],
port: ENV["WEBEX_PORT"],
aud: ENV["WEBEX_ORGANIZATION"],
apikey: ENV["WEBEX_BOTTOKEN"],
domain: ENV["WEBEX_DOMAIN_MAIN"],
api_endpoint: ENV["WEBEX_API_MAIN"],
query: query
).get_recording_details
end

def create_file_name(topic, extension)
subject = topic.split("-").second.lstrip
counter = topic.split("-").last
"#{subject}-#{counter}.#{extension}"
end

def send_file(topic, extension, link)
file_name = create_file_name(topic, extension)
Hearings::DownloadTranscriptionFileJob.perform_later(download_link: link, file_name: file_name)
end
end
6 changes: 1 addition & 5 deletions app/jobs/hearings/get_webex_recordings_list_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Hearings::GetWebexRecordingsListJob < CaseflowJob
def perform
ensure_current_user_is_set
get_recordings_list.ids.each do |n|
get_recording_details(n)
Hearings::GetWebexRecordingsDetailsJob.perform_later(id: n)
end
end

Expand Down Expand Up @@ -47,8 +47,4 @@ def get_recordings_list
query: query
).get_recordings_list
end

def get_recording_details(id)
nil
end
end
4 changes: 2 additions & 2 deletions app/models/hearings/transcription_file.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

class Hearings::TranscriptionFile < CaseflowRecord
class TranscriptionFile < CaseflowRecord
include BelongsToPolymorphicHearingConcern
belongs_to_polymorphic_hearing :hearing

Expand All @@ -25,7 +25,7 @@ def convert_to_rtf!
hearing_info = {
judge: hearing.judge&.full_name,
appeal_id: hearing.appeal&.veteran_file_number,
date: hearing.scheduled_time
date: hearing.scheduled_for
}
file_paths = TranscriptionTransformer.new(tmp_location, hearing_info).call
update_status!(process: :conversion, status: :success)
Expand Down
9 changes: 9 additions & 0 deletions app/services/external_api/webex_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ def get_recordings_list
ExternalApi::WebexService::RecordingsListResponse.new(resp)
end

def get_recording_details
body = nil
method = "GET"
resp = send_webex_request(body, method)
return if resp.nil?

ExternalApi::WebexService::RecordingDetailsResponse.new(resp)
end

private

# :nocov:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

class ExternalApi::WebexService::RecordingDetailsResponse < ExternalApi::WebexService::Response
def data
JSON.parse(resp.raw_body)
end

def mp4_link
data["temporaryDirectDownloadLinks"]["recordingDownloadLink"]
end

def vtt_link
data["temporaryDirectDownloadLinks"]["transcriptionDownloadLink"]
end

def mp3_link
data["temporaryDirectDownloadLinks"]["audioDownloadLink"]
end

def topic
data["topic"]
end
end
79 changes: 64 additions & 15 deletions lib/fakes/webex_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ def get_recordings_list
)
end

def get_recording_details
if error?
return ExternalApi::WebexService::RecordingDetailsResponse.new(
HTTPI::Response.new(@status_code, {}, error_response)
)
end

ExternalApi::WebexService::RecordingDetailsResponse.new(
HTTPI::Response.new(
200,
{},
fake_recording_details_data.to_json
)
)
end

# rubocop:disable Metrics/MethodLength
def fake_recordings_list_data
{
Expand All @@ -78,7 +94,7 @@ def fake_recordings_list_data
"meetingId": "f91b6edce9864428af084977b7c68291_I_166641849979635652",
"scheduledMeetingId": "f91b6edce9864428af084977b7c68291_20200713T121500Z",
"meetingSeriesId": "f91b6edce9864428af084977b7c68291",
"topic": "200103-61110_2000061110_Appeal",
"topic": "200103-61110_2000061110_Hearing",
"createTime": "2020-07-13T17:11:35Z",
"timeRecorded": "2020-07-13T17:05:35Z",
"siteUrl": "site4-example.webex.com",
Expand All @@ -90,10 +106,10 @@ def fake_recordings_list_data
"durationSeconds": 18_416,
"sizeBytes": 168_103,
"shareToMe": false,
"integrationTags": [
"dbaeceebea5c4a63ac9d5ef1edfe36b9",
"85e1d6319aa94c0583a6891280e3437d",
"27226d1311b947f3a68d6bdf8e4e19a1"
"integrationTags": %w[
dbaeceebea5c4a63ac9d5ef1edfe36b9
85e1d6319aa94c0583a6891280e3437d
27226d1311b947f3a68d6bdf8e4e19a1
],
"status": "available"
},
Expand All @@ -102,7 +118,7 @@ def fake_recordings_list_data
"meetingId": "f91b6edce9864428af084977b7c68291_I_166641849979635652",
"scheduledMeetingId": "f91b6edce9864428af084977b7c68291_20200713T121500Z",
"meetingSeriesId": "f91b6edce9864428af084977b7c68291",
"topic": "150000248290335_343_LegacyAppeal",
"topic": "150000248290336_302_LegacyHearing",
"createTime": "2020-07-13T17:11:34Z",
"timeRecorded": "2020-07-13T17:05:35Z",
"siteUrl": "site4-example.webex.com",
Expand All @@ -114,10 +130,10 @@ def fake_recordings_list_data
"durationSeconds": 181_562,
"sizeBytes": 199_134,
"shareToMe": false,
"integrationTags": [
"dbaeceebea5c4a63ac9d5ef1edfe36b9",
"85e1d6319aa94c0583a6891280e3437d",
"27226d1311b947f3a68d6bdf8e4e19a1"
"integrationTags": %w[
dbaeceebea5c4a63ac9d5ef1edfe36b9
85e1d6319aa94c0583a6891280e3437d
27226d1311b947f3a68d6bdf8e4e19a1
],
"status": "available"
},
Expand All @@ -126,7 +142,7 @@ def fake_recordings_list_data
"meetingId": "f91b6edce9864428af084977b7c68291_I_166641849979635652",
"scheduledMeetingId": "f91b6edce9864428af084977b7c68291_20200713T121500Z",
"meetingSeriesId": "f91b6edce9864428af084977b7c68291",
"topic": "231207-1177_1177_Appeal",
"topic": "231207-1177_1177_Hearing",
"createTime": "2020-07-13T17:11:33Z",
"timeRecorded": "2020-07-13T17:05:35Z",
"siteUrl": "site4-example.webex.com",
Expand All @@ -138,16 +154,49 @@ def fake_recordings_list_data
"durationSeconds": 181_562,
"sizeBytes": 199_134,
"shareToMe": true,
"integrationTags": [
"dbaeceebea5c4a63ac9d5ef1edfe36b9",
"85e1d6319aa94c0583a6891280e3437d",
"27226d1311b947f3a68d6bdf8e4e19a1"
"integrationTags": %w[
dbaeceebea5c4a63ac9d5ef1edfe36b9
85e1d6319aa94c0583a6891280e3437d
27226d1311b947f3a68d6bdf8e4e19a1
],
"status": "available"
}
]
}
end

def fake_recording_details_data
{
"id": "4f914b1dfe3c4d11a61730f18c0f5387",
"meetingId": "f91b6edce9864428af084977b7c68291_I_166641849979635652",
"scheduledMeetingId": "f91b6edce9864428af084977b7c68291_20200713T121500Z",
"meetingSeriesId": "f91b6edce9864428af084977b7c68291",
"topic": "Virtual Visit - 180000304_1_LegacyHearing-20240213 1712-1",
"createTime": "2020-07-13T17:11:35Z",
"timeRecorded": "2020-07-13T17:05:35Z",
"siteUrl": "site4-example.webex.com",
"downloadUrl": "https://site4-example.webex.com/site4/lsr.php?RCID=b91990e37417bda24986e46cf43345ab",
"playbackUrl": "https://site4-example.webex.com/site4/ldr.php?RCID=69201a61d1d94a84aca18817261d1a73",
"password": "BgJep@43",
"temporaryDirectDownloadLinks": {
"recordingDownloadLink": "https://www.learningcontainer.com/mp4-sample-video-files-download/#",
"audioDownloadLink": "https://freetestdata.com/audio-files/mp3/",
"transcriptionDownloadLink": "https://www.capsubservices.com/assets/downloads/web/WebVTT.vtt",
"expiration": "2022-05-01T10:30:25Z"
},
"format": "ARF",
"serviceType": "MeetingCenter",
"durationSeconds": 18_416,
"sizeBytes": 168_103,
"shareToMe": false,
"integrationTags": %w[
dbaeceebea5c4a63ac9d5ef1edfe36b9
85e1d6319aa94c0583a6891280e3437d
27226d1311b947f3a68d6bdf8e4e19a1
],
"status": "available"
}
end
# rubocop:enable Metrics/MethodLength

private
Expand Down
18 changes: 9 additions & 9 deletions spec/jobs/hearings/download_transcription_file_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
let(:docket_number) { hearing.docket_number }
let(:file_name) { "#{docket_number}_#{hearing.id}_#{hearing.class}.#{file_type}" }
let(:tmp_location) { File.join(Rails.root, "tmp", "transcription_files", file_type, file_name) }
let(:transcription_file) { Hearings::TranscriptionFile.find_by(file_name: file_name) }
let(:transcription_file) { TranscriptionFile.find_by(file_name: file_name) }
let(:s3_sub_bucket) { "vaec-appeals-caseflow" }
let(:folder_name) { (Rails.deploy_env == :prod) ? s3_sub_bucket : "#{s3_sub_bucket}-#{Rails.deploy_env}" }
let(:s3_sub_folders) do
Expand All @@ -30,7 +30,7 @@

shared_examples "all file types" do
it "saves downloaded file to correct tmp sub-directory" do
allow_any_instance_of(Hearings::TranscriptionFile).to receive(:clean_up_tmp_location).and_return(nil)
allow_any_instance_of(TranscriptionFile).to receive(:clean_up_tmp_location).and_return(nil)
subject
expect(File.exist?(tmp_location)).to be true
end
Expand All @@ -54,7 +54,7 @@
shared_examples "failed download from Webex" do
it "raises error and creates TranscriptionFileRecord" do
expect { subject }.to raise_error(Hearings::DownloadTranscriptionFileJob::FileDownloadError)
.and change(Hearings::TranscriptionFile, :count).by(1)
.and change(TranscriptionFile, :count).by(1)
end

it "updates file_status of TranscriptionFile record, leaves date_receipt_webex nil" do
Expand All @@ -77,7 +77,7 @@

context "successful download from Webex and upload to S3" do
it "creates new TranscriptionFile record" do
expect { subject }.to change(Hearings::TranscriptionFile, :count).by(1)
expect { subject }.to change(TranscriptionFile, :count).by(1)
expect(transcription_file.file_type).to eq(file_type)
end

Expand All @@ -100,7 +100,7 @@
shared_context "convertible file" do
let(:converted_file_name) { file_name.gsub(file_type, conversion_type) }
let(:converted_tmp_location) { tmp_location.gsub(file_type, conversion_type) }
let(:converted_transcription_file) { Hearings::TranscriptionFile.find_by(file_name: converted_file_name) }
let(:converted_transcription_file) { TranscriptionFile.find_by(file_name: converted_file_name) }
let(:converted_s3_location) { "#{folder_name}/#{s3_sub_folders[conversion_type.to_sym]}/#{converted_file_name}" }

it "updates date_receipt_webex of TranscriptionFile record" do
Expand Down Expand Up @@ -133,7 +133,7 @@
after { File.delete(converted_tmp_location) if File.exist?(converted_tmp_location) }

it "creates two new TranscriptionFile records" do
expect { subject }.to change(Hearings::TranscriptionFile, :count).by(2)
expect { subject }.to change(TranscriptionFile, :count).by(2)
expect(transcription_file.file_type).to eq(file_type)
expect(converted_transcription_file.file_type).to eq(conversion_type)
end
Expand Down Expand Up @@ -171,7 +171,7 @@
include_context "convertible file"

it "creates three new TranscriptionFile records" do
expect { subject }.to change(Hearings::TranscriptionFile, :count).by(3)
expect { subject }.to change(TranscriptionFile, :count).by(3)
expect(transcription_file.file_type).to eq(file_type)
expect(converted_transcription_file.file_type).to eq(conversion_type)
end
Expand All @@ -197,12 +197,12 @@

it "raises error and creates TranscriptionFileRecord" do
expect { subject }.to raise_error(TranscriptionTransformer::FileConversionError)
.and change(Hearings::TranscriptionFile, :count).by(1)
.and change(TranscriptionFile, :count).by(1)
expect(transcription_file.file_type).to eq(file_type)
end

it "saves downloaded file to correct tmp sub-directory" do
allow_any_instance_of(Hearings::TranscriptionFile).to receive(:clean_up_tmp_location).and_return(nil)
allow_any_instance_of(TranscriptionFile).to receive(:clean_up_tmp_location).and_return(nil)
expect { subject }.to raise_error(TranscriptionTransformer::FileConversionError)
expect(File.exist?(tmp_location)).to be true
end
Expand Down
Loading
Loading