def backupProjects()

in app/services/ProjectBackupAssetFolder.scala [291:416]


  def backupProjects(onlyByType:Boolean):Future[BackupResults] = {
    val parallelCopies = config.getOptional[Int]("backup.parallelCopies").getOrElse(1)
    val makeFoldersSetting = config.getOptional[Boolean]("asset_folder_backup_make_folders").getOrElse(true)

    var backupTypes = Array(2,3,4,6)
    val backupTypesSequence = config.getOptional[Seq[Int]]("asset_folder_backup_types").getOrElse(None)
    if (backupTypesSequence != None) {
      backupTypes = backupTypesSequence.iterator.toArray
    }

    def getScanSource() = if(onlyByType) {
      ProjectEntry.scanProjectsForTypes(backupTypes)
    } else {
      ProjectEntry.scanAllProjects
    }

    def getAssetFolder(id:Int) = ProjectMetadata.entryFor(id, ProjectMetadata.ASSET_FOLDER_KEY)

    def getDestFileFor(filePath:String, recordTimestamp:Timestamp, projectId:Option[Int], assetFolderStorage:Int)(implicit db: slick.jdbc.PostgresProfile#Backend#Database): Future[AssetFolderFileEntry] =

        assetFolderFileEntryDAO.entryFor(filePath,1).map({
          case Success(filesList) =>
            if (filesList.isEmpty) {
              //No file entries exist already, create one (at version 1) and proceed
              assetFolderFileEntryDAO.save(AssetFolderFileEntry(None, filePath, assetFolderStorage, 1, recordTimestamp, recordTimestamp, recordTimestamp, projectId, backupOf = None))
              AssetFolderFileEntry(None, filePath, assetFolderStorage, 1, recordTimestamp, recordTimestamp, recordTimestamp, projectId, backupOf = None)
            } else {
                filesList.head
            }
          case Failure(error) => throw error
        })

    for {
      drivers <- loadStorageDrivers()
      storages <- loadAllStorages()
      result <- getScanSource()
        .map(p => {
          logger.debug(s"Checking project ${p.projectTitle} for backup. Type: ${p.projectTypeId}")
          p
        })
        .mapAsync(parallelCopies)(p => {
          logger.debug(s"Got project id.: ${p.id.get}")
          getAssetFolder(p.id.get).onComplete(folderData => folderData match {
            case Failure(error) =>
              logger.debug(s"Attempt at getting asset folder path failed: $error")
            case Success(assetFolderData) =>
              try {
                logger.debug(s"Got asset folder path: ${assetFolderData.get.value.get}")
                val fileArray = getAssetFolderProjectFilePaths(assetFolderData.get.value.get)
                fileArray.foreach(filePath => {
                  logger.debug(s"File path: $filePath")
                  val assetFolderStorage = config.getOptional[Int]("asset_folder_storage").getOrElse(1)
                  logger.debug(s"Storage to access: $assetFolderStorage")
                  val storageObject = StorageEntryHelper.entryFor(assetFolderStorage).onComplete(storageData => storageData match {
                    case Failure(error) =>
                      logger.debug(s"Attempt at getting storage data failed: $error")
                    case Success(storageData) =>
                      val rootPath = storageData.get.rootpath.get
                      logger.debug(s"Root: $rootPath")
                      val fixedPath = filePath.replace(rootPath,"")
                      val recordTimestamp = Timestamp.valueOf(LocalDateTime.now())
                      val assetFolderFileDest = getDestFileFor(fixedPath, recordTimestamp, p.id, assetFolderStorage)
                      val assetFolderBackupStorage = config.getOptional[Int]("asset_folder_backup_storage").getOrElse(1)
                      logger.debug(s"Storage to use: $assetFolderBackupStorage")

                      assetFolderFileDest.map(fileEntry=> {

                        val storageSupportsVersions = storages(assetFolderBackupStorage).supportsVersions
                        logger.debug(s"Back up storage supports versions: $storageSupportsVersions")
                        var attemptCopy = false
                        if (storageSupportsVersions) {
                          attemptCopy = shouldCopy(p.id.get, assetFolderBackupStorage, p, drivers, fileEntry)
                        } else {
                          attemptCopy = true
                        }
                        if (attemptCopy) {
                          val possiblyOldVersionEntry = getOldVersionEntry(p.id.get, assetFolderBackupStorage, p, drivers, fileEntry) match {
                            case Failure(err) =>
                              None
                            case Success(Left(msg)) =>
                              None
                            case Success(Right(maybeMostRecentBackup)) =>
                              maybeMostRecentBackup
                          }

                          logger.debug(s"possiblyOldVersionEntry: $possiblyOldVersionEntry for path: $filePath")

                          getTargetFileEntry(fileEntry, possiblyOldVersionEntry, storages.get(assetFolderBackupStorage).get).onComplete(fileDest => fileDest match {
                            case Failure(error) =>
                              logger.debug(s"Attempt at getting file data failed: $error")
                            case Success(destData) =>
                              destData.getFullPath.onComplete {
                                case Failure(exception) =>
                                  logger.debug(s"Attempt at getting path failed:: $exception")
                                case Success(pathData) =>
                                  if (makeFoldersSetting) {
                                    logger.debug(s"Write path: $pathData")
                                    val pathFolder = Paths.get(pathData).getParent.toString
                                    logger.debug(s"Write folder: $pathFolder")
                                    Files.createDirectories(Paths.get(pathFolder))
                                  }
                                  storageHelper.copyAssetFolderFile(fileEntry, destData)
                              }
                          })
                        }
                      })
                  })
                  Thread.sleep(config.getOptional[Long]("backup.pauseMilliseconds").getOrElse(0))
                })
              } catch {
                case e: java.lang.NullPointerException => logger.debug(s"Could not find any project files to process.")
                case e: java.util.NoSuchElementException => logger.debug(s"Could not find an asset folder path.")
              }
          })
          Thread.sleep(200)
          Future(Right(true))
        })
        .toMat(Sink.fold(BackupResults.empty(0))((acc, elem) => elem match {
          case Right(true) =>
            acc.copy(totalCount = acc.totalCount + 1, successCount = acc.successCount + 1)
          case Right(false) =>
            acc.copy(totalCount = acc.totalCount + 1, notNeededCount = acc.notNeededCount + 1)
        }))(Keep.right)
        .run()
    } yield result
  }