/// <summary> /// Extracts the gzip file. /// </summary> /// <param name="argInputFile"> /// The input file. /// </param> /// <returns> /// </returns> public static bool ExtractGZip(FileInfoEx argInputFile) { if (argInputFile is null) { throw new ArgumentNullException(nameof(argInputFile)); } FileStream originalFileStream = argInputFile.FInfo.OpenRead(); byte[] dataBuffer = new byte[4096]; GZipInputStream gzipStream = new GZipInputStream(originalFileStream); FileInfo fsOut = new FileInfo(Path.Combine(DataStore.AD.CurrentDataFolder.FullName, "data.xml")); FileStream fsOut1 = fsOut.Create(); StreamUtils.Copy(gzipStream, fsOut1, dataBuffer); fsOut1.Flush(); fsOut1.Dispose(); gzipStream.Dispose(); return(true); }
/// <summary> /// This routine is heavily customized to decompress GRAMPS whole of database export file /// (i.e. .gramps) files. /// </summary> /// <param name="inputFile"> /// Input GRAMPS export file. /// </param> /// <returns> /// Flag indicating success or not. /// </returns> public async Task <bool> DecompressGZIP(FileInfoEx inputFile) { await DataStore.CN.MinorStatusAdd("Decompressing GRAMPS GZIP file").ConfigureAwait(false); // Check arguments if (inputFile == null) { DataStore.CN.NotifyError("The input file is null"); return(false); } try { ExtractGZip(inputFile); await DataStore.CN.MinorStatusAdd("GRAMPS file decompressing complete").ConfigureAwait(false); return(true); } catch (UnauthorizedAccessException ex) { DataStore.CN.NotifyError("Unauthorised Access exception when trying to acess file. " + ex.Message); return(false); } }
/// <summary> /// Was the file modified since the last datetime saved? /// </summary> /// <param name="settingsKey"> /// The settings key. /// </param> /// <param name="filenameToCheck"> /// The filename to check. /// </param> /// <returns> /// True if the file was modified since last time. /// </returns> public static bool FileModifiedSinceLastSaveAsync(string settingsKey, FileInfoEx fileToCheck) { if (fileToCheck is null) { throw new ArgumentNullException(nameof(fileToCheck)); } // Check for file exists if (!fileToCheck.Valid) { return(false); } try { DateTime fileDateTime = FileGetDateTimeModified(fileToCheck); // Need to reparse it so the ticks ar ethe same fileDateTime = DateTime.Parse(fileDateTime.ToString(System.Globalization.CultureInfo.CurrentCulture), System.Globalization.CultureInfo.CurrentCulture); // Save a fresh copy if null so we can load next time string oldDateTime = Preferences.Get(settingsKey, string.Empty); if (string.IsNullOrEmpty(oldDateTime)) { Preferences.Set(settingsKey, fileDateTime.ToString(System.Globalization.CultureInfo.CurrentCulture)); // No previous settings entry so do the load (it might be the FirstRun) return(true); } else { DateTime settingsStoredDateTime; settingsStoredDateTime = DateTime.Parse(oldDateTime, System.Globalization.CultureInfo.CurrentCulture); int t = fileDateTime.CompareTo(settingsStoredDateTime); if (t > 0) { return(true); } return(false); } } catch (Exception ex) { Preferences.Remove(settingsKey); DataStore.CN.NotifyException("FileModifiedSinceLastSaveAsync", ex); throw; } }
/// <summary> /// get the StorageFile of the file. /// </summary> /// <param name="relativeFilePath"> /// file path relative to the provider base folder. /// </param> /// <returns> /// StorageFile for the chosen file. /// </returns> public async static Task <FileInfoEx> GetStorageFileAsync(string relativeFilePath) { FileInfoEx resultFile = new FileInfoEx(); // Validate the input if ((relativeFilePath is null) || (string.IsNullOrEmpty(relativeFilePath))) { return(resultFile); } // Check for relative path if (!StoreFileUtility.IsRelativeFilePathValid(relativeFilePath)) { return(resultFile); } // load the real file DirectoryInfo tt = DataStore.AD.CurrentDataFolder; if (tt != null) { try { if (Directory.Exists(Path.Combine(tt.FullName, Path.GetDirectoryName(relativeFilePath)))) { FileInfo[] t = tt.GetFiles(relativeFilePath); if (t.Length > 0) { resultFile.FInfo = t[0]; } } return(resultFile); } catch (FileNotFoundException ex) { await DataStore.CN.MajorStatusAdd(ex.Message + ex.FileName).ConfigureAwait(false); // default to a standard file marker } catch (Exception ex) { DataStore.CN.NotifyException(ex.Message + relativeFilePath, ex); throw; } } return(resultFile); }
/// <summary> /// get the StorageFile of the file. /// </summary> /// <param name="relativeFilePath"> /// file path relative to the provider base folder. /// </param> /// <returns> /// StorageFile for the chosen file. /// </returns> /// TODO Check if same as MakeGetFile public static IFileInfoEx GetStorageFile(string relativeFilePath) { IFileInfoEx resultFile = new FileInfoEx(argRelativeFolder: Path.GetDirectoryName(relativeFilePath), argFileName: Path.GetFileName(relativeFilePath)); // Validate the input if ((relativeFilePath is null) || (string.IsNullOrEmpty(relativeFilePath))) { return(resultFile); } // Check for relative path if (!StoreFileUtility.IsRelativeFilePathValid(relativeFilePath)) { return(resultFile); } // Load the real file if (DataStore.Instance.AD.CurrentDataFolder.Valid) { try { if (Directory.Exists(Path.Combine(DataStore.Instance.AD.CurrentDataFolder.Path, Path.GetDirectoryName(relativeFilePath)))) { FileInfo[] t = DataStore.Instance.AD.CurrentDataFolder.Value.GetFiles(relativeFilePath); if (t.Length > 0) { resultFile.FInfo = t[0]; } } return(resultFile); } catch (FileNotFoundException ex) { App.Current.Services.GetService <IErrorNotifications>().DataLogEntryAdd(ex.Message + ex.FileName); // default to a standard file marker } catch (Exception ex) { App.Current.Services.GetService <IErrorNotifications>().NotifyException(ex.Message + relativeFilePath, ex); throw; } } return(resultFile); }
/// <summary> /// Indexes the file get date time modified. /// </summary> /// <returns> /// </returns> private static DateTime FileGetDateTimeModified(FileInfoEx fileToCheck) { try { if (fileToCheck.Valid) { return(fileToCheck.FInfo.LastWriteTimeUtc); } return(new DateTime()); } catch (Exception ex) { DataStore.CN.NotifyException("Exception while checking FileGetDateTimeModified for =" + fileToCheck.FInfo.FullName, ex); throw; } }
/// <summary> /// Extracts the tared files from the archive. /// NOTE: This is not the file last modified date but if the file has been modified then it /// should be later than any UnTared file date. /// </summary> /// <param name="dataFolder"> /// The data folder. /// </param> /// <param name="tarIn"> /// The tar in. /// </param> /// <param name="asciiTranslate"> /// if set to <c>true</c> [ASCII translate]. /// </param> /// <returns> /// True if the file is UnTARed correctly. /// </returns> public async Task ExtractTarIfNotModified(TarInputStream tarIn, bool asciiTranslate) { if (tarIn is null) { throw new ArgumentNullException(nameof(tarIn)); } TarEntry tarEntry = null; //FileInfo outFile = null; try { while ((tarEntry = tarIn.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } // Debug.WriteLine("Untaring " + tarEntry.Name); string outFileName = Path.GetFileName(tarEntry.Name); // Converts the unix forward slashes in the filenames to windows backslashes string tarName = tarEntry.Name.Replace('/', Path.DirectorySeparatorChar); // Remove any root e.g. '\' because a PathRooted filename defeats Path.Combine if (Path.IsPathRooted(tarName)) { tarName = tarName.Substring(Path.GetPathRoot(tarName).Length); } // Apply further name transformations here as necessary string filename = Path.GetFileName(tarName); string outName = Path.Combine(DataStore.AD.CurrentDataFolder.FullName, tarName); string relativePath = Path.GetDirectoryName(tarEntry.Name); string directoryName = Path.GetDirectoryName(outName); DirectoryInfo newFolder = null; if (relativePath.Length > 0) { newFolder = Directory.CreateDirectory(Path.Combine(DataStore.AD.CurrentDataFolder.FullName, relativePath)); } else { newFolder = DataStore.AD.CurrentDataFolder; } // Check if the folder was created successfully. if (newFolder == null) { // Skip this file. continue; } // Check file modification date if it exists bool okToCopyFlag = true; //// Android uses mimetypes and a type for .gramps files is not in the list TODO //// work how how to add it to the list .gramps are .gz to just rename for now //if (filename == "data.gramps") //{ // filename = CommonConstants.StorageGRAMPSFileName; //} // if tarEntry modtime is less than outFile datemodified // NOTE: This is not the file last modified date but if the file has been // modified then it should be later than any UnTared file date if (await StoreFolder.FolderFileExistsAsync(newFolder, filename).ConfigureAwait(false)) { FileInfoEx newFileName = await StoreFolder.FolderGetFileAsync(newFolder, filename).ConfigureAwait(false); //if (filename == "1024x768.png") //{ //} if (newFileName.Valid) { // TODO Check this compare date and tiem TODO Add delete existing files // option before extract if (tarEntry.ModTime.CompareTo(newFileName.FInfo.LastAccessTime) < 0) { okToCopyFlag = false; } if (newFileName.FInfo.LastWriteTimeUtc == tarEntry.ModTime) { okToCopyFlag = false; } } } if (okToCopyFlag) { if (filename == CommonConstants.StorageGRAMPSFileName) { } await DataStore.CN.ChangeLoadingMessage("Untaring file " + tarEntry.Name).ConfigureAwait(false); Stream outStr = await StoreFolder.FolderCreateFileAsync(newFolder, filename).ConfigureAwait(false); if (asciiTranslate) { CopyWithAsciiTranslate(tarIn, outStr); } else { tarIn.CopyEntryContents(outStr); } outStr.Flush(); outStr.Dispose(); // TODO check of modification date kept Set the modification date/time. This // approach seems to solve timezone issues. // outFile = await newFolder.TryGetItemAsync(filename); //// StorageFile tt = await newFolder.GetFileAsync(filename); // IDictionary<string, object> ttt = await // tt.Properties.RetrievePropertiesAsync(new List<string> { }); // foreach (var item in ttt) { Debug.WriteLine(item); } // BasicProperties outFileProperties = await outFile.GetBasicPropertiesAsync(); // var fileProperties = await file.Properties.RetrievePropertiesAsync( new // List { "System.GPS.Latitude", "System.GPS.Longitude" }); // var fileProperties = await outFileProperties.RetrievePropertiesAsync(new // List { }); // var propertyToSave = new List> { new // KeyValuePair("System.Photo.LensManufacturer", "Pentax") }; // await file.Properties.SavePropertiesAsync(propertyToSave); // var changes = new List<KeyValuePair<string, object>>(); // DateTime modDate = tarEntry.ModTime; // PropertySet t4 = new PropertySet(); // t4.Add("DateModified", modDate); // changes.Add(new KeyValuePair<string, object>("System.ExpandoProperties", t4)); // await tt.Properties.SavePropertiesAsync(changes); // changes.Add(new KeyValuePair<string, object>("System.ExpandoProperties", modDate)); // await tt.Properties.SavePropertiesAsync(ttt); // DateTime myDt = DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc); // t = null; // File.SetLastWriteTime(outName, modDate); // .SetLastWriteTime(t.CreateSafeFileHandle(), modDate); } else { // TODO write to the output log // await DataStore.CN.MinorStatusAdd("File " // + tarEntry.Name + " does not need to be unTARed as its modified date is // earlier than the one in the output folder").ConfigureAwait(false); } // Check file ceated successfully bool checkFileExistsFlag = await StoreFolder.FolderFileExistsAsync(newFolder, filename).ConfigureAwait(false); if (!checkFileExistsFlag) { DataStore.CN.NotifyError("Error UnTaring file: " + newFolder.FullName + "-" + filename + ". File not created. Perhaps the path is too long?"); // TODO copy dummy file in its place } } } catch (Exception ex) { // Handle disk full errors const int HR_ERROR_HANDLE_DISK_FULL = unchecked ((int)0x80070027); const int HR_ERROR_DISK_FULL = unchecked ((int)0x80070070); if (ex.HResult == HR_ERROR_HANDLE_DISK_FULL || ex.HResult == HR_ERROR_DISK_FULL) { DataStore.CN.NotifyException("UnTar Disk Full Exception working on " + tarEntry.Name, ex); } // Handle other errors if (tarEntry != null) { DataStore.CN.NotifyException("UnTar Exception working on " + tarEntry.Name, ex); throw; } else { DataStore.CN.NotifyException("UnTar tarEntry null Exception ", ex); throw; } } }
/// <summary> /// Saves the datetime the file was last modified in System Settings. /// </summary> /// <param name="settingsKey"> /// The settings key. /// </param> /// <param name="filenameToCheck"> /// The filename to check. /// </param> public static void SaveFileModifiedSinceLastSave(string settingsKey, FileInfoEx filename) { Contract.Assert(filename != null); Preferences.Set(settingsKey, filename.FInfo.LastWriteTimeUtc.ToString(System.Globalization.CultureInfo.CurrentCulture)); }