public static UpdateModule RetrieveData(string updateModuleFilePath) { if (Directory.Exists(updateModuleFilePath)) { throw new ArgumentException(string.Format(@"The path ""{0}"" was not a file path. It was a path to a directory.", updateModuleFilePath), nameof(updateModuleFilePath)); } var module = new UpdateModule(); try { var updateModuleFileType = DetectUpdateModuleFileType(updateModuleFilePath); if (updateModuleFileType == UpdateModuleFileType.Executable) { module.ExecutableModuleProperties = new ExecutableUpdateModuleProperties(updateModuleFilePath); } var fileInfo = new FileInfo(updateModuleFilePath); module.UpdateModuleFileType = updateModuleFileType; module.FileSize = fileInfo.Length; module.LastModifiedDateTimeUtc = fileInfo.LastWriteTimeUtc; module.UpdateModuleFilePath = updateModuleFilePath; module.FielHash = FileHashHelper.ComputeFileHash(updateModuleFilePath); } catch (Exception e) { throw new UpdateModuleDataRetrieveException(updateModuleFilePath, e); } return(module); }
private void FillMissingHashes(SVR_VideoLocal vlocal) { bool needcrc32 = string.IsNullOrEmpty(vlocal.CRC32); bool needmd5 = string.IsNullOrEmpty(vlocal.MD5); bool needsha1 = string.IsNullOrEmpty(vlocal.SHA1); if (needcrc32 || needmd5 || needsha1) { FillVideoHashes(vlocal); } needcrc32 = string.IsNullOrEmpty(vlocal.CRC32); needmd5 = string.IsNullOrEmpty(vlocal.MD5); needsha1 = string.IsNullOrEmpty(vlocal.SHA1); if (needcrc32 || needmd5 || needsha1) { ShokoService.CmdProcessorHasher.QueueState = PrettyDescriptionHashing; DateTime start = DateTime.Now; List <string> tp = new List <string>(); if (needsha1) { tp.Add("SHA1"); } if (needmd5) { tp.Add("MD5"); } if (needcrc32) { tp.Add("CRC32"); } logger.Trace("Calculating missing {1} hashes for: {0}", FileName, string.Join(",", tp)); // update the VideoLocal record with the Hash, since cloud support we calculate everything Hashes hashes = FileHashHelper.GetHashInfo(FileName.Replace("/", $"{System.IO.Path.DirectorySeparatorChar}"), true, ShokoServer.OnHashProgress, needcrc32, needmd5, needsha1); TimeSpan ts = DateTime.Now - start; logger.Trace("Hashed file in {0:#0.0} seconds --- {1} ({2})", ts.TotalSeconds, FileName, Utils.FormatByteSize(vlocal.FileSize)); if (String.IsNullOrEmpty(vlocal.Hash)) { vlocal.Hash = hashes.ED2K?.ToUpperInvariant(); } if (needsha1) { vlocal.SHA1 = hashes.SHA1?.ToUpperInvariant(); } if (needmd5) { vlocal.MD5 = hashes.MD5?.ToUpperInvariant(); } if (needcrc32) { vlocal.CRC32 = hashes.CRC32?.ToUpperInvariant(); } AzureWebAPI.Send_FileHash(new List <SVR_VideoLocal> { vlocal }); } }
public override string GetFileHash(string virtualPath, System.Collections.IEnumerable virtualPathDependencies) { if (IsVirtualPath(virtualPath)) { string filepath = GetRealPath(virtualPath); return(FileHashHelper.ComputeMD5(filepath)); } else { return(Previous.GetFileHash(virtualPath, virtualPathDependencies)); } }
// Diff public S3FileHashStatus[] GetSysncStatus(IEnumerable <SlimFileInfo> localFiles, IEnumerable <S3Object> s3Objects, string prefix) { if (localFiles == null) { throw new ArgumentNullException(nameof(localFiles)); } if (s3Objects == null) { throw new ArgumentNullException(nameof(s3Objects)); } // Dictionary for Remote S3 and Local File var s3Dictionary = s3Objects.ToDictionary(x => x.Key, x => x); var localDictionary = localFiles.ToDictionary(x => GetS3Key(prefix, x.MultiplatformRelativePath), x => x); // Get State for Local files S3FileHashStatus[] statuses = null; var localExists = localDictionary.Select(x => { int chunkSize = 0; string fileETag = ""; if (s3Dictionary.TryGetValue(x.Key, out S3Object s3Object)) { var bytes = FileHashHelper.GetFileBinary(x.Value.FullPath); var s3ETagChunkCount = s3Object.GetETagChunkCount(); chunkSize = FileHashHelper.GetChunkSize(bytes.Length, s3ETagChunkCount); fileETag = FileHashHelper.CalculateEtag(bytes, chunkSize); } return(new S3FileHashStatus(x.Value, fileETag, chunkSize, s3Object)); }) .ToArray(); // Get State for Remote S3 var remoteOnly = s3Objects .Where(x => !localDictionary.TryGetValue(x.Key, out var slimFileInfo)) .Select(x => new S3FileHashStatus(null, "", 0, x)) .ToArray(); // Concat local and remote statuses = localExists.Concat(remoteOnly).ToArray(); return(statuses); }
public static void RunImport_DropFolders() { // get a complete list of files List<string> fileList = new List<string>(); ImportFolderRepository repNetShares = new ImportFolderRepository(); foreach (ImportFolder share in repNetShares.GetAll()) { if (!share.FolderIsDropSource) continue; logger.Debug("ImportFolder: {0} || {1}", share.ImportFolderName, share.ImportFolderLocation); Utils.GetFilesForImportFolder(share.ImportFolderLocation, ref fileList); } // get a list of all the shares we are looking at int filesFound = 0, videosFound = 0; int i = 0; // get a list of all files in the share foreach (string fileName in fileList) { i++; filesFound++; logger.Info("Processing File {0}/{1} --- {2}", i, fileList.Count, fileName); if (!FileHashHelper.IsVideo(fileName)) continue; videosFound++; CommandRequest_HashFile cr_hashfile = new CommandRequest_HashFile(fileName, false); cr_hashfile.Save(); } logger.Debug("Found {0} files", filesFound); logger.Debug("Found {0} videos", videosFound); }
private VideoLocal ProcessFile_LocalInfo() { // hash and read media info for file int nshareID = -1; string filePath = ""; ImportFolderRepository repNS = new ImportFolderRepository(); List <ImportFolder> shares = repNS.GetAll(); DataAccessHelper.GetShareAndPath(FileName, shares, ref nshareID, ref filePath); if (!File.Exists(FileName)) { logger.Error("File does not exist: {0}", FileName); return(null); } int numAttempts = 0; // Wait 3 minutes seconds before giving up on trying to access the file while ((!CanAccessFile(FileName)) && (numAttempts < 180)) { numAttempts++; Thread.Sleep(1000); Console.WriteLine("Attempt # " + numAttempts.ToString()); } // if we failed to access the file, get ouuta here if (numAttempts == 180) { logger.Error("Could not access file: " + FileName); return(null); } // check if we have already processed this file VideoLocal vlocal = null; VideoLocalRepository repVidLocal = new VideoLocalRepository(); FileNameHashRepository repFNHash = new FileNameHashRepository(); List <VideoLocal> vidLocals = repVidLocal.GetByFilePathAndShareID(filePath, nshareID); FileInfo fi = new FileInfo(FileName); if (vidLocals.Count > 0) { vlocal = vidLocals[0]; logger.Trace("VideoLocal record found in database: {0}", vlocal.VideoLocalID); if (ForceHash) { vlocal.FileSize = fi.Length; vlocal.DateTimeUpdated = DateTime.Now; } } else { logger.Trace("VideoLocal, creating new record"); vlocal = new VideoLocal(); vlocal.DateTimeUpdated = DateTime.Now; vlocal.DateTimeCreated = vlocal.DateTimeUpdated; vlocal.FilePath = filePath; vlocal.FileSize = fi.Length; vlocal.ImportFolderID = nshareID; vlocal.Hash = ""; vlocal.CRC32 = ""; vlocal.MD5 = ""; vlocal.SHA1 = ""; vlocal.IsIgnored = 0; vlocal.IsVariation = 0; } // check if we need to get a hash this file Hashes hashes = null; if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash) { // try getting the hash from the CrossRef if (!ForceHash) { CrossRef_File_EpisodeRepository repCrossRefs = new CrossRef_File_EpisodeRepository(); List <CrossRef_File_Episode> crossRefs = repCrossRefs.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize); if (crossRefs.Count == 1) { vlocal.Hash = crossRefs[0].Hash; vlocal.HashSource = (int)HashSource.DirectHash; } } // try getting the hash from the LOCAL cache if (!ForceHash && string.IsNullOrEmpty(vlocal.Hash)) { List <FileNameHash> fnhashes = repFNHash.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize); if (fnhashes != null && fnhashes.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes) { repFNHash.Delete(fnh.FileNameHashID); } } if (fnhashes != null && fnhashes.Count == 1) { logger.Trace("Got hash from LOCAL cache: {0} ({1})", FileName, fnhashes[0].Hash); vlocal.Hash = fnhashes[0].Hash; vlocal.HashSource = (int)HashSource.WebCacheFileName; } } // hash the file if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash) { DateTime start = DateTime.Now; logger.Trace("Calculating hashes for: {0}", FileName); // update the VideoLocal record with the Hash hashes = FileHashHelper.GetHashInfo(FileName, true, MainWindow.OnHashProgress, ServerSettings.Hash_CRC32, ServerSettings.Hash_MD5, ServerSettings.Hash_SHA1); TimeSpan ts = DateTime.Now - start; logger.Trace("Hashed file in {0} seconds --- {1} ({2})", ts.TotalSeconds.ToString("#0.0"), FileName, Utils.FormatByteSize(vlocal.FileSize)); vlocal.Hash = hashes.ed2k; vlocal.CRC32 = hashes.crc32; vlocal.MD5 = hashes.md5; vlocal.SHA1 = hashes.sha1; vlocal.HashSource = (int)HashSource.DirectHash; } // We should have a hash by now // before we save it, lets make sure there is not any other record with this hash (possible duplicate file) VideoLocal vidTemp = repVidLocal.GetByHash(vlocal.Hash); if (vidTemp != null) { // don't delete it, if it is actually the same record if (vidTemp.VideoLocalID != vlocal.VideoLocalID) { // delete the VideoLocal record logger.Warn("Deleting duplicate video file record"); logger.Warn("---------------------------------------------"); logger.Warn("Keeping record for: {0}", vlocal.FullServerPath); logger.Warn("Deleting record for: {0}", vidTemp.FullServerPath); logger.Warn("---------------------------------------------"); // check if we have a record of this in the database, if not create one DuplicateFileRepository repDups = new DuplicateFileRepository(); List <DuplicateFile> dupFiles = repDups.GetByFilePathsAndImportFolder(vlocal.FilePath, vidTemp.FilePath, vlocal.ImportFolderID, vidTemp.ImportFolderID); if (dupFiles.Count == 0) { dupFiles = repDups.GetByFilePathsAndImportFolder(vidTemp.FilePath, vlocal.FilePath, vidTemp.ImportFolderID, vlocal.ImportFolderID); } if (dupFiles.Count == 0) { DuplicateFile dup = new DuplicateFile(); dup.DateTimeUpdated = DateTime.Now; dup.FilePathFile1 = vlocal.FilePath; dup.FilePathFile2 = vidTemp.FilePath; dup.ImportFolderIDFile1 = vlocal.ImportFolderID; dup.ImportFolderIDFile2 = vidTemp.ImportFolderID; dup.Hash = vlocal.Hash; repDups.Save(dup); } repVidLocal.Delete(vidTemp.VideoLocalID); } } repVidLocal.Save(vlocal); // also save the filename to hash record // replace the existing records just in case it was corrupt FileNameHash fnhash = null; List <FileNameHash> fnhashes2 = repFNHash.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize); if (fnhashes2 != null && fnhashes2.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes2) { repFNHash.Delete(fnh.FileNameHashID); } } if (fnhashes2 != null && fnhashes2.Count == 1) { fnhash = fnhashes2[0]; } else { fnhash = new FileNameHash(); } fnhash.FileName = Path.GetFileName(vlocal.FilePath); fnhash.FileSize = vlocal.FileSize; fnhash.Hash = vlocal.Hash; fnhash.DateTimeUpdated = DateTime.Now; repFNHash.Save(fnhash); } // now check if we have stored a VideoInfo record bool refreshMediaInfo = false; VideoInfoRepository repVidInfo = new VideoInfoRepository(); VideoInfo vinfo = repVidInfo.GetByHash(vlocal.Hash); if (vinfo == null) { refreshMediaInfo = true; vinfo = new VideoInfo(); vinfo.Hash = vlocal.Hash; vinfo.Duration = 0; vinfo.FileSize = fi.Length; vinfo.DateTimeUpdated = DateTime.Now; vinfo.FileName = filePath; vinfo.AudioBitrate = ""; vinfo.AudioCodec = ""; vinfo.VideoBitrate = ""; vinfo.VideoBitDepth = ""; vinfo.VideoCodec = ""; vinfo.VideoFrameRate = ""; vinfo.VideoResolution = ""; repVidInfo.Save(vinfo); } else { // check if we need to update the media info if (vinfo.VideoCodec.Trim().Length == 0) { refreshMediaInfo = true; } else { refreshMediaInfo = false; } } if (refreshMediaInfo) { logger.Trace("Getting media info for: {0}", FileName); MediaInfoResult mInfo = FileHashHelper.GetMediaInfo(FileName, true); vinfo.AudioBitrate = string.IsNullOrEmpty(mInfo.AudioBitrate) ? "" : mInfo.AudioBitrate; vinfo.AudioCodec = string.IsNullOrEmpty(mInfo.AudioCodec) ? "" : mInfo.AudioCodec; vinfo.DateTimeUpdated = vlocal.DateTimeUpdated; vinfo.Duration = mInfo.Duration; vinfo.FileName = filePath; vinfo.FileSize = fi.Length; vinfo.VideoBitrate = string.IsNullOrEmpty(mInfo.VideoBitrate) ? "" : mInfo.VideoBitrate; vinfo.VideoBitDepth = string.IsNullOrEmpty(mInfo.VideoBitDepth) ? "" : mInfo.VideoBitDepth; vinfo.VideoCodec = string.IsNullOrEmpty(mInfo.VideoCodec) ? "" : mInfo.VideoCodec; vinfo.VideoFrameRate = string.IsNullOrEmpty(mInfo.VideoFrameRate) ? "" : mInfo.VideoFrameRate; vinfo.VideoResolution = string.IsNullOrEmpty(mInfo.VideoResolution) ? "" : mInfo.VideoResolution; vinfo.FullInfo = string.IsNullOrEmpty(mInfo.FullInfo) ? "" : mInfo.FullInfo; repVidInfo.Save(vinfo); } // now add a command to process the file CommandRequest_ProcessFile cr_procfile = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false); cr_procfile.Save(); return(vlocal); }
static void Main(string[] args) { var ovfFile = @"D:\vms\template\AirFASE_B2_150907-vbm.ovf"; RemoveSoundNodes(ovfFile); var ovfSha1 = FileHashHelper.SHA1File(ovfFile); Console.WriteLine(ovfSha1); Console.ReadKey(); return; var file = @"F:\vm-share\airfase-b2\vb-airfase-b2\vb-airfase-b2.ovf"; var targetFile = file.Replace(".ovf", "-vmx.ovf"); if (File.Exists(targetFile)) { File.Delete(targetFile); } var rplist = new List <VmRpItem>(); //rplist.Add(new VmRpItem() //{ // Source = "", // Target = "" //}); //var allLines = File.ReadAllLines(file); //Console.WriteLine("Line Count: {0}",allLines.Length); //Console.ReadKey(); //return; rplist.Add(new VmRpItem() { Source = "<vssd:VirtualSystemType>virtualbox-2.2</vssd:VirtualSystemType>", Target = "<vssd:VirtualSystemType>vmx-07</vssd:VirtualSystemType>" }); rplist.Add(new VmRpItem() { Source = "<rasd:Caption>sataController0</rasd:Caption>", Target = "<rasd:Caption>SCSIController</rasd:Caption>" }); rplist.Add(new VmRpItem() { Source = "<rasd:Description>SATA Controller</rasd:Description>", Target = "<rasd:Description>SCSI Controller</rasd:Description>" }); rplist.Add(new VmRpItem() { Source = "<rasd:ElementName>sataController0</rasd:ElementName>", Target = "<rasd:ElementName>SCSIController</rasd:ElementName>" }); rplist.Add(new VmRpItem() { Source = "<rasd:ResourceSubType>AHCI</rasd:ResourceSubType>", Target = "<rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>" }); rplist.Add(new VmRpItem() { Source = "<rasd:ResourceType>20</rasd:ResourceType>", Target = "<rasd:ResourceType>6</rasd:ResourceType>" }); bool isxmlend = false; using (var fs = File.OpenRead(file)) { using (var sr = new StreamReader(fs, Encoding.ASCII)) { long count = fs.Length; long wcount = 0; var s = string.Empty; //using (var ws = File.CreateText(file.Replace(".ova", "-vmx.ova"))) //{ var waitWrite = new List <string>(); while (!sr.EndOfStream) { s = sr.ReadLine(); // Console.WriteLine(s); var wt = s; wcount++; if (!isxmlend) { Console.WriteLine(s); foreach (var rp in rplist) { wt = wt.Replace(rp.Source, rp.Target); } Console.WriteLine(wt); if (s.Equals(EndString)) { isxmlend = true; // break; } } else { // break; } var wb = Encoding.ASCII.GetBytes(s); var wbcount = wb.Length; wcount += wbcount; ////ws.WriteLine(wt); waitWrite.Add(wt); if (waitWrite.Count >= 200000) { File.AppendAllLines(targetFile, waitWrite, Encoding.ASCII); waitWrite.Clear(); var recent = ((decimal)wcount / count) * 100; Console.WriteLine("Now processed: {0}.", recent); } } if (waitWrite != null && waitWrite.Count > 0) { File.AppendAllLines(targetFile, waitWrite, Encoding.ASCII); waitWrite.Clear(); var recent = 100;//((decimal)wcount / count) * 100; Console.WriteLine("Now processed: {0}.", recent); } } } Console.WriteLine("Press Enter Exit."); Console.ReadLine(); }
public static Media GenerateMediaFromVideoLocal(VideoLocal v) { VideoInfo info = v.VideoInfo; Media m = null; if (info != null) { if (!string.IsNullOrEmpty(info.FullInfo)) { try { m = XmlDeserializeFromString <Media>(info.FullInfo); } catch (Exception) { info.FullInfo = null; } } if (string.IsNullOrEmpty(info.FullInfo)) { try { VideoInfoRepository repo = new VideoInfoRepository(); MediaInfoResult mInfo = FileHashHelper.GetMediaInfo(v.FullServerPath, true); info.AudioBitrate = string.IsNullOrEmpty(mInfo.AudioBitrate) ? "" : mInfo.AudioBitrate; info.AudioCodec = string.IsNullOrEmpty(mInfo.AudioCodec) ? "" : mInfo.AudioCodec; info.Duration = mInfo.Duration; info.VideoBitrate = string.IsNullOrEmpty(mInfo.VideoBitrate) ? "" : mInfo.VideoBitrate; info.VideoBitDepth = string.IsNullOrEmpty(mInfo.VideoBitDepth) ? "" : mInfo.VideoBitDepth; info.VideoCodec = string.IsNullOrEmpty(mInfo.VideoCodec) ? "" : mInfo.VideoCodec; info.VideoFrameRate = string.IsNullOrEmpty(mInfo.VideoFrameRate) ? "" : mInfo.VideoFrameRate; info.VideoResolution = string.IsNullOrEmpty(mInfo.VideoResolution) ? "" : mInfo.VideoResolution; info.FullInfo = string.IsNullOrEmpty(mInfo.FullInfo) ? "" : mInfo.FullInfo; repo.Save(info); m = XmlDeserializeFromString <Media>(info.FullInfo); } catch (Exception) { //FILE DO NOT EXIST } } } if (m != null) { m.Id = v.VideoLocalID.ToString(); List <Stream> subs = SubtitleHelper.GetSubtitleStreams(v.FullServerPath); if (subs.Count > 0) { m.Parts[0].Streams.AddRange(subs); } foreach (Part p in m.Parts) { p.Id = null; p.Accessible = "1"; p.Exists = "1"; bool vid = false; bool aud = false; bool txt = false; foreach (Stream ss in p.Streams.ToArray()) { if ((ss.StreamType == "1") && !vid) { vid = true; } if ((ss.StreamType == "2") && !aud) { aud = true; ss.Selected = "1"; } if ((ss.StreamType == "3") && !txt) { txt = true; ss.Selected = "1"; } } } } return(m); }
private static void PopulateVideoEpisodeFromVideoLocal(Video l, VideoLocal v, JMMType type, int userid) { l.Type = "episode"; l.Summary = "Episode Overview Not Available"; //TODO Intenationalization l.Title = Path.GetFileNameWithoutExtension(v.FilePath); l.Key = ContructVideoLocalIdUrl(userid, v.VideoLocalID, type); l.AddedAt = v.DateTimeCreated.ToUnixTime(); l.UpdatedAt = v.DateTimeUpdated.ToUnixTime(); l.OriginallyAvailableAt = v.DateTimeCreated.ToPlexDate(); l.Year = v.DateTimeCreated.Year.ToString(); VideoInfo info = v.VideoInfo; Media m = null; if (info != null) { if (!string.IsNullOrEmpty(info.FullInfo)) { try { m = XmlDeserializeFromString <Media>(info.FullInfo); } catch (Exception) { info.FullInfo = null; } } if (string.IsNullOrEmpty(info.FullInfo)) { VideoInfoRepository repo = new VideoInfoRepository(); MediaInfoResult mInfo = FileHashHelper.GetMediaInfo(v.FullServerPath, true); info.AudioBitrate = string.IsNullOrEmpty(mInfo.AudioBitrate) ? "" : mInfo.AudioBitrate; info.AudioCodec = string.IsNullOrEmpty(mInfo.AudioCodec) ? "" : mInfo.AudioCodec; info.Duration = mInfo.Duration; info.VideoBitrate = string.IsNullOrEmpty(mInfo.VideoBitrate) ? "" : mInfo.VideoBitrate; info.VideoBitDepth = string.IsNullOrEmpty(mInfo.VideoBitDepth) ? "" : mInfo.VideoBitDepth; info.VideoCodec = string.IsNullOrEmpty(mInfo.VideoCodec) ? "" : mInfo.VideoCodec; info.VideoFrameRate = string.IsNullOrEmpty(mInfo.VideoFrameRate) ? "" : mInfo.VideoFrameRate; info.VideoResolution = string.IsNullOrEmpty(mInfo.VideoResolution) ? "" : mInfo.VideoResolution; info.FullInfo = string.IsNullOrEmpty(mInfo.FullInfo) ? "" : mInfo.FullInfo; repo.Save(info); m = XmlDeserializeFromString <Media>(info.FullInfo); } } l.Medias = new List <Media>(); if (m != null) { m.Id = null; List <JMMContracts.PlexContracts.Stream> subs = SubtitleHelper.GetSubtitleStreams(v.FullServerPath); if (subs.Count > 0) { foreach (JMMContracts.PlexContracts.Stream s in subs) { s.Key = ConstructFileStream(userid, s.File); } m.Parts[0].Streams.AddRange(subs); } foreach (Part p in m.Parts) { p.Id = null; string ff = Path.GetExtension(v.FullServerPath); p.Key = ConstructVideoLocalStream(userid, v.VideoLocalID, ff); p.Accessible = "1"; p.Exists = "1"; bool vid = false; bool aud = false; bool txt = false; foreach (JMMContracts.PlexContracts.Stream ss in p.Streams.ToArray()) { if ((ss.StreamType == "1") && (!vid)) { vid = true; } if ((ss.StreamType == "2") && (!aud)) { aud = true; ss.Selected = "1"; } if ((ss.StreamType == "3") && (!txt)) { txt = true; ss.Selected = "1"; } } } l.Medias.Add(m); l.Duration = m.Duration; } }
private void ProcessFile_LocalInfo() { // hash and read media info for file int nshareID = -1; (SVR_ImportFolder folder, string filePath) = VideoLocal_PlaceRepository.GetFromFullPath(FileName); if (folder == null) { logger.Error($"Unable to locate Import Folder for {FileName}"); return; } IFileSystem f = folder.FileSystem; if (f == null) { logger.Error("Unable to open filesystem for: {0}", FileName); return; } long filesize = 0; if (folder.CloudID == null) // Local Access { if (!File.Exists(FileName)) { logger.Error("File does not exist: {0}", FileName); return; } int numAttempts = 0; // Wait 1 minute before giving up on trying to access the file while ((filesize = CanAccessFile(FileName)) == 0 && (numAttempts < 60)) { numAttempts++; Thread.Sleep(1000); logger.Error($@"Failed to access, (or filesize is 0) Attempt # {numAttempts}, {FileName}"); } // if we failed to access the file, get ouuta here if (numAttempts >= 60) { logger.Error("Could not access file: " + FileName); return; } //For systems with no locking while (FileModified(FileName, 3)) { Thread.Sleep(1000); logger.Error($@"An external process is modifying the file, {FileName}"); } } IObject source = f.Resolve(FileName); if (source == null || source.Status != Status.Ok || !(source is IFile source_file)) { logger.Error("Could not access file: " + FileName); return; } if (folder.CloudID.HasValue) { filesize = source_file.Size; } nshareID = folder.ImportFolderID; // check if we have already processed this file SVR_VideoLocal_Place vlocalplace = Repo.Instance.VideoLocal_Place.GetByFilePathAndImportFolderID(filePath, nshareID); SVR_VideoLocal vlocal = null; var filename = Path.GetFileName(filePath); if (vlocalplace != null) { vlocal = vlocalplace.VideoLocal; if (vlocal != null) { logger.Trace("VideoLocal record found in database: {0}", FileName); // This will only happen with DB corruption, so just clean up the mess. if (vlocalplace.FullServerPath == null) { if (vlocal.Places.Count == 1) { Repo.Instance.VideoLocal.Delete(vlocal); vlocal = null; } Repo.Instance.VideoLocal_Place.Delete(vlocalplace); vlocalplace = null; } if (vlocal != null && ForceHash) { vlocal.FileSize = filesize; vlocal.DateTimeUpdated = DateTime.Now; } } } bool duplicate = false; using (var txn = Repo.Instance.VideoLocal.BeginAddOrUpdate(() => vlocal, () => { logger.Trace("No existing VideoLocal, creating temporary record"); return(new SVR_VideoLocal { DateTimeUpdated = DateTime.Now, DateTimeCreated = DateTimeUpdated, FileName = filename, FileSize = filesize, Hash = string.Empty, CRC32 = string.Empty, MD5 = source_file?.MD5?.ToUpperInvariant() ?? string.Empty, SHA1 = source_file?.SHA1?.ToUpperInvariant() ?? string.Empty, IsIgnored = 0, IsVariation = 0 }); })) { if (vlocalplace == null) { logger.Trace("No existing VideoLocal_Place, creating a new record"); vlocalplace = new SVR_VideoLocal_Place { FilePath = filePath, ImportFolderID = nshareID, ImportFolderType = folder.ImportFolderType }; // Make sure we have an ID vlocalplace = Repo.Instance.VideoLocal_Place.BeginAdd(vlocalplace).Commit(); } using (var txn_vl = Repo.Instance.VideoLocal_Place.BeginAddOrUpdate(() => vlocalplace)) { // check if we need to get a hash this file if (string.IsNullOrEmpty(txn.Entity.Hash) || ForceHash) { logger.Trace("No existing hash in VideoLocal, checking XRefs"); if (!ForceHash) { // try getting the hash from the CrossRef List <CrossRef_File_Episode> crossRefs = Repo.Instance.CrossRef_File_Episode.GetByFileNameAndSize(filename, txn.Entity.FileSize); if (crossRefs.Any()) { txn.Entity.Hash = crossRefs[0].Hash; txn.Entity.HashSource = (int)HashSource.DirectHash; } } // try getting the hash from the LOCAL cache if (!ForceHash && string.IsNullOrEmpty(txn.Entity.Hash)) { List <FileNameHash> fnhashes = Repo.Instance.FileNameHash.GetByFileNameAndSize(filename, txn.Entity.FileSize); if (fnhashes != null && fnhashes.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes) { Repo.Instance.FileNameHash.Delete(fnh.FileNameHashID); } } // reinit this to check if we erased them fnhashes = Repo.Instance.FileNameHash.GetByFileNameAndSize(filename, txn.Entity.FileSize); if (fnhashes != null && fnhashes.Count == 1) { logger.Trace("Got hash from LOCAL cache: {0} ({1})", FileName, fnhashes[0].Hash); txn.Entity.Hash = fnhashes[0].Hash; txn.Entity.HashSource = (int)HashSource.WebCacheFileName; } } if (string.IsNullOrEmpty(txn.Entity.Hash)) { FillVideoHashes(txn.Entity); } //Cloud and no hash, Nothing to do, except maybe Get the mediainfo.... if (string.IsNullOrEmpty(txn.Entity.Hash) && folder.CloudID.HasValue) { logger.Trace("No Hash found for cloud " + filename + " putting in videolocal table with empty ED2K"); vlocal = txn.Commit(true); using (var upd = Repo.Instance.VideoLocal_Place.BeginAddOrUpdate(() => vlocalplace)) { upd.Entity.VideoLocalID = vlocal.VideoLocalID; vlocalplace = upd.Commit(); } if (vlocalplace.RefreshMediaInfo()) { txn_vl.Commit(true); } return; } // hash the file if (string.IsNullOrEmpty(txn.Entity.Hash) || ForceHash) { logger.Info("Hashing File: {0}", FileName); ShokoService.CmdProcessorHasher.QueueState = PrettyDescriptionHashing; DateTime start = DateTime.Now; // update the VideoLocal record with the Hash, since cloud support we calculate everything var hashes = FileHashHelper.GetHashInfo(FileName.Replace("/", $"{System.IO.Path.DirectorySeparatorChar}"), true, ShokoServer.OnHashProgress, true, true, true); TimeSpan ts = DateTime.Now - start; logger.Trace("Hashed file in {0:#0.0} seconds --- {1} ({2})", ts.TotalSeconds, FileName, Utils.FormatByteSize(txn.Entity.FileSize)); txn.Entity.Hash = hashes.ED2K?.ToUpperInvariant(); txn.Entity.CRC32 = hashes.CRC32?.ToUpperInvariant(); txn.Entity.MD5 = hashes.MD5?.ToUpperInvariant(); txn.Entity.SHA1 = hashes.SHA1?.ToUpperInvariant(); txn.Entity.HashSource = (int)HashSource.DirectHash; } FillMissingHashes(txn.Entity); // We should have a hash by now // before we save it, lets make sure there is not any other record with this hash (possible duplicate file) SVR_VideoLocal tlocal = Repo.Instance.VideoLocal.GetByHash(txn.Entity.Hash); bool changed = false; if (tlocal != null) { logger.Trace("Found existing VideoLocal with hash, merging info from it"); // Aid with hashing cloud. Merge hashes and save, regardless of duplicate file changed = tlocal.MergeInfoFrom(txn.Entity); vlocal = tlocal; List <SVR_VideoLocal_Place> preps = vlocal.Places.Where( a => a.ImportFolder.CloudID == folder.CloudID && !vlocalplace.FullServerPath.Equals(a.FullServerPath)).ToList(); foreach (var prep in preps) { if (prep == null) { continue; } // clean up, if there is a 'duplicate file' that is invalid, remove it. if (prep.FullServerPath == null) { Repo.Instance.VideoLocal_Place.Delete(prep); } else { FileSystemResult dupFileSystemResult = (FileSystemResult)prep.ImportFolder?.FileSystem?.Resolve(prep.FullServerPath); if (dupFileSystemResult == null || dupFileSystemResult.Status != Status.Ok) { Repo.Instance.VideoLocal_Place.Delete(prep); } } } var dupPlace = txn.Entity.Places.FirstOrDefault( a => a.ImportFolder.CloudID == folder.CloudID && !vlocalplace.FullServerPath.Equals(a.FullServerPath)); if (dupPlace != null) { logger.Warn("Found Duplicate File"); logger.Warn("---------------------------------------------"); logger.Warn($"New File: {vlocalplace.FullServerPath}"); logger.Warn($"Existing File: {dupPlace.FullServerPath}"); logger.Warn("---------------------------------------------"); // check if we have a record of this in the database, if not create one List <DuplicateFile> dupFiles = Repo.Instance.DuplicateFile.GetByFilePathsAndImportFolder( vlocalplace.FilePath, dupPlace.FilePath, vlocalplace.ImportFolderID, dupPlace.ImportFolderID); if (dupFiles.Count == 0) { dupFiles = Repo.Instance.DuplicateFile.GetByFilePathsAndImportFolder(dupPlace.FilePath, vlocalplace.FilePath, dupPlace.ImportFolderID, vlocalplace.ImportFolderID); } if (dupFiles.Count == 0) { DuplicateFile dup = new DuplicateFile { DateTimeUpdated = DateTime.Now, FilePathFile1 = vlocalplace.FilePath, FilePathFile2 = dupPlace.FilePath, ImportFolderIDFile1 = vlocalplace.ImportFolderID, ImportFolderIDFile2 = dupPlace.ImportFolderID, Hash = txn.Entity.Hash }; Repo.Instance.DuplicateFile.BeginAdd(dup).Commit(); } //Notify duplicate, don't delete duplicate = true; } } if (!duplicate || changed) { vlocal = txn.Commit(); } } } using (var upd = Repo.Instance.VideoLocal_Place.BeginAddOrUpdate(() => vlocalplace)) { upd.Entity.VideoLocalID = vlocal.VideoLocalID; upd.Commit(); } } if (duplicate) { CommandRequest_ProcessFile cr_procfile3 = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false); cr_procfile3.Save(); return; } // also save the filename to hash record // replace the existing records just in case it was corrupt List <FileNameHash> fnhashes2 = Repo.Instance.FileNameHash.GetByFileNameAndSize(filename, vlocal.FileSize); if (fnhashes2 != null && fnhashes2.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes2) { Repo.Instance.FileNameHash.Delete(fnh.FileNameHashID); } } using (var upd = Repo.Instance.FileNameHash.BeginAddOrUpdate(() => fnhashes2?.Count == 1 ? fnhashes2[0] : null)) { upd.Entity.FileName = filename; upd.Entity.FileSize = vlocal.FileSize; upd.Entity.Hash = vlocal.Hash; upd.Entity.DateTimeUpdated = DateTime.Now; upd.Commit(); } if ((vlocal.Media == null) || vlocal.MediaVersion < SVR_VideoLocal.MEDIA_VERSION || vlocal.Duration == 0) { if (vlocalplace.RefreshMediaInfo()) { using (var upd = Repo.Instance.VideoLocal.BeginAddOrUpdate(() => vlocalplace.VideoLocal)) upd.Commit(true); } } // now add a command to process the file CommandRequest_ProcessFile cr_procfile = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false); cr_procfile.Save(); }
private void ProcessFile_LocalInfo() { // hash and read media info for file int nshareID = -1; Tuple <SVR_ImportFolder, string> tup = VideoLocal_PlaceRepository.GetFromFullPath(FileName); if (tup == null) { logger.Error($"Unable to locate Import Folder for {FileName}"); return; } SVR_ImportFolder folder = tup.Item1; string filePath = tup.Item2; long filesize = 0; Exception e = null; if (!File.Exists(FileName)) { logger.Error("File does not exist: {0}", FileName); return; } if (ServerSettings.Instance.Import.FileLockChecking) { int numAttempts = 0; bool writeAccess = folder.IsDropSource == 1; bool aggressive = ServerSettings.Instance.Import.AggressiveFileLockChecking; // At least 1s between to ensure that size has the chance to change int waitTime = ServerSettings.Instance.Import.FileLockWaitTimeMS; if (waitTime < 1000) { waitTime = ServerSettings.Instance.Import.FileLockWaitTimeMS = 4000; ServerSettings.Instance.SaveSettings(); } if (!aggressive) { // Wait 1 minute before giving up on trying to access the file while ((filesize = CanAccessFile(FileName, writeAccess, ref e)) == 0 && (numAttempts < 60)) { numAttempts++; Thread.Sleep(waitTime); logger.Trace($@"Failed to access, (or filesize is 0) Attempt # {numAttempts}, {FileName}"); } } else { // Wait 1 minute before giving up on trying to access the file // first only do read to not get in something's way while ((filesize = CanAccessFile(FileName, false, ref e)) == 0 && (numAttempts < 60)) { numAttempts++; Thread.Sleep(1000); logger.Trace($@"Failed to access, (or filesize is 0) Attempt # {numAttempts}, {FileName}"); } // if we failed to access the file, get ouuta here if (numAttempts >= 60) { logger.Error("Could not access file: " + FileName); logger.Error(e); return; } int seconds = ServerSettings.Instance.Import.AggressiveFileLockWaitTimeSeconds; if (seconds < 0) { seconds = ServerSettings.Instance.Import.AggressiveFileLockWaitTimeSeconds = 8; ServerSettings.Instance.SaveSettings(); } Thread.Sleep(waitTime); numAttempts = 0; //For systems with no locking while (FileModified(FileName, seconds, ref filesize, writeAccess, ref e) && numAttempts < 60) { numAttempts++; Thread.Sleep(waitTime); // Only show if it's more than 'seconds' past if (numAttempts != 0 && numAttempts * 2 % seconds == 0) { logger.Warn( $@"The modified date is too soon. Waiting to ensure that no processes are writing to it. {numAttempts}/60 {FileName}" ); } } } // if we failed to access the file, get ouuta here if (numAttempts >= 60 || filesize == 0) { logger.Error("Could not access file: " + FileName); logger.Error(e); return; } } if (!File.Exists(FileName)) { logger.Error("Could not access file: " + FileName); return; } FileInfo sourceFile = new FileInfo(FileName); nshareID = folder.ImportFolderID; // check if we have already processed this file SVR_VideoLocal_Place vlocalplace = RepoFactory.VideoLocalPlace.GetByFilePathAndImportFolderID(filePath, nshareID); SVR_VideoLocal vlocal = null; var filename = Path.GetFileName(filePath); if (vlocalplace != null) { vlocal = vlocalplace.VideoLocal; if (vlocal != null) { logger.Trace("VideoLocal record found in database: {0}", FileName); // This will only happen with DB corruption, so just clean up the mess. if (vlocalplace.FullServerPath == null) { if (vlocal.Places.Count == 1) { RepoFactory.VideoLocal.Delete(vlocal); vlocal = null; } RepoFactory.VideoLocalPlace.Delete(vlocalplace); vlocalplace = null; } if (vlocal != null && ForceHash) { vlocal.FileSize = filesize; vlocal.DateTimeUpdated = DateTime.Now; } } } if (vlocal == null) { // TODO support reading MD5 and SHA1 from files via the standard way logger.Trace("No existing VideoLocal, creating temporary record"); vlocal = new SVR_VideoLocal { DateTimeUpdated = DateTime.Now, DateTimeCreated = DateTimeUpdated, FileName = filename, FileSize = filesize, Hash = string.Empty, CRC32 = string.Empty, MD5 = string.Empty, SHA1 = string.Empty, IsIgnored = 0, IsVariation = 0 }; } if (vlocalplace == null) { logger.Trace("No existing VideoLocal_Place, creating a new record"); vlocalplace = new SVR_VideoLocal_Place { FilePath = filePath, ImportFolderID = nshareID, ImportFolderType = folder.ImportFolderType }; // Make sure we have an ID RepoFactory.VideoLocalPlace.Save(vlocalplace); } // check if we need to get a hash this file if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash) { logger.Trace("No existing hash in VideoLocal, checking XRefs"); if (!ForceHash) { // try getting the hash from the CrossRef List <CrossRef_File_Episode> crossRefs = RepoFactory.CrossRef_File_Episode.GetByFileNameAndSize(filename, vlocal.FileSize); if (crossRefs.Any()) { vlocal.Hash = crossRefs[0].Hash; vlocal.HashSource = (int)HashSource.DirectHash; } } // try getting the hash from the LOCAL cache if (!ForceHash && string.IsNullOrEmpty(vlocal.Hash)) { List <FileNameHash> fnhashes = RepoFactory.FileNameHash.GetByFileNameAndSize(filename, vlocal.FileSize); if (fnhashes != null && fnhashes.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes) { RepoFactory.FileNameHash.Delete(fnh.FileNameHashID); } } // reinit this to check if we erased them fnhashes = RepoFactory.FileNameHash.GetByFileNameAndSize(filename, vlocal.FileSize); if (fnhashes != null && fnhashes.Count == 1) { logger.Trace("Got hash from LOCAL cache: {0} ({1})", FileName, fnhashes[0].Hash); vlocal.Hash = fnhashes[0].Hash; vlocal.HashSource = (int)HashSource.WebCacheFileName; } } if (string.IsNullOrEmpty(vlocal.Hash)) { FillVideoHashes(vlocal); } // hash the file if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash) { logger.Info("Hashing File: {0}", FileName); ShokoService.CmdProcessorHasher.QueueState = PrettyDescriptionHashing; DateTime start = DateTime.Now; // update the VideoLocal record with the Hash, since cloud support we calculate everything var hashes = FileHashHelper.GetHashInfo(FileName.Replace("/", $"{Path.DirectorySeparatorChar}"), true, ShokoServer.OnHashProgress, true, true, true); TimeSpan ts = DateTime.Now - start; logger.Trace("Hashed file in {0:#0.0} seconds --- {1} ({2})", ts.TotalSeconds, FileName, Utils.FormatByteSize(vlocal.FileSize)); vlocal.Hash = hashes.ED2K?.ToUpperInvariant(); vlocal.CRC32 = hashes.CRC32?.ToUpperInvariant(); vlocal.MD5 = hashes.MD5?.ToUpperInvariant(); vlocal.SHA1 = hashes.SHA1?.ToUpperInvariant(); vlocal.HashSource = (int)HashSource.DirectHash; } FillMissingHashes(vlocal); // We should have a hash by now // before we save it, lets make sure there is not any other record with this hash (possible duplicate file) SVR_VideoLocal tlocal = RepoFactory.VideoLocal.GetByHash(vlocal.Hash); bool duplicate = false; bool changed = false; if (tlocal != null) { logger.Trace("Found existing VideoLocal with hash, merging info from it"); // Aid with hashing cloud. Merge hashes and save, regardless of duplicate file changed = tlocal.MergeInfoFrom(vlocal); vlocal = tlocal; List <SVR_VideoLocal_Place> preps = vlocal.Places.Where(a => !vlocalplace.FullServerPath.Equals(a.FullServerPath)).ToList(); foreach (var prep in preps) { if (prep == null) { continue; } // clean up, if there is a 'duplicate file' that is invalid, remove it. if (prep.FullServerPath == null) { RepoFactory.VideoLocalPlace.Delete(prep); } else { if (!File.Exists(prep.FullServerPath)) { RepoFactory.VideoLocalPlace.Delete(prep); } } } var dupPlace = vlocal.Places.FirstOrDefault(a => !vlocalplace.FullServerPath.Equals(a.FullServerPath)); if (dupPlace != null) { logger.Warn("Found Duplicate File"); logger.Warn("---------------------------------------------"); logger.Warn($"New File: {vlocalplace.FullServerPath}"); logger.Warn($"Existing File: {dupPlace.FullServerPath}"); logger.Warn("---------------------------------------------"); if (ServerSettings.Instance.Import.AutomaticallyDeleteDuplicatesOnImport) { vlocalplace.RemoveRecordAndDeletePhysicalFile(); return; } // check if we have a record of this in the database, if not create one List <DuplicateFile> dupFiles = RepoFactory.DuplicateFile.GetByFilePathsAndImportFolder( vlocalplace.FilePath, dupPlace.FilePath, vlocalplace.ImportFolderID, dupPlace.ImportFolderID); if (dupFiles.Count == 0) { dupFiles = RepoFactory.DuplicateFile.GetByFilePathsAndImportFolder(dupPlace.FilePath, vlocalplace.FilePath, dupPlace.ImportFolderID, vlocalplace.ImportFolderID); } if (dupFiles.Count == 0) { DuplicateFile dup = new DuplicateFile { DateTimeUpdated = DateTime.Now, FilePathFile1 = vlocalplace.FilePath, FilePathFile2 = dupPlace.FilePath, ImportFolderIDFile1 = vlocalplace.ImportFolderID, ImportFolderIDFile2 = dupPlace.ImportFolderID, Hash = vlocal.Hash }; RepoFactory.DuplicateFile.Save(dup); } //Notify duplicate, don't delete duplicate = true; } } if (!duplicate || changed) { RepoFactory.VideoLocal.Save(vlocal, true); } vlocalplace.VideoLocalID = vlocal.VideoLocalID; RepoFactory.VideoLocalPlace.Save(vlocalplace); if (duplicate) { CommandRequest_ProcessFile cr_procfile3 = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false); cr_procfile3.Save(); return; } // also save the filename to hash record // replace the existing records just in case it was corrupt FileNameHash fnhash; List <FileNameHash> fnhashes2 = RepoFactory.FileNameHash.GetByFileNameAndSize(filename, vlocal.FileSize); if (fnhashes2 != null && fnhashes2.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes2) { RepoFactory.FileNameHash.Delete(fnh.FileNameHashID); } } if (fnhashes2 != null && fnhashes2.Count == 1) { fnhash = fnhashes2[0]; } else { fnhash = new FileNameHash(); } fnhash.FileName = filename; fnhash.FileSize = vlocal.FileSize; fnhash.Hash = vlocal.Hash; fnhash.DateTimeUpdated = DateTime.Now; RepoFactory.FileNameHash.Save(fnhash); } else { FillMissingHashes(vlocal); } if (((vlocal.Media?.GeneralStream?.Duration ?? 0) == 0) || vlocal.MediaVersion < SVR_VideoLocal.MEDIA_VERSION) { if (vlocalplace.RefreshMediaInfo()) { RepoFactory.VideoLocal.Save(vlocalplace.VideoLocal, true); } } // now add a command to process the file CommandRequest_ProcessFile cr_procfile = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false, SkipMyList); cr_procfile.Save(); }
public static void RunImport_NewFiles() { VideoLocalRepository repVidLocals = new VideoLocalRepository(); // first build a list of files that we already know about, as we don't want to process them again List<VideoLocal> filesAll = repVidLocals.GetAll(); Dictionary<string, VideoLocal> dictFilesExisting = new Dictionary<string, VideoLocal>(); foreach (VideoLocal vl in filesAll) { try { dictFilesExisting[vl.FullServerPath] = vl; } catch (Exception ex) { string msg = string.Format("Error RunImport_NewFiles XREF: {0} - {1}", vl.ToStringDetailed(), ex.ToString()); logger.Info(msg); //throw; } } // Steps for processing a file // 1. Check if it is a video file // 2. Check if we have a VideoLocal record for that file // ......... // get a complete list of files List<string> fileList = new List<string>(); ImportFolderRepository repNetShares = new ImportFolderRepository(); foreach (ImportFolder share in repNetShares.GetAll()) { logger.Debug("ImportFolder: {0} || {1}", share.ImportFolderName, share.ImportFolderLocation); try { Utils.GetFilesForImportFolder(share.ImportFolderLocation, ref fileList); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } } // get a list fo files that we haven't processed before List<string> fileListNew = new List<string>(); foreach (string fileName in fileList) { if (!dictFilesExisting.ContainsKey(fileName)) fileListNew.Add(fileName); } // get a list of all the shares we are looking at int filesFound = 0, videosFound = 0; int i = 0; // get a list of all files in the share foreach (string fileName in fileListNew) { i++; filesFound++; logger.Info("Processing File {0}/{1} --- {2}", i, fileList.Count, fileName); if (!FileHashHelper.IsVideo(fileName)) continue; videosFound++; CommandRequest_HashFile cr_hashfile = new CommandRequest_HashFile(fileName, false); cr_hashfile.Save(); } logger.Debug("Found {0} files", filesFound); logger.Debug("Found {0} videos", videosFound); }
public static void RunImport_ScanFolder(int importFolderID) { // get a complete list of files List<string> fileList = new List<string>(); ImportFolderRepository repFolders = new ImportFolderRepository(); int filesFound = 0, videosFound = 0; int i = 0; try { ImportFolder fldr = repFolders.GetByID(importFolderID); if (fldr == null) return; VideoLocalRepository repVidLocals = new VideoLocalRepository(); // first build a list of files that we already know about, as we don't want to process them again List<VideoLocal> filesAll = repVidLocals.GetAll(); Dictionary<string, VideoLocal> dictFilesExisting = new Dictionary<string, VideoLocal>(); foreach (VideoLocal vl in filesAll) { try { dictFilesExisting[vl.FullServerPath] = vl; } catch (Exception ex) { string msg = string.Format("Error RunImport_ScanFolder XREF: {0} - {1}", vl.ToStringDetailed(), ex.ToString()); logger.Info(msg); } } logger.Debug("ImportFolder: {0} || {1}", fldr.ImportFolderName, fldr.ImportFolderLocation); Utils.GetFilesForImportFolder(fldr.ImportFolderLocation, ref fileList); // get a list of all files in the share foreach (string fileName in fileList) { i++; if (dictFilesExisting.ContainsKey(fileName)) { if (fldr.IsDropSource != 1) continue; else { // if this is a file in a drop source, try moving it string filePath = string.Empty; int nshareID = 0; DataAccessHelper.GetShareAndPath(fileName, repFolders.GetAll(), ref nshareID, ref filePath); List<VideoLocal> filesSearch = repVidLocals.GetByName(filePath); foreach (VideoLocal vid in filesSearch) vid.MoveFileIfRequired(); } } filesFound++; logger.Info("Processing File {0}/{1} --- {2}", i, fileList.Count, fileName); if (!FileHashHelper.IsVideo(fileName)) continue; videosFound++; CommandRequest_HashFile cr_hashfile = new CommandRequest_HashFile(fileName, false); cr_hashfile.Save(); } logger.Debug("Found {0} new files", filesFound); logger.Debug("Found {0} videos", videosFound); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }
private static void PopulateVideoEpisodeFromVideoLocal(Video l, VideoLocal v, JMMType type) { l.Type = "episode"; l.Summary = "Episode Overview Not Available"; l.Title = Path.GetFileNameWithoutExtension(v.FilePath); l.Key = l.PrimaryExtraKey = ServerUrl(int.Parse(ServerSettings.JMMServerPort), MainWindow.PathAddressKodi + "/GetMetadata/0/" + (int)type + "/" + v.VideoLocalID); l.AddedAt = v.DateTimeCreated.Year.ToString("0000") + "-" + v.DateTimeCreated.Month.ToString("00") + "-" + v.DateTimeCreated.Day.ToString("00") + " " + v.DateTimeCreated.Hour.ToString("00") + ":" + v.DateTimeCreated.Minute.ToString("00") + ":" + v.DateTimeCreated.Millisecond.ToString("00"); l.UpdatedAt = v.DateTimeUpdated.Year.ToString("0000") + "-" + v.DateTimeUpdated.Month.ToString("00") + "-" + v.DateTimeUpdated.Day.ToString("00") + " " + v.DateTimeUpdated.Hour.ToString("00") + ":" + v.DateTimeUpdated.Minute.ToString("00") + ":" + v.DateTimeUpdated.Millisecond.ToString("00"); l.OriginallyAvailableAt = v.DateTimeCreated.Year.ToString("0000") + "-" + v.DateTimeCreated.Month.ToString("00") + "-" + v.DateTimeCreated.Day.ToString("00"); l.Year = v.DateTimeCreated.Year.ToString(); VideoInfo info = v.VideoInfo; Media m = null; if (info != null) { if (!string.IsNullOrEmpty(info.FullInfo)) { try { m = XmlDeserializeFromString <Media>(info.FullInfo); } catch (Exception) { info.FullInfo = null; } } if (string.IsNullOrEmpty(info.FullInfo)) { VideoInfoRepository repo = new VideoInfoRepository(); MediaInfoResult mInfo = FileHashHelper.GetMediaInfo(v.FullServerPath, true, true); info.AudioBitrate = string.IsNullOrEmpty(mInfo.AudioBitrate) ? "" : mInfo.AudioBitrate; info.AudioCodec = string.IsNullOrEmpty(mInfo.AudioCodec) ? "" : mInfo.AudioCodec; info.Duration = mInfo.Duration; info.VideoBitrate = string.IsNullOrEmpty(mInfo.VideoBitrate) ? "" : mInfo.VideoBitrate; info.VideoBitDepth = string.IsNullOrEmpty(mInfo.VideoBitDepth) ? "" : mInfo.VideoBitDepth; info.VideoCodec = string.IsNullOrEmpty(mInfo.VideoCodec) ? "" : mInfo.VideoCodec; info.VideoFrameRate = string.IsNullOrEmpty(mInfo.VideoFrameRate) ? "" : mInfo.VideoFrameRate; info.VideoResolution = string.IsNullOrEmpty(mInfo.VideoResolution) ? "" : mInfo.VideoResolution; info.FullInfo = string.IsNullOrEmpty(mInfo.FullInfo) ? "" : mInfo.FullInfo; repo.Save(info); m = XmlDeserializeFromString <Media>(info.FullInfo); } } l.Medias = new List <Media>(); if (m != null) { m.Id = null; List <JMMContracts.KodiContracts.Stream> subs = SubtitleHelper.GetSubtitleStreamsKodi(v.FullServerPath); if (subs.Count > 0) { foreach (JMMContracts.KodiContracts.Stream s in subs) { s.Key = ServerUrl(int.Parse(ServerSettings.JMMServerFilePort), "file/0/" + Base64EncodeUrl(s.File), KodiObject.IsExternalRequest); } m.Parts[0].Streams.AddRange(subs); } foreach (Part p in m.Parts) { p.Id = null; p.File = v.FullServerPath; string ff = Path.GetExtension(v.FullServerPath); p.Key = ServerUrl(int.Parse(ServerSettings.JMMServerFilePort), "videolocal/0/" + v.VideoLocalID + "/file" + ff, KodiObject.IsExternalRequest); p.Accessible = "1"; p.Exists = "1"; bool vid = false; bool aud = false; bool txt = false; foreach (JMMContracts.KodiContracts.Stream ss in p.Streams.ToArray()) { if ((ss.StreamType == "1") && (!vid)) { vid = true; } if ((ss.StreamType == "2") && (!aud)) { aud = true; ss.Selected = "1"; } if ((ss.StreamType == "3") && (!txt)) { txt = true; ss.Selected = "1"; } } } l.Medias.Add(m); l.Duration = m.Duration; } }
private VideoLocal_Place ProcessFile_LocalInfo() { // hash and read media info for file int nshareID = -1; string filePath = ""; Tuple <ImportFolder, string> tup = VideoLocal_PlaceRepository.GetFromFullPath(FileName); if (tup == null) { logger.Error($"Unable to locate file {FileName} inside the import folders"); return(null); } ImportFolder folder = tup.Item1; filePath = tup.Item2; IFileSystem f = tup.Item1.FileSystem; if (f == null) { logger.Error("Unable to open filesystem for: {0}", FileName); return(null); } long filesize = 0; if (folder.CloudID == null) // Local Access { if (!File.Exists(FileName)) { logger.Error("File does not exist: {0}", FileName); return(null); } int numAttempts = 0; // Wait 3 minutes seconds before giving up on trying to access the file while ((filesize = CanAccessFile(FileName)) == 0 && (numAttempts < 180)) { numAttempts++; Thread.Sleep(1000); Console.WriteLine("Attempt # " + numAttempts.ToString()); } // if we failed to access the file, get ouuta here if (numAttempts == 180) { logger.Error("Could not access file: " + FileName); return(null); } } FileSystemResult <IObject> source = f.Resolve(FileName); if (source == null || !source.IsOk || (!(source.Result is IFile))) { logger.Error("Could not access file: " + FileName); return(null); } IFile source_file = (IFile)source.Result; if (folder.CloudID.HasValue) { filesize = source_file.Size; } nshareID = folder.ImportFolderID; // check if we have already processed this file VideoLocal_Place vlocalplace = RepoFactory.VideoLocalPlace.GetByFilePathAndShareID(filePath, nshareID); VideoLocal vlocal; if (vlocalplace != null) { vlocal = vlocalplace.VideoLocal; logger.Trace("VideoLocal record found in database: {0}", vlocal.VideoLocalID); if (ForceHash) { vlocal.FileSize = filesize; vlocal.DateTimeUpdated = DateTime.Now; } } else { logger.Trace("VideoLocal, creating temporary record"); vlocal = new VideoLocal(); vlocal.DateTimeUpdated = DateTime.Now; vlocal.DateTimeCreated = vlocal.DateTimeUpdated; vlocal.FileName = Path.GetFileName(filePath); vlocal.FileSize = filesize; vlocal.Hash = string.Empty; vlocal.CRC32 = string.Empty; vlocal.MD5 = source_file.MD5.ToUpperInvariant() ?? string.Empty; vlocal.SHA1 = source_file.SHA1.ToUpperInvariant() ?? string.Empty; vlocal.IsIgnored = 0; vlocal.IsVariation = 0; vlocalplace = new VideoLocal_Place(); vlocalplace.FilePath = filePath; vlocalplace.ImportFolderID = nshareID; vlocalplace.ImportFolderType = folder.ImportFolderType; } // check if we need to get a hash this file Hashes hashes = null; if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash) { // try getting the hash from the CrossRef if (!ForceHash) { List <CrossRef_File_Episode> crossRefs = RepoFactory.CrossRef_File_Episode.GetByFileNameAndSize(vlocal.FileName, vlocal.FileSize); if (crossRefs.Count == 1) { vlocal.Hash = crossRefs[0].Hash; vlocal.HashSource = (int)HashSource.DirectHash; } } // try getting the hash from the LOCAL cache if (!ForceHash && string.IsNullOrEmpty(vlocal.Hash)) { List <FileNameHash> fnhashes = RepoFactory.FileNameHash.GetByFileNameAndSize(vlocal.FileName, vlocal.FileSize); if (fnhashes != null && fnhashes.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes) { RepoFactory.FileNameHash.Delete(fnh.FileNameHashID); } } if (fnhashes != null && fnhashes.Count == 1) { logger.Trace("Got hash from LOCAL cache: {0} ({1})", FileName, fnhashes[0].Hash); vlocal.Hash = fnhashes[0].Hash; vlocal.HashSource = (int)HashSource.WebCacheFileName; } } if (string.IsNullOrEmpty(vlocal.Hash)) { FillVideoHashes(vlocal); } if (string.IsNullOrEmpty(vlocal.Hash) && folder.CloudID.HasValue) { //Cloud and no hash, Nothing to do, except maybe Get the mediainfo.... logger.Trace("No Hash found for cloud " + vlocal.FileName + " putting in videolocal table with empty ED2K"); RepoFactory.VideoLocal.Save(vlocal, false); vlocalplace.VideoLocalID = vlocal.VideoLocalID; RepoFactory.VideoLocalPlace.Save(vlocalplace); if (vlocalplace.RefreshMediaInfo()) { RepoFactory.VideoLocal.Save(vlocalplace.VideoLocal, true); } return(vlocalplace); } // hash the file if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash) { JMMService.CmdProcessorHasher.QueueState = PrettyDescriptionHashing; DateTime start = DateTime.Now; logger.Trace("Calculating ED2K hashes for: {0}", FileName); // update the VideoLocal record with the Hash, since cloud support we calculate everything hashes = FileHashHelper.GetHashInfo(FileName.Replace("/", "\\"), true, MainWindow.OnHashProgress, true, true, true); TimeSpan ts = DateTime.Now - start; logger.Trace("Hashed file in {0} seconds --- {1} ({2})", ts.TotalSeconds.ToString("#0.0"), FileName, Utils.FormatByteSize(vlocal.FileSize)); vlocal.Hash = hashes.ed2k?.ToUpperInvariant(); vlocal.CRC32 = hashes.crc32?.ToUpperInvariant(); vlocal.MD5 = hashes.md5?.ToUpperInvariant(); vlocal.SHA1 = hashes.sha1?.ToUpperInvariant(); vlocal.HashSource = (int)HashSource.DirectHash; } FillMissingHashes(vlocal); // We should have a hash by now // before we save it, lets make sure there is not any other record with this hash (possible duplicate file) VideoLocal tlocal = RepoFactory.VideoLocal.GetByHash(vlocal.Hash); bool intercloudfolder = false; VideoLocal_Place prep = tlocal?.Places.FirstOrDefault(a => a.ImportFolder.CloudID == folder.CloudID && a.ImportFolderID == folder.ImportFolderID && vlocalplace.VideoLocal_Place_ID != a.VideoLocal_Place_ID); if (prep != null) { // delete the VideoLocal record logger.Warn("Deleting duplicate video file record"); logger.Warn("---------------------------------------------"); logger.Warn($"Keeping record for: {vlocalplace.FullServerPath}"); logger.Warn($"Deleting record for: {prep.FullServerPath}"); logger.Warn("---------------------------------------------"); // check if we have a record of this in the database, if not create one List <DuplicateFile> dupFiles = RepoFactory.DuplicateFile.GetByFilePathsAndImportFolder(vlocalplace.FilePath, prep.FilePath, vlocalplace.ImportFolderID, prep.ImportFolderID); if (dupFiles.Count == 0) { dupFiles = RepoFactory.DuplicateFile.GetByFilePathsAndImportFolder(prep.FilePath, vlocalplace.FilePath, prep.ImportFolderID, vlocalplace.ImportFolderID); } if (dupFiles.Count == 0) { DuplicateFile dup = new DuplicateFile(); dup.DateTimeUpdated = DateTime.Now; dup.FilePathFile1 = vlocalplace.FilePath; dup.FilePathFile2 = prep.FilePath; dup.ImportFolderIDFile1 = vlocalplace.ImportFolderID; dup.ImportFolderIDFile2 = prep.ImportFolderID; dup.Hash = vlocal.Hash; RepoFactory.DuplicateFile.Save(dup); } //Notify duplicate, don't delete } else if (tlocal != null) { vlocal = tlocal; intercloudfolder = true; } if (!intercloudfolder) { RepoFactory.VideoLocal.Save(vlocal, true); } vlocalplace.VideoLocalID = vlocal.VideoLocalID; RepoFactory.VideoLocalPlace.Save(vlocalplace); if (intercloudfolder) { CommandRequest_ProcessFile cr_procfile3 = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false); cr_procfile3.Save(); return(vlocalplace); } // also save the filename to hash record // replace the existing records just in case it was corrupt FileNameHash fnhash = null; List <FileNameHash> fnhashes2 = RepoFactory.FileNameHash.GetByFileNameAndSize(vlocal.FileName, vlocal.FileSize); if (fnhashes2 != null && fnhashes2.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes2) { RepoFactory.FileNameHash.Delete(fnh.FileNameHashID); } } if (fnhashes2 != null && fnhashes2.Count == 1) { fnhash = fnhashes2[0]; } else { fnhash = new FileNameHash(); } fnhash.FileName = vlocal.FileName; fnhash.FileSize = vlocal.FileSize; fnhash.Hash = vlocal.Hash; fnhash.DateTimeUpdated = DateTime.Now; RepoFactory.FileNameHash.Save(fnhash); } else { FillMissingHashes(vlocal); } if ((vlocal.Media == null) || vlocal.MediaVersion < VideoLocal.MEDIA_VERSION || vlocal.Duration == 0) { if (vlocalplace.RefreshMediaInfo()) { RepoFactory.VideoLocal.Save(vlocalplace.VideoLocal, true); } } // now add a command to process the file CommandRequest_ProcessFile cr_procfile = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false); cr_procfile.Save(); return(vlocalplace); }
private void WorkerIntegrityScanner_DoWork(object sender, DoWorkEventArgs e) { if (RunScan != null && RunScan.GetScanStatus() != ScanStatus.Finish) { bool paused = ShokoService.CmdProcessorHasher.Paused; ShokoService.CmdProcessorHasher.Paused = true; SVR_Scan s = RunScan; s.Status = (int)ScanStatus.Running; RepoFactory.Scan.Save(s); Refresh(); List <ScanFile> files = RepoFactory.ScanFile.GetWaiting(s.ScanID); int cnt = 0; foreach (ScanFile sf in files) { try { if (!File.Exists(sf.FullName)) { sf.Status = (int)ScanFileStatus.ErrorFileNotFound; } else { FileInfo f = new FileInfo(sf.FullName); if (sf.FileSize != f.Length) { sf.Status = (int)ScanFileStatus.ErrorInvalidSize; } else { ShokoService.CmdProcessorHasher.QueueState = new QueueStateStruct() { queueState = QueueStateEnum.HashingFile, extraParams = new[] { sf.FullName } }; Hashes hashes = FileHashHelper.GetHashInfo(sf.FullName, true, OnHashProgress, false, false, false); if (string.IsNullOrEmpty(hashes.ED2K)) { sf.Status = (int)ScanFileStatus.ErrorMissingHash; } else { sf.HashResult = hashes.ED2K; if (!sf.Hash.Equals(sf.HashResult, StringComparison.InvariantCultureIgnoreCase)) { sf.Status = (int)ScanFileStatus.ErrorInvalidHash; } else { sf.Status = (int)ScanFileStatus.ProcessedOK; } } } } } catch (Exception) { sf.Status = (int)ScanFileStatus.ErrorIOError; } cnt++; sf.CheckDate = DateTime.Now; RepoFactory.ScanFile.Save(sf); if (sf.Status > (int)ScanFileStatus.ProcessedOK) { Scanner.Instance.AddErrorScan(sf); } Refresh(); if (cancelIntegrityCheck) { break; } } if (files.Any(a => a.GetScanFileStatus() == ScanFileStatus.Waiting)) { s.Status = (int)ScanStatus.Standby; } else { s.Status = (int)ScanStatus.Finish; } RepoFactory.Scan.Save(s); Refresh(); RunScan = null; ShokoService.CmdProcessorHasher.Paused = paused; } }
public static MvcHtmlString RenderReferences(this HtmlHelper html, string htmlTagTemplate, bool appendHash, params string[] referencePaths) { var urlHelper = new UrlHelper(html.ViewContext.RequestContext); var sb = new StringBuilder(); foreach (var path in referencePaths) { var url = path; if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)) { // External files, no hash appending process sb.Append(string.Format(htmlTagTemplate, url)); } else { Bundle bundle = null; if (url.StartsWith("~")) { // Is the path provided a bundle path? bundle = BundleTable.Bundles.GetBundleFor(url); } if (bundle != null) { if (bundle is StyleBundle) { sb.Append(Styles.Render(url)); } else if (bundle is ScriptBundle) { sb.Append(Scripts.Render(url)); } } else { url = urlHelper.Content(url); if (appendHash) { // TODO: handle proxy url try { var filePath = HttpContext.Current.Server.MapPath(path); url = "{0}?v={1}".FormatWith(url, FileHashHelper.GetFileHash(filePath)); } catch (Exception) { url = url; } } sb.Append(string.Format(htmlTagTemplate, url)); } } } return(new MvcHtmlString(sb.ToString())); }
public override void ProcessCommand() { logger.Info("Reading Media Info for File: {0}", VideoLocalID); try { VideoLocalRepository repVids = new VideoLocalRepository(); VideoLocal vlocal = repVids.GetByID(VideoLocalID); if (vlocal == null) { logger.Error("Cound not find Video: {0}", VideoLocalID); return; } if (!File.Exists(vlocal.FullServerPath)) { logger.Error("Cound not find physical file: {0}", vlocal.FullServerPath); return; } int nshareID = -1; VideoInfoRepository repVidInfo = new VideoInfoRepository(); VideoInfo vinfo = repVidInfo.GetByHash(vlocal.Hash); ImportFolderRepository repNS = new ImportFolderRepository(); List <ImportFolder> shares = repNS.GetAll(); string fileName = vlocal.FullServerPath; string filePath = ""; DataAccessHelper.GetShareAndPath(fileName, shares, ref nshareID, ref filePath); FileInfo fi = new FileInfo(fileName); if (vinfo == null) { vinfo = new VideoInfo(); vinfo.Hash = vlocal.Hash; vinfo.Duration = 0; vinfo.FileSize = fi.Length; vinfo.DateTimeUpdated = DateTime.Now; vinfo.FileName = filePath; vinfo.AudioBitrate = ""; vinfo.AudioCodec = ""; vinfo.VideoBitrate = ""; vinfo.VideoBitDepth = ""; vinfo.VideoCodec = ""; vinfo.VideoFrameRate = ""; vinfo.VideoResolution = ""; } logger.Trace("Getting media info for: {0}", fileName); MediaInfoResult mInfo = FileHashHelper.GetMediaInfo(fileName, true); vinfo.AudioBitrate = string.IsNullOrEmpty(mInfo.AudioBitrate) ? "" : mInfo.AudioBitrate; vinfo.AudioCodec = string.IsNullOrEmpty(mInfo.AudioCodec) ? "" : mInfo.AudioCodec; vinfo.DateTimeUpdated = vlocal.DateTimeUpdated; vinfo.Duration = mInfo.Duration; vinfo.FileName = filePath; vinfo.FileSize = fi.Length; vinfo.VideoBitrate = string.IsNullOrEmpty(mInfo.VideoBitrate) ? "" : mInfo.VideoBitrate; vinfo.VideoBitDepth = string.IsNullOrEmpty(mInfo.VideoBitDepth) ? "" : mInfo.VideoBitDepth; vinfo.VideoCodec = string.IsNullOrEmpty(mInfo.VideoCodec) ? "" : mInfo.VideoCodec; vinfo.VideoFrameRate = string.IsNullOrEmpty(mInfo.VideoFrameRate) ? "" : mInfo.VideoFrameRate; vinfo.VideoResolution = string.IsNullOrEmpty(mInfo.VideoResolution) ? "" : mInfo.VideoResolution; vinfo.FullInfo = string.IsNullOrEmpty(mInfo.FullInfo) ? "" : mInfo.FullInfo; repVidInfo.Save(vinfo); } catch (Exception ex) { logger.Error("Error processing CommandRequest_ReadMediaInfo: {0} - {1}", VideoLocalID, ex.ToString()); return; } }
public static UpdatePackage RetrieveData(string updatePackageFilePath) { if (Directory.Exists(updatePackageFilePath)) { throw new ArgumentException(string.Format(@"The path ""{0}"" was not a file path. It was a path to a directory.", updatePackageFilePath), nameof(updatePackageFilePath)); } var package = new UpdatePackage(); var updatePackageType = DetectUpdatePackageType(updatePackageFilePath); if (updatePackageType == UpdatePackageType.MSCF) { string workFolderPath = null; try { workFolderPath = CreateWorkFolder(); ExtractMscfUpdatePackageFile(updatePackageFilePath, workFolderPath); if (VerifyWsusScanCabExistence(workFolderPath)) { // .msu package var packageXmlFilePath = GetFilePathDirectlyUnderFolder(workFolderPath, "*.xml"); package.PropertiesFromXmlFile = new UpdatePackageMetadataFromXmlFile(packageXmlFilePath); var packagePropertyFilePath = GetFilePathDirectlyUnderFolder(workFolderPath, "*-pkgProperties*.txt"); package.PropertiesFromPropertyFile = new UpdatePackageMetadataFromPropertyFile(packagePropertyFilePath); var innerCabFilePath = GetInnerCabFilePath(package.PropertiesFromXmlFile.InnerCabFileLocation, workFolderPath); var innerCabWorkFolderPath = CreateWorkFolder(workFolderPath); ExtractMscfUpdatePackageFile(innerCabFilePath, innerCabWorkFolderPath); var updateMumFilePath = GetFilePathDirectlyUnderFolder(innerCabWorkFolderPath, "update.mum"); package.PropertiesFromUpdateMumFile = new UpdatePackageMetadataFromUpdateMumFile(updateMumFilePath); package.UpdateModules = RetrieveUpdateModules(innerCabWorkFolderPath); } else { // .cab package throw new NotImplementedException(string.Format(@"The CAB file type update package does not support currently. The package file path was ""{0}"".", updatePackageFilePath)); } } catch (Exception e) { throw new MscfUpdatePackageDataRetrieveException(updatePackageFilePath, e); } finally { if (workFolderPath != null && Directory.Exists(workFolderPath)) { Directory.Delete(workFolderPath, true); } } } else { throw new UnknownUpdatePackageTypeException(updatePackageFilePath); } package.UpdatePackageFielPath = updatePackageFilePath; package.FielHash = FileHashHelper.ComputeFileHash(updatePackageFilePath); package.UpdatePackageType = updatePackageType; return(package); }