/// <summary> /// Set required files from the XML document /// </summary> private void SetRequiredFiles() { // Itterate through the RF XML and populate the RF collection XmlNodeList fileNodes = _requiredFilesXml.SelectNodes("/files/file"); foreach (XmlNode file in fileNodes) { RequiredFile rf = new RequiredFile(); XmlAttributeCollection attributes = file.Attributes; rf.FileType = attributes["type"].Value; rf.Downloading = false; rf.Complete = false; rf.LastChecked = DateTime.Now; rf.ChunkOffset = 0; rf.ChunkSize = 0; // Fill in some information that we already know if (rf.FileType == "media") { rf.Id = int.Parse(attributes["id"].Value); rf.Path = attributes["path"].Value; rf.SaveAs = (attributes["saveAs"] == null || string.IsNullOrEmpty(attributes["saveAs"].Value)) ? rf.Path : attributes["saveAs"].Value; rf.Http = (attributes["download"].Value == "http"); rf.ChunkSize = 512000; } else if (rf.FileType == "layout") { rf.Id = int.Parse(attributes["id"].Value); rf.Path = attributes["path"].Value; rf.Http = (attributes["download"].Value == "http"); if (rf.Http) { rf.SaveAs = attributes["saveAs"].Value; } else { rf.Path = rf.Path + ".xlf"; rf.SaveAs = rf.Path; } rf.ChunkSize = rf.Size; } else if (rf.FileType == "resource") { // Do something special here. Check to see if the resource file already exists otherwise add to RF try { // Set the ID to be some random number rf.Id = int.Parse(attributes["id"].Value); rf.LayoutId = int.Parse(attributes["layoutid"].Value); rf.RegionId = attributes["regionid"].Value; rf.MediaId = attributes["mediaid"].Value; rf.Path = rf.MediaId + ".htm"; rf.SaveAs = rf.Path; // Set the size to something arbitary rf.Size = 10000; // Check to see if this has already been downloaded if (File.Exists(ApplicationSettings.Default.LibraryPath + @"\" + rf.MediaId + ".htm")) { // Has it expired? int updated = 0; try { updated = (attributes["updated"] != null) ? int.Parse(attributes["updated"].Value) : 0; } catch (Exception e) { Debug.WriteLine("Can't read Updated attribute from Resource node. e = " + e.Message, "RequiredFiles"); } DateTime updatedDt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); updatedDt = updatedDt.AddSeconds(updated); DateTime fileUpdatedDt = File.GetLastWriteTimeUtc(ApplicationSettings.Default.LibraryPath + @"\" + rf.MediaId + ".htm"); if (fileUpdatedDt > updatedDt) { Debug.WriteLine("Resource node does not need updating. Current: " + fileUpdatedDt + ", XMDS: " + updatedDt + ", updated: " + updated, "RequiredFiles"); rf.Complete = true; } else { Debug.WriteLine("Resource node needs updating. Current: " + fileUpdatedDt + ", XMDS: " + updatedDt, "RequiredFiles"); } } // Add to the Rf Node RequiredFileList.Add(rf); continue; } catch { // Forget about this resource continue; } } else { continue; } // This stuff only executes for Layout/Files items rf.Md5 = attributes["md5"].Value; rf.Size = double.Parse(attributes["size"].Value); // Does this file already exist in the RF node? We might receive duplicates. bool found = false; foreach (RequiredFile existingRf in RequiredFileList) { if (existingRf.Id == rf.Id && existingRf.FileType == rf.FileType) { found = true; break; } } if (found) { Trace.WriteLine(new LogMessage("RequiredFiles - SetRequiredFiles", "Duplicate file detected, ignoring. FileId = " + rf.Id), LogType.Audit.ToString()); continue; } // Does this file exist? if (File.Exists(ApplicationSettings.Default.LibraryPath + @"\" + rf.SaveAs)) { // Compare MD5 of the file we currently have, to what we should have if (rf.Md5 != CacheManager.Instance.GetMD5(rf.SaveAs)) { Trace.WriteLine(new LogMessage("RequiredFiles - SetRequiredFiles", "MD5 different for existing file: " + rf.SaveAs), LogType.Info.ToString()); // They are different CacheManager.Instance.Remove(rf.SaveAs); // TODO: Resume the file download under certain conditions. Make sure its not bigger than it should be. // Make sure it is fairly fresh FileInfo info = new FileInfo(ApplicationSettings.Default.LibraryPath + @"\" + rf.SaveAs); if (info.Length < rf.Size && info.LastWriteTime > DateTime.Now.AddDays(-1)) { // Continue the file rf.ChunkOffset = (int)info.Length; } else { // Delete the old file as it is wrong try { File.Delete(ApplicationSettings.Default.LibraryPath + @"\" + rf.SaveAs); } catch (Exception ex) { Trace.WriteLine(new LogMessage("CompareAndCollect", "Unable to delete incorrect file because: " + ex.Message)); } } } else { // The MD5 is equal - we already have an up to date version of this file. rf.Complete = true; CacheManager.Instance.Add(rf.SaveAs, rf.Md5); } } else { // File does not exist, therefore remove it from the cache manager (on the off chance that it is in there for some reason) CacheManager.Instance.Remove(rf.SaveAs); } RequiredFileList.Add(rf); } }
/// <summary> /// Set required files from the XML document /// </summary> private void SetRequiredFiles() { // Itterate through the RF XML and populate the RF collection XmlNodeList fileNodes = _requiredFilesXml.SelectNodes("/files/file"); foreach (XmlNode file in fileNodes) { RequiredFile rf = new RequiredFile(); XmlAttributeCollection attributes = file.Attributes; rf.FileType = attributes["type"].Value; rf.Downloading = false; rf.Complete = false; rf.LastChecked = DateTime.Now; rf.ChunkOffset = 0; rf.ChunkSize = 0; // Fill in some information that we already know if (rf.FileType == "media") { string[] filePart = attributes["path"].Value.Split('.'); rf.Id = int.Parse(filePart[0]); rf.Path = attributes["path"].Value; rf.ChunkSize = 512000; } else if (rf.FileType == "layout") { rf.Id = int.Parse(attributes["path"].Value); rf.Path = attributes["path"].Value + ".xlf"; rf.ChunkSize = rf.Size; } else if (rf.FileType == "resource") { // Do something special here. Check to see if the resource file already exists otherwise add to RF try { // Set the ID to be some random number rf.Id = int.Parse(attributes["id"].Value); rf.LayoutId = int.Parse(attributes["layoutid"].Value); rf.RegionId = attributes["regionid"].Value; rf.MediaId = attributes["mediaid"].Value; rf.Path = rf.MediaId + ".htm"; // Set the size to something arbitary rf.Size = 10000; // Check to see if this has already been downloaded if (File.Exists(Settings.Default.LibraryPath + @"\" + rf.MediaId + ".htm")) { // Has it expired? int updated = 0; try { updated = int.Parse(attributes["updated"].Value); } catch (Exception) {} DateTime updatedDt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); updatedDt = updatedDt.AddSeconds(updated); if (File.GetLastWriteTimeUtc(Settings.Default.LibraryPath + @"\" + rf.MediaId + ".htm") > updatedDt) rf.Complete = true; } // Add to the Rf Node RequiredFileList.Add(rf); continue; } catch { // Forget about this resource continue; } } else continue; // This stuff only executes for Layout/Files items rf.Md5 = attributes["md5"].Value; rf.Size = int.Parse(attributes["size"].Value); Trace.WriteLine(new LogMessage("RequiredFiles - SetRequiredFiles", "Building required file node for " + rf.Id.ToString()), LogType.Audit.ToString()); // Does this file already exist in the RF node? We might receive duplicates. bool found = false; foreach (RequiredFile existingRf in RequiredFileList) { if (existingRf.Id == rf.Id && existingRf.FileType == rf.FileType) { found = true; break; } } if (found) { Trace.WriteLine(new LogMessage("RequiredFiles - SetRequiredFiles", "Duplicate file detected, ignoring. FileId = " + rf.Id), LogType.Audit.ToString()); continue; } // Does this file exist? if (File.Exists(Settings.Default.LibraryPath + @"\" + rf.Path)) { // Compare MD5 of the file we currently have, to what we should have if (rf.Md5 != _cacheManager.GetMD5(rf.Path)) { Trace.WriteLine(new LogMessage("RequiredFiles - SetRequiredFiles", "MD5 different for existing file: " + rf.Path), LogType.Info.ToString()); // They are different _cacheManager.Remove(rf.Path); // TODO: Resume the file download under certain conditions. Make sure its not bigger than it should be. // Make sure it is fairly fresh FileInfo info = new FileInfo(Settings.Default.LibraryPath + @"\" + rf.Path); if (info.Length < rf.Size && info.LastWriteTime > DateTime.Now.AddDays(-1)) { // Continue the file rf.ChunkOffset = (int)info.Length; } else { // Delete the old file as it is wrong try { File.Delete(Properties.Settings.Default.LibraryPath + @"\" + rf.Path); } catch (Exception ex) { Trace.WriteLine(new LogMessage("CompareAndCollect", "Unable to delete incorrect file because: " + ex.Message)); } } } else { // The MD5 is equal - we already have an up to date version of this file. rf.Complete = true; _cacheManager.Add(rf.Path, rf.Md5); } } else { // File does not exist, therefore remove it from the cache manager (on the off chance that it is in there for some reason) _cacheManager.Remove(rf.Path); } RequiredFileList.Add(rf); } }
/// <summary> /// Gets the files contained within FileList /// </summary> public void GetFile() { if (_currentFile > (_files.Count - 1)) { System.Diagnostics.Debug.WriteLine(String.Format("Finished Receiving {0} files", _files.Count)); // Clean up _files.Clear(); xmdsFile.Dispose(); // Write Required Files _requiredFiles.WriteRequiredFiles(); // Finished getting this file list CollectionComplete(); } else { // Get the current file into the currentfilelist if the current one is finished if (_currentFileList.complete) { _currentFileList = _files[_currentFile]; } System.Diagnostics.Debug.WriteLine(String.Format("Getting the file : {0} chunk : {1}", _currentFileList.path, _currentFileList.chunkOffset.ToString())); // Request the file xmdsFile.GetFileAsync(Properties.Settings.Default.ServerKey, hardwareKey.Key, _currentFileList.path, _currentFileList.type, _currentFileList.chunkOffset, _currentFileList.chunkSize, Properties.Settings.Default.Version); _currentFileList.downloading = true; } }
/// <summary> /// Set required files from the XML document /// </summary> private void SetRequiredFiles() { // Itterate through the RF XML and populate the RF collection XmlNodeList fileNodes = _requiredFilesXml.SelectNodes("/files/file"); foreach (XmlNode file in fileNodes) { RequiredFile rf = new RequiredFile(); XmlAttributeCollection attributes = file.Attributes; rf.FileType = attributes["type"].Value; rf.Complete = 0; rf.Md5 = ""; rf.LastChecked = DateTime.Now; if (rf.FileType == "media") { string[] filePart = attributes["path"].Value.Split('.'); rf.Id = int.Parse(filePart[0]); rf.Path = attributes["path"].Value; } else if (rf.FileType == "layout") { rf.Id = int.Parse(attributes["path"].Value); rf.Path = attributes["path"].Value + ".xlf"; } else { continue; } _requiredFiles.Add(rf); } }
/// <summary> /// Compares the xml file list with the files currently in the library /// Downloads any missing files /// For file types of Layout will fire a LayoutChanged event, giving the filename of the layout changed /// </summary> public void CompareAndCollect() { XmlNodeList fileNodes = _xml.SelectNodes("/files/file"); //Inspect each file we have here foreach (XmlNode file in fileNodes) { XmlAttributeCollection attributes = file.Attributes; RequiredFile fileList = new RequiredFile(); if (attributes["type"].Value == "layout") { // Layout string path = attributes["path"].Value; // Does this file exist? if (File.Exists(Properties.Settings.Default.LibraryPath + @"\" + path + ".xlf")) { // Calculate a MD5 for the current file String md5 = _cacheManager.GetMD5(path + ".xlf"); System.Diagnostics.Debug.WriteLine(String.Format("Comparing current MD5 [{0}] with given MD5 [{1}]", md5, attributes["md5"].Value)); // Now we have the md5, compare it to the md5 in the xml if (attributes["md5"].Value != md5) { // They are different _cacheManager.Remove(path + ".xlf"); //TODO: This might be bad! Delete the old layout as it is wrong try { File.Delete(Properties.Settings.Default.LibraryPath + @"\" + path + ".xlf"); } catch (Exception ex) { Trace.WriteLine(new LogMessage("CompareAndCollect", "Unable to delete incorrect file because: " + ex.Message)); } // Get the file and save it fileList.chunkOffset = 0; fileList.chunkSize = 0; fileList.complete = false; fileList.downloading = false; fileList.path = path; fileList.type = "layout"; fileList.md5 = attributes["md5"].Value; fileList.retrys = 0; _files.Add(fileList); } else { // The MD5 of the current file and the MD5 in RequiredFiles are the same. // Therefore make sure this MD5 is in the CacheManager _cacheManager.Add(path + ".xlf", md5); _requiredFiles.MarkComplete(int.Parse(path), md5); } } else { // No - get the file and save it (no chunks) fileList.chunkOffset = 0; fileList.chunkSize = 0; fileList.complete = false; fileList.downloading = false; fileList.path = path; fileList.type = "layout"; fileList.md5 = attributes["md5"].Value; fileList.retrys = 0; _files.Add(fileList); } } else if (attributes["type"].Value == "media") { // Media string path = attributes["path"].Value; // Does this media exist? if (File.Exists(Properties.Settings.Default.LibraryPath + @"\" + path)) { String md5 = _cacheManager.GetMD5(path); System.Diagnostics.Debug.WriteLine(String.Format("Comparing current MD5 [{0}] with given MD5 [{1}]", md5, attributes["md5"].Value)); // MD5 the file to make sure it is the same. if (md5 != attributes["md5"].Value) { // File changed _cacheManager.Remove(path); // Delete the old media as it is wrong try { File.Delete(Properties.Settings.Default.LibraryPath + @"\" + path); } catch (Exception ex) { Trace.WriteLine(new LogMessage("CompareAndCollect", "Unable to delete incorrect file because: " + ex.Message)); } // Add to queue fileList.chunkOffset = 0; fileList.chunkSize = 512000; fileList.complete = false; fileList.downloading = false; fileList.path = path; fileList.type = "media"; fileList.size = int.Parse(attributes["size"].Value); fileList.md5 = attributes["md5"].Value; fileList.retrys = 0; _files.Add(fileList); } else { // The MD5 of the current file and the MD5 in RequiredFiles are the same. // Therefore make sure this MD5 is in the CacheManager _cacheManager.Add(path, md5); string[] filePart = path.Split('.'); _requiredFiles.MarkComplete(int.Parse(filePart[0]), md5); } } else { // No - Get it (async call - with chunks... through another class?) fileList.chunkOffset = 0; fileList.chunkSize = 512000; fileList.complete = false; fileList.downloading = false; fileList.path = path; fileList.type = "media"; fileList.size = int.Parse(attributes["size"].Value); fileList.md5 = attributes["md5"].Value; fileList.retrys = 0; _files.Add(fileList); } } else if (attributes["type"].Value == "blacklist") { // Expect <file type="blacklist"><file id="" /></file> XmlNodeList items = file.ChildNodes; BlackList blackList = new BlackList(); try { blackList.Truncate(); } catch { } if (items.Count > 0) { blackList.Add(items); blackList.Dispose(); blackList = null; } items = null; } else { //Ignore node } } Debug.WriteLine(String.Format("There are {0} files to get", _files.Count.ToString())); // Output a list of the files we need to get string debugMessage = ""; foreach (RequiredFile fileToGet in _files) debugMessage += string.Format("File: {0}, Type: {1}, MD5: {2}. ", fileToGet.path, fileToGet.type, fileToGet.md5); Debug.WriteLine(debugMessage); // Report the files files back to XMDS _requiredFiles.ReportInventory(); // Write Required Files _requiredFiles.WriteRequiredFiles(); // Is there anything to get? if (_files.Count == 0) { CollectionComplete(); return; } // Start with the first file _currentFile = 0; // Preload the first filelist _currentFileList = _files[_currentFile]; // Get the first file GetFile(); }