backend/app/extraction/archives/RarExtractor.scala (39 lines of code) (raw):

package extraction.archives import java.io.File import com.github.junrar.Junrar import com.google.common.io.Files import extraction.{ExtractionParams, FileExtractor} import ingestion.IngestionContextBuilder import model.Uri import model.manifest.Blob import org.apache.commons.io.FileUtils import services.ingestion.IngestionServices import services.{FingerprintServices, ScratchSpace} import utils.Logging import utils.attempt.Failure import scala.jdk.CollectionConverters._ // Does not support RAR 5 class RarExtractor(scratch: ScratchSpace, ingestionServices: IngestionServices) extends FileExtractor(scratch) with Logging { override def canProcessMimeType = Set("application/x-rar-compressed").contains override def indexing = false override def priority = 6 override def extract(blob: Blob, file: File, params: ExtractionParams): Either[Failure, Unit] = { val extractionRootPath = scratch.createWorkingDir(s"rar/${blob.uri.value}/").toAbsolutePath logger.info(s"Running RAR extractor on '${blob.uri.value}' in temporary working directory '$extractionRootPath'") try { val context = IngestionContextBuilder(blob.uri, params) Junrar.extract(file, extractionRootPath.toFile) val files = Files.fileTraverser().depthFirstPreOrder(extractionRootPath.toFile).iterator().asScala files.foreach { entry => if(entry.isFile) { val entryPath = extractionRootPath.relativize(entry.toPath.toAbsolutePath) val entryContext = context.pushParentDirectories(entryPath).finishWithFile(entry.toPath) val blobUri = Uri(FingerprintServices.createFingerprintFromFile(entry)) ingestionServices.ingestFile(entryContext, blobUri, entry.toPath) } } Right(()) } finally { FileUtils.deleteDirectory(extractionRootPath.toFile) } } }