/// <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 = 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(ApplicationSettings.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 = 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.GetMD5(rf.SaveAs)) { Trace.WriteLine(new LogMessage("RequiredFiles - SetRequiredFiles", "MD5 different for existing file: " + rf.SaveAs), LogType.Info.ToString()); // They are different _cacheManager.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.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.Remove(rf.SaveAs); } RequiredFileList.Add(rf); } }
/// <summary> /// Prepares the Layout.. rendering all the necessary controls /// </summary> private void PrepareLayout(string layoutPath) { // Get this layouts XML XmlDocument layoutXml = new XmlDocument(); DateTime layoutModifiedTime; // Default or not if (layoutPath == ApplicationSettings.Default.LibraryPath + @"\Default.xml" || String.IsNullOrEmpty(layoutPath)) { throw new Exception("Default layout"); } else { // try to open the layout file try { using (FileStream fs = File.Open(layoutPath, FileMode.Open, FileAccess.Read, FileShare.Write)) { using (XmlReader reader = XmlReader.Create(fs)) { layoutXml.Load(reader); reader.Close(); } fs.Close(); } } catch (IOException ioEx) { _cacheManager.Remove(layoutPath); Trace.WriteLine(new LogMessage("MainForm - PrepareLayout", "IOException: " + ioEx.ToString()), LogType.Error.ToString()); throw; } layoutModifiedTime = File.GetLastWriteTime(layoutPath); } // Attributes of the main layout node XmlNode layoutNode = layoutXml.SelectSingleNode("/layout"); XmlAttributeCollection layoutAttributes = layoutNode.Attributes; // Set the background and size of the form _layoutWidth = int.Parse(layoutAttributes["width"].Value, CultureInfo.InvariantCulture); _layoutHeight = int.Parse(layoutAttributes["height"].Value, CultureInfo.InvariantCulture); // Scaling factor, will be applied to all regions _scaleFactor = Math.Min(_clientSize.Width / _layoutWidth, _clientSize.Height / _layoutHeight); // Want to be able to center this shiv - therefore work out which one of these is going to have left overs int backgroundWidth = (int)(_layoutWidth * _scaleFactor); int backgroundHeight = (int)(_layoutHeight * _scaleFactor); double leftOverX; double leftOverY; try { leftOverX = Math.Abs(_clientSize.Width - backgroundWidth); leftOverY = Math.Abs(_clientSize.Height - backgroundHeight); if (leftOverX != 0) { leftOverX = leftOverX / 2; } if (leftOverY != 0) { leftOverY = leftOverY / 2; } } catch { leftOverX = 0; leftOverY = 0; } // New region and region options objects _regions = new Collection <Region>(); RegionOptions options = new RegionOptions(); options.LayoutModifiedDate = layoutModifiedTime; // Deal with the color try { if (layoutAttributes["bgcolor"].Value != "") { this.BackColor = ColorTranslator.FromHtml(layoutAttributes["bgcolor"].Value); options.backgroundColor = layoutAttributes["bgcolor"].Value; } } catch { this.BackColor = Color.Black; // Default black options.backgroundColor = "#000000"; } // Get the background try { if (layoutAttributes["background"] != null && !string.IsNullOrEmpty(layoutAttributes["background"].Value)) { string bgFilePath = ApplicationSettings.Default.LibraryPath + @"\backgrounds\" + backgroundWidth + "x" + backgroundHeight + "_" + layoutAttributes["background"].Value; // Create a correctly sized background image in the temp folder if (!File.Exists(bgFilePath)) { GenerateBackgroundImage(layoutAttributes["background"].Value, backgroundWidth, backgroundHeight, bgFilePath); } BackgroundImage = new Bitmap(bgFilePath); options.backgroundImage = bgFilePath; } else { // Assume there is no background image BackgroundImage = null; options.backgroundImage = ""; } } catch (Exception ex) { Trace.WriteLine(new LogMessage("MainForm - PrepareLayout", "Unable to set background: " + ex.Message), LogType.Error.ToString()); // Assume there is no background image this.BackgroundImage = null; options.backgroundImage = ""; } // Get the regions XmlNodeList listRegions = layoutXml.SelectNodes("/layout/region"); XmlNodeList listMedia = layoutXml.SelectNodes("/layout/region/media"); // Check to see if there are any regions on this layout. if (listRegions.Count == 0 || listMedia.Count == 0) { Trace.WriteLine(new LogMessage("PrepareLayout", string.Format("A layout with {0} regions and {1} media has been detected.", listRegions.Count.ToString(), listMedia.Count.ToString())), LogType.Info.ToString()); if (_schedule.ActiveLayouts == 1) { Trace.WriteLine(new LogMessage("PrepareLayout", "Only 1 layout scheduled and it has nothing to show."), LogType.Info.ToString()); throw new Exception("Only 1 layout schduled and it has nothing to show"); } else { Trace.WriteLine(new LogMessage("PrepareLayout", string.Format(string.Format("An empty layout detected, will show for {0} seconds.", ApplicationSettings.Default.EmptyLayoutDuration.ToString()))), LogType.Info.ToString()); // Put a small dummy region in place, with a small dummy media node - which expires in 10 seconds. XmlDocument dummyXml = new XmlDocument(); dummyXml.LoadXml(string.Format("<region id='blah' width='1' height='1' top='1' left='1'><media id='blah' type='text' duration='{0}'><raw><text></text></raw></media></region>", ApplicationSettings.Default.EmptyLayoutDuration.ToString())); // Replace the list of regions (they mean nothing as they are empty) listRegions = dummyXml.SelectNodes("/region"); } } // Create a start record for this layout _stat = new Stat(); _stat.type = StatType.Layout; _stat.scheduleID = _scheduleId; _stat.layoutID = _layoutId; _stat.fromDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); foreach (XmlNode region in listRegions) { // Is there any media if (region.ChildNodes.Count == 0) { Debug.WriteLine("A region with no media detected"); continue; } //each region XmlAttributeCollection nodeAttibutes = region.Attributes; options.scheduleId = _scheduleId; options.layoutId = _layoutId; options.regionId = nodeAttibutes["id"].Value.ToString(); options.width = (int)(Convert.ToDouble(nodeAttibutes["width"].Value, CultureInfo.InvariantCulture) * _scaleFactor); options.height = (int)(Convert.ToDouble(nodeAttibutes["height"].Value, CultureInfo.InvariantCulture) * _scaleFactor); options.left = (int)(Convert.ToDouble(nodeAttibutes["left"].Value, CultureInfo.InvariantCulture) * _scaleFactor); options.top = (int)(Convert.ToDouble(nodeAttibutes["top"].Value, CultureInfo.InvariantCulture) * _scaleFactor); options.scaleFactor = _scaleFactor; // Store the original width and original height for scaling options.originalWidth = (int)Convert.ToDouble(nodeAttibutes["width"].Value, CultureInfo.InvariantCulture); options.originalHeight = (int)Convert.ToDouble(nodeAttibutes["height"].Value, CultureInfo.InvariantCulture); // Set the backgrounds (used for Web content offsets) options.backgroundLeft = options.left * -1; options.backgroundTop = options.top * -1; // Account for scaling options.left = options.left + (int)leftOverX; options.top = options.top + (int)leftOverY; // All the media nodes for this region / layout combination options.mediaNodes = region.SelectNodes("media"); Region temp = new Region(ref _statLog, ref _cacheManager); temp.DurationElapsedEvent += new Region.DurationElapsedDelegate(temp_DurationElapsedEvent); Debug.WriteLine("Created new region", "MainForm - Prepare Layout"); // Dont be fooled, this innocent little statement kicks everything off temp.regionOptions = options; _regions.Add(temp); Controls.Add(temp); Debug.WriteLine("Adding region", "MainForm - Prepare Layout"); } // We have loaded a layout and therefore are no longer showing the splash screen _showingSplash = false; // Null stuff listRegions = null; listMedia = null; }