Example #1
0
            public void CloneBackup(String game, String into)
            {
                Log.Info("cloning backup of '" + game + "' into '" + into + "'");
                game = FileOperations.GetFileName(game);
                BackupSet set = GetBackupSetForName(game);

                if (set != null)
                {
                    String from = SAVE.configuration.backupPath + "/" + game;
                    String to   = SAVE.configuration.backupPath + "/" + into;
                    Log.Info("cloning backup from '" + from + "' into '" + into + "'");
                    if (FileOperations.DirectoryExists(from))
                    {
                        if (FileOperations.DirectoryExists(to))
                        {
                            Log.Error("cloning of backup failed: target folder exists");
                            return;
                        }
                        FileOperations.CopyDirectory(from, to);
                        BackupSet clone = GetBackupSetForName(into);
                        if (clone != null)
                        {
                            clone.ScanBackups();
                        }
                    }
                    else
                    {
                        Log.Error("cloning of backup failed: no backup folder to clone");
                    }
                }
                else
                {
                    Log.Error("cloning of backup failed: no backup set '" + game + "' found");
                }
            }
Example #2
0
            public void CloneGameFromBackup(String game, String into)
            {
                Log.Info("cloning game from backup of '" + game + "' into '" + into + "'");
                BackupSet set = GetBackupSetForName(game);

                if (set != null)
                {
                    String from = set.Latest();
                    String to   = SAVE_ROOT + "/" + into;
                    Log.Info("cloning game from '" + from + "' into '" + into + "'");
                    if (FileOperations.DirectoryExists(from))
                    {
                        if (FileOperations.DirectoryExists(to))
                        {
                            Log.Error("cloning of game failed: target folder exists");
                            return;
                        }
                        FileOperations.CopyDirectory(from, to);
                        ScanSavegames();
                    }
                    else
                    {
                        Log.Error("cloning of game failed: no backup folder to clone");
                    }
                }
                else
                {
                    Log.Error("cloning of game failed: no backup set '" + game + "' found");
                }
            }
Example #3
0
 private void RestoreFilesFromBackup(String backup, bool recurse = false)
 {
     Log.Info("copy game files from backup " + backup);
     Log.Detail("save game path to restore is '" + pathSaveGame + "'");
     //
     DeleteSaveGameFiles();
     //
     // create save game Folder if not existent
     if (!FileOperations.DirectoryExists(pathSaveGame))
     {
         Log.Info("creating save game folder " + pathSaveGame);
         FileOperations.CreateDirectoryRetry(pathSaveGame);
     }
     //
     foreach (String file in FileOperations.GetFiles(backup))
     {
         try
         {
             String name = FileOperations.GetFileName(file);
             Log.Detail("restoring file " + name + " from " + file);
             if (!name.Equals(OK_FILE) && !name.Equals(RESTORED_FILE))
             {
                 Log.Info("copy file " + name);
                 FileOperations.CopyFile(file, pathSaveGame + "/" + name);
             }
         }
         catch (Exception e)
         {
             Log.Exception(e);
             Log.Error("failed to copy file '" + file + "'");
             throw e;
         }
     }
     // copy recurse?
     if (recurse)
     {
         Log.Info("recurse restore");
         foreach (String folder in FileOperations.GetDirectories(backup))
         {
             String name   = FileOperations.GetFileName(folder);
             String target = pathSaveGame + "/" + name;
             FileOperations.CopyDirectory(folder, target);
         }
     }
 }
Example #4
0
            public void CloneGame(String game, String into)
            {
                String from = SAVE_ROOT + "/" + game;
                String to   = SAVE_ROOT + "/" + into;

                Log.Info("cloning game from '" + from + "' into '" + into + "'");
                if (FileOperations.DirectoryExists(from))
                {
                    if (FileOperations.DirectoryExists(to))
                    {
                        Log.Error("cloning of game failed: target folder exists");
                        return;
                    }
                    FileOperations.CopyDirectory(from, to);
                    ScanSavegames();
                }
                else
                {
                    Log.Error("cloning of game failed: no save game folder to clone");
                }
            }
Example #5
0
            public String CreateBackup(bool preRestore = false)
            {
                String backupRootFolder = SAVE.configuration.backupPath + "/" + name;

                Log.Info("creating backup of save game '" + name + "' in '" + backupRootFolder + "'");
                if (!FileOperations.DirectoryExists(backupRootFolder))
                {
                    Log.Info("creating root backup folder " + backupRootFolder);
                    FileOperations.CreateDirectory(backupRootFolder);
                }

                // files to backup
                String[] gameFiles = FileOperations.GetFiles(pathSaveGame);
                if (gameFiles == null | gameFiles.Length == 0)
                {
                    Log.Info("no files to backup for backup set " + name);
                    status = STATUS.NONE;
                    return(null);
                }

                DateTime time         = DateTime.Now;
                String   timestamp    = time.Hour.ToString("00") + time.Minute.ToString("00") + time.Second.ToString("00");
                String   datestamp    = time.Year.ToString("0000") + time.Month.ToString("00") + time.Day.ToString("00");
                String   backupFolder = backupRootFolder + "/" + datestamp + "-" + timestamp;
                String   backupName   = FileOperations.GetFileName(backupFolder);

                if (!FileOperations.DirectoryExists(backupFolder))
                {
                    FileOperations.CreateDirectory(backupFolder);
                    if (preRestore)
                    {
                        FileOperations.CreateFile(backupFolder + "/" + RESTORED_FILE);
                    }
                }
                else
                {
                    Log.Warning("backup folder '" + backupFolder + "' already existing");
                    return(backupFolder);
                }

                // backup files
                foreach (String sourceFile in gameFiles)
                {
                    Log.Info("creating backup of file " + sourceFile);
                    // do not copy the restore marker
                    if (sourceFile.Equals(RESTORED_FILE))
                    {
                        continue;
                    }

                    String filename = FileOperations.GetFileName(sourceFile);
                    try
                    {
                        FileOperations.CopyFile(sourceFile, backupFolder + "/" + filename);
                    }
                    catch (Exception e)
                    {
                        Log.Exception(e);
                        Log.Error("failed to create backup of file " + sourceFile + " in " + backupFolder + ": " + e.Message);
                        status = STATUS.FAILED;
                        return(backupFolder);
                    }
                }
                // backup subfolders if enabled
                if (SAVE.configuration.recurseBackup)
                {
                    foreach (String sourceFolder in FileOperations.GetDirectories(pathSaveGame))
                    {
                        Log.Info("creating backup of folder " + sourceFolder);
                        String foldername = FileOperations.GetFileName(sourceFolder);
                        try
                        {
                            FileOperations.CopyDirectory(sourceFolder, backupFolder + "/" + foldername);
                        }
                        catch (Exception e)
                        {
                            Log.Exception(e);
                            Log.Error("failed to create backup of folder " + sourceFolder + " in " + backupFolder + ": " + e.Message);
                            status = STATUS.FAILED;
                            return(backupFolder);
                        }
                    }
                }
                try
                {
                    FileOperations.CreateFile(backupFolder + "/" + OK_FILE);
                    status    = STATUS.OK;
                    this.time = time;
                    backups.Add(backupName);
                    SortBackupsByName();
                    CreateBackupArray();
                    // compress backup if enabled
                    if (SAVE.configuration.compressBackups)
                    {
                        CompressBackup(backupFolder);
                    }
                    else
                    {
                        Log.Detail("backup compression disabled");
                    }
                    Log.Info("backup successful in " + backupFolder);
                }
                catch
                {
                    Log.Error("failed to finish backup in " + backupFolder);
                    status = STATUS.FAILED;
                    return(backupFolder);
                }
                return(backupFolder);
            }
Example #6
0
        [RequestSizeLimit(250_000_000)]  // 250MB.
        public async Task <IActionResult> UploadLiftFile(string projectId, [FromForm] FileUpload fileUpload)
        {
            if (!await _permissionService.HasProjectPermission(HttpContext, Permission.ImportExport))
            {
                return(Forbid());
            }

            // Sanitize projectId
            if (!Sanitization.SanitizeId(projectId))
            {
                return(new UnsupportedMediaTypeResult());
            }

            // Ensure Lift file has not already been imported.
            if (!await _projRepo.CanImportLift(projectId))
            {
                return(BadRequest("A Lift file has already been uploaded."));
            }

            var liftStoragePath = FileStorage.GenerateLiftImportDirPath(projectId);

            // Clear out any files left by a failed import
            RobustIO.DeleteDirectoryAndContents(liftStoragePath);

            var file = fileUpload.File;

            if (file is null)
            {
                return(BadRequest("Null File"));
            }

            // Ensure file is not empty
            if (file.Length == 0)
            {
                return(BadRequest("Empty File"));
            }

            // Copy zip file data to a new temporary file
            fileUpload.FilePath = Path.GetTempFileName();
            await using (var fs = new FileStream(fileUpload.FilePath, FileMode.OpenOrCreate))
            {
                await file.CopyToAsync(fs);
            }

            // Make temporary destination for extracted files
            var extractDir = FileOperations.GetRandomTempDir();

            // Extract the zip to new created directory.
            FileOperations.ExtractZipFile(fileUpload.FilePath, extractDir, true);

            // Check number of directories extracted
            var directoriesExtracted = Directory.GetDirectories(extractDir);
            var extractedDirPath     = "";

            switch (directoriesExtracted.Length)
            {
            // If there was one directory, we're good
            case 1:
            {
                extractedDirPath = directoriesExtracted.First();
                break;
            }

            // If there were two, and there was a __MACOSX directory, ignore it
            case 2:
            {
                var numDirs = 0;
                foreach (var dir in directoriesExtracted)
                {
                    if (dir.EndsWith("__MACOSX"))
                    {
                        Directory.Delete(dir, true);
                    }
                    else         // This directory probably matters
                    {
                        extractedDirPath = dir;
                        numDirs++;
                    }
                }
                // Both directories seemed important
                if (numDirs == 2)
                {
                    return(BadRequest("Your zip file should have one directory."));
                }
                break;
            }

            // There were 0 or more than 2 directories
            default:
            {
                return(BadRequest(
                           "Your zip file structure has the wrong number of directories."));
            }
            }

            // Copy the extracted contents into the persistent storage location for the project.
            FileOperations.CopyDirectory(extractedDirPath, liftStoragePath);
            Directory.Delete(extractDir, true);

            // Search for the lift file within the extracted files
            var extractedLiftNameArr = Directory.GetFiles(liftStoragePath);
            var extractedLiftPath    = Array.FindAll(extractedLiftNameArr, x => x.EndsWith(".lift"));

            if (extractedLiftPath.Length > 1)
            {
                return(BadRequest("More than one .lift file detected."));
            }
            if (extractedLiftPath.Length == 0)
            {
                return(BadRequest("No lift files detected."));
            }

            int liftParseResult;
            // Sets the projectId of our parser to add words to that project
            var liftMerger = _liftService.GetLiftImporterExporter(projectId, _wordRepo);

            try
            {
                // Add character set to project from ldml file
                var proj = await _projRepo.GetProject(projectId);

                if (proj is null)
                {
                    return(NotFound(projectId));
                }

                _liftService.LdmlImport(
                    Path.Combine(liftStoragePath, "WritingSystems"),
                    proj.VernacularWritingSystem.Bcp47, _projRepo, proj);

                var parser = new LiftParser <LiftObject, LiftEntry, LiftSense, LiftExample>(liftMerger);

                // Import words from lift file
                liftParseResult = parser.ReadLiftFile(extractedLiftPath.FirstOrDefault());
                await liftMerger.SaveImportEntries();
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"Error importing lift file {fileUpload.Name} into project {projectId}.");
                return(BadRequest("Error processing the lift data. Contact support for help."));
            }

            // Store that we have imported Lift data already for this project to signal the frontend
            // not to attempt to import again.
            var project = await _projRepo.GetProject(projectId);

            if (project is null)
            {
                return(NotFound(projectId));
            }

            project.LiftImported = true;
            await _projRepo.Update(projectId, project);

            return(Ok(liftParseResult));
        }