Merge lp:~dangarner/xibo/105-client-test into lp:~xibo-maintainers/xibo/encke

Proposed by Dan Garner
Status: Merged
Merged at revision: not available
Proposed branch: lp:~dangarner/xibo/105-client-test
Merge into: lp:~xibo-maintainers/xibo/encke
Diff against target: 2815 lines (+1840/-276)
25 files modified
client/dotNET/About.cs (+1/-1)
client/dotNET/BlackList.cs (+3/-0)
client/dotNET/CacheManager.cs (+161/-0)
client/dotNET/FileCollector.cs (+286/-38)
client/dotNET/MainForm.cs (+55/-3)
client/dotNET/Properties/Settings.Designer.cs (+22/-4)
client/dotNET/Properties/Settings.settings (+9/-3)
client/dotNET/Region.cs (+81/-57)
client/dotNET/Rss.cs (+97/-11)
client/dotNET/Schedule.cs (+40/-6)
client/dotNET/TemporaryHtml.cs (+217/-106)
client/dotNET/Text.cs (+52/-0)
client/dotNET/Video.cs (+19/-0)
client/dotNET/VideoPlayer.cs (+5/-0)
client/dotNET/Web References/xmds/Reference.cs (+19/-19)
client/dotNET/XiboClient.csproj (+33/-4)
client/dotNET/app.config (+15/-9)
client/dotNET/bin/Release/XiboClient.exe.config (+6/-0)
client/dotNET/bin/Release/XiboClient.vshost.exe.config (+6/-0)
server/install/database/9.sql (+15/-1)
server/lib/pages/content.class.php (+78/-13)
server/lib/pages/stats.class.php (+1/-1)
server/template/pages/dashboard.php (+9/-0)
server/template/pages/login_box.php (+12/-0)
server/upgrade.php.OTHER (+598/-0)
To merge this branch: bzr merge lp:~dangarner/xibo/105-client-test
Reviewer Review Type Date Requested Status
Xibo Maintainters Pending
Review via email: mp+16640@code.launchpad.net
To post a comment you must log in.
lp:~dangarner/xibo/105-client-test updated
91. By Dan Garner

[server] Incorrect case on a column in the stats download
[dotnetclient] Dispose of the WebClient on Rss

92. By Dan Garner

[dotnetclient] Text Scaling improvements - now matches Python Client. Single Layout now expires correctly. RSS Cleans up temporary HTML.

93. By Dan Garner

[dotnetclient] Updated the default settings for new installs.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'client/dotNET/About.cs'
2--- client/dotNET/About.cs 2009-11-29 12:44:35 +0000
3+++ client/dotNET/About.cs 2009-12-31 11:13:17 +0000
4@@ -34,7 +34,7 @@
5 InitializeComponent();
6
7 label1.Text = Application.ProductName;
8- label2.Text = Application.ProductVersion;
9+ label2.Text = Properties.Settings.Default.ClientVersion;
10 }
11
12 private void buttonHelp_Click(object sender, EventArgs e)
13
14=== modified file 'client/dotNET/BlackList.cs'
15--- client/dotNET/BlackList.cs 2009-03-08 11:40:17 +0000
16+++ client/dotNET/BlackList.cs 2009-12-31 11:13:17 +0000
17@@ -23,6 +23,7 @@
18 using System.Text;
19 using System.Xml;
20 using System.Windows.Forms;
21+using System.Diagnostics;
22
23 namespace XiboClient
24 {
25@@ -89,6 +90,8 @@
26 /// <param name="items">The XMLNodeList containing the blacklist items. Each node must have an "id".</param>
27 public void Add(XmlNodeList items)
28 {
29+ Trace.WriteLine(new LogMessage("Blacklist - Add", "Adding XMLNodeList to Blacklist"), LogType.Info.ToString());
30+
31 foreach (XmlNode node in items)
32 {
33 XmlAttributeCollection attributes = node.Attributes;
34
35=== modified file 'client/dotNET/CacheManager.cs'
36--- client/dotNET/CacheManager.cs 2009-11-26 22:01:46 +0000
37+++ client/dotNET/CacheManager.cs 2009-12-31 11:13:17 +0000
38@@ -1,3 +1,4 @@
39+<<<<<<< TREE
40 /*
41 * Xibo - Digitial Signage - http://www.xibo.org.uk
42 * Copyright (C) 2009 Daniel Garner
43@@ -94,3 +95,163 @@
44 public DateTime cacheDate;
45 }
46 }
47+=======
48+/*
49+ * Xibo - Digitial Signage - http://www.xibo.org.uk
50+ * Copyright (C) 2009 Daniel Garner
51+ *
52+ * This file is part of Xibo.
53+ *
54+ * Xibo is free software: you can redistribute it and/or modify
55+ * it under the terms of the GNU Affero General Public License as published by
56+ * the Free Software Foundation, either version 3 of the License, or
57+ * any later version.
58+ *
59+ * Xibo is distributed in the hope that it will be useful,
60+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
61+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62+ * GNU Affero General Public License for more details.
63+ *
64+ * You should have received a copy of the GNU Affero General Public License
65+ * along with Xibo. If not, see <http://www.gnu.org/licenses/>.
66+ */
67+using System;
68+using System.Collections.Generic;
69+using System.Collections.ObjectModel;
70+using System.Text;
71+using System.IO;
72+using System.Windows.Forms;
73+using System.Xml.Serialization;
74+using System.Diagnostics;
75+
76+namespace XiboClient
77+{
78+ public class CacheManager
79+ {
80+ public Collection<Md5Resource> _files;
81+
82+ public CacheManager()
83+ {
84+ _files = new Collection<Md5Resource>();
85+ }
86+
87+ /// <summary>
88+ /// Gets the MD5 for the given path
89+ /// </summary>
90+ /// <param name="path"></param>
91+ /// <returns></returns>
92+ public String GetMD5(String path)
93+ {
94+ // Either we already have the MD5 stored
95+ foreach (Md5Resource file in _files)
96+ {
97+ if (file.path == path)
98+ {
99+ // Check to see if this file has been modified since the MD5 cache
100+ DateTime lastWrite = File.GetLastWriteTime(Properties.Settings.Default.LibraryPath + @"\" + path);
101+
102+ if (lastWrite > file.cacheDate)
103+ {
104+ // Get the MD5 again
105+ return CalcMD5(path);
106+ }
107+
108+ return file.md5;
109+ }
110+ }
111+
112+ return CalcMD5(path);
113+ }
114+
115+ /// <summary>
116+ /// Calculates the MD5 for a path
117+ /// </summary>
118+ /// <param name="path"></param>
119+ /// <returns></returns>
120+ private string CalcMD5(String path)
121+ {
122+ // Open the file and get the MD5
123+ using (FileStream md5Fs = new FileStream(Properties.Settings.Default.LibraryPath + @"\" + path, FileMode.Open, FileAccess.Read))
124+ {
125+ return Hashes.MD5(md5Fs);
126+ }
127+ }
128+
129+ /// <summary>
130+ /// Adds a MD5 to the CacheManager
131+ /// </summary>
132+ /// <param name="path"></param>
133+ /// <param name="md5"></param>
134+ public void Add(String path, String md5)
135+ {
136+ // First check to see if this path is in the collection
137+ foreach (Md5Resource file in _files)
138+ {
139+ if (file.path == path)
140+ return;
141+ }
142+
143+ // We need to generate the MD5 and store it for later
144+ Md5Resource md5Resource = new Md5Resource();
145+
146+ md5Resource.path = path;
147+ md5Resource.md5 = md5;
148+ md5Resource.cacheDate = DateTime.Now;
149+
150+ // Add the resource to the collection
151+ _files.Add(md5Resource);
152+
153+ System.Diagnostics.Debug.WriteLine(new LogMessage("Add", "Adding new MD5 to CacheManager"), LogType.Info.ToString());
154+ }
155+
156+ /// <summary>
157+ /// Removes the MD5 resource associated with the Path given
158+ /// </summary>
159+ /// <param name="path"></param>
160+ public void Remove(String path)
161+ {
162+ // Loop through all MD5s and remove any that match the path
163+ for (int i = 0; i < _files.Count; i++)
164+ {
165+ Md5Resource file = _files[i];
166+
167+ if (file.path == path)
168+ {
169+ _files.Remove(file);
170+
171+ System.Diagnostics.Debug.WriteLine(new LogMessage("Remove", "Removing stale MD5 from the CacheManager"), LogType.Info.ToString());
172+ }
173+ }
174+ }
175+
176+ /// <summary>
177+ /// Writes the CacheManager to disk
178+ /// </summary>
179+ public void WriteCacheManager()
180+ {
181+ Debug.WriteLine(new LogMessage("CacheManager - WriteCacheManager", "About to Write the Cache Manager"), LogType.Info.ToString());
182+
183+ try
184+ {
185+ using (StreamWriter streamWriter = new StreamWriter(Application.UserAppDataPath + "\\" + Properties.Settings.Default.CacheManagerFile))
186+ {
187+ XmlSerializer xmlSerializer = new XmlSerializer(typeof(CacheManager));
188+
189+ xmlSerializer.Serialize(streamWriter, this);
190+ }
191+ }
192+ catch (Exception ex)
193+ {
194+ System.Diagnostics.Trace.WriteLine(new LogMessage("MainForm_FormClosing", "Unable to write CacheManager to disk because: " + ex.Message));
195+ }
196+ }
197+ }
198+
199+ public struct Md5Resource
200+ {
201+ public String md5;
202+ public String path;
203+ public DateTime cacheDate;
204+ }
205+}
206+>>>>>>> MERGE-SOURCE
207
208=== modified file 'client/dotNET/FileCollector.cs'
209--- client/dotNET/FileCollector.cs 2009-11-28 10:39:06 +0000
210+++ client/dotNET/FileCollector.cs 2009-12-31 11:13:17 +0000
211@@ -89,15 +89,34 @@
212 // Does this file exist?
213 if (File.Exists(Properties.Settings.Default.LibraryPath + @"\" + path + ".xlf"))
214 {
215+<<<<<<< TREE
216 // Read the current layout into a string
217 String md5 = _cacheManager.GetMD5(path + ".xlf");
218
219 System.Diagnostics.Debug.WriteLine(String.Format("Comparing current MD5 [{0}] with given MD5 [{1}]", md5, attributes["md5"].Value));
220+=======
221+ // Calculate a MD5 for the current file
222+ String md5 = _cacheManager.GetMD5(path + ".xlf");
223+
224+ System.Diagnostics.Debug.WriteLine(String.Format("Comparing current MD5 [{0}] with given MD5 [{1}]", md5, attributes["md5"].Value));
225+>>>>>>> MERGE-SOURCE
226
227 // Now we have the md5, compare it to the md5 in the xml
228 if (attributes["md5"].Value != md5)
229 {
230- // They are different
231+ // They are different
232+ _cacheManager.Remove(path + ".xlf");
233+
234+ //TODO: This might be bad! Delete the old layout as it is wrong
235+ try
236+ {
237+ File.Delete(Properties.Settings.Default.LibraryPath + @"\" + path + ".xlf");
238+ }
239+ catch (Exception ex)
240+ {
241+ Trace.WriteLine(new LogMessage("CompareAndCollect", "Unable to delete incorrect file because: " + ex.Message));
242+ }
243+
244 // Get the file and save it
245 fileList.chunkOffset = 0;
246 fileList.chunkSize = 0;
247@@ -110,6 +129,12 @@
248
249 files.Add(fileList);
250 }
251+ else
252+ {
253+ // The MD5 of the current file and the MD5 in RequiredFiles are the same.
254+ // Therefore make sure this MD5 is in the CacheManager
255+ _cacheManager.Add(path + ".xlf", md5);
256+ }
257 }
258 else
259 {
260@@ -132,30 +157,76 @@
261 string path = attributes["path"].Value;
262
263 // Does this media exist?
264- if (File.Exists(Properties.Settings.Default.LibraryPath + @"\" + path))
265- {
266- String md5 = _cacheManager.GetMD5(path);
267-
268- System.Diagnostics.Debug.WriteLine(String.Format("Comparing current MD5 [{0}] with given MD5 [{1}]", md5, attributes["md5"].Value));
269-
270- // MD5 the file to make sure it is the same.
271- if (md5 != attributes["md5"].Value)
272- {
273- // File changed
274- fileList.chunkOffset = 0;
275- fileList.chunkSize = 512000;
276- fileList.complete = false;
277- fileList.downloading = false;
278- fileList.path = path;
279- fileList.type = "media";
280- fileList.size = int.Parse(attributes["size"].Value);
281- fileList.md5 = attributes["md5"].Value;
282- fileList.retrys = 0;
283-
284- files.Add(fileList);
285- }
286- }
287- else
288+<<<<<<< TREE
289+ if (File.Exists(Properties.Settings.Default.LibraryPath + @"\" + path))
290+ {
291+ String md5 = _cacheManager.GetMD5(path);
292+
293+ System.Diagnostics.Debug.WriteLine(String.Format("Comparing current MD5 [{0}] with given MD5 [{1}]", md5, attributes["md5"].Value));
294+
295+ // MD5 the file to make sure it is the same.
296+ if (md5 != attributes["md5"].Value)
297+ {
298+ // File changed
299+ fileList.chunkOffset = 0;
300+ fileList.chunkSize = 512000;
301+ fileList.complete = false;
302+ fileList.downloading = false;
303+ fileList.path = path;
304+ fileList.type = "media";
305+ fileList.size = int.Parse(attributes["size"].Value);
306+ fileList.md5 = attributes["md5"].Value;
307+ fileList.retrys = 0;
308+
309+ files.Add(fileList);
310+ }
311+ }
312+ else
313+=======
314+ if (File.Exists(Properties.Settings.Default.LibraryPath + @"\" + path))
315+ {
316+ String md5 = _cacheManager.GetMD5(path);
317+
318+ System.Diagnostics.Debug.WriteLine(String.Format("Comparing current MD5 [{0}] with given MD5 [{1}]", md5, attributes["md5"].Value));
319+
320+ // MD5 the file to make sure it is the same.
321+ if (md5 != attributes["md5"].Value)
322+ {
323+ // File changed
324+ _cacheManager.Remove(path);
325+
326+ // Delete the old media as it is wrong
327+ try
328+ {
329+ File.Delete(Properties.Settings.Default.LibraryPath + @"\" + path);
330+ }
331+ catch (Exception ex)
332+ {
333+ Trace.WriteLine(new LogMessage("CompareAndCollect", "Unable to delete incorrect file because: " + ex.Message));
334+ }
335+
336+ // Add to queue
337+ fileList.chunkOffset = 0;
338+ fileList.chunkSize = 512000;
339+ fileList.complete = false;
340+ fileList.downloading = false;
341+ fileList.path = path;
342+ fileList.type = "media";
343+ fileList.size = int.Parse(attributes["size"].Value);
344+ fileList.md5 = attributes["md5"].Value;
345+ fileList.retrys = 0;
346+
347+ files.Add(fileList);
348+ }
349+ else
350+ {
351+ // The MD5 of the current file and the MD5 in RequiredFiles are the same.
352+ // Therefore make sure this MD5 is in the CacheManager
353+ _cacheManager.Add(path, md5);
354+ }
355+ }
356+ else
357+>>>>>>> MERGE-SOURCE
358 {
359 // No - Get it (async call - with chunks... through another class?)
360 fileList.chunkOffset = 0;
361@@ -218,6 +289,7 @@
362
363 void xmdsFile_GetFileCompleted(object sender, XiboClient.xmds.GetFileCompletedEventArgs e)
364 {
365+<<<<<<< TREE
366 try
367 {
368 // Expect new schedule XML
369@@ -363,19 +435,195 @@
370
371 // Before we get the next file render any waiting events
372 System.Windows.Forms.Application.DoEvents();
373- }
374- }
375- catch (Exception ex)
376- {
377- Trace.WriteLine(new LogMessage("xmdsFile_GetFileCompleted", "Unable to get the file. Exception: " + ex.Message));
378-
379- // Consider this file complete because we couldn't write it....
380- _currentFileList.complete = true;
381- _currentFile++;
382- }
383-
384- // Get the next file
385- GetFile();
386+=======
387+ try
388+ {
389+ // Expect new schedule XML
390+ if (e.Error != null)
391+ {
392+ //There was an error - what do we do?
393+ // Log it
394+ System.Diagnostics.Debug.WriteLine(e.Error.Message, "WS Error");
395+
396+ System.Diagnostics.Trace.WriteLine(String.Format("Error From WebService Get File. File=[{1}], Error=[{0}], Try No [{2}]", e.Error.Message, _currentFileList.path, _currentFileList.retrys));
397+
398+ // Retry?
399+ //TODO: What if we are disconnected from XMDS?
400+ if (_currentFileList.retrys < 5)
401+ {
402+ // Increment the Retrys
403+ _currentFileList.retrys++;
404+
405+ // Try again
406+ GetFile();
407+ }
408+ else
409+ {
410+ // Blacklist this file
411+ string[] mediaPath = _currentFileList.path.Split('.');
412+ string mediaId = mediaPath[0];
413+
414+ BlackList blackList = new BlackList();
415+ blackList.Add(_currentFileList.path, BlackListType.All, String.Format("Max number of retrys failed. BlackListing for all displays. Error {0}", e.Error.Message));
416+
417+ // Move on
418+ _currentFile++;
419+ }
420+ }
421+ else
422+ {
423+ // Set the flag to indicate we have a connection to XMDS
424+ Properties.Settings.Default.XmdsLastConnection = DateTime.Now;
425+
426+ // What file type were we getting
427+ if (_currentFileList.type == "layout")
428+ {
429+ // Decode this byte[] into a string and stick it in the file.
430+ string layoutXml = Encoding.UTF8.GetString(e.Result);
431+
432+
433+ // We know it is finished and that we need to write to a file
434+ try
435+ {
436+ string fullPath = Properties.Settings.Default.LibraryPath + @"\" + _currentFileList.path + ".xlf";
437+
438+ StreamWriter sw = new StreamWriter(File.Open(fullPath, FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.Default);
439+ sw.Write(layoutXml);
440+ sw.Close();
441+
442+ // This file is complete
443+ _currentFileList.complete = true;
444+ }
445+ catch (IOException ex)
446+ {
447+ //What do we do if we cant open the file stream?
448+ System.Diagnostics.Debug.WriteLine(ex.Message, "FileCollector - GetFileCompleted");
449+ }
450+
451+ // Check it
452+ String md5sum = _cacheManager.GetMD5(_currentFileList.path + ".xlf");
453+
454+ System.Diagnostics.Debug.WriteLine(String.Format("Comparing MD5 of completed download [{0}] with given MD5 [{1}]", md5sum, _currentFileList.md5));
455+
456+ // TODO: What if the MD5 is different?
457+ if (md5sum != _currentFileList.md5)
458+ {
459+ // Error
460+ System.Diagnostics.Trace.WriteLine(new LogMessage("xmdsFile_GetFileCompleted", String.Format("Incorrect MD5 for file: {0}", _currentFileList.path)));
461+ }
462+ else
463+ {
464+ // Add to the CacheManager
465+ _cacheManager.Add(_currentFileList.path + ".xlf", md5sum);
466+ }
467+
468+ // Fire a layout complete event
469+ LayoutFileChanged(_currentFileList.path + ".xlf");
470+
471+ System.Diagnostics.Trace.WriteLine(String.Format("File downloaded: {0}", _currentFileList.path), "xmdsFile_GetFileCompleted");
472+
473+ _currentFile++;
474+ }
475+ else
476+ {
477+ // Need to write to the file - in append mode
478+ FileStream fs = new FileStream(Properties.Settings.Default.LibraryPath + @"\" + _currentFileList.path, FileMode.Append, FileAccess.Write);
479+
480+ fs.Write(e.Result, 0, e.Result.Length);
481+ fs.Close();
482+ fs.Dispose();
483+
484+ // Increment the chunkOffset by the amount we just asked for
485+ _currentFileList.chunkOffset = _currentFileList.chunkOffset + _currentFileList.chunkSize;
486+
487+ // Has the offset reached the total size?
488+ if (_currentFileList.size > _currentFileList.chunkOffset)
489+ {
490+ int remaining = _currentFileList.size - _currentFileList.chunkOffset;
491+ // There is still more to come
492+ if (remaining < _currentFileList.chunkSize)
493+ {
494+ // Get the remaining
495+ _currentFileList.chunkSize = remaining;
496+ }
497+ }
498+ else
499+ {
500+ String md5sum = _cacheManager.GetMD5(_currentFileList.path);
501+
502+ System.Diagnostics.Debug.WriteLine(String.Format("Comparing MD5 of completed download [{0}] with given MD5 [{1}]", md5sum, _currentFileList.md5));
503+
504+ if (md5sum != _currentFileList.md5)
505+ {
506+ // We need to get this file again
507+ try
508+ {
509+ File.Delete(Properties.Settings.Default.LibraryPath + @"\" + _currentFileList.path);
510+ }
511+ catch (Exception ex)
512+ {
513+ // Unable to delete incorrect file
514+ //TODO: Should we black list this file?
515+ System.Diagnostics.Debug.WriteLine(ex.Message);
516+ }
517+
518+ // Reset the chunk offset (otherwise we will try to get this file again - but from the beginning (no so good)
519+ _currentFileList.chunkOffset = 0;
520+
521+ System.Diagnostics.Trace.WriteLine(String.Format("Error getting file {0}, HASH failed. Starting again", _currentFileList.path));
522+ }
523+ else
524+ {
525+ // Add the MD5 to the CacheManager
526+ _cacheManager.Add(_currentFileList.path, md5sum);
527+
528+ // This file is complete
529+ _currentFileList.complete = true;
530+
531+ // Fire the File Complete event
532+ MediaFileChanged(_currentFileList.path);
533+
534+ System.Diagnostics.Debug.WriteLine(string.Format("File downloaded: {0}", _currentFileList.path));
535+
536+ // All the file has been recieved. Move on to the next file.
537+ _currentFile++;
538+ }
539+ }
540+ }
541+
542+ // Before we get the next file render any waiting events
543+ System.Windows.Forms.Application.DoEvents();
544+>>>>>>> MERGE-SOURCE
545+ }
546+<<<<<<< TREE
547+ }
548+ catch (Exception ex)
549+ {
550+ Trace.WriteLine(new LogMessage("xmdsFile_GetFileCompleted", "Unable to get the file. Exception: " + ex.Message));
551+
552+ // Consider this file complete because we couldn't write it....
553+ _currentFileList.complete = true;
554+ _currentFile++;
555+ }
556+
557+ // Get the next file
558+ GetFile();
559+=======
560+ }
561+ catch (Exception ex)
562+ {
563+ Trace.WriteLine(new LogMessage("xmdsFile_GetFileCompleted", "Unable to get the file. Exception: " + ex.Message));
564+
565+ // TODO: Blacklist the file?
566+
567+ // Consider this file complete because we couldn't write it....
568+ _currentFileList.complete = true;
569+ _currentFile++;
570+ }
571+
572+ // Get the next file
573+ GetFile();
574+>>>>>>> MERGE-SOURCE
575 }
576
577 /// <summary>
578
579=== modified file 'client/dotNET/MainForm.cs'
580--- client/dotNET/MainForm.cs 2009-11-02 21:13:29 +0000
581+++ client/dotNET/MainForm.cs 2009-12-31 11:13:17 +0000
582@@ -29,7 +29,13 @@
583 using System.Xml;
584 using System.Net;
585 using System.IO;
586-using System.Drawing.Imaging;
587+<<<<<<< TREE
588+using System.Drawing.Imaging;
589+=======
590+using System.Drawing.Imaging;
591+using System.Xml.Serialization;
592+using System.Diagnostics;
593+>>>>>>> MERGE-SOURCE
594
595 namespace XiboClient
596 {
597@@ -47,12 +53,17 @@
598
599 private StatLog _statLog;
600 private Stat _stat;
601+ private CacheManager _cacheManager;
602
603 public MainForm()
604 {
605 InitializeComponent();
606
607 _statLog = new StatLog();
608+
609+ SetCacheManager();
610+
611+ this.FormClosing += new FormClosingEventHandler(MainForm_FormClosing);
612 }
613
614 private void MainForm_Load(object sender, EventArgs e)
615@@ -76,8 +87,11 @@
616 // Change the default Proxy class
617 OptionForm.SetGlobalProxy();
618
619+ // UserApp data
620+ Debug.WriteLine(new LogMessage("MainForm_Load", "User AppData Path: " + Application.UserAppDataPath), LogType.Info.ToString());
621+
622 // Create the Schedule
623- schedule = new Schedule(Application.UserAppDataPath + "\\" + Properties.Settings.Default.ScheduleFile);
624+ schedule = new Schedule(Application.UserAppDataPath + "\\" + Properties.Settings.Default.ScheduleFile, ref _cacheManager);
625
626 schedule.ScheduleChangeEvent += new Schedule.ScheduleChangeDelegate(schedule_ScheduleChangeEvent);
627
628@@ -94,6 +108,44 @@
629 }
630 }
631
632+
633+ private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
634+ {
635+ // We want to tidy up some stuff as this form closes.
636+
637+ // Flush the stats
638+ _statLog.Flush();
639+
640+ // Write the CacheManager to disk
641+ _cacheManager.WriteCacheManager();
642+
643+ // Flush the logs
644+ System.Diagnostics.Trace.Flush();
645+ }
646+
647+ /// <summary>
648+ /// Sets the CacheManager
649+ /// </summary>
650+ private void SetCacheManager()
651+ {
652+ try
653+ {
654+ using (FileStream fileStream = File.Open(Application.UserAppDataPath + "\\" + Properties.Settings.Default.CacheManagerFile, FileMode.Open))
655+ {
656+ XmlSerializer xmlSerializer = new XmlSerializer(typeof(CacheManager));
657+
658+ _cacheManager = (CacheManager)xmlSerializer.Deserialize(fileStream);
659+ }
660+ }
661+ catch (Exception ex)
662+ {
663+ Trace.WriteLine(new LogMessage("Schedule", "Unable to reuse the Cache Manager because: " + ex.Message));
664+
665+ // Create a new cache manager
666+ _cacheManager = new CacheManager();
667+ }
668+ }
669+
670 /// <summary>
671 /// Handles the ScheduleChange event
672 /// </summary>
673@@ -373,7 +425,7 @@
674 }
675 }
676
677- if (isExpired && (schedule.ActiveLayouts > 1))
678+ if (isExpired)
679 {
680 // Inform each region that the layout containing it has expired
681 foreach (Region temp in regions)
682
683=== modified file 'client/dotNET/Properties/Settings.Designer.cs'
684--- client/dotNET/Properties/Settings.Designer.cs 2009-11-02 22:27:17 +0000
685+++ client/dotNET/Properties/Settings.Designer.cs 2009-12-31 11:13:18 +0000
686@@ -12,7 +12,7 @@
687
688
689 [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
690- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
691+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
692 internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
693
694 private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
695@@ -47,7 +47,7 @@
696 [global::System.Configuration.UserScopedSettingAttribute()]
697 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
698 [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.WebServiceUrl)]
699- [global::System.Configuration.DefaultSettingValueAttribute("http://localhost/1.0.0/server/xmds.php")]
700+ [global::System.Configuration.DefaultSettingValueAttribute("http://localhost/xibo/xmds.php")]
701 public string XiboClient_xmds_xmds {
702 get {
703 return ((string)(this["XiboClient_xmds_xmds"]));
704@@ -59,7 +59,7 @@
705
706 [global::System.Configuration.UserScopedSettingAttribute()]
707 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
708- [global::System.Configuration.DefaultSettingValueAttribute("changetocustomerkey")]
709+ [global::System.Configuration.DefaultSettingValueAttribute("yourserverkey")]
710 public string ServerKey {
711 get {
712 return ((string)(this["ServerKey"]));
713@@ -128,7 +128,7 @@
714
715 [global::System.Configuration.UserScopedSettingAttribute()]
716 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
717- [global::System.Configuration.DefaultSettingValueAttribute("https://www.xibo.co.uk/changetocustomersite")]
718+ [global::System.Configuration.DefaultSettingValueAttribute("http://localhost/xibo")]
719 public string serverURI {
720 get {
721 return ((string)(this["serverURI"]));
722@@ -259,5 +259,23 @@
723 this["collectInterval"] = value;
724 }
725 }
726+
727+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
728+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
729+ [global::System.Configuration.DefaultSettingValueAttribute("cacheManager.xml")]
730+ public string CacheManagerFile {
731+ get {
732+ return ((string)(this["CacheManagerFile"]));
733+ }
734+ }
735+
736+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
737+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
738+ [global::System.Configuration.DefaultSettingValueAttribute("1.0.5")]
739+ public string ClientVersion {
740+ get {
741+ return ((string)(this["ClientVersion"]));
742+ }
743+ }
744 }
745 }
746
747=== modified file 'client/dotNET/Properties/Settings.settings'
748--- client/dotNET/Properties/Settings.settings 2009-07-30 23:01:31 +0000
749+++ client/dotNET/Properties/Settings.settings 2009-12-31 11:13:18 +0000
750@@ -9,10 +9,10 @@
751 <Value Profile="(Default)">schedule.xml</Value>
752 </Setting>
753 <Setting Name="XiboClient_xmds_xmds" Type="(Web Service URL)" Scope="User">
754- <Value Profile="(Default)">http://localhost/1.0.0/server/xmds.php</Value>
755+ <Value Profile="(Default)">http://localhost/xibo/xmds.php</Value>
756 </Setting>
757 <Setting Name="ServerKey" Type="System.String" Scope="User">
758- <Value Profile="(Default)">changetocustomerkey</Value>
759+ <Value Profile="(Default)">yourserverkey</Value>
760 </Setting>
761 <Setting Name="displayName" Type="System.String" Scope="User">
762 <Value Profile="(Default)">COMPUTERNAME</Value>
763@@ -30,7 +30,7 @@
764 <Value Profile="(Default)">True</Value>
765 </Setting>
766 <Setting Name="serverURI" Type="System.String" Scope="User">
767- <Value Profile="(Default)">https://www.xibo.co.uk/changetocustomersite</Value>
768+ <Value Profile="(Default)">http://localhost/xibo</Value>
769 </Setting>
770 <Setting Name="ProxyUser" Type="System.String" Scope="User">
771 <Value Profile="(Default)" />
772@@ -65,5 +65,11 @@
773 <Setting Name="collectInterval" Type="System.Decimal" Scope="User">
774 <Value Profile="(Default)">900</Value>
775 </Setting>
776+ <Setting Name="CacheManagerFile" Type="System.String" Scope="Application">
777+ <Value Profile="(Default)">cacheManager.xml</Value>
778+ </Setting>
779+ <Setting Name="ClientVersion" Type="System.String" Scope="Application">
780+ <Value Profile="(Default)">1.0.5</Value>
781+ </Setting>
782 </Settings>
783 </SettingsFile>
784\ No newline at end of file
785
786=== modified file 'client/dotNET/Region.cs'
787--- client/dotNET/Region.cs 2009-12-28 14:38:48 +0000
788+++ client/dotNET/Region.cs 2009-12-31 11:13:17 +0000
789@@ -22,6 +22,7 @@
790 using System.Text;
791 using System.Windows.Forms;
792 using System.Xml;
793+using System.Diagnostics;
794
795 namespace XiboClient
796 {
797@@ -107,61 +108,69 @@
798 }
799
800 System.Diagnostics.Debug.WriteLine(String.Format("Creating new media: {0}, {1}", options.type, options.mediaid), "Region - EvalOptions");
801-
802- switch (options.type)
803- {
804- case "image":
805- options.uri = Properties.Settings.Default.LibraryPath + @"\" + options.uri;
806- media = new ImagePosition(options);
807- break;
808-
809- case "text":
810- media = new Text(options);
811- break;
812-
813- case "powerpoint":
814- options.uri = Properties.Settings.Default.LibraryPath + @"\" + options.uri;
815- media = new WebContent(options);
816- break;
817-
818- case "video":
819- options.uri = Properties.Settings.Default.LibraryPath + @"\" + options.uri;
820- media = new Video(options);
821- break;
822-
823- case "webpage":
824- media = new WebContent(options);
825- break;
826-
827- case "flash":
828- options.uri = Properties.Settings.Default.LibraryPath + @"\" + options.uri;
829- media = new Flash(options);
830- break;
831-
832- case "ticker":
833- media = new Rss(options);
834- break;
835-
836- case "embedded":
837- media = new Text(options);
838- break;
839-
840- default:
841- //do nothing
842- SetNextMediaNode();
843- return;
844- }
845-
846- //sets up the timer for this media
847- media.Duration = options.duration;
848-
849- //add event handler
850- media.DurationElapsedEvent += new Media.DurationElapsedDelegate(media_DurationElapsedEvent);
851-
852- //any additional media specific render options (and starts the timer)
853- media.RenderMedia();
854-
855- Controls.Add(media);
856+
857+ try
858+ {
859+ switch (options.type)
860+ {
861+ case "image":
862+ options.uri = Properties.Settings.Default.LibraryPath + @"\" + options.uri;
863+ media = new ImagePosition(options);
864+ break;
865+
866+ case "text":
867+ media = new Text(options);
868+ break;
869+
870+ case "powerpoint":
871+ options.uri = Properties.Settings.Default.LibraryPath + @"\" + options.uri;
872+ media = new WebContent(options);
873+ break;
874+
875+ case "video":
876+ options.uri = Properties.Settings.Default.LibraryPath + @"\" + options.uri;
877+ media = new Video(options);
878+ break;
879+
880+ case "webpage":
881+ media = new WebContent(options);
882+ break;
883+
884+ case "flash":
885+ options.uri = Properties.Settings.Default.LibraryPath + @"\" + options.uri;
886+ media = new Flash(options);
887+ break;
888+
889+ case "ticker":
890+ media = new Rss(options);
891+ break;
892+
893+ case "embedded":
894+ media = new Text(options);
895+ break;
896+
897+ default:
898+ //do nothing
899+ SetNextMediaNode();
900+ return;
901+ }
902+
903+ //sets up the timer for this media
904+ media.Duration = options.duration;
905+
906+ //add event handler
907+ media.DurationElapsedEvent += new Media.DurationElapsedDelegate(media_DurationElapsedEvent);
908+
909+ //any additional media specific render options (and starts the timer)
910+ media.RenderMedia();
911+
912+ Controls.Add(media);
913+ }
914+ catch (Exception ex)
915+ {
916+ Trace.WriteLine(new LogMessage("EvalOptions", "Unable to start media. " + ex.Message), LogType.Error.ToString());
917+ SetNextMediaNode();
918+ }
919
920 // This media has started and is being replaced
921 _stat = new Stat();
922@@ -230,7 +239,7 @@
923 // Get a media node
924 bool validNode = false;
925 int numAttempts = 0;
926-
927+
928 while (!validNode)
929 {
930 numAttempts++;
931@@ -253,6 +262,15 @@
932 if (currentSequence >= options.mediaNodes.Count)
933 {
934 currentSequence = 0; //zero it
935+
936+ hasExpired = true; //we have expired (want to raise an expired event to the parent)
937+
938+ System.Diagnostics.Debug.WriteLine("Media Expired:" + options.ToString() + " . Reached the end of the sequence. Starting from the beginning.", "Region - SetNextMediaNode");
939+
940+ DurationElapsedEvent();
941+
942+ // We want to continue on to show the next media (unless the duration elapsed event triggers a region change)
943+ if (layoutExpired) return;
944 }
945 }
946 else
947@@ -265,6 +283,8 @@
948
949 // Type and Duration will always be on the media node
950 options.type = nodeAttributes["type"].Value;
951+
952+ //TODO: Check the type of node we have, and make sure it is supported.
953
954 if (nodeAttributes["duration"].Value != "")
955 {
956@@ -341,7 +361,11 @@
957 }
958 }
959
960- // That should cover all the new options
961+ // TODO: What if the file isnt there?
962+ // Do we need to have access to the CacheManager here... if we did then we could store whether or not a file
963+ // existed in there, instead of having to check it here...
964+ // we could also do away with the BlackList at the top and build it into here (at the moment its file based, we write
965+ // the cachemanager to file anyway)
966 }
967
968 if (numAttempts > options.mediaNodes.Count)
969
970=== modified file 'client/dotNET/Rss.cs'
971--- client/dotNET/Rss.cs 2009-12-28 14:38:48 +0000
972+++ client/dotNET/Rss.cs 2009-12-31 11:13:18 +0000
973@@ -23,7 +23,12 @@
974 using System.IO;
975 using System.Windows.Forms;
976 using System.Xml;
977-using System.Net;
978+<<<<<<< TREE
979+using System.Net;
980+=======
981+using System.Net;
982+using System.Diagnostics;
983+>>>>>>> MERGE-SOURCE
984
985 namespace XiboClient
986 {
987@@ -101,7 +106,10 @@
988 _updateInterval = options.updateInterval;
989 _scrollSpeed = options.scrollSpeed;
990
991- System.Diagnostics.Trace.WriteLine(String.Format("Scrolling Speed: {0}, Update Interval: {1})", _scrollSpeed.ToString(), _updateInterval.ToString()), "Rss - Constructor");
992+ System.Diagnostics.Debug.WriteLine(String.Format("Scrolling Speed: {0}, Update Interval: {1})", _scrollSpeed.ToString(), _updateInterval.ToString()), "Rss - Constructor");
993+
994+ // Generate a temporary file to store the rendered object in.
995+ _tempHtml = new TemporaryHtml();
996
997 // Generate a temporary file to store the rendered object in.
998 _tempHtml = new TemporaryHtml();
999@@ -186,6 +194,7 @@
1000 }
1001 else
1002 {
1003+<<<<<<< TREE
1004 bodyStyle = "background-image: url('" + _backgroundImage + "'); background-attachment:fixed; background-color:" + _backgroundColor + " background-repeat: no-repeat; background-position: " + _backgroundLeft + " " + _backgroundTop + ";";
1005 }
1006
1007@@ -229,6 +238,51 @@
1008
1009 // Store the document text in the temporary HTML space
1010 _tempHtml.HeadContent = _headText;
1011+=======
1012+ bodyStyle = "background-image: url('" + _backgroundImage + "'); background-attachment:fixed; background-color:" + _backgroundColor + " background-repeat: no-repeat; background-position: " + _backgroundLeft + " " + _backgroundTop + ";";
1013+ }
1014+
1015+ // Do we need to include the init function to kick off the text render?
1016+ String initFunction = "";
1017+
1018+ if (_direction == "single")
1019+ {
1020+ initFunction = @"
1021+<script type='text/javascript'>
1022+function init()
1023+{
1024+ var totalDuration = " + _duration.ToString() + @" * 1000;
1025+ var itemCount = $('.XiboRssItem').size();
1026+
1027+ var itemTime = totalDuration / itemCount;
1028+
1029+ if (itemTime < 2000) itemTime = 2000;
1030+
1031+ // Try to get the itemTime from an element we expect to be in the HTML
1032+
1033+ $('#text').cycle({fx: 'fade', timeout:itemTime});
1034+}
1035+</script>";
1036+ }
1037+ else if (_direction != "none")
1038+ {
1039+ initFunction = @"
1040+<script type='text/javascript'>
1041+function init()
1042+{
1043+ tr = new TextRender('text', 'innerText', '" + _direction + @"');
1044+
1045+ var timer = 0;
1046+ timer = setInterval('tr.TimerTick()', " + _scrollSpeed.ToString() + @");
1047+}
1048+</script>";
1049+ }
1050+
1051+ _headText = initFunction + "<style type='text/css'>body {" + bodyStyle + " font-size:" + _scaleFactor.ToString() + "em; }</style>";
1052+
1053+ // Store the document text in the temporary HTML space
1054+ _tempHtml.HeadContent = _headText;
1055+>>>>>>> MERGE-SOURCE
1056 }
1057
1058 /// <summary>
1059@@ -241,15 +295,28 @@
1060 {
1061 System.Diagnostics.Debug.WriteLine("Created at WebClient", "RSS - Refresh local RSS");
1062
1063- _wc = new System.Net.WebClient();
1064- _wc.UseDefaultCredentials = true;
1065- _wc.OpenReadCompleted += new System.Net.OpenReadCompletedEventHandler(wc_OpenReadCompleted);
1066-
1067- _wc.OpenReadAsync(new Uri(_filePath));
1068- }
1069- catch (Exception ex)
1070- {
1071- System.Diagnostics.Trace.WriteLine(String.Format("[*]ScheduleID:{1},LayoutID:{2},MediaID:{3},Message:{0}", ex.Message, _scheduleId, _layoutId, _mediaid));
1072+<<<<<<< TREE
1073+ _wc = new System.Net.WebClient();
1074+ _wc.UseDefaultCredentials = true;
1075+ _wc.OpenReadCompleted += new System.Net.OpenReadCompletedEventHandler(wc_OpenReadCompleted);
1076+
1077+ _wc.OpenReadAsync(new Uri(_filePath));
1078+ }
1079+ catch (Exception ex)
1080+ {
1081+ System.Diagnostics.Trace.WriteLine(String.Format("[*]ScheduleID:{1},LayoutID:{2},MediaID:{3},Message:{0}", ex.Message, _scheduleId, _layoutId, _mediaid));
1082+=======
1083+ _wc = new System.Net.WebClient();
1084+ _wc.UseDefaultCredentials = true;
1085+
1086+ _wc.OpenReadCompleted += new System.Net.OpenReadCompletedEventHandler(wc_OpenReadCompleted);
1087+
1088+ _wc.OpenReadAsync(new Uri(_filePath));
1089+ }
1090+ catch (Exception ex)
1091+ {
1092+ System.Diagnostics.Trace.WriteLine(String.Format("[*]ScheduleID:{1},LayoutID:{2},MediaID:{3},Message:{0}", ex.Message, _scheduleId, _layoutId, _mediaid));
1093+>>>>>>> MERGE-SOURCE
1094 }
1095 }
1096
1097@@ -487,6 +554,25 @@
1098 {
1099 System.Diagnostics.Debug.WriteLine("Web browser control already disposed", "Rss - Dispose");
1100 }
1101+
1102+ try
1103+ {
1104+ _wc.Dispose();
1105+ }
1106+ catch
1107+ {
1108+ System.Diagnostics.Debug.WriteLine("Web Client control already disposed", "Rss - Dispose");
1109+ }
1110+
1111+ // Remove the temporary file we created
1112+ try
1113+ {
1114+ _tempHtml.Dispose();
1115+ }
1116+ catch (Exception ex)
1117+ {
1118+ Trace.WriteLine(new LogMessage("Dispose", String.Format("Unable to dispose TemporaryHtml with exception {0}", ex.Message)));
1119+ }
1120 }
1121
1122 base.Dispose(disposing);
1123
1124=== modified file 'client/dotNET/Schedule.cs'
1125--- client/dotNET/Schedule.cs 2009-11-26 21:21:08 +0000
1126+++ client/dotNET/Schedule.cs 2009-12-31 11:13:18 +0000
1127@@ -25,6 +25,8 @@
1128 using System.Text;
1129 using System.Windows.Forms;
1130 using System.Xml;
1131+using System.Xml.Serialization;
1132+using System.Diagnostics;
1133
1134 namespace XiboClient
1135 {
1136@@ -33,6 +35,7 @@
1137 /// </summary>
1138 class Schedule
1139 {
1140+<<<<<<< TREE
1141 public delegate void ScheduleChangeDelegate(string layoutPath, int scheduleId, int layoutId);
1142 public event ScheduleChangeDelegate ScheduleChangeEvent;
1143
1144@@ -56,15 +59,46 @@
1145 /// </summary>
1146 /// <param name="scheduleLocation"></param>
1147 public Schedule(string scheduleLocation)
1148+=======
1149+ public delegate void ScheduleChangeDelegate(string layoutPath, int scheduleId, int layoutId);
1150+ public event ScheduleChangeDelegate ScheduleChangeEvent;
1151+
1152+ private Collection<LayoutSchedule> layoutSchedule;
1153+ private int currentLayout = 0;
1154+ private string scheduleLocation;
1155+
1156+ //FileCollector
1157+ private XiboClient.xmds.xmds xmds2;
1158+ private bool xmdsProcessing;
1159+ private bool forceChange = false;
1160+
1161+ // Key
1162+ private HardwareKey hardwareKey;
1163+
1164+ // Cache Manager
1165+ private CacheManager _cacheManager;
1166+
1167+ /// <summary>
1168+ /// Create a schedule
1169+ /// </summary>
1170+ /// <param name="scheduleLocation"></param>
1171+ public Schedule(string scheduleLocation, ref CacheManager cacheManager)
1172+>>>>>>> MERGE-SOURCE
1173 {
1174 // Save the schedule location
1175 this.scheduleLocation = scheduleLocation;
1176
1177 // Create a new collection for the layouts in the schedule
1178 layoutSchedule = new Collection<LayoutSchedule>();
1179+<<<<<<< TREE
1180
1181 // Create a new cache manager
1182 _cacheManager = new CacheManager();
1183+=======
1184+
1185+ // Set cachemanager
1186+ _cacheManager = cacheManager;
1187+>>>>>>> MERGE-SOURCE
1188
1189 // Create a new Xmds service object
1190 xmds2 = new XiboClient.xmds.xmds();
1191@@ -119,8 +153,8 @@
1192
1193 if (e.Error != null)
1194 {
1195- //There was an error - what do we do?
1196- System.Diagnostics.Trace.WriteLine(e.Error.Message);
1197+ // There was an error - what do we do?
1198+ System.Diagnostics.Trace.WriteLine(new LogMessage("Schedule - RequiredFilesCompleted", e.Error.Message), LogType.Error.ToString());
1199
1200 // Is it a "not licensed" error
1201 if (e.Error.Message == "This display client is not licensed")
1202@@ -158,9 +192,10 @@
1203 xmdsProcessing = false;
1204
1205 // Log and move on
1206- System.Diagnostics.Debug.WriteLine("Error Comparing and Collecting", "Schedule - RequiredFilesCompleted");
1207- System.Diagnostics.Debug.WriteLine(ex.Message, "Schedule - RequiredFilesCompleted");
1208+ System.Diagnostics.Trace.WriteLine(new LogMessage("Schedule - RequiredFilesCompleted", "Error Comparing and Collecting: " + ex.Message), LogType.Error.ToString());
1209 }
1210+
1211+ _cacheManager.WriteCacheManager();
1212 }
1213 }
1214
1215@@ -298,8 +333,7 @@
1216
1217 if (layoutSchedule.Count == 1 && !forceChange)
1218 {
1219- //dont bother raising the event, just keep on this until the schedule gets changed
1220- return;
1221+ Debug.WriteLine(new LogMessage("Schedule - NextLayout", "Only 1 layout showing, refreshing it"), LogType.Info.ToString());
1222 }
1223
1224 System.Diagnostics.Debug.WriteLine(String.Format("Next layout: {0}", layoutSchedule[currentLayout].layoutFile), "Schedule - Next Layout");
1225
1226=== modified file 'client/dotNET/TemporaryHtml.cs'
1227--- client/dotNET/TemporaryHtml.cs 2009-11-01 11:28:23 +0000
1228+++ client/dotNET/TemporaryHtml.cs 2009-12-31 11:13:18 +0000
1229@@ -1,106 +1,217 @@
1230-using System;
1231-using System.Collections.Generic;
1232-using System.IO;
1233-using System.Text;
1234-using System.Reflection;
1235-using System.Diagnostics;
1236-
1237-namespace XiboClient
1238-{
1239- /// <summary>
1240- /// A temporary html object.
1241- /// Once FileContent is set it will contain the complete HTML page
1242- /// </summary>
1243- class TemporaryHtml : IDisposable
1244- {
1245- private String _fileContent;
1246- private String _headContent;
1247- private String _resourceTemplate;
1248- private String _filePath;
1249-
1250- public TemporaryHtml()
1251- {
1252- // Load the resource file
1253-
1254-
1255- }
1256-
1257- /// <summary>
1258- /// The File content - can only be set once.
1259- /// </summary>
1260- public String BodyContent
1261- {
1262- set
1263- {
1264- // Set the contents of the file
1265- _fileContent = value;
1266-
1267- // Create the temporary file
1268- Store();
1269- }
1270- }
1271-
1272- /// <summary>
1273- /// The Head content - must be added before the body
1274- /// </summary>
1275- public String HeadContent
1276- {
1277- set
1278- {
1279- // Set the head content
1280- _headContent = value;
1281- }
1282- }
1283-
1284- public String Path
1285- {
1286- get
1287- {
1288- return _filePath;
1289- }
1290- }
1291-
1292- /// <summary>
1293- /// Stores the file
1294- /// </summary>
1295- private void Store()
1296- {
1297- // Create a temporary file
1298- _filePath = System.IO.Path.GetTempFileName();
1299-
1300- // Open the resource file
1301- Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
1302-
1303- // Use the assembly to get the HtmlTemplate resource
1304- using (Stream resourceStream = assembly.GetManifestResourceStream("XiboClient.Resources.HtmlTemplate.htm"))
1305- {
1306- using (TextReader tw = new StreamReader(resourceStream))
1307- {
1308- _resourceTemplate = tw.ReadToEnd();
1309- }
1310- }
1311-
1312- // Insert the file content into the resource file
1313- _resourceTemplate = _resourceTemplate.Replace("<!--[[[HEADCONTENT]]]-->", _headContent);
1314- _resourceTemplate = _resourceTemplate.Replace("<!--[[[BODYCONTENT]]]-->", _fileContent);
1315-
1316- // Write it to the file
1317- using (StreamWriter sw = new StreamWriter(File.Open(_filePath, FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8))
1318- {
1319- sw.Write(_resourceTemplate);
1320- sw.Close();
1321- }
1322- }
1323-
1324-
1325- #region IDisposable Members
1326-
1327- public void Dispose()
1328- {
1329- // Remove the temporary file
1330- File.Delete(_filePath);
1331- }
1332-
1333- #endregion
1334- }
1335-}
1336+<<<<<<< TREE
1337+using System;
1338+using System.Collections.Generic;
1339+using System.IO;
1340+using System.Text;
1341+using System.Reflection;
1342+using System.Diagnostics;
1343+
1344+namespace XiboClient
1345+{
1346+ /// <summary>
1347+ /// A temporary html object.
1348+ /// Once FileContent is set it will contain the complete HTML page
1349+ /// </summary>
1350+ class TemporaryHtml : IDisposable
1351+ {
1352+ private String _fileContent;
1353+ private String _headContent;
1354+ private String _resourceTemplate;
1355+ private String _filePath;
1356+
1357+ public TemporaryHtml()
1358+ {
1359+ // Load the resource file
1360+
1361+
1362+ }
1363+
1364+ /// <summary>
1365+ /// The File content - can only be set once.
1366+ /// </summary>
1367+ public String BodyContent
1368+ {
1369+ set
1370+ {
1371+ // Set the contents of the file
1372+ _fileContent = value;
1373+
1374+ // Create the temporary file
1375+ Store();
1376+ }
1377+ }
1378+
1379+ /// <summary>
1380+ /// The Head content - must be added before the body
1381+ /// </summary>
1382+ public String HeadContent
1383+ {
1384+ set
1385+ {
1386+ // Set the head content
1387+ _headContent = value;
1388+ }
1389+ }
1390+
1391+ public String Path
1392+ {
1393+ get
1394+ {
1395+ return _filePath;
1396+ }
1397+ }
1398+
1399+ /// <summary>
1400+ /// Stores the file
1401+ /// </summary>
1402+ private void Store()
1403+ {
1404+ // Create a temporary file
1405+ _filePath = System.IO.Path.GetTempFileName();
1406+
1407+ // Open the resource file
1408+ Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
1409+
1410+ // Use the assembly to get the HtmlTemplate resource
1411+ using (Stream resourceStream = assembly.GetManifestResourceStream("XiboClient.Resources.HtmlTemplate.htm"))
1412+ {
1413+ using (TextReader tw = new StreamReader(resourceStream))
1414+ {
1415+ _resourceTemplate = tw.ReadToEnd();
1416+ }
1417+ }
1418+
1419+ // Insert the file content into the resource file
1420+ _resourceTemplate = _resourceTemplate.Replace("<!--[[[HEADCONTENT]]]-->", _headContent);
1421+ _resourceTemplate = _resourceTemplate.Replace("<!--[[[BODYCONTENT]]]-->", _fileContent);
1422+
1423+ // Write it to the file
1424+ using (StreamWriter sw = new StreamWriter(File.Open(_filePath, FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8))
1425+ {
1426+ sw.Write(_resourceTemplate);
1427+ sw.Close();
1428+ }
1429+ }
1430+
1431+
1432+ #region IDisposable Members
1433+
1434+ public void Dispose()
1435+ {
1436+ // Remove the temporary file
1437+ File.Delete(_filePath);
1438+ }
1439+
1440+ #endregion
1441+ }
1442+}
1443+=======
1444+using System;
1445+using System.Collections.Generic;
1446+using System.IO;
1447+using System.Text;
1448+using System.Reflection;
1449+using System.Diagnostics;
1450+
1451+namespace XiboClient
1452+{
1453+ /// <summary>
1454+ /// A temporary html object.
1455+ /// Once FileContent is set it will contain the complete HTML page
1456+ /// </summary>
1457+ class TemporaryHtml : IDisposable
1458+ {
1459+ private String _fileContent;
1460+ private String _headContent;
1461+ private String _resourceTemplate;
1462+ private String _filePath;
1463+
1464+ public TemporaryHtml()
1465+ {
1466+ // Load the resource file
1467+
1468+
1469+ }
1470+
1471+ /// <summary>
1472+ /// The File content - can only be set once.
1473+ /// </summary>
1474+ public String BodyContent
1475+ {
1476+ set
1477+ {
1478+ // Set the contents of the file
1479+ _fileContent = value;
1480+
1481+ // Create the temporary file
1482+ Store();
1483+ }
1484+ }
1485+
1486+ /// <summary>
1487+ /// The Head content - must be added before the body
1488+ /// </summary>
1489+ public String HeadContent
1490+ {
1491+ set
1492+ {
1493+ // Set the head content
1494+ _headContent = value;
1495+ }
1496+ }
1497+
1498+ public String Path
1499+ {
1500+ get
1501+ {
1502+ return _filePath;
1503+ }
1504+ }
1505+
1506+ /// <summary>
1507+ /// Stores the file
1508+ /// </summary>
1509+ private void Store()
1510+ {
1511+ // Create a temporary file
1512+ _filePath = System.IO.Path.GetTempFileName();
1513+
1514+ Debug.WriteLine(_filePath);
1515+
1516+ // Open the resource file
1517+ Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
1518+
1519+ // Use the assembly to get the HtmlTemplate resource
1520+ using (Stream resourceStream = assembly.GetManifestResourceStream("XiboClient.Resources.HtmlTemplate.htm"))
1521+ {
1522+ using (TextReader tw = new StreamReader(resourceStream))
1523+ {
1524+ _resourceTemplate = tw.ReadToEnd();
1525+ }
1526+ }
1527+
1528+ // Insert the file content into the resource file
1529+ _resourceTemplate = _resourceTemplate.Replace("<!--[[[HEADCONTENT]]]-->", _headContent);
1530+ _resourceTemplate = _resourceTemplate.Replace("<!--[[[BODYCONTENT]]]-->", _fileContent);
1531+
1532+ // Write it to the file
1533+ using (StreamWriter sw = new StreamWriter(File.Open(_filePath, FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8))
1534+ {
1535+ sw.Write(_resourceTemplate);
1536+ sw.Close();
1537+ }
1538+ }
1539+
1540+
1541+ #region IDisposable Members
1542+
1543+ public void Dispose()
1544+ {
1545+ // Remove the temporary file
1546+ File.Delete(_filePath);
1547+ }
1548+
1549+ #endregion
1550+ }
1551+}
1552+>>>>>>> MERGE-SOURCE
1553
1554=== modified file 'client/dotNET/Text.cs'
1555--- client/dotNET/Text.cs 2009-11-30 20:52:08 +0000
1556+++ client/dotNET/Text.cs 2009-12-31 11:13:18 +0000
1557@@ -108,6 +108,7 @@
1558 if (_direction == "left" || _direction == "right") textWrap = "white-space: nowrap";
1559
1560 textRender += string.Format("<div id='text' style='position:relative;overflow:hidden;width:{0}; height:{1};'>", this.width - 10, this.height);
1561+<<<<<<< TREE
1562 textRender += string.Format("<div id='innerText' style='position:absolute; left: 0px; top: 0px; width:{2} {0}'>{1}</div></div>", textWrap, _documentText, this.width - 10);
1563
1564 _tempHtml.BodyContent = textRender;
1565@@ -157,6 +158,57 @@
1566 /// <summary>
1567 /// Render media
1568 /// </summary>
1569+=======
1570+ textRender += string.Format("<div id='innerText' style='position:absolute; left: 0px; top: 0px; width:{2} {0}'>{1}</div></div>", textWrap, _documentText, this.width - 10);
1571+
1572+ _tempHtml.BodyContent = textRender;
1573+ }
1574+ }
1575+
1576+ /// <summary>
1577+ /// Generates the Head Html for this Document
1578+ /// </summary>
1579+ private void GenerateHeadHtml()
1580+ {
1581+ // Handle the background
1582+ String bodyStyle;
1583+
1584+ if (_backgroundImage == null || _backgroundImage == "")
1585+ {
1586+ bodyStyle = "background-color:" + _backgroundColor + " ;";
1587+ }
1588+ else
1589+ {
1590+ bodyStyle = "background-image: url('" + _backgroundImage + "'); background-attachment:fixed; background-color:" + _backgroundColor + " background-repeat: no-repeat; background-position: " + _backgroundLeft + " " + _backgroundTop + ";";
1591+ }
1592+
1593+ // Do we need to include the init function to kick off the text render?
1594+ String initFunction = "";
1595+
1596+ if (_direction != "none")
1597+ {
1598+ initFunction = @"
1599+<script type='text/javascript'>
1600+function init()
1601+{
1602+ tr = new TextRender('text', 'innerText', '" + _direction + @"');
1603+
1604+ var timer = 0;
1605+ timer = setInterval('tr.TimerTick()', " + _scrollSpeed.ToString() + @");
1606+}
1607+</script>";
1608+ }
1609+
1610+ _headText = _headJavaScript + initFunction + "<style type='text/css'>body {" + bodyStyle + " font-size:" + _scaleFactor.ToString() + "em; }</style>";
1611+
1612+ // Store the document text in the temporary HTML space
1613+ _tempHtml.HeadContent = _headText;
1614+ }
1615+
1616+ /// <summary>
1617+ /// Render media
1618+ /// </summary>
1619+>>>>>>> MERGE-SOURCE
1620 public override void RenderMedia()
1621 {
1622 base.StartTimer();
1623
1624=== modified file 'client/dotNET/Video.cs'
1625--- client/dotNET/Video.cs 2009-11-30 20:52:08 +0000
1626+++ client/dotNET/Video.cs 2009-12-31 11:13:18 +0000
1627@@ -81,6 +81,7 @@
1628 {
1629 if (disposing)
1630 {
1631+<<<<<<< TREE
1632 // Dispose of managed resources
1633 }
1634
1635@@ -89,13 +90,31 @@
1636
1637 try
1638 {
1639+=======
1640+
1641+ }
1642+
1643+ try
1644+ {
1645+>>>>>>> MERGE-SOURCE
1646 videoPlayer.Hide();
1647+<<<<<<< TREE
1648+=======
1649+ Controls.Remove(videoPlayer);
1650+>>>>>>> MERGE-SOURCE
1651 videoPlayer.Dispose();
1652 }
1653+<<<<<<< TREE
1654 catch
1655 {
1656 System.Diagnostics.Debug.WriteLine("Unable to dispose of video player", "Dispose");
1657 }
1658+=======
1659+ catch
1660+ {
1661+
1662+ }
1663+>>>>>>> MERGE-SOURCE
1664
1665 base.Dispose(disposing);
1666 }
1667
1668=== modified file 'client/dotNET/VideoPlayer.cs'
1669--- client/dotNET/VideoPlayer.cs 2009-12-03 20:50:32 +0000
1670+++ client/dotNET/VideoPlayer.cs 2009-12-31 11:13:18 +0000
1671@@ -60,6 +60,7 @@
1672 {
1673 if (e.newState == 8)
1674 {
1675+<<<<<<< TREE
1676 // indicate we are stopped
1677 axWindowsMediaPlayer1.Visible = false;
1678
1679@@ -67,6 +68,10 @@
1680
1681 // Fire an event to say we have elapsed
1682 VideoPlayerElapsedEvent();
1683+=======
1684+ // indicate we are stopped
1685+ finished = true;
1686+>>>>>>> MERGE-SOURCE
1687 }
1688 }
1689
1690
1691=== modified file 'client/dotNET/Web References/xmds/Reference.cs'
1692--- client/dotNET/Web References/xmds/Reference.cs 2009-07-26 11:40:59 +0000
1693+++ client/dotNET/Web References/xmds/Reference.cs 2009-12-31 11:13:18 +0000
1694@@ -1,7 +1,7 @@
1695 //------------------------------------------------------------------------------
1696 // <auto-generated>
1697 // This code was generated by a tool.
1698-// Runtime Version:2.0.50727.1433
1699+// Runtime Version:2.0.50727.4927
1700 //
1701 // Changes to this file may cause incorrect behavior and will be lost if
1702 // the code is regenerated.
1703@@ -9,7 +9,7 @@
1704 //------------------------------------------------------------------------------
1705
1706 //
1707-// This source code was auto-generated by Microsoft.VSDesigner, Version 2.0.50727.1433.
1708+// This source code was auto-generated by Microsoft.VSDesigner, Version 2.0.50727.4927.
1709 //
1710 #pragma warning disable 1591
1711
1712@@ -23,7 +23,7 @@
1713
1714
1715 /// <remarks/>
1716- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1717+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1718 [System.Diagnostics.DebuggerStepThroughAttribute()]
1719 [System.ComponentModel.DesignerCategoryAttribute("code")]
1720 [System.Web.Services.WebServiceBindingAttribute(Name="xmdsBinding", Namespace="urn:xmds")]
1721@@ -421,11 +421,11 @@
1722 }
1723
1724 /// <remarks/>
1725- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1726+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1727 public delegate void RegisterDisplayCompletedEventHandler(object sender, RegisterDisplayCompletedEventArgs e);
1728
1729 /// <remarks/>
1730- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1731+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1732 [System.Diagnostics.DebuggerStepThroughAttribute()]
1733 [System.ComponentModel.DesignerCategoryAttribute("code")]
1734 public partial class RegisterDisplayCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
1735@@ -447,11 +447,11 @@
1736 }
1737
1738 /// <remarks/>
1739- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1740+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1741 public delegate void RequiredFilesCompletedEventHandler(object sender, RequiredFilesCompletedEventArgs e);
1742
1743 /// <remarks/>
1744- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1745+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1746 [System.Diagnostics.DebuggerStepThroughAttribute()]
1747 [System.ComponentModel.DesignerCategoryAttribute("code")]
1748 public partial class RequiredFilesCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
1749@@ -473,11 +473,11 @@
1750 }
1751
1752 /// <remarks/>
1753- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1754+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1755 public delegate void GetFileCompletedEventHandler(object sender, GetFileCompletedEventArgs e);
1756
1757 /// <remarks/>
1758- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1759+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1760 [System.Diagnostics.DebuggerStepThroughAttribute()]
1761 [System.ComponentModel.DesignerCategoryAttribute("code")]
1762 public partial class GetFileCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
1763@@ -499,11 +499,11 @@
1764 }
1765
1766 /// <remarks/>
1767- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1768+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1769 public delegate void ScheduleCompletedEventHandler(object sender, ScheduleCompletedEventArgs e);
1770
1771 /// <remarks/>
1772- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1773+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1774 [System.Diagnostics.DebuggerStepThroughAttribute()]
1775 [System.ComponentModel.DesignerCategoryAttribute("code")]
1776 public partial class ScheduleCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
1777@@ -525,11 +525,11 @@
1778 }
1779
1780 /// <remarks/>
1781- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1782+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1783 public delegate void RecieveXmlLogCompletedEventHandler(object sender, RecieveXmlLogCompletedEventArgs e);
1784
1785 /// <remarks/>
1786- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1787+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1788 [System.Diagnostics.DebuggerStepThroughAttribute()]
1789 [System.ComponentModel.DesignerCategoryAttribute("code")]
1790 public partial class RecieveXmlLogCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
1791@@ -551,11 +551,11 @@
1792 }
1793
1794 /// <remarks/>
1795- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1796+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1797 public delegate void BlackListCompletedEventHandler(object sender, BlackListCompletedEventArgs e);
1798
1799 /// <remarks/>
1800- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1801+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1802 [System.Diagnostics.DebuggerStepThroughAttribute()]
1803 [System.ComponentModel.DesignerCategoryAttribute("code")]
1804 public partial class BlackListCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
1805@@ -577,11 +577,11 @@
1806 }
1807
1808 /// <remarks/>
1809- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1810+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1811 public delegate void SubmitLogCompletedEventHandler(object sender, SubmitLogCompletedEventArgs e);
1812
1813 /// <remarks/>
1814- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1815+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1816 [System.Diagnostics.DebuggerStepThroughAttribute()]
1817 [System.ComponentModel.DesignerCategoryAttribute("code")]
1818 public partial class SubmitLogCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
1819@@ -603,11 +603,11 @@
1820 }
1821
1822 /// <remarks/>
1823- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1824+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1825 public delegate void SubmitStatsCompletedEventHandler(object sender, SubmitStatsCompletedEventArgs e);
1826
1827 /// <remarks/>
1828- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
1829+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.4918")]
1830 [System.Diagnostics.DebuggerStepThroughAttribute()]
1831 [System.ComponentModel.DesignerCategoryAttribute("code")]
1832 public partial class SubmitStatsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
1833
1834=== modified file 'client/dotNET/XiboClient.csproj'
1835--- client/dotNET/XiboClient.csproj 2009-12-28 14:38:48 +0000
1836+++ client/dotNET/XiboClient.csproj 2009-12-31 11:13:18 +0000
1837@@ -1,8 +1,8 @@
1838-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1839+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
1840 <PropertyGroup>
1841 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
1842 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
1843- <ProductVersion>8.0.50727</ProductVersion>
1844+ <ProductVersion>9.0.30729</ProductVersion>
1845 <SchemaVersion>2.0</SchemaVersion>
1846 <ProjectGuid>{9E6CFE88-0171-4360-BDF4-84D74A90FD55}</ProjectGuid>
1847 <OutputType>WinExe</OutputType>
1848@@ -16,6 +16,14 @@
1849 <IsWebBootstrapper>false</IsWebBootstrapper>
1850 <StartupObject>XiboClient.Program</StartupObject>
1851 <TargetZone>LocalIntranet</TargetZone>
1852+ <FileUpgradeFlags>
1853+ </FileUpgradeFlags>
1854+ <OldToolsVersion>2.0</OldToolsVersion>
1855+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
1856+ <UpgradeBackupLocation>
1857+ </UpgradeBackupLocation>
1858+ <TargetFrameworkSubset>
1859+ </TargetFrameworkSubset>
1860 <PublishUrl>T:\Development\Version 2\Client\</PublishUrl>
1861 <Install>true</Install>
1862 <InstallFrom>Disk</InstallFrom>
1863@@ -26,8 +34,9 @@
1864 <UpdatePeriodically>false</UpdatePeriodically>
1865 <UpdateRequired>false</UpdateRequired>
1866 <MapFileExtensions>true</MapFileExtensions>
1867- <CreateWebPageOnPublish>false</CreateWebPageOnPublish>
1868+ <ApplicationRevision>0</ApplicationRevision>
1869 <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
1870+ <UseApplicationTrust>false</UseApplicationTrust>
1871 <BootstrapperEnabled>true</BootstrapperEnabled>
1872 </PropertyGroup>
1873 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
1874@@ -211,11 +220,31 @@
1875 </COMReference>
1876 </ItemGroup>
1877 <ItemGroup>
1878+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
1879+ <Visible>False</Visible>
1880+ <ProductName>.NET Framework Client Profile</ProductName>
1881+ <Install>false</Install>
1882+ </BootstrapperPackage>
1883 <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
1884 <Visible>False</Visible>
1885- <ProductName>.NET Framework 2.0</ProductName>
1886+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
1887 <Install>true</Install>
1888 </BootstrapperPackage>
1889+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
1890+ <Visible>False</Visible>
1891+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
1892+ <Install>false</Install>
1893+ </BootstrapperPackage>
1894+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
1895+ <Visible>False</Visible>
1896+ <ProductName>.NET Framework 3.5</ProductName>
1897+ <Install>false</Install>
1898+ </BootstrapperPackage>
1899+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
1900+ <Visible>False</Visible>
1901+ <ProductName>.NET Framework 3.5 SP1</ProductName>
1902+ <Install>false</Install>
1903+ </BootstrapperPackage>
1904 </ItemGroup>
1905 <ItemGroup>
1906 <WebReferences Include="Web References\" />
1907
1908=== modified file 'client/dotNET/app.config'
1909--- client/dotNET/app.config 2009-07-30 23:01:31 +0000
1910+++ client/dotNET/app.config 2009-12-31 11:13:18 +0000
1911@@ -1,11 +1,11 @@
1912-<?xml version="1.0" encoding="utf-8" ?>
1913+<?xml version="1.0"?>
1914 <configuration>
1915 <configSections>
1916- <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
1917- <section name="XiboClient.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
1918+ <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
1919+ <section name="XiboClient.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
1920 </sectionGroup>
1921- <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
1922- <section name="XiboClient.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
1923+ <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
1924+ <section name="XiboClient.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
1925 </sectionGroup>
1926 </configSections>
1927 <userSettings>
1928@@ -14,10 +14,10 @@
1929 <value>DEFAULT</value>
1930 </setting>
1931 <setting name="XiboClient_xmds_xmds" serializeAs="String">
1932- <value>http://localhost/1.0.0/server/xmds.php</value>
1933+ <value>http://localhost/xibo/xmds.php</value>
1934 </setting>
1935 <setting name="ServerKey" serializeAs="String">
1936- <value>changetocustomerkey</value>
1937+ <value>yourserverkey</value>
1938 </setting>
1939 <setting name="displayName" serializeAs="String">
1940 <value>COMPUTERNAME</value>
1941@@ -32,7 +32,7 @@
1942 <value>True</value>
1943 </setting>
1944 <setting name="serverURI" serializeAs="String">
1945- <value>https://www.xibo.co.uk/changetocustomersite</value>
1946+ <value>http://localhost/xibo</value>
1947 </setting>
1948 <setting name="ProxyUser" serializeAs="String">
1949 <value />
1950@@ -77,6 +77,12 @@
1951 <setting name="StatsLogFile" serializeAs="String">
1952 <value>stats.xml</value>
1953 </setting>
1954+ <setting name="CacheManagerFile" serializeAs="String">
1955+ <value>cacheManager.xml</value>
1956+ </setting>
1957+ <setting name="ClientVersion" serializeAs="String">
1958+ <value>1.0.5</value>
1959+ </setting>
1960 </XiboClient.Properties.Settings>
1961 </applicationSettings>
1962-</configuration>
1963\ No newline at end of file
1964+<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
1965
1966=== renamed file 'client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll' => 'client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll.OTHER'
1967Binary files client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll 2009-11-01 23:23:15 +0000 and client/dotNET/bin/Release/AxInterop.ShockwaveFlashObjects.dll.OTHER 2009-12-31 11:13:18 +0000 differ
1968=== renamed file 'client/dotNET/bin/Release/AxInterop.WMPLib.dll' => 'client/dotNET/bin/Release/AxInterop.WMPLib.dll.OTHER'
1969Binary files client/dotNET/bin/Release/AxInterop.WMPLib.dll 2009-11-01 23:23:15 +0000 and client/dotNET/bin/Release/AxInterop.WMPLib.dll.OTHER 2009-12-31 11:13:18 +0000 differ
1970=== renamed file 'client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll' => 'client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll.OTHER'
1971Binary files client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll 2009-11-01 23:23:15 +0000 and client/dotNET/bin/Release/Interop.ShockwaveFlashObjects.dll.OTHER 2009-12-31 11:13:18 +0000 differ
1972=== renamed file 'client/dotNET/bin/Release/Interop.WMPLib.dll' => 'client/dotNET/bin/Release/Interop.WMPLib.dll.OTHER'
1973Binary files client/dotNET/bin/Release/Interop.WMPLib.dll 2009-11-01 23:23:15 +0000 and client/dotNET/bin/Release/Interop.WMPLib.dll.OTHER 2009-12-31 11:13:18 +0000 differ
1974=== modified file 'client/dotNET/bin/Release/XiboClient.exe.config'
1975--- client/dotNET/bin/Release/XiboClient.exe.config 2009-07-30 23:01:31 +0000
1976+++ client/dotNET/bin/Release/XiboClient.exe.config 2009-12-31 11:13:18 +0000
1977@@ -77,6 +77,12 @@
1978 <setting name="StatsLogFile" serializeAs="String">
1979 <value>stats.xml</value>
1980 </setting>
1981+ <setting name="CacheManagerFile" serializeAs="String">
1982+ <value>cacheManager.xml</value>
1983+ </setting>
1984+ <setting name="ClientVersion" serializeAs="String">
1985+ <value>1.0.5</value>
1986+ </setting>
1987 </XiboClient.Properties.Settings>
1988 </applicationSettings>
1989 </configuration>
1990\ No newline at end of file
1991
1992=== modified file 'client/dotNET/bin/Release/XiboClient.vshost.exe.config'
1993--- client/dotNET/bin/Release/XiboClient.vshost.exe.config 2009-07-30 23:01:31 +0000
1994+++ client/dotNET/bin/Release/XiboClient.vshost.exe.config 2009-12-31 11:13:18 +0000
1995@@ -77,6 +77,12 @@
1996 <setting name="StatsLogFile" serializeAs="String">
1997 <value>stats.xml</value>
1998 </setting>
1999+ <setting name="CacheManagerFile" serializeAs="String">
2000+ <value>cacheManager.xml</value>
2001+ </setting>
2002+ <setting name="ClientVersion" serializeAs="String">
2003+ <value>1.0.5</value>
2004+ </setting>
2005 </XiboClient.Properties.Settings>
2006 </applicationSettings>
2007 </configuration>
2008\ No newline at end of file
2009
2010=== modified file 'server/install/database/9.sql'
2011--- server/install/database/9.sql 2009-12-28 14:45:26 +0000
2012+++ server/install/database/9.sql 2009-12-31 11:13:18 +0000
2013@@ -1,3 +1,4 @@
2014+<<<<<<< TREE
2015 INSERT INTO `pages` (
2016 `pageID` ,
2017 `name` ,
2018@@ -11,4 +12,17 @@
2019
2020
2021 INSERT INTO `menuitem` (`MenuItemID`, `MenuID`, `PageID`, `Args`, `Text`, `Class`, `Img`, `Sequence`)
2022-VALUES (NULL, 2, 28, 'http://wiki.xibo.org.uk/wiki/Manual:TOC', 'Manual', 'help_button', 'img/dashboard/help.png', '10');
2023\ No newline at end of file
2024+VALUES (NULL, 2, 28, 'http://wiki.xibo.org.uk/wiki/Manual:TOC', 'Manual', 'help_button', 'img/dashboard/help.png', '10');=======
2025+INSERT INTO `pages` (
2026+`pageID` ,
2027+`name` ,
2028+`pagegroupID`
2029+)
2030+VALUES (
2031+28 , 'manual', '2'
2032+);
2033+
2034+INSERT INTO `menuitem` (`MenuItemID`, `MenuID`, `PageID`, `Args`, `Text`, `Class`, `Img`, `Sequence`)
2035+VALUES (NULL, 2, 28, 'http://wiki.xibo.org.uk/wiki/Manual:TOC', 'Manual', 'help_button', 'img/dashboard/help.png', '10');
2036+
2037+UPDATE `module` SET `ValidExtensions` = 'ppt,pps,pptx' WHERE `module`.`ModuleID` =4 LIMIT 1 ;>>>>>>> MERGE-SOURCE
2038
2039=== modified file 'server/lib/pages/content.class.php'
2040--- server/lib/pages/content.class.php 2009-12-28 14:36:27 +0000
2041+++ server/lib/pages/content.class.php 2009-12-31 11:13:18 +0000
2042@@ -60,6 +60,7 @@
2043 */
2044 function LibraryFilter()
2045 {
2046+<<<<<<< TREE
2047 $db =& $this->db;
2048
2049 $mediatype = ""; //1
2050@@ -128,21 +129,85 @@
2051 </table>
2052 </form>
2053 </div>
2054+=======
2055+ $db =& $this->db;
2056+
2057+ $mediatype = ""; //1
2058+ $usertype = 0; //3
2059+ $playlistid = ""; //4
2060+
2061+ if (isset($_SESSION['content']['mediatype'])) $mediatype = $_SESSION['content']['mediatype'];
2062+ if (isset($_SESSION['content']['usertype'])) $usertype = $_SESSION['content']['usertype'];
2063+ if (isset($_SESSION['content']['playlistid'])) $playlistid = $_SESSION['content']['playlistid'];
2064+
2065+ //shared list
2066+ $shared = "All";
2067+ if (isset($_SESSION['content']['shared'])) $shared = $_SESSION['content']['shared'];
2068+ $shared_list = dropdownlist("SELECT 'all','All' UNION SELECT permissionID, permission FROM permission", "shared", $shared);
2069+
2070+ $filter_userid = "";
2071+ if (isset($_SESSION['content']['filter_userid'])) $filter_userid = $_SESSION['content']['filter_userid'];
2072+
2073+ $user_list = listcontent("all|All,".userlist("SELECT DISTINCT userid FROM layout"),"filter_userid", $filter_userid);
2074+
2075+ //retired list
2076+ $retired = "0";
2077+ if(isset($_SESSION['playlist']['filter_retired'])) $retired = $_SESSION['playlist']['retired'];
2078+ $retired_list = listcontent("all|All,1|Yes,0|No","filter_retired",$retired);
2079+
2080+ //type list query to get all playlists that are in the database which have NOT been assigned to the display
2081+ $sql = "SELECT 'all', 'all' ";
2082+ $sql .= "UNION ";
2083+ $sql .= "SELECT type, type ";
2084+ $sql .= "FROM media ";
2085+ $sql .= "GROUP BY type ";
2086+
2087+ $type_list = dropdownlist($sql,"mediatype",$mediatype);
2088+
2089+ $filterForm = <<<END
2090+ <div class="FilterDiv" id="LibraryFilter">
2091+ <form>
2092+ <input type="hidden" name="p" value="content">
2093+ <input type="hidden" name="q" value="LibraryGrid">
2094+ <input type="hidden" name="pages" id="pages">
2095+
2096+ <table id="content_filterform" class="filterform">
2097+ <tr>
2098+ <td>Name</td>
2099+ <td><input type='text' name='2' id='2' /></td>
2100+ <td>Type</td>
2101+ <td>$type_list</td>
2102+ <td>Retired</td>
2103+ <td>$retired_list</td>
2104+ </tr>
2105+ <tr>
2106+ <td>Owner</td>
2107+ <td>$user_list</td>
2108+ <td></td>
2109+ <td></td>
2110+ <td>Shared</td>
2111+ <td>$shared_list</td>
2112+
2113+ </tr>
2114+ </table>
2115+ </form>
2116+ </div>
2117+>>>>>>> MERGE-SOURCE
2118 END;
2119-
2120- $id = uniqid();
2121-
2122- $xiboGrid = <<<HTML
2123- <div class="XiboGrid" id="$id">
2124- <div class="XiboFilter">
2125- $filterForm
2126- </div>
2127- <div class="XiboData">
2128-
2129- </div>
2130- </div>
2131+
2132+ $id = uniqid();
2133+
2134+ $xiboGrid = <<<HTML
2135+ <div class="XiboGrid" id="$id">
2136+ <div class="XiboFilter">
2137+ $filterForm
2138+ </div>
2139+ <div class="XiboData">
2140+
2141+ </div>
2142+ </div>
2143 HTML;
2144- echo $xiboGrid;
2145+ echo $xiboGrid;
2146 }
2147
2148 /**
2149
2150=== modified file 'server/lib/pages/layout.class.php'
2151=== modified file 'server/lib/pages/module.class.php'
2152=== modified file 'server/lib/pages/stats.class.php'
2153--- server/lib/pages/stats.class.php 2009-08-08 11:04:39 +0000
2154+++ server/lib/pages/stats.class.php 2009-12-31 11:13:18 +0000
2155@@ -132,7 +132,7 @@
2156 while($row = $db->get_assoc_row($result))
2157 {
2158 // Read the columns
2159- $type = Kit::ValidateParam($row['type'], _STRING);
2160+ $type = Kit::ValidateParam($row['Type'], _STRING);
2161 $fromdt = Kit::ValidateParam($row['start'], _STRING);
2162 $todt = Kit::ValidateParam($row['end'], _STRING);
2163 $layout = Kit::ValidateParam($row['Layout'], _STRING);
2164
2165=== modified file 'server/modules/powerpoint.module.php'
2166=== modified file 'server/template/pages/dashboard.php'
2167--- server/template/pages/dashboard.php 2009-12-28 14:45:26 +0000
2168+++ server/template/pages/dashboard.php 2009-12-31 11:13:18 +0000
2169@@ -43,7 +43,16 @@
2170 $title = __($title);
2171 $img = Kit::ValidateParam($menuItem['Img'], _STRING);
2172
2173+<<<<<<< TREE
2174 $href = 'index.php?p=' . $uri . '&' . $args;
2175+=======
2176+
2177+ $href = 'index.php?p=' . $uri . '&' . $args;
2178+
2179+ // Override the HREF for the Manual Button
2180+ if ($uri == 'manual')
2181+ $href = $args;
2182+>>>>>>> MERGE-SOURCE
2183
2184 // Override the HREF for the Manual Button
2185 if ($uri == 'manual')
2186
2187=== modified file 'server/template/pages/login_box.php'
2188--- server/template/pages/login_box.php 2009-12-28 14:35:16 +0000
2189+++ server/template/pages/login_box.php 2009-12-31 11:13:18 +0000
2190@@ -85,8 +85,20 @@
2191 <?php displayMessage(); ?>
2192 <br />
2193 <p><a href="http://www.xibo.org.uk"><img src='img/login/complogo.png'></a></p>
2194+<<<<<<< TREE
2195
2196 <p>Version <?php echo VERSION; ?> | <a href="https://code.launchpad.net/~xibo-maintainers/xibo/encke">Source</a> | <a class="XiboFormButton" href="index.php?p=index&q=About" title="<?php echo __('About Xibo'); ?>"><?php echo __('About'); ?></a></p>
2197+=======
2198+ <p>Version <?php echo VERSION; ?> | <a href="https://code.launchpad.net/~xibo-maintainers/xibo/halley">Source</a></p>
2199+
2200+ <div id="forgotten_details" style="display:none">
2201+ <?php
2202+ /*global $user;
2203+
2204+ $user->forget_details();*/
2205+ ?>
2206+ </div>
2207+>>>>>>> MERGE-SOURCE
2208 </div>
2209
2210 <div class="login_foot">
2211
2212=== added file 'server/upgrade.php.OTHER'
2213--- server/upgrade.php.OTHER 1970-01-01 00:00:00 +0000
2214+++ server/upgrade.php.OTHER 2009-12-31 11:13:18 +0000
2215@@ -0,0 +1,598 @@
2216+<?php
2217+/*
2218+ * Xibo - Digitial Signage - http://www.xibo.org.uk
2219+ * Copyright (C) 2009 Alex Harrington
2220+ *
2221+ * This file is part of Xibo.
2222+ *
2223+ * Xibo is free software: you can redistribute it and/or modify
2224+ * it under the terms of the GNU Affero General Public License as published by
2225+ * the Free Software Foundation, either version 3 of the License, or
2226+ * any later version.
2227+ *
2228+ * Xibo is distributed in the hope that it will be useful,
2229+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2230+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2231+ * GNU Affero General Public License for more details.
2232+ *
2233+ * You should have received a copy of the GNU Affero General Public License
2234+ * along with Xibo. If not, see <http://www.gnu.org/licenses/>.
2235+ */
2236+
2237+DEFINE('XIBO', true);
2238+
2239+include('lib/app/kit.class.php');
2240+include('config/db_config.php');
2241+include('config/config.class.php');
2242+require('settings.php');
2243+
2244+// Once we've calculated the upgrade in step 2 below, we need
2245+// to have included the appropriate upgrade php files
2246+// before we restore the session, so objects get recreated properly.
2247+//
2248+// Check to see if we've passed that point, and if so look at what was posted
2249+// to include those classes.
2250+
2251+if (Kit::GetParam("includes", _POST, _BOOL)) {
2252+ foreach ($_POST as $key => $post) {
2253+ // $key should be like 1-2, 1-3 etc
2254+ // Split $key on - character.
2255+
2256+ $parts = explode('-', $key);
2257+ if (count($parts) == 2) {
2258+ $step = Kit::ValidateParam($parts[0], _INT);
2259+ if (file_exists('install/database/' . $step . '.php')) {
2260+ include_once('install/database/' . $step . '.php');
2261+ }
2262+ }
2263+ }
2264+}
2265+
2266+session_start();
2267+
2268+define('_CHECKBOX', "checkbox");
2269+define('_INPUTBOX', "inputbox");
2270+define('_PASSWORDBOX', "password");
2271+
2272+// create a database class instance
2273+$db = new database();
2274+
2275+if (!$db->connect_db($dbhost, $dbuser, $dbpass)) reportError(0, "Unable to connect to the MySQL database using the settings stored in settings.php.<br /><br />MySQL Error:<br />" . $db->error());
2276+if (!$db->select_db($dbname)) reportError(0, "Unable to select the MySQL database using the settings stored in settings.php.<br /><br />MySQL Error:<br />" . $db->error());
2277+
2278+include('install/header_upgrade.inc');
2279+
2280+if (! $_SESSION['step']) {
2281+ $_SESSION['step'] = 0;
2282+}
2283+
2284+if (Kit::GetParam('skipstep',_POST,_INT) == 1) {
2285+ // Cheat the $_SESSION['step'] variable if required
2286+ // Used if there are environment warnings and we want to retest.
2287+ $_SESSION['step'] = 1;
2288+}
2289+
2290+if ($_SESSION['step'] == 0) {
2291+
2292+ $_SESSION['step'] = 1;
2293+
2294+ # First step of the process.
2295+ # Show a welcome screen and authenticate the user
2296+ ?>
2297+ Welcome to the Xibo Upgrade!<br /><br />
2298+ The upgrade program will take you through the process one step at a time.<br /><br />
2299+ Lets get started!<br /><br />
2300+ Please enter your xibo_admin password:<br /><br />
2301+ <form action="upgrade.php" method="POST">
2302+ <div class="install_table">
2303+ <input type="password" name="password" length="12" />
2304+ </div>
2305+ <div class="loginbutton"><button type="submit">Next ></button></div>
2306+ </form>
2307+ <?php
2308+}
2309+elseif ($_SESSION['step'] == 1) {
2310+ $_SESSION['step'] = 2;
2311+
2312+ if (! $_SESSION['auth']) {
2313+
2314+ # Check password
2315+
2316+ $password = Kit::GetParam('password',_POST,_PASSWORD);
2317+ $password_hash = md5($password);
2318+
2319+ $SQL = sprintf("SELECT `UserID` FROM `user` WHERE UserPassword='%s' AND UserName='xibo_admin'",
2320+ $db->escape_string($password_hash));
2321+ if (! $result = $db->query($SQL)) {
2322+ reportError("0", "An error occured checking your password.<br /><br />MySQL Error:<br />" . mysql_error());
2323+ }
2324+
2325+ if ($db->num_rows($result) == 0) {
2326+ $_SESSION['auth'] = false;
2327+ reportError("0", "Password incorrect. Please try again.");
2328+ }
2329+ else {
2330+ $_SESSION['auth'] = true;
2331+ $_SESSION['db'] = $db;
2332+ }
2333+
2334+ }
2335+## Check server meets specs (as specs might have changed in this release)
2336+ ?>
2337+ <p>First we need to check if your server meets Xibo's requirements.</p>
2338+ <?php
2339+ $db = new Database();
2340+ $cObj = new Config($db);
2341+ echo $cObj->CheckEnvironment();
2342+ if ($cObj->EnvironmentFault()) {
2343+ $_SESSION['step'] = 1;
2344+ ?>
2345+ <form action="upgrade.php" method="POST">
2346+ <div class="loginbutton"><button type="submit">Retest</button></div>
2347+ </form>
2348+ <?php
2349+ }
2350+ else if ($cObj->EnvironmentWarning()) {
2351+ ?>
2352+ <form action="upgrade.php" method="POST">
2353+ <input type="hidden" name="skipstep" value="1">
2354+ <div class="loginbutton"><button type="submit">Retest</button></div>
2355+ </form>
2356+ <form action="upgrade.php" method="POST">
2357+ <div class="loginbutton"><button type="submit">Next ></button></div>
2358+ </form>
2359+ <?php
2360+ }
2361+ else {
2362+ ?>
2363+ <form action="upgrade.php" method="POST">
2364+ <div class="loginbutton"><button type="submit">Next ></button></div>
2365+ </form>
2366+ <?php
2367+ }
2368+}
2369+elseif ($_SESSION['step'] == 2) {
2370+ checkAuth();
2371+# Calculate the upgrade
2372+
2373+ $_SESSION['upgradeFrom'] = Config::Version($db, 'DBVersion');
2374+
2375+ if ($_SESSION['upgradeFrom'] < 1) {
2376+ $_SESSION['upgradeFrom'] = 1;
2377+ }
2378+
2379+ // Get a list of .sql and .php files for the upgrade
2380+ $sql_files = ls('*.sql','install/database',false,array('return_files'));
2381+ $php_files = ls('*.php','install/database',false,array('return_files'));
2382+
2383+ // Sort by natural filename (eg 10 is bigger than 2)
2384+ natcasesort($sql_files);
2385+ natcasesort($php_files);
2386+
2387+ $_SESSION['phpFiles'] = $php_files;
2388+ $_SESSION['sqlFiles'] = $sql_files;
2389+
2390+ $max_sql = Kit::ValidateParam(substr(end($sql_files),0,-4),_INT);
2391+ $max_php = Kit::ValidateParam(substr(end($php_files),0,-4),_INT);
2392+ $_SESSION['upgradeTo'] = max($max_sql, $max_php);
2393+
2394+ if (! $_SESSION['upgradeTo']) {
2395+ reportError("2", "Unable to calculate the upgradeTo value. Check for non-numeric SQL and PHP files in the 'install/datbase' directory.", "Retry");
2396+ }
2397+
2398+ echo '<div class="info">';
2399+ echo '<p>Upgrading from database version ' . $_SESSION['upgradeFrom'] . ' to ' . $_SESSION['upgradeTo'];
2400+ echo '</p></div><hr width="25%"/>';
2401+ echo '<form action="upgrade.php" method="POST">';
2402+
2403+ // Loop for $i between upgradeFrom + 1 and upgradeTo.
2404+ // If a php file exists for that upgrade, make an instance of it and call Questions so we can
2405+ // Ask the user for input.
2406+ for ($i=$_SESSION['upgradeFrom'] + 1; $i <= $_SESSION['upgradeTo']; $i++) {
2407+ if (file_exists('install/database/' . $i . '.php')) {
2408+ include_once('install/database/' . $i . '.php');
2409+ $stepName = 'Step' . $i;
2410+
2411+ // Check that a class called Step$i exists
2412+ if (class_exists($stepName)) {
2413+ $_SESSION['Step' . $i] = new $stepName($db);
2414+ // Call Questions on the object and send the resulting hash to createQuestions routine
2415+ createQuestions($i, $_SESSION['Step' . $i]->Questions());
2416+ }
2417+ else {
2418+ print "Warning: We included $i.php, but it did not include a class of appropriate name.";
2419+ }
2420+ }
2421+ }
2422+
2423+ echo '<div class="info"><p>';
2424+ echo "Perform automatic database backup?";
2425+ echo '</p></div><div class="install-table">';
2426+ echo '<input type="checkbox" name="doBackup" checked />';
2427+ echo '</div><hr width="25%" />';
2428+
2429+ $_SESSION['step'] = 3;
2430+ echo '<input type="hidden" name="includes" value="true" />';
2431+ echo '<p><input type="submit" value="Next >" /></p>';
2432+ echo '</form>';
2433+
2434+?>
2435+ <?php
2436+}
2437+elseif ($_SESSION['step'] == 3) {
2438+ // $_SESSION['step'] = 0;
2439+ $fault = false;
2440+ $fault_string = "";
2441+
2442+ foreach ($_POST as $key => $post) {
2443+ // $key should be like 1-2, 1-3 etc
2444+ // Split $key on - character.
2445+
2446+ $parts = explode('-', $key);
2447+ if (count($parts) == 2) {
2448+ $step_num = 'Step' . $parts[0];
2449+ include_once('install/database/' . $parts[0] . '.php');
2450+ // $_SESSION['q'][$step_num] = unserialize($_SESSION['q'][$step_num]);
2451+;
2452+ $response = $_SESSION[$step_num]->ValidateQuestion($parts[1], $post);
2453+ if (! $response == true) {
2454+ // The upgrade routine for this step wasn't happy.
2455+ $fault = true;
2456+ $fault_string .= $response . "<br />\n";
2457+ }
2458+ }
2459+ }
2460+
2461+ if ($fault) {
2462+ // Report the error, and a back button
2463+ echo "FAIL: " . $fault_string;
2464+ }
2465+ else {
2466+ $doBackup = Kit::GetParam("doBackup", $_POST, _BOOL);
2467+
2468+ set_time_limit(0);
2469+ // Backup the database
2470+ echo '<div class="info"><p>';
2471+ if ($doBackup) {
2472+ echo 'Backing up your database';
2473+ backup_tables($db, '*');
2474+ }
2475+ else {
2476+ echo 'Skipping database backup';
2477+ }
2478+ echo '</p>';
2479+
2480+ $sqlStatementCount = 0;
2481+ // Now loop over the entire upgrade. Run the SQLs and PHP interleaved.
2482+ for ($i=$_SESSION['upgradeFrom'] + 1; (($i <= $_SESSION['upgradeTo']) && ($fault==false)) ; $i++) {
2483+ if (file_exists('install/database/' . $i . '.sql')) {
2484+ echo '<p>' . $i . '.sql ';
2485+ flush();
2486+ $delimiter = ';';
2487+ $sql_file = @file_get_contents('install/database/' . $i . '.sql');
2488+ $sql_file = remove_remarks($sql_file);
2489+ $sql_file = split_sql_file($sql_file, $delimiter);
2490+
2491+ foreach ($sql_file as $sql) {
2492+ print ".";
2493+ $sqlStatementCount++;
2494+ flush();
2495+ if (! $db->query($sql)) {
2496+ $fault = true;
2497+ reportError("0", "An error occured populating the database.<br /><br />MySQL Error:<br />" . $db->error() . "<br /><br />SQL executed:<br />" . $sql . "<br /><br />Statement number: " . $sqlStatementCount);
2498+ }
2499+ }
2500+ echo '</p>';
2501+ }
2502+ if (file_exists('install/database/' . $i . '.php')) {
2503+ $stepName = 'Step' . $i;
2504+ echo '<p>' . $i . '.php ';
2505+ flush();
2506+ if (! $_SESSION[$stepName]->Boot()) {
2507+ $fault = true;
2508+ }
2509+ echo '</p>';
2510+ }
2511+ }
2512+ echo '</div>';
2513+ if (! $fault) {
2514+ if (! unlink('install.php')) {
2515+ echo "Unable to delete install.php. Please remove this file manually.";
2516+ }
2517+ if (! unlink('upgrade.php')) {
2518+ echo "Unable to delete upgrade.php. Please remove this file manually.";
2519+ }
2520+
2521+ echo '<b>Upgrade is complete!</b><br /><br />';
2522+ echo '<form method="POST" action="index.php">';
2523+ echo '<input type="submit" value="Login" />';
2524+ echo '</form>';
2525+ }
2526+ else {
2527+ echo '<b>There was an error during the upgrade. Please take a screenshot of this page and seek help!</b>';
2528+ }
2529+ session_destroy();
2530+ }
2531+}
2532+else {
2533+ reportError("0","A required parameter was missing. Please go through the installer sequentially!","Start Again");
2534+}
2535+
2536+include('install/footer.inc');
2537+
2538+# Functions
2539+function checkPHP() {
2540+ # Check PHP version > 5
2541+ return (version_compare("5.1.0",phpversion(), "<="));
2542+}
2543+
2544+function reportError($step, $message, $button_text="&lt; Back") {
2545+ $_SESSION['step'] = $step;
2546+?>
2547+ <div class="info">
2548+ <?php print $message; ?>
2549+ </div>
2550+ <form action="upgrade.php" method="POST">
2551+ <button type="submit"><?php print $button_text; ?></button>
2552+ </form>
2553+ <?php
2554+ include('install/footer.inc');
2555+ die();
2556+}
2557+
2558+function checkAuth() {
2559+ if (! $_SESSION['auth']) {
2560+ reportError(1, "You must authenticate to run the upgrade.");
2561+ }
2562+}
2563+
2564+// Taken from http://forums.devshed.com/php-development-5/php-wont-load-sql-from-file-515902.html
2565+// By Crackster
2566+/**
2567+ * remove_remarks will strip the sql comment lines out of an uploaded sql file
2568+ */
2569+function remove_remarks($sql){
2570+ $sql = preg_replace('/\n{2,}/', "\n", preg_replace('/^[-].*$/m', "\n", $sql));
2571+ $sql = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql));
2572+ return $sql;
2573+}
2574+
2575+// Taken from http://forums.devshed.com/php-development-5/php-wont-load-sql-from-file-515902.html
2576+// By Crackster
2577+/**
2578+ * split_sql_file will split an uploaded sql file into single sql statements.
2579+ * Note: expects trim() to have already been run on $sql.
2580+ */
2581+function split_sql_file($sql, $delimiter){
2582+ $sql = str_replace("\r" , '', $sql);
2583+ $data = preg_split('/' . preg_quote($delimiter, '/') . '$/m', $sql);
2584+ $data = array_map('trim', $data);
2585+ // The empty case
2586+ $end_data = end($data);
2587+ if (empty($end_data))
2588+ {
2589+ unset($data[key($data)]);
2590+ }
2591+ return $data;
2592+}
2593+
2594+/**
2595+ * This funtion will take a pattern and a folder as the argument and go thru it(recursivly if needed)and return the list of
2596+ * all files in that folder.
2597+ * Link : http://www.bin-co.com/php/scripts/filesystem/ls/
2598+ * License : BSD
2599+ * Arguments : $pattern - The pattern to look out for [OPTIONAL]
2600+ * $folder - The path of the directory of which's directory list you want [OPTIONAL]
2601+ * $recursivly - The funtion will traverse the folder tree recursivly if this is true. Defaults to false. [OPTIONAL]
2602+ * $options - An array of values 'return_files' or 'return_folders' or both
2603+ * Returns : A flat list with the path of all the files(no folders) that matches the condition given.
2604+ */
2605+function ls($pattern="*", $folder="", $recursivly=false, $options=array('return_files','return_folders')) {
2606+ if($folder) {
2607+ $current_folder = realpath('.');
2608+ if(in_array('quiet', $options)) { // If quiet is on, we will suppress the 'no such folder' error
2609+ if(!file_exists($folder)) return array();
2610+ }
2611+
2612+ if(!chdir($folder)) return array();
2613+ }
2614+
2615+
2616+ $get_files = in_array('return_files', $options);
2617+ $get_folders= in_array('return_folders', $options);
2618+ $both = array();
2619+ $folders = array();
2620+
2621+ // Get the all files and folders in the given directory.
2622+ if($get_files) $both = glob($pattern, GLOB_BRACE + GLOB_MARK);
2623+ if($recursivly or $get_folders) $folders = glob("*", GLOB_ONLYDIR + GLOB_MARK);
2624+
2625+ //If a pattern is specified, make sure even the folders match that pattern.
2626+ $matching_folders = array();
2627+ if($pattern !== '*') $matching_folders = glob($pattern, GLOB_ONLYDIR + GLOB_MARK);
2628+
2629+ //Get just the files by removing the folders from the list of all files.
2630+ $all = array_values(array_diff($both,$folders));
2631+
2632+ if($recursivly or $get_folders) {
2633+ foreach ($folders as $this_folder) {
2634+ if($get_folders) {
2635+ //If a pattern is specified, make sure even the folders match that pattern.
2636+ if($pattern !== '*') {
2637+ if(in_array($this_folder, $matching_folders)) array_push($all, $this_folder);
2638+ }
2639+ else array_push($all, $this_folder);
2640+ }
2641+
2642+ if($recursivly) {
2643+ // Continue calling this function for all the folders
2644+ $deep_items = ls($pattern, $this_folder, $recursivly, $options); # :RECURSION:
2645+ foreach ($deep_items as $item) {
2646+ array_push($all, $this_folder . $item);
2647+ }
2648+ }
2649+ }
2650+ }
2651+
2652+ if($folder) chdir($current_folder);
2653+ return $all;
2654+}
2655+
2656+// Taken from http://davidwalsh.name/backup-mysql-database-php
2657+// No explicit license. Assumed public domain.
2658+// Ammended to use a database object by Alex Harrington.
2659+// If this is your code, and wish for us to remove it, please contact
2660+// info@xibo.org.uk
2661+/* backup the db OR just a table */
2662+function backup_tables($db,$tables = '*')
2663+{
2664+ //get all of the tables
2665+ if($tables == '*')
2666+ {
2667+ $tables = array();
2668+ $result = $db->query('SHOW TABLES');
2669+ while($row = $db->get_row($result))
2670+ {
2671+ $tables[] = $row[0];
2672+ }
2673+ }
2674+ else
2675+ {
2676+ $tables = is_array($tables) ? $tables : explode(',',$tables);
2677+ }
2678+
2679+ // Open file for writing at length 0.
2680+ $handle = fopen(Config::GetSetting($db,'LIBRARY_LOCATION') . 'db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
2681+
2682+ //cycle through
2683+ foreach($tables as $table)
2684+ {
2685+ echo '.';
2686+ flush();
2687+ $result = $db->query('SELECT * FROM `'.$table .'`');
2688+ $num_fields = $db->num_fields($result);
2689+
2690+ $return = 'DROP TABLE IF EXISTS `'.$table.'`;';
2691+ fwrite($handle, $return);
2692+
2693+ $row2 = $db->get_row($db->query('SHOW CREATE TABLE `'.$table.'`'));
2694+ $return = "\n\n".$row2[1].";\n\n";
2695+ fwrite($handle,$return);
2696+
2697+ for ($i = 0; $i < $num_fields; $i++)
2698+ {
2699+ while($row = $db->get_row($result))
2700+ {
2701+ $return = 'INSERT INTO `'.$table.'` VALUES(';
2702+ fwrite($handle, $return);
2703+ for($j=0; $j<$num_fields; $j++)
2704+ {
2705+ $return = '';
2706+ $row[$j] = addslashes($row[$j]);
2707+ $row[$j] = ereg_replace("\n","\\n",$row[$j]);
2708+ if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
2709+ if ($j<($num_fields-1)) { $return.= ','; }
2710+ fwrite($handle, $return);
2711+ }
2712+ $return = ");\n";
2713+ fwrite($handle, $return);
2714+ }
2715+ }
2716+ $return ="\n\n\n";
2717+ fwrite ($handle, $return);
2718+ }
2719+
2720+ fclose($handle);
2721+}
2722+
2723+
2724+function gen_secret() {
2725+ # Generates a random 12 character alphanumeric string to use as a salt
2726+ mt_srand((double)microtime()*1000000);
2727+ $key = "";
2728+ for ($i=0; $i < 12; $i++) {
2729+ $c = mt_rand(0,2);
2730+ if ($c == 0) {
2731+ $key .= chr(mt_rand(65,90));
2732+ }
2733+ elseif ($c == 1) {
2734+ $key .= chr(mt_rand(97,122));
2735+ }
2736+ else {
2737+ $key .= chr(mt_rand(48,57));
2738+ }
2739+ }
2740+
2741+ return $key;
2742+}
2743+
2744+function createQuestions($step, $questions) {
2745+ // Takes a multi-dimensional array eg:
2746+ // $q[0]['question'] = "May we collect anonymous usage statistics?";
2747+ // $q[0]['type'] = _CHECKBOX;
2748+ // $q[0]['default'] = true;
2749+ //
2750+ // And turns it in to an HTML form for the user to complete.
2751+ foreach ($questions as $qnum => $question) {
2752+ echo '<div class="info"><p>';
2753+ echo $question['question'];
2754+ echo '</p></div><div class="install-table">';
2755+
2756+ if (($question['type'] == _INPUTBOX) || ($question['type'] == _PASSWORD)) {
2757+ echo '<input type="';
2758+ if ($question['type'] == _INPUTBOX) {
2759+ echo 'text';
2760+ }
2761+ else {
2762+ echo 'password';
2763+ }
2764+ echo '" name="' . $step . '-' . $qnum .'" value="'. $question['default'] .'" length="12" />';
2765+ }
2766+ elseif ($question['type'] == _CHECKBOX) {
2767+ echo '<input type="checkbox" name="' . $step . '-' . $qnum . '" ';
2768+ if ($question['default']) {
2769+ echo 'checked ';
2770+ }
2771+ echo '/>';
2772+ }
2773+ echo '</div><hr width="25%" />';
2774+ }
2775+}
2776+
2777+//function __autoload($class_name) {
2778+// if (substr($class_name,0,4) == "Step") {
2779+// $class_name = substr($class_name,4);
2780+// require_once install/database/$class_name . '.php';
2781+// }
2782+//}
2783+
2784+class UpgradeStep
2785+{
2786+ protected $db;
2787+ protected $q;
2788+ protected $a;
2789+
2790+ public function __construct($db)
2791+ {
2792+ $this->db =& $db;
2793+ $this->q = array();
2794+ $this->a = array();
2795+ }
2796+
2797+ public function Boot()
2798+ {
2799+
2800+ }
2801+
2802+ public function Questions()
2803+ {
2804+ return array();
2805+ }
2806+
2807+ public function ValidateQuestion($questionNumber,$response)
2808+ {
2809+ return true;
2810+ }
2811+}
2812+
2813+?>
2814
2815=== modified file 'server/xmds.php'

Subscribers

People subscribed via source and target branches