~dangarner/xibo/client-watchdog-170a2

« back to all changes in this revision

Viewing changes to client/dotNET/Media/CefWebMedia.cs

  • Committer: Dan Garner
  • Date: 2014-09-18 17:14:29 UTC
  • mfrom: (332.5.23 client-170-alpha)
  • Revision ID: dan@xibo.org.uk-20140918171429-z7rcbo23apafonwl
Merged lp:~dangarner/xibo/client-170alpha

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
using System;
 
2
using System.Collections.Generic;
 
3
using System.Diagnostics;
 
4
using System.Drawing;
 
5
using System.IO;
 
6
using System.Linq;
 
7
using System.Text;
 
8
using System.Text.RegularExpressions;
 
9
using System.Windows.Forms;
 
10
using XiboClient.Control;
 
11
using Xilium.CefGlue;
 
12
using Xilium.CefGlue.WindowsForms;
 
13
 
 
14
namespace XiboClient
 
15
{
 
16
    class CefWebMedia : Media
 
17
    {
 
18
        private bool _disposed = false;
 
19
        private bool _startWhenReady = false;
 
20
        private string _filePath;
 
21
        private RegionOptions _options;
 
22
        private TemporaryFile _temporaryFile;
 
23
        private CefWebBrowser _webView;
 
24
 
 
25
        public CefWebMedia(RegionOptions options)
 
26
            : base(options.width, options.height, options.top, options.left)
 
27
        {
 
28
            // Collect some options from the Region Options passed in
 
29
            // and store them in member variables.
 
30
            _options = options;
 
31
 
 
32
            // Set the file path
 
33
            _filePath = ApplicationSettings.Default.LibraryPath + @"\" + _options.mediaid + ".htm";
 
34
 
 
35
            // We will need a temporary file to store this HTML
 
36
            _temporaryFile = new TemporaryFile();
 
37
 
 
38
            Color backgroundColor = ColorTranslator.FromHtml(_options.backgroundColor);
 
39
 
 
40
            CefBrowserSettings settings = new CefBrowserSettings();
 
41
            settings.BackgroundColor = new CefColor(backgroundColor.A, backgroundColor.R, backgroundColor.G, backgroundColor.B);
 
42
 
 
43
            // Create the web view we will use
 
44
            _webView = new CefWebBrowser();
 
45
            _webView.BrowserSettings = settings;
 
46
            _webView.Dock = DockStyle.Fill;
 
47
            _webView.BrowserCreated += _webView_BrowserCreated;
 
48
            _webView.LoadEnd += _webView_LoadEnd;
 
49
            _webView.Size = Size;
 
50
 
 
51
            // Check to see if the HTML is ready for us.
 
52
            if (HtmlReady())
 
53
            {
 
54
                // Write to temporary file
 
55
                SaveToTemporaryFile();
 
56
 
 
57
                _startWhenReady = true;
 
58
            }
 
59
            else
 
60
            {
 
61
                RefreshFromXmds();
 
62
            }
 
63
 
 
64
            // We need to come up with a way of setting this control to Visible = false here and still kicking
 
65
            // off the webbrowser.
 
66
            // I think we can do this by hacking some bits into the Cef.WinForms dll.
 
67
            // Currently if we set this to false a browser isn't initialised by the library because it initializes it in OnHandleCreated
 
68
            // We also need a way to protect against the web browser never being created for some reason.
 
69
            // If it isn't then the control will never exipre (we might need to start the timer and then reset it).
 
70
            // Maybe:
 
71
            // Start the timer and then base.RestartTimer() in _webview_LoadEnd
 
72
            //base.StartTimer();
 
73
            
 
74
            //_webView.Visible = false;
 
75
 
 
76
            Controls.Add(_webView);
 
77
 
 
78
            // Show the control
 
79
            Show();
 
80
        }
 
81
 
 
82
        void _webView_BrowserCreated(object sender, EventArgs e)
 
83
        {
 
84
            if (_disposed)
 
85
                return;
 
86
 
 
87
            if (_startWhenReady)
 
88
                // Navigate to temp file
 
89
                _webView.Browser.GetMainFrame().LoadUrl(_temporaryFile.Path);
 
90
        }
 
91
 
 
92
        void _webView_LoadEnd(object sender, LoadEndEventArgs e)
 
93
        {
 
94
            if (_disposed)
 
95
                return;
 
96
 
 
97
            // Start the timer
 
98
            base.StartTimer();
 
99
        }
 
100
 
 
101
        public override void RenderMedia()
 
102
        {
 
103
            // We don't do anything in here as we want to start the timer from when the web view has loaded
 
104
        }
 
105
 
 
106
        private bool HtmlReady()
 
107
        {
 
108
            // Pull the RSS feed, and put it in a temporary file cache
 
109
            // We want to check the file exists first
 
110
            if (!File.Exists(_filePath) || _options.updateInterval == 0)
 
111
                return false;
 
112
 
 
113
            // It exists - therefore we want to get the last time it was updated
 
114
            DateTime lastWriteDate = File.GetLastWriteTime(_filePath);
 
115
 
 
116
            if (_options.LayoutModifiedDate.CompareTo(lastWriteDate) > 0 || DateTime.Now.CompareTo(lastWriteDate.AddHours(_options.updateInterval * 1.0 / 60.0)) > 0)
 
117
                return false;
 
118
            else
 
119
                return true;
 
120
        }
 
121
 
 
122
        /// <summary>
 
123
        /// Updates the position of the background and saves to a temporary file
 
124
        /// </summary>
 
125
        private void SaveToTemporaryFile()
 
126
        {
 
127
            // read the contents of the file
 
128
            using (StreamReader reader = new StreamReader(_filePath))
 
129
            {
 
130
                string cachedFile = reader.ReadToEnd();
 
131
 
 
132
                // Handle the background
 
133
                String bodyStyle;
 
134
 
 
135
                if (_options.backgroundImage == null || _options.backgroundImage == "")
 
136
                {
 
137
                    bodyStyle = "background-color:" + _options.backgroundColor + " ;";
 
138
                }
 
139
                else
 
140
                {
 
141
                    bodyStyle = "background-image: url('" + _options.backgroundImage.Replace('\\', '/') + "'); background-attachment:fixed; background-color:" + _options.backgroundColor + "; background-repeat: no-repeat; background-position: " + _options.backgroundLeft + "px " + _options.backgroundTop + "px;";
 
142
                }
 
143
 
 
144
                string html = cachedFile.Replace("</head>", "<style type='text/css'>body {" + bodyStyle + " }</style></head>");
 
145
 
 
146
                // We also want to parse out the duration using a regular expression
 
147
                try
 
148
                {
 
149
                    Match match = Regex.Match(html, "<!-- DURATION=(.*?) -->");
 
150
 
 
151
                    if (match.Success)
 
152
                    {
 
153
                        // We have a match, so override our duration.
 
154
                        Duration = Convert.ToInt32(match.Groups[1].Value);
 
155
                    }
 
156
                }
 
157
                catch
 
158
                {
 
159
                    Trace.WriteLine(new LogMessage("Html - SaveToTemporaryFile", "Unable to pull duration using RegEx").ToString());
 
160
                }
 
161
 
 
162
                _temporaryFile.FileContent = html;
 
163
            }
 
164
        }
 
165
 
 
166
        /// <summary>
 
167
        /// Refresh the Local cache of the DataSetView HTML
 
168
        /// </summary>
 
169
        private void RefreshFromXmds()
 
170
        {
 
171
            xmds.xmds xmds = new XiboClient.xmds.xmds();
 
172
            xmds.Url = ApplicationSettings.Default.XiboClient_xmds_xmds;
 
173
            xmds.GetResourceCompleted += new XiboClient.xmds.GetResourceCompletedEventHandler(xmds_GetResourceCompleted);
 
174
 
 
175
            xmds.GetResourceAsync(ApplicationSettings.Default.ServerKey, ApplicationSettings.Default.HardwareKey, _options.layoutId, _options.regionId, _options.mediaid, ApplicationSettings.Default.Version);
 
176
        }
 
177
 
 
178
        /// <summary>
 
179
        /// Refresh Complete
 
180
        /// </summary>
 
181
        /// <param name="sender"></param>
 
182
        /// <param name="e"></param>
 
183
        private void xmds_GetResourceCompleted(object sender, XiboClient.xmds.GetResourceCompletedEventArgs e)
 
184
        {
 
185
            try
 
186
            {
 
187
                // Success / Failure
 
188
                if (e.Error != null)
 
189
                {
 
190
                    Trace.WriteLine(new LogMessage("xmds_GetResource", "Unable to get Resource: " + e.Error.Message), LogType.Error.ToString());
 
191
 
 
192
                    // Start the timer so that we expire
 
193
                    base.RenderMedia();
 
194
                }
 
195
                else
 
196
                {
 
197
                    // Write to the library
 
198
                    using (StreamWriter sw = new StreamWriter(File.Open(_filePath, FileMode.Create, FileAccess.Write, FileShare.Read)))
 
199
                    {
 
200
                        sw.Write(e.Result);
 
201
                        sw.Close();
 
202
                    }
 
203
 
 
204
                    // Write to temporary file
 
205
                    SaveToTemporaryFile();
 
206
 
 
207
                    // Handle Navigate in here because we will not have done it during first load
 
208
                    _webView.Browser.GetMainFrame().LoadUrl(_temporaryFile.Path);
 
209
                }
 
210
            }
 
211
            catch (ObjectDisposedException)
 
212
            {
 
213
                Trace.WriteLine(new LogMessage("WebMedia", "Retrived the data set, stored the document but the media has already expired."), LogType.Error.ToString());
 
214
            }
 
215
            catch (Exception ex)
 
216
            {
 
217
                Trace.WriteLine(new LogMessage("WebMedia", "Unknown exception " + ex.Message), LogType.Error.ToString());
 
218
 
 
219
                // This should exipre the media
 
220
                Duration = 5;
 
221
                base.RenderMedia();
 
222
            }
 
223
        }
 
224
 
 
225
        /// <summary>
 
226
        /// Dispose of this text item
 
227
        /// </summary>
 
228
        /// <param name="disposing"></param>
 
229
        protected override void Dispose(bool disposing)
 
230
        {
 
231
            _disposed = true;
 
232
 
 
233
            if (disposing)
 
234
            {
 
235
                // Remove the webbrowser control
 
236
                try
 
237
                {
 
238
                    if (_webView != null)
 
239
                        _webView.Dispose();
 
240
                }
 
241
                catch
 
242
                {
 
243
                    Trace.WriteLine(new LogMessage("WebBrowser still in use.", String.Format("Dispose")));
 
244
                }
 
245
 
 
246
                // Delete the temporary file
 
247
                try
 
248
                {
 
249
                    if (_temporaryFile != null)
 
250
                        _temporaryFile.Dispose();
 
251
                }
 
252
                catch
 
253
                {
 
254
                    Debug.WriteLine("Unable to delete temporary file", "CefWebMedia - Dispose");
 
255
                }
 
256
            }
 
257
 
 
258
            base.Dispose(disposing);
 
259
        }
 
260
    }
 
261
}