Merge lp:~dangarner/xibo/1.2.2-pre into lp:xibo/1.2

Proposed by Dan Garner
Status: Merged
Merged at revision: 213
Proposed branch: lp:~dangarner/xibo/1.2.2-pre
Merge into: lp:xibo/1.2
Diff against target: 1513 lines (+770/-99)
24 files modified
client/dotNET/CacheManager.cs (+75/-1)
client/dotNET/FileCollector.cs (+50/-29)
client/dotNET/MainForm.cs (+45/-22)
client/dotNET/Properties/Settings.Designer.cs (+13/-1)
client/dotNET/Properties/Settings.settings (+4/-1)
client/dotNET/Region.cs (+6/-7)
client/dotNET/RequiredFiles.cs (+206/-0)
client/dotNET/Schedule.cs (+1/-1)
client/dotNET/ScheduleManager.cs (+16/-1)
client/dotNET/Web References/xmds/Reference.cs (+67/-0)
client/dotNET/Web References/xmds/xmds.wsdl (+23/-0)
client/dotNET/XiboClient.csproj (+1/-0)
client/dotNET/app.config (+4/-1)
client/dotNET/bin/Release/XiboClient.exe.config (+4/-1)
client/dotNET/bin/Release/XiboClient.vshost.exe.config (+4/-1)
server/install/database/27.sql (+9/-0)
server/lib/app/kit.class.php (+9/-13)
server/lib/data/display.data.class.php (+60/-16)
server/lib/data/schedule.data.class.php (+5/-0)
server/lib/pages/display.class.php (+74/-4)
server/lib/pages/layout.class.php (+6/-0)
server/lib/pages/region.class.php (+5/-0)
server/lib/service/service.wsdl (+23/-0)
server/lib/service/xmdssoap.class.php (+60/-0)
To merge this branch: bzr merge lp:~dangarner/xibo/1.2.2-pre
Reviewer Review Type Date Requested Status
Xibo Maintainters Pending
Review via email: mp+51554@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'client/dotNET/CacheManager.cs'
--- client/dotNET/CacheManager.cs 2010-04-19 21:45:10 +0000
+++ client/dotNET/CacheManager.cs 2011-02-28 15:09:32 +0000
@@ -25,6 +25,7 @@
25using System.Windows.Forms;25using System.Windows.Forms;
26using System.Xml.Serialization;26using System.Xml.Serialization;
27using System.Diagnostics;27using System.Diagnostics;
28using System.Xml;
2829
29namespace XiboClient30namespace XiboClient
30{31{
@@ -173,7 +174,7 @@
173 /// </summary>174 /// </summary>
174 /// <param name="path"></param>175 /// <param name="path"></param>
175 /// <returns>True is it is and false if it isnt</returns>176 /// <returns>True is it is and false if it isnt</returns>
176 public bool IsValid(String path)177 public bool IsValidPath(String path)
177 {178 {
178 // TODO: what makes a path valid?179 // TODO: what makes a path valid?
179 // Currently a path is valid if it is in the cache180 // Currently a path is valid if it is in the cache
@@ -185,6 +186,10 @@
185 {186 {
186 if (file.path == path)187 if (file.path == path)
187 {188 {
189 // If we cached it over 2 minutes ago, then check the GetLastWriteTime
190 if (file.cacheDate > DateTime.Now.AddMinutes(-2))
191 return true;
192
188 try193 try
189 {194 {
190 // Check to see if this file has been modified since the MD5 cache195 // Check to see if this file has been modified since the MD5 cache
@@ -209,6 +214,75 @@
209 // Reached the end of the cache and havent found the file.214 // Reached the end of the cache and havent found the file.
210 return false;215 return false;
211 }216 }
217
218 /// <summary>
219 /// Is the provided layout file a valid layout (has all media)
220 /// </summary>
221 /// <param name="layoutFile"></param>
222 /// <returns></returns>
223 public bool IsValidLayout(string layoutFile)
224 {
225 Debug.WriteLine("Checking Layout " + layoutFile + " is valid");
226
227 if (!IsValidPath(layoutFile))
228 return false;
229
230 // Load the XLF, get all media ID's
231 XmlDocument layoutXml = new XmlDocument();
232 layoutXml.Load(Properties.Settings.Default.LibraryPath + @"\" + layoutFile);
233
234 XmlNodeList mediaNodes = layoutXml.SelectNodes("//media");
235
236 foreach (XmlNode media in mediaNodes)
237 {
238 // Is this a stored media type?
239 switch (media.Attributes["type"].Value)
240 {
241 case "video":
242 case "image":
243 case "flash":
244 case "ppt":
245
246 // Get the path and see if its valid
247 if (!IsValidPath(media.InnerText))
248 return false;
249
250 break;
251
252 default:
253 continue;
254 }
255 }
256
257 return true;
258 }
259
260 /// <summary>
261 /// Regenerate from Required Files
262 /// </summary>
263 public void Regenerate()
264 {
265 if (!File.Exists(Application.UserAppDataPath + "\\" + Properties.Settings.Default.RequiredFilesFile))
266 return;
267
268 // Open the XML file and check each required file that isnt already there
269 XmlDocument xml = new XmlDocument();
270 xml.Load(Application.UserAppDataPath + "\\" + Properties.Settings.Default.RequiredFilesFile);
271
272 XmlNodeList fileNodes = xml.SelectNodes("//RequiredFile/Path");
273
274 foreach (XmlNode file in fileNodes)
275 {
276 string path = file.InnerText;
277
278 // Does the file exist?
279 if (!File.Exists(Properties.Settings.Default.LibraryPath + @"\" + path))
280 continue;
281
282 // Add this file to the cache manager
283 Add(path, GetMD5(path));
284 }
285 }
212 }286 }
213287
214 public struct Md5Resource288 public struct Md5Resource
215289
=== modified file 'client/dotNET/FileCollector.cs'
--- client/dotNET/FileCollector.cs 2011-01-30 18:13:32 +0000
+++ client/dotNET/FileCollector.cs 2011-02-28 15:09:32 +0000
@@ -31,28 +31,26 @@
31 class FileCollector31 class FileCollector
32 {32 {
33 private CacheManager _cacheManager;33 private CacheManager _cacheManager;
34 private RequiredFiles _requiredFiles;
35 private XmlDocument _xml;
3436
35 public FileCollector(CacheManager cacheManager, string xmlString)37 public FileCollector(CacheManager cacheManager, string xmlString)
36 {38 {
37 _cacheManager = cacheManager;39 _cacheManager = cacheManager;
3840
39 xml = new XmlDocument();41 // Load the XML file RF call
42 _xml = new XmlDocument();
43 _xml.LoadXml(xmlString);
4044
41 try45 // Create a required files object
42 {46 _requiredFiles = new RequiredFiles();
43 xml.LoadXml(xmlString);47 _requiredFiles.RequiredFilesXml = _xml;
44 }
45 catch (Exception e)
46 {
47 //Log this error
48 System.Diagnostics.Debug.WriteLine(e.Message);
49 }
5048
51 // Get the key for later use49 // Get the key for later use
52 hardwareKey = new HardwareKey();50 hardwareKey = new HardwareKey();
5351
54 // Make a new filelist collection52 // Make a new filelist collection
55 files = new Collection<FileList>();53 _files = new Collection<RequiredFile>();
5654
57 // Create a webservice call55 // Create a webservice call
58 xmdsFile = new XiboClient.xmds.xmds();56 xmdsFile = new XiboClient.xmds.xmds();
@@ -73,13 +71,13 @@
73 /// </summary>71 /// </summary>
74 public void CompareAndCollect()72 public void CompareAndCollect()
75 {73 {
76 XmlNodeList fileNodes = xml.SelectNodes("/files/file");74 XmlNodeList fileNodes = _xml.SelectNodes("/files/file");
7775
78 //Inspect each file we have here76 //Inspect each file we have here
79 foreach (XmlNode file in fileNodes)77 foreach (XmlNode file in fileNodes)
80 {78 {
81 XmlAttributeCollection attributes = file.Attributes;79 XmlAttributeCollection attributes = file.Attributes;
82 FileList fileList = new FileList();80 RequiredFile fileList = new RequiredFile();
8381
84 if (attributes["type"].Value == "layout")82 if (attributes["type"].Value == "layout")
85 {83 {
@@ -120,13 +118,15 @@
120 fileList.md5 = attributes["md5"].Value;118 fileList.md5 = attributes["md5"].Value;
121 fileList.retrys = 0;119 fileList.retrys = 0;
122120
123 files.Add(fileList);121 _files.Add(fileList);
124 }122 }
125 else123 else
126 {124 {
127 // The MD5 of the current file and the MD5 in RequiredFiles are the same.125 // The MD5 of the current file and the MD5 in RequiredFiles are the same.
128 // Therefore make sure this MD5 is in the CacheManager126 // Therefore make sure this MD5 is in the CacheManager
129 _cacheManager.Add(path + ".xlf", md5);127 _cacheManager.Add(path + ".xlf", md5);
128
129 _requiredFiles.MarkComplete(int.Parse(path), md5);
130 }130 }
131 }131 }
132 else132 else
@@ -141,7 +141,7 @@
141 fileList.md5 = attributes["md5"].Value;141 fileList.md5 = attributes["md5"].Value;
142 fileList.retrys = 0;142 fileList.retrys = 0;
143143
144 files.Add(fileList);144 _files.Add(fileList);
145 }145 }
146 }146 }
147 else if (attributes["type"].Value == "media")147 else if (attributes["type"].Value == "media")
@@ -183,13 +183,16 @@
183 fileList.md5 = attributes["md5"].Value;183 fileList.md5 = attributes["md5"].Value;
184 fileList.retrys = 0;184 fileList.retrys = 0;
185185
186 files.Add(fileList);186 _files.Add(fileList);
187 }187 }
188 else188 else
189 {189 {
190 // The MD5 of the current file and the MD5 in RequiredFiles are the same.190 // The MD5 of the current file and the MD5 in RequiredFiles are the same.
191 // Therefore make sure this MD5 is in the CacheManager191 // Therefore make sure this MD5 is in the CacheManager
192 _cacheManager.Add(path, md5);192 _cacheManager.Add(path, md5);
193
194 string[] filePart = path.Split('.');
195 _requiredFiles.MarkComplete(int.Parse(filePart[0]), md5);
193 }196 }
194 }197 }
195 else198 else
@@ -205,7 +208,7 @@
205 fileList.md5 = attributes["md5"].Value;208 fileList.md5 = attributes["md5"].Value;
206 fileList.retrys = 0;209 fileList.retrys = 0;
207210
208 files.Add(fileList);211 _files.Add(fileList);
209 }212 }
210 }213 }
211 else if (attributes["type"].Value == "blacklist")214 else if (attributes["type"].Value == "blacklist")
@@ -234,18 +237,24 @@
234 }237 }
235 }238 }
236239
237 Debug.WriteLine(String.Format("There are {0} files to get", files.Count.ToString()));240 Debug.WriteLine(String.Format("There are {0} files to get", _files.Count.ToString()));
238241
239 // Output a list of the files we need to get242 // Output a list of the files we need to get
240 string debugMessage = "";243 string debugMessage = "";
241244
242 foreach (FileList fileToGet in files)245 foreach (RequiredFile fileToGet in _files)
243 debugMessage += string.Format("File: {0}, Type: {1}, MD5: {2}. ", fileToGet.path, fileToGet.type, fileToGet.md5);246 debugMessage += string.Format("File: {0}, Type: {1}, MD5: {2}. ", fileToGet.path, fileToGet.type, fileToGet.md5);
244247
245 Debug.WriteLine(debugMessage);248 Debug.WriteLine(debugMessage);
246249
250 // Report the files files back to XMDS
251 _requiredFiles.ReportInventory();
252
253 // Write Required Files
254 _requiredFiles.WriteRequiredFiles();
255
247 // Is there anything to get?256 // Is there anything to get?
248 if (files.Count == 0)257 if (_files.Count == 0)
249 {258 {
250 CollectionComplete();259 CollectionComplete();
251 return;260 return;
@@ -255,7 +264,7 @@
255 _currentFile = 0;264 _currentFile = 0;
256265
257 // Preload the first filelist266 // Preload the first filelist
258 _currentFileList = files[_currentFile];267 _currentFileList = _files[_currentFile];
259268
260 // Get the first file269 // Get the first file
261 GetFile();270 GetFile();
@@ -375,6 +384,10 @@
375 {384 {
376 // Add to the CacheManager385 // Add to the CacheManager
377 _cacheManager.Add(_currentFileList.path + ".xlf", md5sum);386 _cacheManager.Add(_currentFileList.path + ".xlf", md5sum);
387
388 // Report this completion back to XMDS
389 _requiredFiles.MarkComplete(int.Parse(_currentFileList.path), md5sum);
390 _requiredFiles.ReportInventory();
378 }391 }
379392
380 // Fire a layout complete event393 // Fire a layout complete event
@@ -445,6 +458,11 @@
445458
446 System.Diagnostics.Debug.WriteLine(string.Format("File downloaded: {0}", _currentFileList.path));459 System.Diagnostics.Debug.WriteLine(string.Format("File downloaded: {0}", _currentFileList.path));
447460
461 // Report this completion back to XMDS
462 string[] filePart = _currentFileList.path.Split('.');
463 _requiredFiles.MarkComplete(int.Parse(filePart[0]), md5sum);
464 _requiredFiles.ReportInventory();
465
448 // All the file has been recieved. Move on to the next file.466 // All the file has been recieved. Move on to the next file.
449 _currentFile++;467 _currentFile++;
450 }468 }
@@ -475,13 +493,16 @@
475 /// </summary>493 /// </summary>
476 public void GetFile()494 public void GetFile()
477 {495 {
478 if (_currentFile > (files.Count - 1))496 if (_currentFile > (_files.Count - 1))
479 {497 {
480 System.Diagnostics.Debug.WriteLine(String.Format("Finished Recieving {0} files", files.Count));498 System.Diagnostics.Debug.WriteLine(String.Format("Finished Receiving {0} files", _files.Count));
481499
482 // Clean up500 // Clean up
483 files.Clear();501 _files.Clear();
484 xmdsFile.Dispose(); 502 xmdsFile.Dispose();
503
504 // Write Required Files
505 _requiredFiles.WriteRequiredFiles();
485506
486 // Finished getting this file list507 // Finished getting this file list
487 CollectionComplete();508 CollectionComplete();
@@ -491,7 +512,7 @@
491 // Get the current file into the currentfilelist if the current one is finished512 // Get the current file into the currentfilelist if the current one is finished
492 if (_currentFileList.complete)513 if (_currentFileList.complete)
493 {514 {
494 _currentFileList = files[_currentFile];515 _currentFileList = _files[_currentFile];
495 }516 }
496517
497 System.Diagnostics.Debug.WriteLine(String.Format("Getting the file : {0} chunk : {1}", _currentFileList.path, _currentFileList.chunkOffset.ToString()));518 System.Diagnostics.Debug.WriteLine(String.Format("Getting the file : {0} chunk : {1}", _currentFileList.path, _currentFileList.chunkOffset.ToString()));
@@ -504,7 +525,7 @@
504 }525 }
505526
506 [Serializable]527 [Serializable]
507 private struct FileList528 private struct RequiredFile
508 {529 {
509 public string path;530 public string path;
510 public string type;531 public string type;
@@ -519,9 +540,9 @@
519540
520 private XmlDocument xml;541 private XmlDocument xml;
521 private HardwareKey hardwareKey;542 private HardwareKey hardwareKey;
522 private Collection<FileList> files;543 private Collection<RequiredFile> _files;
523 private int _currentFile;544 private int _currentFile;
524 private FileList _currentFileList;545 private RequiredFile _currentFileList;
525 private xmds.xmds xmdsFile;546 private xmds.xmds xmdsFile;
526547
527 public event LayoutFileChangedDelegate LayoutFileChanged;548 public event LayoutFileChangedDelegate LayoutFileChanged;
528549
=== modified file 'client/dotNET/MainForm.cs'
--- client/dotNET/MainForm.cs 2011-01-30 18:13:32 +0000
+++ client/dotNET/MainForm.cs 2011-02-28 15:09:32 +0000
@@ -72,14 +72,45 @@
7272
73 _statLog = new StatLog();73 _statLog = new StatLog();
7474
75 this.FormClosing += new FormClosingEventHandler(MainForm_FormClosing);
76 this.Shown += new EventHandler(MainForm_Shown);
77 }
78
79 /// <summary>
80 /// Called after the form has been shown
81 /// </summary>
82 /// <param name="sender"></param>
83 /// <param name="e"></param>
84 void MainForm_Shown(object sender, EventArgs e)
85 {
86 // Process any stuff that has happened during the loading process
87 Application.DoEvents();
88
75 // Create a cachemanager89 // Create a cachemanager
76 SetCacheManager();90 SetCacheManager();
7791
78 this.FormClosing += new FormClosingEventHandler(MainForm_FormClosing);92 try
93 {
94 // Create the Schedule
95 _schedule = new Schedule(Application.UserAppDataPath + "\\" + Properties.Settings.Default.ScheduleFile, ref _cacheManager);
96
97 // Bind to the schedule change event - notifys of changes to the schedule
98 _schedule.ScheduleChangeEvent += new Schedule.ScheduleChangeDelegate(schedule_ScheduleChangeEvent);
99
100 // Initialize the other schedule components
101 _schedule.InitializeComponents();
102 }
103 catch (Exception ex)
104 {
105 Debug.WriteLine(ex.Message, LogType.Error.ToString());
106 MessageBox.Show("Fatal Error initialising the application", "Fatal Error");
107 Close();
108 Dispose();
109 }
79 }110 }
80111
81 /// <summary>112 /// <summary>
82 /// Called when the form has finished loading113 /// Called before the form has loaded for the first time
83 /// </summary>114 /// </summary>
84 /// <param name="sender"></param>115 /// <param name="sender"></param>
85 /// <param name="e"></param>116 /// <param name="e"></param>
@@ -96,30 +127,13 @@
96 Cursor.Position = new Point(_clientSize.Width, _clientSize.Height);127 Cursor.Position = new Point(_clientSize.Width, _clientSize.Height);
97 Cursor.Hide();128 Cursor.Hide();
98129
130 ShowSplashScreen();
131
99 // Change the default Proxy class132 // Change the default Proxy class
100 OptionForm.SetGlobalProxy();133 OptionForm.SetGlobalProxy();
101134
102 // UserApp data135 // UserApp data
103 Debug.WriteLine(new LogMessage("MainForm_Load", "User AppData Path: " + Application.UserAppDataPath), LogType.Info.ToString());136 Debug.WriteLine(new LogMessage("MainForm_Load", "User AppData Path: " + Application.UserAppDataPath), LogType.Info.ToString());
104
105 try
106 {
107 // Create the Schedule
108 _schedule = new Schedule(Application.UserAppDataPath + "\\" + Properties.Settings.Default.ScheduleFile, ref _cacheManager);
109
110 // Bind to the schedule change event - notifys of changes to the schedule
111 _schedule.ScheduleChangeEvent += new Schedule.ScheduleChangeDelegate(schedule_ScheduleChangeEvent);
112
113 // Initialize the other schedule components
114 _schedule.InitializeComponents();
115 }
116 catch (Exception ex)
117 {
118 Debug.WriteLine(ex.Message, LogType.Error.ToString());
119 MessageBox.Show("Fatal Error initialising the application", "Fatal Error");
120 Close();
121 Dispose();
122 }
123 }137 }
124138
125 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)139 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
@@ -152,11 +166,20 @@
152 }166 }
153 catch (Exception ex)167 catch (Exception ex)
154 {168 {
155 Trace.WriteLine(new LogMessage("Schedule", "Unable to reuse the Cache Manager because: " + ex.Message));169 Trace.WriteLine(new LogMessage("MainForm - SetCacheManager", "Unable to reuse the Cache Manager because: " + ex.Message));
156170
157 // Create a new cache manager171 // Create a new cache manager
158 _cacheManager = new CacheManager();172 _cacheManager = new CacheManager();
159 }173 }
174
175 try
176 {
177 _cacheManager.Regenerate();
178 }
179 catch (Exception ex)
180 {
181 Trace.WriteLine(new LogMessage("MainForm - SetCacheManager", "Regenerate failed because: " + ex.Message));
182 }
160 }183 }
161184
162 /// <summary>185 /// <summary>
163186
=== modified file 'client/dotNET/Properties/Settings.Designer.cs'
--- client/dotNET/Properties/Settings.Designer.cs 2011-02-14 16:21:56 +0000
+++ client/dotNET/Properties/Settings.Designer.cs 2011-02-28 15:09:32 +0000
@@ -271,7 +271,7 @@
271 271
272 [global::System.Configuration.ApplicationScopedSettingAttribute()]272 [global::System.Configuration.ApplicationScopedSettingAttribute()]
273 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]273 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
274 [global::System.Configuration.DefaultSettingValueAttribute("1.2.1")]274 [global::System.Configuration.DefaultSettingValueAttribute("1.2.2")]
275 public string ClientVersion {275 public string ClientVersion {
276 get {276 get {
277 return ((string)(this["ClientVersion"]));277 return ((string)(this["ClientVersion"]));
@@ -370,5 +370,17 @@
370 this["emptyLayoutDuration"] = value;370 this["emptyLayoutDuration"] = value;
371 }371 }
372 }372 }
373
374 [global::System.Configuration.UserScopedSettingAttribute()]
375 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
376 [global::System.Configuration.DefaultSettingValueAttribute("requiredFiles.xml")]
377 public string RequiredFilesFile {
378 get {
379 return ((string)(this["RequiredFilesFile"]));
380 }
381 set {
382 this["RequiredFilesFile"] = value;
383 }
384 }
373 }385 }
374}386}
375387
=== modified file 'client/dotNET/Properties/Settings.settings'
--- client/dotNET/Properties/Settings.settings 2011-02-14 16:21:56 +0000
+++ client/dotNET/Properties/Settings.settings 2011-02-28 15:09:32 +0000
@@ -69,7 +69,7 @@
69 <Value Profile="(Default)">cacheManager.xml</Value>69 <Value Profile="(Default)">cacheManager.xml</Value>
70 </Setting>70 </Setting>
71 <Setting Name="ClientVersion" Type="System.String" Scope="Application">71 <Setting Name="ClientVersion" Type="System.String" Scope="Application">
72 <Value Profile="(Default)">1.2.1</Value>72 <Value Profile="(Default)">1.2.2</Value>
73 </Setting>73 </Setting>
74 <Setting Name="scrollStepAmount" Type="System.Decimal" Scope="User">74 <Setting Name="scrollStepAmount" Type="System.Decimal" Scope="User">
75 <Value Profile="(Default)">1</Value>75 <Value Profile="(Default)">1</Value>
@@ -95,5 +95,8 @@
95 <Setting Name="emptyLayoutDuration" Type="System.Decimal" Scope="User">95 <Setting Name="emptyLayoutDuration" Type="System.Decimal" Scope="User">
96 <Value Profile="(Default)">10</Value>96 <Value Profile="(Default)">10</Value>
97 </Setting>97 </Setting>
98 <Setting Name="RequiredFilesFile" Type="System.String" Scope="User">
99 <Value Profile="(Default)">requiredFiles.xml</Value>
100 </Setting>
98 </Settings>101 </Settings>
99</SettingsFile>102</SettingsFile>
100\ No newline at end of file103\ No newline at end of file
101104
=== modified file 'client/dotNET/Region.cs'
--- client/dotNET/Region.cs 2010-11-09 21:23:31 +0000
+++ client/dotNET/Region.cs 2011-02-28 15:09:32 +0000
@@ -310,12 +310,11 @@
310 }310 }
311311
312 // We cannot have a 0 duration here... not sure why we would... but312 // We cannot have a 0 duration here... not sure why we would... but
313 if (options.duration == 0)313 if (options.duration == 0 && options.type != "video")
314 options.duration = int.Parse(Properties.Settings.Default.emptyLayoutDuration.ToString());314 {
315315 int emptyLayoutDuration = int.Parse(Properties.Settings.Default.emptyLayoutDuration.ToString());
316 // Fail safe316 options.duration = (emptyLayoutDuration == 0) ? 10 : emptyLayoutDuration;
317 if (options.duration == 0)317 }
318 options.duration = 10;
319318
320 // There will be some stuff on option nodes319 // There will be some stuff on option nodes
321 XmlNode optionNode = mediaNode.FirstChild; 320 XmlNode optionNode = mediaNode.FirstChild;
@@ -386,7 +385,7 @@
386 if (options.type == "video" || options.type == "flash" || options.type == "image" || options.type == "powerpoint")385 if (options.type == "video" || options.type == "flash" || options.type == "image" || options.type == "powerpoint")
387 {386 {
388 // Use the cache manager to determine if the file is valid387 // Use the cache manager to determine if the file is valid
389 validNode = _cacheManager.IsValid(options.uri);388 validNode = _cacheManager.IsValidPath(options.uri);
390 }389 }
391 }390 }
392391
393392
=== added file 'client/dotNET/RequiredFiles.cs'
--- client/dotNET/RequiredFiles.cs 1970-01-01 00:00:00 +0000
+++ client/dotNET/RequiredFiles.cs 2011-02-28 15:09:32 +0000
@@ -0,0 +1,206 @@
1/*
2 * Xibo - Digitial Signage - http://www.xibo.org.uk
3 * Copyright (C) 2011 Daniel Garner
4 *
5 * This file is part of Xibo.
6 *
7 * Xibo is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * any later version.
11 *
12 * Xibo is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with Xibo. If not, see <http://www.gnu.org/licenses/>.
19 */
20using System;
21using System.Collections.Generic;
22using System.Collections.ObjectModel;
23using System.Text;
24using System.IO;
25using System.Security.Cryptography;
26using System.Xml;
27using System.Diagnostics;
28using System.Windows.Forms;
29using System.Xml.Serialization;
30
31namespace XiboClient
32{
33 public class RequiredFiles
34 {
35 private XmlDocument _requiredFilesXml;
36 public Collection<RequiredFile> _requiredFiles;
37 private xmds.xmds _report;
38
39 public RequiredFiles()
40 {
41 _requiredFiles = new Collection<RequiredFile>();
42
43 // Create a webservice call
44 _report = new XiboClient.xmds.xmds();
45
46 // Start up the Xmds Service Object
47 _report.Credentials = null;
48 _report.Url = Properties.Settings.Default.XiboClient_xmds_xmds;
49 _report.UseDefaultCredentials = false;
50 }
51
52 /// <summary>
53 /// Set required files from the XML document
54 /// </summary>
55 private void SetRequiredFiles()
56 {
57 // Itterate through the RF XML and populate the RF collection
58 XmlNodeList fileNodes = _requiredFilesXml.SelectNodes("/files/file");
59
60 foreach (XmlNode file in fileNodes)
61 {
62 RequiredFile rf = new RequiredFile();
63
64 XmlAttributeCollection attributes = file.Attributes;
65
66 rf.FileType = attributes["type"].Value;
67 rf.Complete = 0;
68 rf.Md5 = "";
69 rf.LastChecked = DateTime.Now;
70
71 if (rf.FileType == "media")
72 {
73 string[] filePart = attributes["path"].Value.Split('.');
74 rf.Id = int.Parse(filePart[0]);
75 rf.Path = attributes["path"].Value;
76 }
77 else if (rf.FileType == "layout")
78 {
79 rf.Id = int.Parse(attributes["path"].Value);
80 rf.Path = attributes["path"].Value + ".xlf";
81 }
82 else
83 {
84 continue;
85 }
86
87 _requiredFiles.Add(rf);
88 }
89 }
90
91 /// <summary>
92 /// Required Files XML
93 /// </summary>
94 public XmlDocument RequiredFilesXml
95 {
96 set
97 {
98 _requiredFilesXml = value;
99 SetRequiredFiles();
100 }
101 }
102
103 /// <summary>
104 /// Mark a RequiredFile as complete
105 /// </summary>
106 /// <param name="id"></param>
107 /// <param name="md5"></param>
108 public void MarkComplete(int id, string md5)
109 {
110 foreach (RequiredFile rf in _requiredFiles)
111 {
112 if (rf.Id == id)
113 {
114 RequiredFile newRf = rf;
115
116 newRf.Complete = 1;
117 newRf.Md5 = md5;
118
119
120 _requiredFiles.Add(newRf);
121 _requiredFiles.Remove(rf);
122
123 return;
124 }
125 }
126 }
127
128 /// <summary>
129 /// Mark a RequiredFile as incomplete
130 /// </summary>
131 /// <param name="id"></param>
132 /// <param name="md5"></param>
133 public void MarkIncomplete(int id, string md5)
134 {
135 foreach (RequiredFile rf in _requiredFiles)
136 {
137 if (rf.Id == id)
138 {
139 RequiredFile newRf = rf;
140
141 newRf.Complete = 0;
142 newRf.Md5 = md5;
143
144 _requiredFiles.Add(newRf);
145 _requiredFiles.Remove(rf);
146
147 return;
148 }
149 }
150 }
151
152 /// <summary>
153 /// Writes Required Files to disk
154 /// </summary>
155 public void WriteRequiredFiles()
156 {
157 Debug.WriteLine(new LogMessage("RequiredFiles - WriteRequiredFiles", "About to Write RequiredFiles"), LogType.Info.ToString());
158
159 try
160 {
161 using (StreamWriter streamWriter = new StreamWriter(Application.UserAppDataPath + "\\" + Properties.Settings.Default.RequiredFilesFile))
162 {
163 XmlSerializer xmlSerializer = new XmlSerializer(typeof(RequiredFiles));
164
165 xmlSerializer.Serialize(streamWriter, this);
166 }
167 }
168 catch (Exception ex)
169 {
170 System.Diagnostics.Trace.WriteLine(new LogMessage("RequiredFiles - WriteRequiredFiles", "Unable to write RequiredFiles to disk because: " + ex.Message));
171 }
172 }
173
174 /// <summary>
175 /// Report Required Files to XMDS
176 /// </summary>
177 public void ReportInventory()
178 {
179 HardwareKey hardwareKey = new HardwareKey();
180
181 // Build the XML required by media file
182 string xml = "";
183
184 foreach (RequiredFile rf in _requiredFiles)
185 {
186 xml += string.Format("<file type=\"{0}\" id=\"{1}\" complete=\"{2}\" lastChecked=\"{3}\" md5=\"{4}\" />",
187 rf.FileType, rf.Id.ToString(), rf.Complete.ToString(), rf.LastChecked.ToString(), rf.Md5);
188 }
189
190 xml = string.Format("<files>{0}</files>", xml);
191
192 _report.MediaInventoryAsync(Properties.Settings.Default.Version, Properties.Settings.Default.ServerKey,
193 hardwareKey.Key, xml);
194 }
195 }
196
197 public struct RequiredFile
198 {
199 public string FileType;
200 public int Id;
201 public int Complete;
202 public DateTime LastChecked;
203 public string Md5;
204 public string Path;
205 }
206}
0207
=== modified file 'client/dotNET/Schedule.cs'
--- client/dotNET/Schedule.cs 2010-08-22 16:49:09 +0000
+++ client/dotNET/Schedule.cs 2011-02-28 15:09:32 +0000
@@ -74,7 +74,7 @@
74 _cacheManager = cacheManager;74 _cacheManager = cacheManager;
7575
76 // Create a schedule manager76 // Create a schedule manager
77 _scheduleManager = new ScheduleManager(scheduleLocation);77 _scheduleManager = new ScheduleManager(_cacheManager, scheduleLocation);
7878
79 // Create a new Xmds service object79 // Create a new Xmds service object
80 _xmds2 = new XiboClient.xmds.xmds();80 _xmds2 = new XiboClient.xmds.xmds();
8181
=== modified file 'client/dotNET/ScheduleManager.cs'
--- client/dotNET/ScheduleManager.cs 2010-08-25 21:39:53 +0000
+++ client/dotNET/ScheduleManager.cs 2011-02-28 15:09:32 +0000
@@ -42,13 +42,15 @@
42 private Collection<LayoutSchedule> _layoutSchedule;42 private Collection<LayoutSchedule> _layoutSchedule;
43 private Collection<LayoutSchedule> _currentSchedule;43 private Collection<LayoutSchedule> _currentSchedule;
44 private bool _refreshSchedule;44 private bool _refreshSchedule;
45 private CacheManager _cacheManager;
4546
46 /// <summary>47 /// <summary>
47 /// Creates a new schedule Manager48 /// Creates a new schedule Manager
48 /// </summary>49 /// </summary>
49 /// <param name="scheduleLocation"></param>50 /// <param name="scheduleLocation"></param>
50 public ScheduleManager(string scheduleLocation)51 public ScheduleManager(CacheManager cacheManager, string scheduleLocation)
51 {52 {
53 _cacheManager = cacheManager;
52 _location = scheduleLocation;54 _location = scheduleLocation;
5355
54 // Create an empty layout schedule56 // Create an empty layout schedule
@@ -178,6 +180,19 @@
178 // For each layout in the schedule determine if it is currently inside the _currentSchedule, and whether it should be180 // For each layout in the schedule determine if it is currently inside the _currentSchedule, and whether it should be
179 foreach (LayoutSchedule layout in _layoutSchedule)181 foreach (LayoutSchedule layout in _layoutSchedule)
180 {182 {
183 // Is the layout valid in the cachemanager?
184 try
185 {
186 if (!_cacheManager.IsValidLayout(layout.id + ".xlf"))
187 continue;
188 }
189 catch
190 {
191 // TODO: Ignore this layout.. raise an error?
192 Trace.WriteLine("Unable to determine if layout is valid or not");
193 continue;
194 }
195
181 // If this is the default, skip it196 // If this is the default, skip it
182 if (layout.NodeName == "default")197 if (layout.NodeName == "default")
183 {198 {
184199
=== modified file 'client/dotNET/Web References/xmds/Reference.cs'
--- client/dotNET/Web References/xmds/Reference.cs 2010-11-09 21:23:31 +0000
+++ client/dotNET/Web References/xmds/Reference.cs 2011-02-28 15:09:32 +0000
@@ -45,6 +45,8 @@
45 45
46 private System.Threading.SendOrPostCallback SubmitStatsOperationCompleted;46 private System.Threading.SendOrPostCallback SubmitStatsOperationCompleted;
47 47
48 private System.Threading.SendOrPostCallback MediaInventoryOperationCompleted;
49
48 private bool useDefaultCredentialsSetExplicitly;50 private bool useDefaultCredentialsSetExplicitly;
49 51
50 /// <remarks/>52 /// <remarks/>
@@ -108,6 +110,9 @@
108 public event SubmitStatsCompletedEventHandler SubmitStatsCompleted;110 public event SubmitStatsCompletedEventHandler SubmitStatsCompleted;
109 111
110 /// <remarks/>112 /// <remarks/>
113 public event MediaInventoryCompletedEventHandler MediaInventoryCompleted;
114
115 /// <remarks/>
111 [System.Web.Services.Protocols.SoapRpcMethodAttribute("urn:xmds#RegisterDisplay", RequestNamespace="urn:xmds", ResponseNamespace="urn:xmds")]116 [System.Web.Services.Protocols.SoapRpcMethodAttribute("urn:xmds#RegisterDisplay", RequestNamespace="urn:xmds", ResponseNamespace="urn:xmds")]
112 [return: System.Xml.Serialization.SoapElementAttribute("ActivationMessage")]117 [return: System.Xml.Serialization.SoapElementAttribute("ActivationMessage")]
113 public string RegisterDisplay(string serverKey, string hardwareKey, string displayName, string version) {118 public string RegisterDisplay(string serverKey, string hardwareKey, string displayName, string version) {
@@ -402,6 +407,42 @@
402 }407 }
403 408
404 /// <remarks/>409 /// <remarks/>
410 [System.Web.Services.Protocols.SoapRpcMethodAttribute("urn:xmds#MediaInventory", RequestNamespace="urn:xmds", ResponseNamespace="urn:xmds")]
411 [return: System.Xml.Serialization.SoapElementAttribute("success")]
412 public bool MediaInventory(string version, string serverKey, string hardwareKey, [System.Xml.Serialization.SoapElementAttribute("mediaInventory")] string mediaInventory1) {
413 object[] results = this.Invoke("MediaInventory", new object[] {
414 version,
415 serverKey,
416 hardwareKey,
417 mediaInventory1});
418 return ((bool)(results[0]));
419 }
420
421 /// <remarks/>
422 public void MediaInventoryAsync(string version, string serverKey, string hardwareKey, string mediaInventory1) {
423 this.MediaInventoryAsync(version, serverKey, hardwareKey, mediaInventory1, null);
424 }
425
426 /// <remarks/>
427 public void MediaInventoryAsync(string version, string serverKey, string hardwareKey, string mediaInventory1, object userState) {
428 if ((this.MediaInventoryOperationCompleted == null)) {
429 this.MediaInventoryOperationCompleted = new System.Threading.SendOrPostCallback(this.OnMediaInventoryOperationCompleted);
430 }
431 this.InvokeAsync("MediaInventory", new object[] {
432 version,
433 serverKey,
434 hardwareKey,
435 mediaInventory1}, this.MediaInventoryOperationCompleted, userState);
436 }
437
438 private void OnMediaInventoryOperationCompleted(object arg) {
439 if ((this.MediaInventoryCompleted != null)) {
440 System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
441 this.MediaInventoryCompleted(this, new MediaInventoryCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
442 }
443 }
444
445 /// <remarks/>
405 public new void CancelAsync(object userState) {446 public new void CancelAsync(object userState) {
406 base.CancelAsync(userState);447 base.CancelAsync(userState);
407 }448 }
@@ -627,6 +668,32 @@
627 }668 }
628 }669 }
629 }670 }
671
672 /// <remarks/>
673 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4927")]
674 public delegate void MediaInventoryCompletedEventHandler(object sender, MediaInventoryCompletedEventArgs e);
675
676 /// <remarks/>
677 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4927")]
678 [System.Diagnostics.DebuggerStepThroughAttribute()]
679 [System.ComponentModel.DesignerCategoryAttribute("code")]
680 public partial class MediaInventoryCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
681
682 private object[] results;
683
684 internal MediaInventoryCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
685 base(exception, cancelled, userState) {
686 this.results = results;
687 }
688
689 /// <remarks/>
690 public bool Result {
691 get {
692 this.RaiseExceptionIfNecessary();
693 return ((bool)(this.results[0]));
694 }
695 }
696 }
630}697}
631698
632#pragma warning restore 1591699#pragma warning restore 1591
633\ No newline at end of file700\ No newline at end of file
634701
=== modified file 'client/dotNET/Web References/xmds/xmds.wsdl'
--- client/dotNET/Web References/xmds/xmds.wsdl 2010-11-09 21:23:31 +0000
+++ client/dotNET/Web References/xmds/xmds.wsdl 2011-02-28 15:09:32 +0000
@@ -81,6 +81,15 @@
81 <wsdl:message name="SubmitStatsResponse">81 <wsdl:message name="SubmitStatsResponse">
82 <wsdl:part name="success" type="xsd:boolean" />82 <wsdl:part name="success" type="xsd:boolean" />
83 </wsdl:message>83 </wsdl:message>
84 <wsdl:message name="MediaInventoryRequest">
85 <wsdl:part name="version" type="xsd:string" />
86 <wsdl:part name="serverKey" type="xsd:string" />
87 <wsdl:part name="hardwareKey" type="xsd:string" />
88 <wsdl:part name="mediaInventory" type="xsd:string" />
89 </wsdl:message>
90 <wsdl:message name="MediaInventoryResponse">
91 <wsdl:part name="success" type="xsd:boolean" />
92 </wsdl:message>
84 <wsdl:portType name="xmdsPortType">93 <wsdl:portType name="xmdsPortType">
85 <wsdl:operation name="RegisterDisplay">94 <wsdl:operation name="RegisterDisplay">
86 <documentation>Registered the Display on the Xibo Network</documentation>95 <documentation>Registered the Display on the Xibo Network</documentation>
@@ -122,6 +131,11 @@
122 <wsdl:input message="tns:SubmitStatsRequest" />131 <wsdl:input message="tns:SubmitStatsRequest" />
123 <wsdl:output message="tns:SubmitStatsResponse" />132 <wsdl:output message="tns:SubmitStatsResponse" />
124 </wsdl:operation>133 </wsdl:operation>
134 <wsdl:operation name="MediaInventory">
135 <documentation>Report back the clients MediaInventory</documentation>
136 <wsdl:input message="tns:MediaInventoryRequest" />
137 <wsdl:output message="tns:MediaInventoryResponse" />
138 </wsdl:operation>
125 </wsdl:portType>139 </wsdl:portType>
126 <wsdl:binding name="xmdsBinding" type="tns:xmdsPortType">140 <wsdl:binding name="xmdsBinding" type="tns:xmdsPortType">
127 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />141 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />
@@ -197,6 +211,15 @@
197 <soap:body use="encoded" namespace="urn:xmds" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />211 <soap:body use="encoded" namespace="urn:xmds" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
198 </wsdl:output>212 </wsdl:output>
199 </wsdl:operation>213 </wsdl:operation>
214 <wsdl:operation name="MediaInventory">
215 <soap:operation soapAction="urn:xmds#MediaInventory" style="rpc" />
216 <wsdl:input>
217 <soap:body use="encoded" namespace="urn:xmds" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
218 </wsdl:input>
219 <wsdl:output>
220 <soap:body use="encoded" namespace="urn:xmds" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
221 </wsdl:output>
222 </wsdl:operation>
200 </wsdl:binding>223 </wsdl:binding>
201 <wsdl:service name="xmds">224 <wsdl:service name="xmds">
202 <wsdl:port name="xmdsPort" binding="tns:xmdsBinding">225 <wsdl:port name="xmdsPort" binding="tns:xmdsBinding">
203226
=== modified file 'client/dotNET/XiboClient.csproj'
--- client/dotNET/XiboClient.csproj 2011-02-09 17:15:43 +0000
+++ client/dotNET/XiboClient.csproj 2011-02-28 15:09:32 +0000
@@ -161,6 +161,7 @@
161 <Compile Include="Region.cs">161 <Compile Include="Region.cs">
162 <SubType>Component</SubType>162 <SubType>Component</SubType>
163 </Compile>163 </Compile>
164 <Compile Include="RequiredFiles.cs" />
164 <Compile Include="Rss.cs">165 <Compile Include="Rss.cs">
165 <SubType>Form</SubType>166 <SubType>Form</SubType>
166 </Compile>167 </Compile>
167168
=== modified file 'client/dotNET/app.config'
--- client/dotNET/app.config 2011-02-14 16:21:56 +0000
+++ client/dotNET/app.config 2011-02-28 15:09:32 +0000
@@ -79,6 +79,9 @@
79 <setting name="emptyLayoutDuration" serializeAs="String">79 <setting name="emptyLayoutDuration" serializeAs="String">
80 <value>10</value>80 <value>10</value>
81 </setting>81 </setting>
82 <setting name="RequiredFilesFile" serializeAs="String">
83 <value>requiredFiles.xml</value>
84 </setting>
82 </XiboClient.Properties.Settings>85 </XiboClient.Properties.Settings>
83 </userSettings>86 </userSettings>
84 <applicationSettings>87 <applicationSettings>
@@ -102,7 +105,7 @@
102 <value>cacheManager.xml</value>105 <value>cacheManager.xml</value>
103 </setting>106 </setting>
104 <setting name="ClientVersion" serializeAs="String">107 <setting name="ClientVersion" serializeAs="String">
105 <value>1.2.1</value>108 <value>1.2.2</value>
106 </setting>109 </setting>
107 <setting name="xmdsResetTimeout" serializeAs="String">110 <setting name="xmdsResetTimeout" serializeAs="String">
108 <value>900</value>111 <value>900</value>
109112
=== modified file 'client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll'
110Binary files client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll 2010-04-19 21:45:10 +0000 and client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll 2011-02-28 15:09:32 +0000 differ113Binary files client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll 2010-04-19 21:45:10 +0000 and client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll 2011-02-28 15:09:32 +0000 differ
=== modified file 'client/dotNET/bin/Release/AxInterop.WMPLib.dll'
111Binary files client/dotNET/bin/Release/AxInterop.WMPLib.dll 2010-04-19 21:45:10 +0000 and client/dotNET/bin/Release/AxInterop.WMPLib.dll 2011-02-28 15:09:32 +0000 differ114Binary files client/dotNET/bin/Release/AxInterop.WMPLib.dll 2010-04-19 21:45:10 +0000 and client/dotNET/bin/Release/AxInterop.WMPLib.dll 2011-02-28 15:09:32 +0000 differ
=== modified file 'client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll'
112Binary files client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll 2010-04-19 21:45:10 +0000 and client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll 2011-02-28 15:09:32 +0000 differ115Binary files client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll 2010-04-19 21:45:10 +0000 and client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll 2011-02-28 15:09:32 +0000 differ
=== modified file 'client/dotNET/bin/Release/Interop.WMPLib.dll'
113Binary files client/dotNET/bin/Release/Interop.WMPLib.dll 2010-04-19 21:45:10 +0000 and client/dotNET/bin/Release/Interop.WMPLib.dll 2011-02-28 15:09:32 +0000 differ116Binary files client/dotNET/bin/Release/Interop.WMPLib.dll 2010-04-19 21:45:10 +0000 and client/dotNET/bin/Release/Interop.WMPLib.dll 2011-02-28 15:09:32 +0000 differ
=== modified file 'client/dotNET/bin/Release/XiboClient.exe.config'
--- client/dotNET/bin/Release/XiboClient.exe.config 2011-02-14 16:21:56 +0000
+++ client/dotNET/bin/Release/XiboClient.exe.config 2011-02-28 15:09:32 +0000
@@ -79,6 +79,9 @@
79 <setting name="emptyLayoutDuration" serializeAs="String">79 <setting name="emptyLayoutDuration" serializeAs="String">
80 <value>10</value>80 <value>10</value>
81 </setting>81 </setting>
82 <setting name="RequiredFilesFile" serializeAs="String">
83 <value>requiredFiles.xml</value>
84 </setting>
82 </XiboClient.Properties.Settings>85 </XiboClient.Properties.Settings>
83 </userSettings>86 </userSettings>
84 <applicationSettings>87 <applicationSettings>
@@ -102,7 +105,7 @@
102 <value>cacheManager.xml</value>105 <value>cacheManager.xml</value>
103 </setting>106 </setting>
104 <setting name="ClientVersion" serializeAs="String">107 <setting name="ClientVersion" serializeAs="String">
105 <value>1.2.1</value>108 <value>1.2.2</value>
106 </setting>109 </setting>
107 <setting name="xmdsResetTimeout" serializeAs="String">110 <setting name="xmdsResetTimeout" serializeAs="String">
108 <value>900</value>111 <value>900</value>
109112
=== modified file 'client/dotNET/bin/Release/XiboClient.vshost.exe.config'
--- client/dotNET/bin/Release/XiboClient.vshost.exe.config 2011-02-14 16:21:56 +0000
+++ client/dotNET/bin/Release/XiboClient.vshost.exe.config 2011-02-28 15:09:32 +0000
@@ -79,6 +79,9 @@
79 <setting name="emptyLayoutDuration" serializeAs="String">79 <setting name="emptyLayoutDuration" serializeAs="String">
80 <value>10</value>80 <value>10</value>
81 </setting>81 </setting>
82 <setting name="RequiredFilesFile" serializeAs="String">
83 <value>requiredFiles.xml</value>
84 </setting>
82 </XiboClient.Properties.Settings>85 </XiboClient.Properties.Settings>
83 </userSettings>86 </userSettings>
84 <applicationSettings>87 <applicationSettings>
@@ -102,7 +105,7 @@
102 <value>cacheManager.xml</value>105 <value>cacheManager.xml</value>
103 </setting>106 </setting>
104 <setting name="ClientVersion" serializeAs="String">107 <setting name="ClientVersion" serializeAs="String">
105 <value>1.2.1</value>108 <value>1.2.2</value>
106 </setting>109 </setting>
107 <setting name="xmdsResetTimeout" serializeAs="String">110 <setting name="xmdsResetTimeout" serializeAs="String">
108 <value>900</value>111 <value>900</value>
109112
=== added file 'server/install/database/27.sql'
--- server/install/database/27.sql 1970-01-01 00:00:00 +0000
+++ server/install/database/27.sql 2011-02-28 15:09:32 +0000
@@ -0,0 +1,9 @@
1
2ALTER TABLE `display` ADD `MediaInventoryStatus` TINYINT NOT NULL ,
3ADD `MediaInventoryXml` LONGTEXT NULL;
4
5/* VERSION UPDATE */
6/* Set the version table, etc */
7UPDATE `version` SET `app_ver` = '1.2.2-pre', `XmdsVersion` = 2;
8UPDATE `setting` SET `value` = 0 WHERE `setting` = 'PHONE_HOME_DATE';
9UPDATE `version` SET `DBVersion` = '27';
0\ No newline at end of file10\ No newline at end of file
111
=== modified file 'server/lib/app/kit.class.php'
--- server/lib/app/kit.class.php 2010-12-01 14:49:39 +0000
+++ server/lib/app/kit.class.php 2011-02-28 15:09:32 +0000
@@ -376,9 +376,7 @@
376 static function ClassLoader($class)376 static function ClassLoader($class)
377 {377 {
378 if (class_exists($class))378 if (class_exists($class))
379 {379 return;
380 return true;
381 }
382380
383 $class = strtolower($class);381 $class = strtolower($class);
384382
@@ -387,28 +385,26 @@
387 {385 {
388 include_once('lib/pages/' . $class . '.class.php');386 include_once('lib/pages/' . $class . '.class.php');
389 }387 }
390 elseif (file_exists('lib/data/' . $class . '.data.class.php'))388
389 if (file_exists('lib/data/' . $class . '.data.class.php'))
391 {390 {
392 include_once('lib/data/' . $class . '.data.class.php');391 include_once('lib/data/' . $class . '.data.class.php');
393 }392 }
394 elseif (file_exists('modules/' . $class . '.module.php'))393
394 if (file_exists('modules/' . $class . '.module.php'))
395 {395 {
396 include_once('modules/' . $class . '.module.php');396 include_once('modules/' . $class . '.module.php');
397 }397 }
398 elseif (file_exists('modules/' . $class . '.php'))398
399 if (file_exists('modules/' . $class . '.php'))
399 {400 {
400 include_once('modules/' . $class . '.php');401 include_once('modules/' . $class . '.php');
401 }402 }
402 elseif (file_exists('lib/service/' . $class . '.class.php'))403
404 if (file_exists('lib/service/' . $class . '.class.php'))
403 {405 {
404 include_once('lib/service/' . $class . '.class.php');406 include_once('lib/service/' . $class . '.class.php');
405 }407 }
406 else
407 {
408 return false;
409 }
410
411 return true;
412 }408 }
413409
414 /**410 /**
415411
=== modified file 'server/lib/data/display.data.class.php'
--- server/lib/data/display.data.class.php 2011-02-10 20:42:24 +0000
+++ server/lib/data/display.data.class.php 2011-02-28 15:09:32 +0000
@@ -251,7 +251,7 @@
251 * @return 251 * @return
252 * @param $license Object252 * @param $license Object
253 */253 */
254 public function Touch($license, $clientAddress = '')254 public function Touch($license, $clientAddress = '', $mediaInventoryComplete = 0, $mediaInventoryXml = '')
255 {255 {
256 $db =& $this->db;256 $db =& $this->db;
257 $time = time();257 $time = time();
@@ -266,6 +266,13 @@
266 if ($clientAddress != '')266 if ($clientAddress != '')
267 $SQL .= sprintf(" , ClientAddress = '%s' ", $db->escape_string($clientAddress));267 $SQL .= sprintf(" , ClientAddress = '%s' ", $db->escape_string($clientAddress));
268268
269 // Media Inventory Settings (if appropriate)
270 if ($mediaInventoryComplete != 0)
271 $SQL .= sprintf(" , MediaInventoryStatus = %d ", $mediaInventoryComplete);
272
273 if ($mediaInventoryXml != '')
274 $SQL .= sprintf(" , MediaInventoryXml = '%s' ", $mediaInventoryXml);
275
269 // Restrict to the display license276 // Restrict to the display license
270 $SQL .= " WHERE license = '%s'";277 $SQL .= " WHERE license = '%s'";
271 $SQL = sprintf($SQL, $time, $license);278 $SQL = sprintf($SQL, $time, $license);
@@ -284,31 +291,68 @@
284 }291 }
285292
286 /**293 /**
287 * Edits the default layout for a display294 * Flags a display as being incomplete
288 * @param <type> $displayId295 * @param <type> $displayId
289 * @param <type> $defaultLayoutId
290 * @return <type>
291 */296 */
292 public function EditDefaultLayout($displayId, $defaultLayoutId)297 private function FlagIncomplete($displayId)
293 {298 {
294 $db =& $this->db;299 $db =& $this->db;
295300
296 Debug::LogEntry($db, 'audit', 'IN', 'Display', 'EditDefaultLayout');301 Debug::LogEntry($db, 'audit', sprintf('Flag DisplayID %d incomplete.', $displayId), 'display', 'NotifyDisplays');
297302
298 $SQL = sprintf('UPDATE display SET defaultLayoutId = %d WHERE displayID = %d ', $defaultLayoutId, $displayId);303 $SQL = sprintf("UPDATE display SET MediaInventoryStatus = 3 WHERE displayID = %d", $displayId);
299304
300 if (!$db->query($SQL))305 if (!$db->query($SQL))
301 {306 {
302 trigger_error($db->error());307 trigger_error($db->error());
303 $this->SetError(25012, __('Error updating this displays default layout.'));308 return $this->SetError(25004, 'Unable to Flag Display as incomplete');
304
305 return false;
306 }309 }
307310
308
309 Debug::LogEntry($db, 'audit', 'OUT', 'Display', 'EditDefaultLayout');
310
311 return true;311 return true;
312 }312 }
313
314 /**
315 * Notify displays of this layout change
316 * @param <type> $layoutId
317 */
318 public function NotifyDisplays($layoutId)
319 {
320 $db =& $this->db;
321 $currentdate = time();
322 $rfLookahead = Kit::ValidateParam(Config::GetSetting($db,'REQUIRED_FILES_LOOKAHEAD'), _INT);
323
324 $rfLookahead = $currentdate + $rfLookahead;
325
326 Debug::LogEntry($db, 'audit', sprintf('Checking for Displays to refresh on Layout %d', $layoutId), 'display', 'NotifyDisplays');
327
328 // Which displays does a change to this layout effect?
329 $SQL = " SELECT DISTINCT display.DisplayID ";
330 $SQL .= " FROM schedule_detail ";
331 $SQL .= " INNER JOIN lkdisplaydg ";
332 $SQL .= " ON lkdisplaydg.DisplayGroupID = schedule_detail.DisplayGroupID ";
333 $SQL .= " INNER JOIN display ";
334 $SQL .= " ON lkdisplaydg.DisplayID = display.displayID ";
335 $SQL .= " WHERE schedule_detail.layoutID = %d ";
336 $SQL .= " AND schedule_detail.FromDT < %d AND schedule_detail.ToDT > %d ";
337 $SQL .= " UNION ";
338 $SQL .= " SELECT DisplayID FROM display WHERE DefaultLayoutID = %d";
339
340 $SQL = sprintf($SQL, $layoutId, $rfLookahead, $currentdate - 3600, $layoutId);
341
342 Debug::LogEntry($db, 'audit', $SQL, 'display', 'NotifyDisplays');
343
344 if (!$result = $db->query($SQL))
345 {
346 trigger_error($db->error());
347 return $this->SetError(25037, __('Unable to get layouts for Notify'));
348 }
349
350 while ($row = $db->get_assoc_row($result))
351 {
352 // Notify each display in turn
353 $displayId = Kit::ValidateParam($row['DisplayID'], _INT);
354 $this->FlagIncomplete($displayId);
355 }
356 }
313}357}
314?>358?>
315359
=== modified file 'server/lib/data/schedule.data.class.php'
--- server/lib/data/schedule.data.class.php 2011-02-10 19:46:44 +0000
+++ server/lib/data/schedule.data.class.php 2011-02-28 15:09:32 +0000
@@ -164,6 +164,11 @@
164 }164 }
165 }165 }
166 }166 }
167
168 // Notify (dont error)
169 Kit::ClassLoader('Display');
170 $displayObject = new Display($db);
171 $displayObject->NotifyDisplays($layoutID);
167 172
168 Debug::LogEntry($db, 'audit', 'OUT', 'Schedule', 'Add');173 Debug::LogEntry($db, 'audit', 'OUT', 'Schedule', 'Add');
169 174
170175
=== modified file 'server/lib/pages/display.class.php'
--- server/lib/pages/display.class.php 2011-02-13 17:16:01 +0000
+++ server/lib/pages/display.class.php 2011-02-28 15:09:32 +0000
@@ -37,6 +37,8 @@
37 private $email_alert;37 private $email_alert;
38 private $alert_timeout;38 private $alert_timeout;
39 private $ajax;39 private $ajax;
40 private $mediaInventoryStatus;
41 private $mediaInventoryXml;
4042
41 function __construct(database $db, user $user)43 function __construct(database $db, user $user)
42 {44 {
@@ -71,7 +73,9 @@
71 display.isAuditing,73 display.isAuditing,
72 display.email_alert,74 display.email_alert,
73 display.alert_timeout,75 display.alert_timeout,
74 display.ClientAddress76 display.ClientAddress,
77 display.MediaInventoryStatus,
78 display.MediaInventoryXml
75 FROM display79 FROM display
76 WHERE display.displayid = %d80 WHERE display.displayid = %d
77SQL;81SQL;
@@ -95,8 +99,10 @@
95 $this->licensed = Kit::ValidateParam($row[4], _INT);99 $this->licensed = Kit::ValidateParam($row[4], _INT);
96 $this->inc_schedule = Kit::ValidateParam($row[5], _INT);100 $this->inc_schedule = Kit::ValidateParam($row[5], _INT);
97 $this->auditing = Kit::ValidateParam($row[6], _INT);101 $this->auditing = Kit::ValidateParam($row[6], _INT);
98 $this->email_alert = Kit::ValidateParam($row[7], _INT);102 $this->email_alert = Kit::ValidateParam($row[7], _INT);
99 $this->alert_timeout = Kit::ValidateParam($row[8], _INT);103 $this->alert_timeout = Kit::ValidateParam($row[8], _INT);
104 $this->mediaInventoryStatus = Kit::ValidateParam($row[9], _INT);
105 $this->mediaInventoryXml = Kit::ValidateParam($row[10], _HTMLSTRING);
100 }106 }
101 }107 }
102108
@@ -309,7 +315,12 @@
309 CASE WHEN display.licensed = 1 THEN '<img src="img/act.gif">' ELSE '<img src="img/disact.gif">' END AS licensed,315 CASE WHEN display.licensed = 1 THEN '<img src="img/act.gif">' ELSE '<img src="img/disact.gif">' END AS licensed,
310 CASE WHEN display.email_alert = 1 THEN '<img src="img/act.gif">' ELSE '<img src="img/disact.gif">' END AS email_alert,316 CASE WHEN display.email_alert = 1 THEN '<img src="img/act.gif">' ELSE '<img src="img/disact.gif">' END AS email_alert,
311 displaygroup.DisplayGroupID,317 displaygroup.DisplayGroupID,
312 display.ClientAddress318 display.ClientAddress,
319 CASE WHEN display.MediaInventoryStatus = 1 THEN '<img src="img/act.gif">'
320 WHEN display.MediaInventoryStatus = 2 THEN '<img src="img/warn.gif">'
321 ELSE '<img src="img/disact.gif">'
322 END AS MediaInventoryStatus,
323 display.MediaInventoryXml
313 FROM display324 FROM display
314 INNER JOIN lkdisplaydg ON lkdisplaydg.DisplayID = display.DisplayID325 INNER JOIN lkdisplaydg ON lkdisplaydg.DisplayID = display.DisplayID
315 INNER JOIN displaygroup ON displaygroup.DisplayGroupID = lkdisplaydg.DisplayGroupID326 INNER JOIN displaygroup ON displaygroup.DisplayGroupID = lkdisplaydg.DisplayGroupID
@@ -341,6 +352,8 @@
341 $msgGroupSecurity = __('Group Security');352 $msgGroupSecurity = __('Group Security');
342 $msgClientAddress = __('IP Address');353 $msgClientAddress = __('IP Address');
343 $msgDefault = __('Default Layout');354 $msgDefault = __('Default Layout');
355 $msgStatus = __('Status');
356 $msgMediaInventory = __('Media Inventory');
344357
345 $output = <<<END358 $output = <<<END
346 <div class="info_table">359 <div class="info_table">
@@ -356,6 +369,7 @@
356 <th>$msgLogIn</th>369 <th>$msgLogIn</th>
357 <th>$msgLastA</th>370 <th>$msgLastA</th>
358 <th>$msgClientAddress</th>371 <th>$msgClientAddress</th>
372 <th>$msgStatus</th>
359 <th>$msgAction</th>373 <th>$msgAction</th>
360 </tr>374 </tr>
361 </thead>375 </thead>
@@ -385,6 +399,7 @@
385 // Do we want to make a VNC link out of the display name?399 // Do we want to make a VNC link out of the display name?
386 $vncTemplate = Config::GetSetting($db, 'SHOW_DISPLAY_AS_VNCLINK');400 $vncTemplate = Config::GetSetting($db, 'SHOW_DISPLAY_AS_VNCLINK');
387 $linkTarget = Kit::ValidateParam(Config::GetSetting($db, 'SHOW_DISPLAY_AS_VNC_TGT'), _STRING);401 $linkTarget = Kit::ValidateParam(Config::GetSetting($db, 'SHOW_DISPLAY_AS_VNC_TGT'), _STRING);
402 $mediaInventoryStatusLight = Kit::ValidateParam($aRow[10], _STRING);
388403
389 if ($vncTemplate != '' && $clientAddress != '')404 if ($vncTemplate != '' && $clientAddress != '')
390 {405 {
@@ -424,6 +439,7 @@
424 <td>$loggedin</td>439 <td>$loggedin</td>
425 <td>$lastaccessed</td>440 <td>$lastaccessed</td>
426 <td>$clientAddress</td>441 <td>$clientAddress</td>
442 <td>$mediaInventoryStatusLight</td>
427 <td>$buttons</td>443 <td>$buttons</td>
428END;444END;
429 }445 }
@@ -720,5 +736,59 @@
720 $response->SetFormSubmitResponse(__('Display Saved.'));736 $response->SetFormSubmitResponse(__('Display Saved.'));
721 $response->Respond();737 $response->Respond();
722 }738 }
739
740 /**
741 * Shows the inventory XML for the display
742 */
743 public function MediaInventory()
744 {
745 $db =& $this->db;
746 $response = new ResponseManager();
747 $displayId = Kit::GetParam('DisplayId', _GET, _INT);
748
749 if ($displayId == 0)
750 trigger_error(__('No DisplayId Given'));
751
752 // Get the media inventory xml for this display
753 $SQL = "SELECT MediaInventoryXml FROM display WHERE DisplayId = %d";
754 $SQL = sprintf($SQL, $displayId);
755
756 if (!$mediaInventoryXml = $db->GetSingleValue($SQL, 'MediaInventoryXml', _HTMLSTRING))
757 {
758 trigger_error($db->error());
759 trigger_error(__('Unable to get the Inventory for this Display'), E_USER_ERROR);
760 }
761
762 // Load the XML into a DOMDocument
763 $document = new DOMDocument("1.0");
764
765 if (!$document->loadXML($mediaInventoryXml))
766 trigger_error(__('Invalid Media Inventory'), E_USER_ERROR);
767
768 // Output a table
769 $table = '<table><tr><th>Type</th><th>Id</th><th>Complete</th><th>Last Checked</th><th>MD5</th></tr>';
770
771 foreach ($document->documentElement->childNodes as $node)
772 {
773 $type = $node->getAttribute('type');
774 $id = $node->getAttribute('id');
775 $complete = $node->getAttribute('complete');
776 $lastChecked = $node->getAttribute('lastChecked');
777 $md5 = $node->getAttribute('md5');
778
779 if ($complete == 0)
780 $complete = __('No');
781 else
782 $complete = __('Yes');
783
784 $table .= sprintf('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>', $type, $id, $complete, $lastChecked, $md5);
785 }
786
787 $table .= '</table>';
788
789 $response->SetFormRequestResponse($table, __('Media Inventory'), '550px', '350px');
790 $response->AddButton(__('Close'), 'XiboDialogClose()');
791 $response->Respond();
792 }
723}793}
724?>794?>
725795
=== modified file 'server/lib/pages/layout.class.php'
--- server/lib/pages/layout.class.php 2011-02-10 21:01:27 +0000
+++ server/lib/pages/layout.class.php 2011-02-28 15:09:32 +0000
@@ -427,6 +427,12 @@
427 trigger_error($layoutObject->GetErrorMessage(), E_USER_ERROR);427 trigger_error($layoutObject->GetErrorMessage(), E_USER_ERROR);
428 }428 }
429429
430 // Notify (dont error)
431 Kit::ClassLoader('display');
432 $displayObject = new Display($db);
433 $displayObject->NotifyDisplays($this->layoutid);
434
435
430 $response->SetFormSubmitResponse(__('Layout Details Changed.'));436 $response->SetFormSubmitResponse(__('Layout Details Changed.'));
431 $response->Respond();437 $response->Respond();
432 }438 }
433439
=== modified file 'server/lib/pages/region.class.php'
--- server/lib/pages/region.class.php 2010-05-29 11:16:24 +0000
+++ server/lib/pages/region.class.php 2011-02-28 15:09:32 +0000
@@ -76,6 +76,11 @@
76 $this->errMsg = __("Unable to Update that layouts XML with a new Media Node");76 $this->errMsg = __("Unable to Update that layouts XML with a new Media Node");
77 return false;77 return false;
78 }78 }
79
80 // Notify (dont error)
81 Kit::ClassLoader('display');
82 $displayObject = new Display($db);
83 $displayObject->NotifyDisplays($layoutid);
79 84
80 return true;85 return true;
81 }86 }
8287
=== modified file 'server/lib/service/service.wsdl'
--- server/lib/service/service.wsdl 2010-01-31 00:38:32 +0000
+++ server/lib/service/service.wsdl 2011-02-28 15:09:32 +0000
@@ -80,6 +80,15 @@
80 <message name="SubmitStatsResponse">80 <message name="SubmitStatsResponse">
81 <part name="success" type="xsd:boolean" />81 <part name="success" type="xsd:boolean" />
82 </message>82 </message>
83 <message name="MediaInventoryRequest">
84 <part name="version" type="xsd:string" />
85 <part name="serverKey" type="xsd:string" />
86 <part name="hardwareKey" type="xsd:string" />
87 <part name="mediaInventory" type="xsd:string" />
88 </message>
89 <message name="MediaInventoryResponse">
90 <part name="success" type="xsd:boolean" />
91 </message>
83 <portType name="xmdsPortType">92 <portType name="xmdsPortType">
84 <operation name="RegisterDisplay">93 <operation name="RegisterDisplay">
85 <documentation>Registered the Display on the Xibo Network</documentation>94 <documentation>Registered the Display on the Xibo Network</documentation>
@@ -121,6 +130,11 @@
121 <input message="tns:SubmitStatsRequest"/>130 <input message="tns:SubmitStatsRequest"/>
122 <output message="tns:SubmitStatsResponse"/>131 <output message="tns:SubmitStatsResponse"/>
123 </operation>132 </operation>
133 <operation name="MediaInventory">
134 <documentation>Report back the clients MediaInventory</documentation>
135 <input message="tns:MediaInventoryRequest" />
136 <output message="tns:MediaInventoryResponse" />
137 </operation>
124 </portType>138 </portType>
125 <binding name="xmdsBinding" type="tns:xmdsPortType">139 <binding name="xmdsBinding" type="tns:xmdsPortType">
126 <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>140 <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
@@ -196,6 +210,15 @@
196 <soap:body use="encoded" namespace="urn:xmds" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>210 <soap:body use="encoded" namespace="urn:xmds" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
197 </output>211 </output>
198 </operation>212 </operation>
213 <operation name="MediaInventory">
214 <soap:operation soapAction="urn:xmds#MediaInventory" style="rpc"/>
215 <input>
216 <soap:body use="encoded" namespace="urn:xmds" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
217 </input>
218 <output>
219 <soap:body use="encoded" namespace="urn:xmds" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
220 </output>
221 </operation>
199 </binding>222 </binding>
200 <service name="xmds">223 <service name="xmds">
201 <port name="xmdsPort" binding="tns:xmdsBinding">224 <port name="xmdsPort" binding="tns:xmdsBinding">
202225
=== modified file 'server/lib/service/xmdssoap.class.php'
--- server/lib/service/xmdssoap.class.php 2011-02-07 16:46:09 +0000
+++ server/lib/service/xmdssoap.class.php 2011-02-28 15:09:32 +0000
@@ -848,6 +848,66 @@
848 }848 }
849849
850 /**850 /**
851 * Store the media inventory for a client
852 * @param <type> $hardwareKey
853 * @param <type> $inventory
854 */
855 public function MediaInventory($version, $serverKey, $hardwareKey, $inventory)
856 {
857 $db =& $this->db;
858
859 // Sanitize
860 $serverKey = Kit::ValidateParam($serverKey, _STRING);
861 $hardwareKey = Kit::ValidateParam($hardwareKey, _STRING);
862 $version = Kit::ValidateParam($version, _STRING);
863 $inventory = Kit::ValidateParam($inventory, _HTMLSTRING);
864
865 // Make sure we are talking the same language
866 if (!$this->CheckVersion($version))
867 throw new SoapFault('Receiver', "Your client is not of the correct version for communication with this server. You can get the latest from http://www.xibo.org.uk");
868
869 // Auth this request...
870 if (!$this->AuthDisplay($hardwareKey))
871 throw new SoapFault('Receiver', 'This display client is not licensed');
872
873 if ($this->isAuditing == 1) Debug::LogEntry ($db, 'audit', $inventory, 'xmds', 'MediaInventory', '', $this->displayId);
874
875 // Check that the $inventory contains something
876 if ($inventory == '')
877 throw new SoapFault('Receiver', 'Inventory Cannot be Empty');
878
879 // Load the XML into a DOMDocument
880 $document = new DOMDocument("1.0");
881 $document->loadXML($inventory);
882
883 // Assume we are complete (but we are getting some)
884 $mediaInventoryComplete = 1;
885
886 foreach ($document->documentElement->childNodes as $node)
887 {
888 // Make sure we dont consider any text nodes
889 if ($node->nodeType == XML_TEXT_NODE) continue;
890
891 $mediaId = $node->getAttribute('id');
892 $complete = $node->getAttribute('complete');
893 $md5 = $node->getAttribute('md5');
894 $lastChecked = $node->getAttribute('lastChecked');
895
896 // Check the MD5?
897
898 // If this item is a 0 then set not complete
899 if ($complete == 0)
900 $mediaInventoryComplete = 2;
901 }
902
903 // Touch the display record
904 $displayObject = new Display($db);
905 $displayObject->Touch($hardwareKey, '', $mediaInventoryComplete, $inventory);
906
907 return true;
908 }
909
910 /**
851 * Authenticates the display911 * Authenticates the display
852 * @param <type> $hardwareKey912 * @param <type> $hardwareKey
853 * @return <type>913 * @return <type>

Subscribers

People subscribed via source and target branches