diff --git a/Control/Region.cs b/Control/Region.cs index 5a565481..19812734 100644 --- a/Control/Region.cs +++ b/Control/Region.cs @@ -1,13 +1,14 @@ -/* - * Xibo - Digitial Signage - http://www.xibo.org.uk - * Copyright (C) 2006-2016 Daniel Garner +/** + * Copyright (C) 2019 Xibo Signage Ltd + * + * Xibo - Digital Signage - http://www.xibo.org.uk * * This file is part of Xibo. * * Xibo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or - * any later version. + * any later version. * * Xibo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -24,6 +25,7 @@ using System.Xml; using System.Diagnostics; using XiboClient.Properties; +using System.Globalization; namespace XiboClient { @@ -45,6 +47,7 @@ class Region : Panel private RegionOptions _options; private bool _hasExpired = false; private bool _layoutExpired = false; + private bool _sizeResetRequired = false; private int _currentSequence = -1; /// @@ -128,6 +131,21 @@ public bool hasExpired() return _hasExpired; } + private void SetDimensions(int left, int top, int width, int height) + { + // Evaluate the width, etc + Location = new System.Drawing.Point(left, top); + Size = new System.Drawing.Size(width, height); + } + + private void SetDimensions(System.Drawing.Point location, System.Drawing.Size size) + { + Debug.WriteLine("Setting Dimensions to " + size.ToString() + ", " + location.ToString()); + // Evaluate the width, etc + Size = size; + Location = location; + } + /// /// Evaulates the change in options /// @@ -139,8 +157,7 @@ private void EvalOptions() if (initialMedia) { // Evaluate the width, etc - Location = new System.Drawing.Point(_options.left, _options.top); - Size = new System.Drawing.Size(_options.width, _options.height); + SetDimensions(_options.left, _options.top, _options.width, _options.height); } // Try to populate a new media object for this region @@ -214,6 +231,18 @@ private void EvalOptions() // Start the new media try { + // See if we need to change our Region Dimensions + if (newMedia.RegionSizeChangeRequired()) + { + SetDimensions(newMedia.GetRegionLocation(), newMedia.GetRegionSize()); + _sizeResetRequired = true; + } + else if (_sizeResetRequired) + { + SetDimensions(_options.left, _options.top, _options.width, _options.height); + _sizeResetRequired = false; + } + StartMedia(newMedia); } catch (Exception ex) @@ -263,6 +292,8 @@ private bool SetNextMediaNodeInOptions() _options.uri = ""; _options.direction = "none"; _options.javaScript = ""; + _options.FromDt = DateTime.MinValue; + _options.ToDt = DateTime.MaxValue; _options.Dictionary = new MediaDictionary(); // Tidy up old audio if necessary @@ -320,6 +351,12 @@ private bool SetNextMediaNodeInOptions() if (nodeAttributes["id"].Value != null) _options.mediaid = nodeAttributes["id"].Value; + // Set the file id + if (nodeAttributes["fileId"] != null) + { + _options.FileId = int.Parse(nodeAttributes["fileId"].Value); + } + // Check isnt blacklisted if (_blackList.BlackListed(_options.mediaid)) { @@ -338,8 +375,19 @@ private bool SetNextMediaNodeInOptions() // Parse the options for this media node ParseOptionsForMediaNode(mediaNode, nodeAttributes); + // Is this widget inside the from/to date? + if (!(_options.FromDt <= DateTime.Now && _options.ToDt > DateTime.Now)) { + Trace.WriteLine(new LogMessage("Region", "SetNextMediaNode: Widget outside from/to date."), LogType.Audit.ToString()); + + // Increment the number of attempts and try again + numAttempts++; + + // Carry on + continue; + } + // Is this a file based media node? - if (_options.type == "video" || _options.type == "flash" || _options.type == "image" || _options.type == "powerpoint" || _options.type == "audio") + if (_options.type == "video" || _options.type == "flash" || _options.type == "image" || _options.type == "powerpoint" || _options.type == "audio" || _options.type == "htmlpackage") { // Use the cache manager to determine if the file is valid validNode = _cacheManager.IsValidPath(_options.uri); @@ -392,6 +440,24 @@ private void ParseOptionsForMediaNode(XmlNode mediaNode, XmlAttributeCollection Trace.WriteLine("Duration is Empty, using a default of 60.", "Region - SetNextMediaNode"); } + // Widget From/To dates (v2 onward) + try + { + if (nodeAttributes["fromDt"] != null) + { + _options.FromDt = DateTime.Parse(nodeAttributes["fromDt"].Value, CultureInfo.InvariantCulture); + } + + if (nodeAttributes["toDt"] != null) + { + _options.ToDt = DateTime.Parse(nodeAttributes["toDt"].Value, CultureInfo.InvariantCulture); + } + } + catch (Exception e) + { + Trace.WriteLine(new LogMessage("Region", "ParseOptionsForMediaNode: Unable to parse widget from/to dates."), LogType.Error.ToString()); + } + // We cannot have a 0 duration here... not sure why we would... but if (_options.duration == 0 && _options.type != "video" && _options.type != "localvideo") { @@ -605,6 +671,10 @@ private Media CreateNextMediaNode(RegionOptions options) media = new ShellCommand(options); break; + case "htmlpackage": + media = new HtmlPackage(options); + break; + default: throw new InvalidOperationException("Not a valid media node type: " + options.type); } diff --git a/Logic/ApplicationSettings.cs b/Logic/ApplicationSettings.cs index ba7f3240..95637838 100644 --- a/Logic/ApplicationSettings.cs +++ b/Logic/ApplicationSettings.cs @@ -1,13 +1,14 @@ -/* - * Xibo - Digitial Signage - http://www.xibo.org.uk - * Copyright (C) 2006-18 Spring Signage Ltd +/** + * Copyright (C) 2019 Xibo Signage Ltd + * + * Xibo - Digital Signage - http://www.xibo.org.uk * * This file is part of Xibo. * * Xibo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or - * any later version. + * any later version. * * Xibo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -40,9 +41,9 @@ public class ApplicationSettings private List _globalProperties; // Application Specific Settings we want to protect - private string _clientVersion = "1.8.12"; - private string _version = "5"; - private int _clientCodeVersion = 133; + private readonly string _clientVersion = "2 R200"; + private readonly string _version = "5"; + private readonly int _clientCodeVersion = 200; public string ClientVersion { get { return _clientVersion; } } public string Version { get { return _version; } } diff --git a/Logic/RegionOptions.cs b/Logic/RegionOptions.cs index 583dd67e..855f4d65 100644 --- a/Logic/RegionOptions.cs +++ b/Logic/RegionOptions.cs @@ -1,13 +1,14 @@ -/* - * Xibo - Digitial Signage - http://www.xibo.org.uk - * Copyright (C) 2013-16 Daniel Garner +/** + * Copyright (C) 2019 Xibo Signage Ltd + * + * Xibo - Digital Signage - http://www.xibo.org.uk * * This file is part of Xibo. * * Xibo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or - * any later version. + * any later version. * * Xibo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -19,6 +20,7 @@ */ using System; using System.Collections.Generic; +using System.Drawing; using System.Text; using System.Xml; @@ -38,6 +40,10 @@ struct RegionOptions public int originalWidth; public int originalHeight; + // Widget From/To dates + public DateTime FromDt { get; set; } + public DateTime ToDt { get; set; } + public int backgroundLeft; public int backgroundTop; @@ -67,6 +73,7 @@ struct RegionOptions public string regionId; public int scheduleId; public int CurrentIndex; + public int FileId { get; set; } //general options public string backgroundImage; @@ -76,6 +83,8 @@ struct RegionOptions public DateTime LayoutModifiedDate { get; set; } + public Size LayoutSize { get; set; } + /// /// Audio associated with the widget /// diff --git a/MainForm.cs b/MainForm.cs index 60256bb3..c0eb0aa5 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -628,7 +628,6 @@ private void PrepareLayout(string layoutPath) _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); @@ -657,6 +656,7 @@ private void PrepareLayout(string layoutPath) _regions = new Collection(); RegionOptions options = new RegionOptions(); options.LayoutModifiedDate = layoutModifiedTime; + options.LayoutSize = ClientSize; // Deal with the color try diff --git a/Media/HtmlPackage.cs b/Media/HtmlPackage.cs new file mode 100644 index 00000000..b3a727f0 --- /dev/null +++ b/Media/HtmlPackage.cs @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2019 Xibo Signage Ltd + * + * Xibo - Digital Signage - http://www.xibo.org.uk + * + * This file is part of Xibo. + * + * Xibo is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * Xibo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Xibo. If not, see . + */ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; + +namespace XiboClient +{ + class HtmlPackage : IeWebMedia + { + public HtmlPackage(RegionOptions options) + : base(options) + { + string pathToMediaFile = Path.Combine(ApplicationSettings.Default.LibraryPath, options.uri); + string pathToPackageFolder = Path.Combine(ApplicationSettings.Default.LibraryPath, "package_" + options.FileId); + string pathToStatusFile = Path.Combine(pathToPackageFolder, "_updated"); + + // Configure the file path to indicate which file should be opened by the browser + _filePath = ApplicationSettings.Default.EmbeddedServerAddress + "package_" + options.FileId + "/" + options.Dictionary.Get("nominatedFile", "index.html"); + + // Check to see if our package has been extracted already + // if not, then extract it + if (!(Directory.Exists(pathToPackageFolder) && IsUpdated(pathToStatusFile, File.GetLastWriteTime(pathToMediaFile)))) + { + // Extract our file into the specified folder. + ZipFile.ExtractToDirectory(pathToMediaFile, pathToPackageFolder); + + // Add in our extraction date. + WriteUpdatedFlag(pathToStatusFile); + } + } + + protected override bool IsNativeOpen() + { + return true; + } + + /// + /// Updated Flag + /// + /// + private void WriteUpdatedFlag(string path) + { + try + { + File.WriteAllText(path, DateTime.Now.ToString()); + } + catch (Exception e) + { + Trace.WriteLine(new LogMessage("HtmlPackage", "WriteUpdatedFlag: Failed to update status file: " + path + ". e = " + e.Message), LogType.Error.ToString()); + } + } + + /// + /// Check whether we've updated recently + /// + /// + /// + /// + private bool IsUpdated(string path, DateTime lastModified) + { + // Check that it is up to date by looking for our special file. + try + { + string flag = File.ReadAllText(path); + DateTime updated = DateTime.Parse(flag); + + return updated > lastModified; + } + catch (Exception e) + { + Trace.WriteLine(new LogMessage("HtmlPackage", "IsUpdated: Failed to read status file: " + path + ". e = " + e.Message), LogType.Error.ToString()); + return false; + } + } + } +} diff --git a/Media/IeWebMedia.cs b/Media/IeWebMedia.cs index 3018ef24..34e404ab 100644 --- a/Media/IeWebMedia.cs +++ b/Media/IeWebMedia.cs @@ -1,13 +1,14 @@ -/* - * Xibo - Digitial Signage - http://www.xibo.org.uk - * Copyright (C) 2014-2018 Spring Signage Ltd +/** + * Copyright (C) 2019 Xibo Signage Ltd + * + * Xibo - Digital Signage - http://www.xibo.org.uk * * This file is part of Xibo. * * Xibo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or - * any later version. + * any later version. * * Xibo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -32,7 +33,7 @@ namespace XiboClient class IeWebMedia : Media { private bool _disposed = false; - private string _filePath; + protected string _filePath; private string _localWebPath; private RegionOptions _options; private WebBrowser _webBrowser; @@ -46,14 +47,11 @@ public IeWebMedia(RegionOptions options) // and store them in member variables. _options = options; - // Check to see if the mode option is present. - string modeId = options.Dictionary.Get("modeid"); - bool nativeOpen = modeId != string.Empty && modeId == "1"; - - if (nativeOpen) + // Set the file path/local web path + if (IsNativeOpen()) { // If we are modeid == 1, then just open the webpage without adjusting the file path - _filePath = Uri.UnescapeDataString(options.uri).Replace('+', ' '); + _filePath = Uri.UnescapeDataString(_options.uri).Replace('+', ' '); } else { @@ -61,7 +59,23 @@ public IeWebMedia(RegionOptions options) _filePath = ApplicationSettings.Default.LibraryPath + @"\" + _options.mediaid + ".htm"; _localWebPath = ApplicationSettings.Default.EmbeddedServerAddress + _options.mediaid + ".htm"; } + } + /// + /// Is this a native open widget + /// + /// + protected virtual bool IsNativeOpen() + { + string modeId = _options.Dictionary.Get("modeid"); + return modeId != string.Empty && modeId == "1"; + } + + /// + /// Render Media + /// + public override void RenderMedia() + { // Create the web view we will use _webBrowser = new WebBrowser(); _webBrowser.DocumentCompleted += _webBrowser_DocumentCompleted; @@ -70,9 +84,9 @@ public IeWebMedia(RegionOptions options) _webBrowser.ScriptErrorsSuppressed = true; _webBrowser.Visible = false; - if (nativeOpen) + if (IsNativeOpen()) { - // Nativate directly + // Navigate directly _webBrowser.Navigate(_filePath); } else if (HtmlReady()) @@ -90,8 +104,8 @@ public IeWebMedia(RegionOptions options) Controls.Add(_webBrowser); - // Show the control - Show(); + // Render media shows the controls and starts timers, etc + base.RenderMedia(); } /// diff --git a/Media/Media.cs b/Media/Media.cs index dfdae7ff..1c5ff668 100644 --- a/Media/Media.cs +++ b/Media/Media.cs @@ -24,6 +24,7 @@ using XiboClient.Properties; using System.Management; using System.Diagnostics; +using System.Drawing; namespace XiboClient { @@ -253,5 +254,32 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } + + /// + /// Is a region size change required + /// + /// + public virtual bool RegionSizeChangeRequired() + { + return false; + } + + /// + /// Get Region Size + /// + /// + public virtual Size GetRegionSize() + { + return new Size(_width, _height); + } + + /// + /// Get Region Location + /// + /// + public virtual Point GetRegionLocation() + { + return new Point(_top, _left); + } } } diff --git a/Media/Video.cs b/Media/Video.cs index b8dfd357..55fc4b69 100644 --- a/Media/Video.cs +++ b/Media/Video.cs @@ -1,13 +1,14 @@ -/* - * Xibo - Digitial Signage - http://www.xibo.org.uk - * Copyright (C) 2006-2015 Daniel Garner +/** + * Copyright (C) 2019 Xibo Signage Ltd + * + * Xibo - Digital Signage - http://www.xibo.org.uk * * This file is part of Xibo. * * Xibo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or - * any later version. + * any later version. * * Xibo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -37,6 +38,7 @@ class Video : Media private int _duration; private bool _expired = false; private bool _detectEnd = false; + private RegionOptions _options; /// /// Constructor @@ -45,12 +47,27 @@ class Video : Media public Video(RegionOptions options) : base(options.width, options.height, options.top, options.left) { + _options = options; _filePath = Uri.UnescapeDataString(options.uri).Replace('+',' '); _duration = options.duration; _videoPlayer = new VideoPlayer(); - _videoPlayer.Width = options.width; - _videoPlayer.Height = options.height; + + // Should this video be full screen? + if (options.Dictionary.Get("showFullScreen", "0") == "1") + { + Width = options.LayoutSize.Width; + Height = options.LayoutSize.Height; + _videoPlayer.Width = options.LayoutSize.Width; + _videoPlayer.Height = options.LayoutSize.Height; + } + else + { + _videoPlayer.Width = options.width; + _videoPlayer.Height = options.height; + } + + // Assert the location after setting the control size _videoPlayer.Location = new System.Drawing.Point(0, 0); // Should we loop? @@ -166,5 +183,46 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } + + /// + /// Is a region size change required + /// + /// + public override bool RegionSizeChangeRequired() + { + return (_options.Dictionary.Get("showFullScreen", "0") == "1"); + } + + /// + /// Get Region Size + /// + /// + public override System.Drawing.Size GetRegionSize() + { + if (RegionSizeChangeRequired()) + { + return new System.Drawing.Size(_videoPlayer.Width, _videoPlayer.Height); + } + else + { + return base.GetRegionSize(); + } + } + + /// + /// Get Region Location + /// + /// + public override System.Drawing.Point GetRegionLocation() + { + if (RegionSizeChangeRequired()) + { + return new System.Drawing.Point(0, 0); + } + else + { + return base.GetRegionLocation(); + } + } } } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 9411133f..e147dae6 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -30,6 +30,6 @@ // Build Number // Revision // -[assembly: AssemblyVersion("10.8.12.0")] -[assembly: AssemblyFileVersion("10.8.12.0")] +[assembly: AssemblyVersion("2.0.0.200")] +[assembly: AssemblyFileVersion("2.0.0.200")] [assembly: NeutralResourcesLanguageAttribute("en-GB")] diff --git a/XiboClient.csproj b/XiboClient.csproj index 9fc296e1..f93ba629 100644 --- a/XiboClient.csproj +++ b/XiboClient.csproj @@ -115,6 +115,8 @@ + + @@ -161,6 +163,9 @@ Form + + Form + Form diff --git a/XmdsAgents/LibraryAgent.cs b/XmdsAgents/LibraryAgent.cs index d1901b4a..33913434 100644 --- a/XmdsAgents/LibraryAgent.cs +++ b/XmdsAgents/LibraryAgent.cs @@ -1,13 +1,14 @@ -/* - * Xibo - Digitial Signage - http://www.xibo.org.uk - * Copyright (C) 2006 - 2016 Daniel Garner +/** + * Copyright (C) 2019 Xibo Signage Ltd + * + * Xibo - Digital Signage - http://www.xibo.org.uk * * This file is part of Xibo. * * Xibo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or - * any later version. + * any later version. * * Xibo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -136,6 +137,18 @@ public void Run() { Trace.WriteLine(new LogMessage("LibraryAgent - Run", "Deleting old file: " + fileInfo.Name), LogType.Info.ToString()); File.Delete(fileInfo.FullName); + + // Is this a HTZ file? + if (fileInfo.Extension.ToLower() == ".htz") + { + // Also delete the extracted version of this file + string pathToPackageFolder = Path.Combine(ApplicationSettings.Default.LibraryPath, "package_" + fileInfo.Name.Replace(fileInfo.Extension, "")); + + if (Directory.Exists(pathToPackageFolder)) + { + Directory.Delete(pathToPackageFolder, true); + } + } } } }