Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Server Side Scripting added along with other changes.

  * Added Qt Script support to the Html server allowing for JSP/ASP type
    server side scripting. See http://mythbackend:6544/ and select the
    "Sample Pages" menu choice.

  * Added API support for built in types.  Now, QString, bool, int,
    QFileInfo, QStringList, etc. types can be returned from API methods.

    This change modifies some of the XML schema produced by these functions.

  * When an API method is called via http, if the method name starts with
    Get or Put, it can be left off and the http method (GET / POST) will
    be used to determine if the get or put version should be called.

  * GetPreviewImage & GetRecording now respond with a redirect (301) if
    the wrong host is called.

  * WSDL support has changed and is still NOT working.  More fixes to come.
  • Loading branch information...
commit 25755892849b2f098553f8cb003ed5172c7acdda 1 parent 0b33d93
@dblain dblain authored
Showing with 1,964 additions and 489 deletions.
  1. +1 −1  mythtv/html/html.pro
  2. +3 −0  mythtv/html/index.html
  3. +39 −0 mythtv/html/js/inspect.js
  4. +148 −0 mythtv/html/samples/index.qsp
  5. +91 −0 mythtv/html/samples/recorded.qsp
  6. +4 −4 mythtv/html/setup/js/storagegroups.js
  7. +1 −1  mythtv/libs/libmyth/libmyth.pro
  8. +0 −18 mythtv/libs/libmythservicecontracts/datacontracthelper.h
  9. +14 −1 mythtv/libs/libmythservicecontracts/datacontracts/connectionInfo.h
  10. +10 −3 mythtv/libs/libmythservicecontracts/datacontracts/databaseInfo.h
  11. +12 −1 mythtv/libs/libmythservicecontracts/datacontracts/encoder.h
  12. +19 −1 mythtv/libs/libmythservicecontracts/datacontracts/encoderList.h
  13. +49 −10 mythtv/libs/libmythservicecontracts/datacontracts/programAndChannel.h
  14. +20 −1 mythtv/libs/libmythservicecontracts/datacontracts/programGuide.h
  15. +20 −1 mythtv/libs/libmythservicecontracts/datacontracts/programList.h
  16. +10 −1 mythtv/libs/libmythservicecontracts/datacontracts/recording.h
  17. +18 −2 mythtv/libs/libmythservicecontracts/datacontracts/settingList.h
  18. +10 −1 mythtv/libs/libmythservicecontracts/datacontracts/storageGroupDir.h
  19. +19 −1 mythtv/libs/libmythservicecontracts/datacontracts/storageGroupDirList.h
  20. +0 −59 mythtv/libs/libmythservicecontracts/datacontracts/stringList.h
  21. +0 −59 mythtv/libs/libmythservicecontracts/datacontracts/successFail.h
  22. +11 −1 mythtv/libs/libmythservicecontracts/datacontracts/wolInfo.h
  23. +0 −2  mythtv/libs/libmythservicecontracts/libmythservicecontracts.pro
  24. +38 −26 mythtv/libs/libmythservicecontracts/service.cpp
  25. +12 −4 mythtv/libs/libmythservicecontracts/service.h
  26. +18 −9 mythtv/libs/libmythservicecontracts/services/contentServices.h
  27. +10 −0 mythtv/libs/libmythservicecontracts/services/dvrServices.h
  28. +12 −1 mythtv/libs/libmythservicecontracts/services/guideServices.h
  29. +21 −11 mythtv/libs/libmythservicecontracts/services/mythServices.h
  30. +32 −4 mythtv/libs/libmythupnp/htmlserver.cpp
  31. +9 −1 mythtv/libs/libmythupnp/htmlserver.h
  32. +6 −0 mythtv/libs/libmythupnp/httprequest.cpp
  33. +37 −0 mythtv/libs/libmythupnp/httprequest.h
  34. +9 −0 mythtv/libs/libmythupnp/httpserver.cpp
  35. +4 −0 mythtv/libs/libmythupnp/httpserver.h
  36. +4 −4 mythtv/libs/libmythupnp/libmythupnp.pro
  37. +5 −2 mythtv/libs/libmythupnp/serializers/jsonSerializer.cpp
  38. +6 −2 mythtv/libs/libmythupnp/serializers/jsonSerializer.h
  39. +6 −5 mythtv/libs/libmythupnp/serializers/serializer.cpp
  40. +8 −4 mythtv/libs/libmythupnp/serializers/serializer.h
  41. +4 −2 mythtv/libs/libmythupnp/serializers/soapSerializer.h
  42. +51 −12 mythtv/libs/libmythupnp/serializers/xmlSerializer.cpp
  43. +8 −2 mythtv/libs/libmythupnp/serializers/xmlSerializer.h
  44. +297 −0 mythtv/libs/libmythupnp/serverSideScripting.cpp
  45. +112 −0 mythtv/libs/libmythupnp/serverSideScripting.h
  46. +166 −54 mythtv/libs/libmythupnp/servicehost.cpp
  47. +1 −1  mythtv/libs/libmythupnp/servicehost.h
  48. +25 −0 mythtv/libs/libmythupnp/upnp.cpp
  49. +4 −0 mythtv/libs/libmythupnp/upnp.h
  50. +226 −43 mythtv/libs/libmythupnp/wsdl.cpp
  51. +18 −2 mythtv/libs/libmythupnp/wsdl.h
  52. +21 −0 mythtv/programs/mythbackend/mediaserver.cpp
  53. +1 −1  mythtv/programs/mythbackend/mythbackend.pro
  54. +47 −44 mythtv/programs/mythbackend/services/content.cpp
  55. +13 −9 mythtv/programs/mythbackend/services/content.h
  56. +51 −0 mythtv/programs/mythbackend/services/dvr.h
  57. +9 −10 mythtv/programs/mythbackend/services/guide.cpp
  58. +54 −1 mythtv/programs/mythbackend/services/guide.h
  59. +27 −56 mythtv/programs/mythbackend/services/myth.cpp
  60. +88 −9 mythtv/programs/mythbackend/services/myth.h
  61. +4 −1 mythtv/programs/mythfrontend/main.cpp
  62. +1 −1  mythtv/programs/mythfrontend/mythfrontend.pro
View
2  mythtv/html/html.pro
@@ -10,7 +10,7 @@ win32:QMAKE_COPY_DIR = sh ./cpsimple
html.path = $${PREFIX}/share/mythtv/html/
html.files = index.html overview.html
-html.files += css images js misc setup
+html.files += css images js misc setup samples
INSTALLS += html
View
3  mythtv/html/index.html
@@ -65,6 +65,9 @@
-->
<li><a class='menuitem' href='/Status/GetStatusHTML'>Backend Status</a></li>
<li><a class='menuitem' href='/misc/wsdl.html'>WSDL Links</a></li>
+ <li><hr></li>
+ <li><a class='menuitem' href='/samples/index.qsp'>Sample Pages</a></li>
+
</ul>
<br>
<center><a class='menuitem' href='http://www.mythtv.org'>www.mythtv.org</a></center>
View
39 mythtv/html/js/inspect.js
@@ -0,0 +1,39 @@
+function inspect(obj, maxLevels, level)
+{
+ var str = '', type, msg;
+ if(level == null) level = 0;
+
+ if(maxLevels == null) maxLevels = 1;
+ if(maxLevels < 1)
+ return '<font color="red">Error: Levels number must be > 0</font>';
+
+ if(obj == null)
+ return '<font color="red">Error: Object <b>NULL</b></font>';
+
+ str += '<ul>';
+
+ for(property in obj)
+ {
+ try
+ {
+ type = typeof(obj[property]);
+ str += '<li>(' + type + ') ' + property +
+ ( (obj[property]==null)?(': <b>null</b>'):('')) + '</li>';
+
+ if((type == 'object') && (obj[property] != null) && (level+1 < maxLevels))
+ str += inspect(obj[property], maxLevels, level+1);
+ }
+ catch(err)
+ {
+ if(typeof(err) == 'string') msg = err;
+ else if(err.message) msg = err.message;
+ else if(err.description) msg = err.description;
+ else msg = 'Unknown';
+
+ str += '<li><font color="red">(Error) ' + property + ': ' + msg +'</font></li>';
+ }
+ }
+ str += '</ul>';
+
+ return str;
+}
View
148 mythtv/html/samples/index.qsp
@@ -0,0 +1,148 @@
+<html>
+<head>
+<title>
+MythTV mythbackend Internal Web Server
+</title>
+<link rel="stylesheet" href="/css/site.css" type="text/css">
+<link rel="icon" href="/images/favicon.ico" type="image/x-icon">
+<link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon">
+<script language="JavaScript" type="text/javascript" src="/js/jquery.min.js"></script>
+<script language="JavaScript" type="text/javascript" src="/js/inspect.js"></script>
+
+<script language="JavaScript" type="text/javascript">
+
+$(document).ready(function()
+{
+ jQuery.ajaxSetup({ type: "GET",
+ contentType: "application/json; charset=utf-8",
+ data: "{}",
+ dataType: "json" });
+
+ $("#Settings").change( GetSettingValue );
+});
+
+function GetSettingValue()
+{
+ var sKey = $("#Settings").val();
+
+ jQuery.getJSON(
+ "Myth/GetSetting",
+ { "Key": sKey },
+ function( data )
+ {
+ if (data.hasOwnProperty( 'd' ))
+ data = data.d;
+
+
+ $("#debug").html( inspect( data , 10 ) );
+
+
+ $("#SettingValue").val( data.SettingList.Settings[0].Value );
+ });
+}
+
+</script>
+
+</head>
+<body>
+
+<!-- Header -->
+<div id="header">
+ <div id="header_logo">
+ <a href="/"><img src="/images/mythtv.png" class="png" width="180" height="64" border="0" alt="MythTV"></a>
+ </div>
+
+ <div id="header_title">
+ </div>
+
+ <div id="header_end">
+ </div>
+</div><!-- header -->
+
+<div id="menu-bg">
+ <div id="menu-title" align=center>
+ Setup
+ </div>
+
+ <div id="menu">
+ <ul>
+ <li><a class='menuitem' href='/samples/index.qsp'>Server Side Script</a></li>
+ <li><a class='menuitem' href='/samples/recorded.qsp'>Recorded Sample</a></li>
+ </ul>
+ <br>
+ <center><a class='menuitem' href='/'>Back To Main Menu</a></center>
+ </div>
+</div>
+
+<div id="content">
+<br>
+<h3>Sample Server Side Script Page...</h3>
+<hr>
+<p>
+This implementation of Server Side scripting is a simple adaptation of the old jsp &amp; asp model.
+It leverages the Qt Script Engine and exposes all API Classes to the running script.
+</p>
+<p>
+Server side scripting is accomplished by wrapping script code that you wish to be executed on the server with <span style="color: yellow;">&lt;%</span> and <span style="color: yellow;">%&gt;</span>
+</p>
+<p>
+Values generated from the script can be inserted into the rendered html page using the following approaches:
+</p>
+<li>From within script code:</li>
+ <div style="margin-left:30px">
+ <p>There is an object available with a variable named '<b>os</b>' that has two methods available <b>write</b> and <b>writeln</b></p>
+ <h5>Example:</h5>
+ <pre>os.writeln( "This is text written from within server side script code" );</pre>
+ </div>
+<li>Embedded in html:</li>
+ <div style="margin-left:30px">
+ <p><span style="color: yellow;">&lt;%=</span> script variable/statement <span style="color: yellow;">%&gt;</span></p>
+ </div>
+
+<h3>Using the API classes</h3>
+<p>To use one of the API classes, it's as simple as assigning a variable to a new instances of the class you want to use.
+<pre><b>var myth = new Myth()</b></pre>
+then calling the method:
+<pre><b>var list = myth.GetHosts();</b></pre>
+</p>
+<br>
+
+<div style="margin-left:30px">
+ Hosts:
+ <select id="hosts">
+<%
+ var myth = new Myth();
+
+ var list = myth.GetHosts();
+
+ for (var nIdx=0; nIdx < list.length; nIdx++)
+ {
+%>
+ <option value="<%= nIdx %>"><%=list[nIdx]%></option>
+<% } %>
+ </select>
+</div>
+<hr>
+<div style="margin-left:30px">
+ List of Settings:
+ <select id="Settings" onchange="GetSettingValue()">
+<%
+ var sList = myth.GetSetting( "", "", "");
+
+ var keys = sList.Settings;
+
+ for (var sValue in sList.Settings)
+ {
+%>
+ <option value="<%= sValue %>"><%=sValue %></option>
+<% } %>
+ </select>
+ <br>
+ Value (uses ajax to retrieve value): <input type="text" id="SettingValue" />
+
+</div>
+<div id="debug" > </div>
+</div> <!-- content -->
+
+</body>
+</html>
View
91 mythtv/html/samples/recorded.qsp
@@ -0,0 +1,91 @@
+<html>
+<head>
+<title>
+MythTV mythbackend Internal Web Server
+</title>
+<link rel="stylesheet" href="/css/site.css" type="text/css">
+<link rel="icon" href="/images/favicon.ico" type="image/x-icon">
+<link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon">
+</head>
+<body>
+
+<!-- Header -->
+<div id="header">
+ <div id="header_logo">
+ <a href="/"><img src="/images/mythtv.png" class="png" width="180" height="64" border="0" alt="MythTV"></a>
+ </div>
+
+ <div id="header_title">
+ </div>
+
+ <div id="header_end">
+ </div>
+</div><!-- header -->
+
+<div id="menu-bg">
+ <div id="menu-title" align=center>
+ Setup
+ </div>
+
+ <div id="menu">
+ <ul>
+ <li><a class='menuitem' href='/samples/index.qsp'>Server Side Script</a></li>
+ <li><a class='menuitem' href='/samples/recorded.qsp'>Recorded Sample</a></li>
+ </ul>
+ <br>
+ <center><a class='menuitem' href='/'>Back To Main Menu</a></center>
+ </div>
+</div>
+
+<div id="content">
+<br>
+<h3>Sample Server Side Script Page... List of Recorded Programs<super>*</super></h3>
+<super>*</super>This would be better implemented as an ajax call.
+<hr>
+<table border="1">
+<%
+
+ var oDvr = new Dvr();
+
+ var list = oDvr.GetRecorded( true, 0, -1);
+
+ for (var nIdx=0; nIdx < list.Programs.length; nIdx++)
+ {
+ var program = list.Programs[ nIdx ];
+%>
+ <tr>
+ <td><img src="/Content/GetPreviewImage?ChanId=<%= program.Channel.ChanId%>&StartTime=<%= ISODateString( program.StartTime ) %>" ></img></td>
+
+ <td><%= program.StartTime %></td>
+ <td><%= ISODateString( program.StartTime ) %></td>
+ <td><%=program.Description %></td>
+ </tr>
+<%
+ }
+
+%>
+</table>
+<%
+%>
+</div>
+<div id="debug" > </div>
+</div> <!-- content -->
+<%
+
+function ISODateString(d)
+{
+ function pad(n)
+ {
+ return n<10 ? '0'+n : n
+ }
+ return d.getFullYear()+'-'
+ + pad(d.getMonth()+1)+'-'
+ + pad(d.getDate())+'T'
+ + pad(d.getHours())+':'
+ + pad(d.getMinutes())+':'
+ + pad(d.getSeconds())
+}
+
+%>
+</body>
+</html>
View
8 mythtv/html/setup/js/storagegroups.js
@@ -81,10 +81,10 @@ function addStorageGroupDir( group, dir, host ) {
$.post("/Myth/AddStorageGroupDir",
{ GroupName: group, DirName: dir, HostName: host},
function(data) {
- if (data.SuccessFail.Result == "true")
+ if (data.bool == "true")
result = 1;
else
- alert("data.SuccessFail.Result != true");
+ alert("data.bool != true");
}, "json").error(function(data) {
alert("Error: unable to add Storage Group Directory");
});
@@ -103,10 +103,10 @@ function removeStorageGroupDir( group, dir, host ) {
$.post("/Myth/RemoveStorageGroupDir",
{ GroupName: group, DirName: dir, HostName: host},
function(data) {
- if (data.SuccessFail.Result == "true")
+ if (data.bool == "true")
result = 1;
else
- alert("data.SuccessFail.Result != true");
+ alert("data.bool != true");
}, "json").error(function(data) {
alert("Error: unable to remove Storage Group Directory");
});
View
2  mythtv/libs/libmyth/libmyth.pro
@@ -8,7 +8,7 @@ INSTALLS = target
DEFINES += MYTH_API
-QT += network xml sql
+QT += network xml sql script
QMAKE_CLEAN += $(TARGET) $(TARGETA) $(TARGETD) $(TARGET0) $(TARGET1) $(TARGET2)
View
18 mythtv/libs/libmythservicecontracts/datacontracthelper.h
@@ -80,24 +80,6 @@
//////////////////////////////////////////////////////////////////////////////
-#define PROPERTYIMP_PTR_Old( type, name ) \
- private: type* m_##name; \
- public: \
- type* name() \
- { \
- return m_##name; \
- } \
- void set##name( QObject* val) \
- { \
- m_##name = qobject_cast< type* >( val ); \
- } \
- void set##name( type* val) \
- { \
- m_##name = val; \
- }
-
-//////////////////////////////////////////////////////////////////////////////
-
#define PROPERTYIMP_RO_REF( type, name ) \
private: type m_##name; \
public: \
View
15 mythtv/libs/libmythservicecontracts/datacontracts/connectionInfo.h
@@ -34,6 +34,7 @@ namespace DTC
class SERVICE_PUBLIC ConnectionInfo : public QObject
{
Q_OBJECT
+
Q_CLASSINFO( "version" , "1.0" );
Q_PROPERTY( QObject* Database READ Database )
@@ -44,6 +45,17 @@ class SERVICE_PUBLIC ConnectionInfo : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< ConnectionInfo >();
+ qRegisterMetaType< ConnectionInfo* >();
+
+ DatabaseInfo::InitializeCustomTypes();
+ WOLInfo ::InitializeCustomTypes();
+ }
+
+ public:
+
ConnectionInfo(QObject *parent = 0)
: QObject ( parent ),
m_Database ( NULL ),
@@ -75,6 +87,7 @@ typedef ConnectionInfo* ConnectionInfoPtr;
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::ConnectionInfo )
+Q_DECLARE_METATYPE( DTC::ConnectionInfo )
+Q_DECLARE_METATYPE( DTC::ConnectionInfo* )
#endif
View
13 mythtv/libs/libmythservicecontracts/datacontracts/databaseInfo.h
@@ -57,6 +57,14 @@ class SERVICE_PUBLIC DatabaseInfo : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< DatabaseInfo >();
+ qRegisterMetaType< DatabaseInfo* >();
+ }
+
+ public:
+
DatabaseInfo(QObject *parent = 0)
: QObject ( parent ),
m_Ping ( false ),
@@ -82,14 +90,13 @@ class SERVICE_PUBLIC DatabaseInfo : public QObject
m_LocalEnabled = src.m_LocalEnabled ;
m_LocalHostName= src.m_LocalHostName;
}
-
};
typedef DatabaseInfo * DatabaseInfoPtr;
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::DatabaseInfo )
-
+Q_DECLARE_METATYPE( DTC::DatabaseInfo )
+Q_DECLARE_METATYPE( DTC::DatabaseInfo* )
#endif
View
13 mythtv/libs/libmythservicecontracts/datacontracts/encoder.h
@@ -61,6 +61,16 @@ class SERVICE_PUBLIC Encoder : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< Encoder >();
+ qRegisterMetaType< Encoder* >();
+
+ Program::InitializeCustomTypes();
+ }
+
+ public:
+
Encoder(QObject *parent = 0)
: QObject ( parent ),
m_Id ( 0 ),
@@ -97,6 +107,7 @@ class SERVICE_PUBLIC Encoder : public QObject
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::Encoder )
+Q_DECLARE_METATYPE( DTC::Encoder )
+Q_DECLARE_METATYPE( DTC::Encoder* )
#endif
View
20 mythtv/libs/libmythservicecontracts/datacontracts/encoderList.h
@@ -37,12 +37,29 @@ class SERVICE_PUBLIC EncoderList : public QObject
Q_OBJECT
Q_CLASSINFO( "version", "1.0" );
+ // We need to know the type that will ultimately be contained in
+ // any QVariantList or QVariantMap. We do his by specifying
+ // A Q_CLASSINFO entry with "<PropName>_type" as the key
+ // and the type name as the value
+
+ Q_CLASSINFO( "Encoders_type", "DTC::Encoder");
+
Q_PROPERTY( QVariantList Encoders READ Encoders DESIGNABLE true )
PROPERTYIMP_RO_REF( QVariantList, Encoders )
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< EncoderList >();
+ qRegisterMetaType< EncoderList* >();
+
+ Encoder::InitializeCustomTypes();
+ }
+
+ public:
+
EncoderList(QObject *parent = 0)
: QObject( parent )
{
@@ -73,6 +90,7 @@ class SERVICE_PUBLIC EncoderList : public QObject
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::EncoderList )
+Q_DECLARE_METATYPE( DTC::EncoderList )
+Q_DECLARE_METATYPE( DTC::EncoderList* )
#endif
View
59 mythtv/libs/libmythservicecontracts/datacontracts/programAndChannel.h
@@ -41,6 +41,13 @@ class SERVICE_PUBLIC ChannelInfo : public QObject
Q_OBJECT
Q_CLASSINFO( "version", "1.0" );
+ // We need to know the type that will ultimately be contained in
+ // any QVariantList or QVariantMap. We do his by specifying
+ // A Q_CLASSINFO entry with "<PropName>_type" as the key
+ // and the type name as the value
+
+ Q_CLASSINFO( "Programs_type", "DTC::Program");
+
Q_PROPERTY( uint ChanId READ ChanId WRITE setChanId )
Q_PROPERTY( QString ChanNum READ ChanNum WRITE setChanNum )
Q_PROPERTY( QString CallSign READ CallSign WRITE setCallSign )
@@ -71,12 +78,17 @@ class SERVICE_PUBLIC ChannelInfo : public QObject
public:
+ static void InitializeCustomTypes();
+
+ public:
+
ChannelInfo(QObject *parent = 0)
- : QObject ( parent ),
- m_ChanId ( 0 ),
- m_SourceId( 0 ),
- m_InputId ( 0 ),
- m_CommFree( 0 )
+ : QObject ( parent ),
+ m_ChanId ( 0 ),
+ m_SourceId ( 0 ),
+ m_InputId ( 0 ),
+ m_CommFree ( 0 ),
+ m_SerializeDetails( true )
{
}
@@ -159,6 +171,20 @@ class SERVICE_PUBLIC Program : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< Program >();
+ qRegisterMetaType< Program* >();
+
+ if (QMetaType::type( "DTC::ChannelInfo" ) == 0)
+ ChannelInfo::InitializeCustomTypes();
+
+ if (QMetaType::type( "DTC::RecordingInfo" ) == 0)
+ RecordingInfo::InitializeCustomTypes();
+ }
+
+ public:
+
Program(QObject *parent = 0)
: QObject ( parent ),
m_Repeat ( false ),
@@ -167,9 +193,9 @@ class SERVICE_PUBLIC Program : public QObject
m_ProgramFlags ( 0 ),
m_Channel ( NULL ),
m_Recording ( NULL ),
- m_SerializeDetails ( false ),
- m_SerializeChannel ( false ),
- m_SerializeRecording ( false )
+ m_SerializeDetails ( true ),
+ m_SerializeChannel ( true ),
+ m_SerializeRecording ( true )
{
}
@@ -220,9 +246,22 @@ inline Program *ChannelInfo::AddNewProgram()
return pObject;
}
+inline void ChannelInfo::InitializeCustomTypes()
+{
+ qRegisterMetaType< ChannelInfo >();
+ qRegisterMetaType< ChannelInfo* >();
+
+ if (QMetaType::type( "DTC::Program" ) == 0)
+ Program::InitializeCustomTypes();
+}
+
+
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::Program )
-Q_DECLARE_METATYPE( DTC::ChannelInfo )
+Q_DECLARE_METATYPE( DTC::Program )
+Q_DECLARE_METATYPE( DTC::Program* )
+
+Q_DECLARE_METATYPE( DTC::ChannelInfo )
+Q_DECLARE_METATYPE( DTC::ChannelInfo* )
#endif
View
21 mythtv/libs/libmythservicecontracts/datacontracts/programGuide.h
@@ -54,6 +54,14 @@ class SERVICE_PUBLIC ProgramGuide : public QObject
Q_OBJECT
Q_CLASSINFO( "version", "1.0" );
+ // We need to know the type that will ultimately be contained in
+ // any QVariantList or QVariantMap. We do his by specifying
+ // A Q_CLASSINFO entry with "<PropName>_type" as the key
+ // and the type name as the value
+
+ Q_CLASSINFO( "Channels_type", "DTC::Channel");
+
+
Q_PROPERTY( QDateTime StartTime READ StartTime WRITE setStartTime )
Q_PROPERTY( QDateTime EndTime READ EndTime WRITE setEndTime )
Q_PROPERTY( int StartChanId READ StartChanId WRITE setStartChanId )
@@ -84,6 +92,16 @@ class SERVICE_PUBLIC ProgramGuide : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< ProgramGuide >();
+ qRegisterMetaType< ProgramGuide* >();
+
+ ChannelInfo::InitializeCustomTypes();
+ }
+
+ public:
+
ProgramGuide(QObject *parent = 0)
: QObject ( parent ),
m_StartChanId ( 0 ),
@@ -130,6 +148,7 @@ class SERVICE_PUBLIC ProgramGuide : public QObject
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::ProgramGuide )
+Q_DECLARE_METATYPE( DTC::ProgramGuide )
+Q_DECLARE_METATYPE( DTC::ProgramGuide* )
#endif
View
21 mythtv/libs/libmythservicecontracts/datacontracts/programList.h
@@ -39,6 +39,14 @@ class SERVICE_PUBLIC ProgramList : public QObject
Q_OBJECT
Q_CLASSINFO( "version", "1.0" );
+
+ // We need to know the type that will ultimately be contained in
+ // any QVariantList or QVariantMap. We do his by specifying
+ // A Q_CLASSINFO entry with "<PropName>_type" as the key
+ // and the type name as the value
+
+ Q_CLASSINFO( "Programs_type", "DTC::Program");
+
Q_PROPERTY( int StartIndex READ StartIndex WRITE setStartIndex )
Q_PROPERTY( int Count READ Count WRITE setCount )
Q_PROPERTY( int TotalAvailable READ TotalAvailable WRITE setTotalAvailable )
@@ -59,6 +67,16 @@ class SERVICE_PUBLIC ProgramList : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< ProgramList >();
+ qRegisterMetaType< ProgramList* >();
+
+ Program::InitializeCustomTypes();
+ }
+
+ public:
+
ProgramList(QObject *parent = 0)
: QObject ( parent ),
m_StartIndex ( 0 ),
@@ -99,6 +117,7 @@ class SERVICE_PUBLIC ProgramList : public QObject
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::ProgramList )
+Q_DECLARE_METATYPE( DTC::ProgramList )
+Q_DECLARE_METATYPE( DTC::ProgramList* )
#endif
View
11 mythtv/libs/libmythservicecontracts/datacontracts/recording.h
@@ -79,6 +79,14 @@ class SERVICE_PUBLIC RecordingInfo : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< RecordingInfo >();
+ qRegisterMetaType< RecordingInfo* >();
+ }
+
+ public:
+
RecordingInfo(QObject *parent = 0)
: QObject ( parent ),
m_Status ( rsUnknown ),
@@ -117,6 +125,7 @@ class SERVICE_PUBLIC RecordingInfo : public QObject
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::RecordingInfo )
+Q_DECLARE_METATYPE( DTC::RecordingInfo )
+Q_DECLARE_METATYPE( DTC::RecordingInfo* )
#endif
View
20 mythtv/libs/libmythservicecontracts/datacontracts/settingList.h
@@ -34,7 +34,14 @@ namespace DTC
class SERVICE_PUBLIC SettingList : public QObject
{
Q_OBJECT
- Q_CLASSINFO( "version", "1.0" );
+ Q_CLASSINFO( "version" , "1.0" );
+
+ // We need to know the type that will ultimately be contained in
+ // any QVariantList or QVariantMap. We do his by specifying
+ // A Q_CLASSINFO entry with "<PropName>_type" as the key
+ // and the type name as the value
+
+ Q_CLASSINFO( "Settings_type", "QString");
Q_PROPERTY( QString HostName READ HostName WRITE setHostName )
Q_PROPERTY( QVariantMap Settings READ Settings DESIGNABLE true )
@@ -44,6 +51,14 @@ class SERVICE_PUBLIC SettingList : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< SettingList >();
+ qRegisterMetaType< SettingList* >();
+ }
+
+ public:
+
SettingList(QObject *parent = 0)
: QObject( parent )
{
@@ -58,6 +73,7 @@ class SERVICE_PUBLIC SettingList : public QObject
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::SettingList )
+Q_DECLARE_METATYPE( DTC::SettingList )
+Q_DECLARE_METATYPE( DTC::SettingList* )
#endif
View
11 mythtv/libs/libmythservicecontracts/datacontracts/storageGroupDir.h
@@ -28,6 +28,14 @@ class SERVICE_PUBLIC StorageGroupDir : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< StorageGroupDir >();
+ qRegisterMetaType< StorageGroupDir* >();
+ }
+
+ public:
+
StorageGroupDir(QObject *parent = 0)
: QObject ( parent ),
m_Id ( 0 )
@@ -50,6 +58,7 @@ class SERVICE_PUBLIC StorageGroupDir : public QObject
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::StorageGroupDir )
+Q_DECLARE_METATYPE( DTC::StorageGroupDir )
+Q_DECLARE_METATYPE( DTC::StorageGroupDir* )
#endif
View
20 mythtv/libs/libmythservicecontracts/datacontracts/storageGroupDirList.h
@@ -16,12 +16,29 @@ class SERVICE_PUBLIC StorageGroupDirList : public QObject
Q_OBJECT
Q_CLASSINFO( "version", "1.0" );
+ // We need to know the type that will ultimately be contained in
+ // any QVariantList or QVariantMap. We do his by specifying
+ // A Q_CLASSINFO entry with "<PropName>_type" as the key
+ // and the type name as the value
+
+ Q_CLASSINFO( "StorageGroupDirs_type", "DTC::StorageGroupDir");
+
Q_PROPERTY( QVariantList StorageGroupDirs READ StorageGroupDirs DESIGNABLE true )
PROPERTYIMP_RO_REF( QVariantList, StorageGroupDirs )
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< StorageGroupDirList >();
+ qRegisterMetaType< StorageGroupDirList* >();
+
+ StorageGroupDir::InitializeCustomTypes();
+ }
+
+ public:
+
StorageGroupDirList(QObject *parent = 0)
: QObject( parent )
{
@@ -52,6 +69,7 @@ class SERVICE_PUBLIC StorageGroupDirList : public QObject
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::StorageGroupDirList )
+Q_DECLARE_METATYPE( DTC::StorageGroupDirList )
+Q_DECLARE_METATYPE( DTC::StorageGroupDirList* )
#endif
View
59 mythtv/libs/libmythservicecontracts/datacontracts/stringList.h
@@ -1,59 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Program Name: stringList.h
-// Created : Jan. 15, 2010
-//
-// Copyright (c) 2010 David Blain <dblain@mythtv.org>
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or at your option any later version of the LGPL.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library. If not, see <http://www.gnu.org/licenses/>.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef STRINGLIST_H_
-#define STRINGLIST_H_
-
-#include <QStringList>
-
-#include "serviceexp.h"
-#include "datacontracthelper.h"
-
-namespace DTC
-{
-
-class SERVICE_PUBLIC StringList : public QObject
-{
- Q_OBJECT
- Q_CLASSINFO( "version", "1.0" );
-
- Q_PROPERTY( QStringList Values READ Values DESIGNABLE true )
-
- PROPERTYIMP_RO_REF( QStringList, Values )
-
- public:
-
- StringList(QObject *parent = 0)
- : QObject( parent )
- {
- }
-
- StringList( const StringList &src )
- : m_Values( src.m_Values )
- {
- }
-};
-
-} // namespace DTC
-
-Q_DECLARE_METATYPE( DTC::StringList )
-
-#endif
View
59 mythtv/libs/libmythservicecontracts/datacontracts/successFail.h
@@ -1,59 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Program Name: successFail.h
-// Created : Jan. 15, 2010
-//
-// Copyright (c) 2010 David Blain <dblain@mythtv.org>
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or at your option any later version of the LGPL.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library. If not, see <http://www.gnu.org/licenses/>.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef SUCCESSFAIL_H_
-#define SUCCESSFAIL_H_
-
-#include <QObject>
-
-#include "serviceexp.h"
-#include "datacontracthelper.h"
-
-namespace DTC
-{
-
-class SERVICE_PUBLIC SuccessFail : public QObject
-{
- Q_OBJECT
- Q_CLASSINFO( "version", "1.0" );
-
- Q_PROPERTY ( bool Result READ Result WRITE setResult )
-
- PROPERTYIMP( bool, Result )
-
- public:
-
- SuccessFail(QObject *parent = 0)
- : QObject( parent )
- {
- }
-
- SuccessFail( const SuccessFail &src )
- : m_Result( src.m_Result )
- {
- }
-};
-
-} // namespace DTC
-
-Q_DECLARE_METATYPE( DTC::SuccessFail )
-
-#endif
View
12 mythtv/libs/libmythservicecontracts/datacontracts/wolInfo.h
@@ -49,6 +49,14 @@ class SERVICE_PUBLIC WOLInfo : public QObject
public:
+ static void InitializeCustomTypes()
+ {
+ qRegisterMetaType< WOLInfo >();
+ qRegisterMetaType< WOLInfo* >();
+ }
+
+ public:
+
WOLInfo(QObject *parent = 0)
: QObject ( parent ),
m_Enabled ( false ),
@@ -75,6 +83,8 @@ typedef WOLInfo* WOLInfoPtr;
} // namespace DTC
-Q_DECLARE_METATYPE( DTC::WOLInfo )
+Q_DECLARE_METATYPE( DTC::WOLInfo )
+Q_DECLARE_METATYPE( DTC::WOLInfo* )
+
#endif
View
2  mythtv/libs/libmythservicecontracts/libmythservicecontracts.pro
@@ -20,7 +20,6 @@ HEADERS += services/contentServices.h services/dvrServices.h
HEADERS += datacontracts/connectionInfo.h datacontracts/databaseInfo.h
HEADERS += datacontracts/programAndChannel.h datacontracts/programGuide.h
HEADERS += datacontracts/recording.h datacontracts/settingList.h
-HEADERS += datacontracts/stringList.h datacontracts/successFail.h
HEADERS += datacontracts/wolInfo.h datacontracts/programList.h
HEADERS += datacontracts/encoder.h datacontracts/encoderList.h
HEADERS += datacontracts/storageGroupDir.h datacontracts/storageGroupDirList.h
@@ -47,7 +46,6 @@ incDatacontracts.path = $${PREFIX}/include/mythtv/libmythservicecontracts/dataco
incDatacontracts.files = datacontracts/connectionInfo.h datacontracts/databaseInfo.h
incDatacontracts.files += datacontracts/programAndChannel.h datacontracts/programGuide.h
incDatacontracts.files += datacontracts/recording.h datacontracts/settingList.h
-incDatacontracts.files += datacontracts/stringList.h datacontracts/successFail.h
incDatacontracts.files += datacontracts/wolInfo.h
INSTALLS += inc incServices incDatacontracts
View
64 mythtv/libs/libmythservicecontracts/service.cpp
@@ -27,55 +27,67 @@
//
//////////////////////////////////////////////////////////////////////////////
-QVariant Service::ConvertToVariant( const QString &sTypeName, void *pValue )
+QVariant Service::ConvertToVariant( int nType, void *pValue )
{
- // -=>NOTE: Only intrinsic or Qt type conversions should be here
- // All others should be added to overridden implementation.
+ // -=>NOTE: This assumes any UserType will be derived from QObject...
+ // (Exception for QFileInfo )
+ if ( nType == QMetaType::type( "QFileInfo" ))
+ return QVariant::fromValue< QFileInfo >( *((QFileInfo *)pValue) );
- if ( sTypeName.compare( "QFileInfo*", Qt::CaseInsensitive ) == 0 )
+ if (nType > QMetaType::User)
{
- QFileInfo *pInfo = reinterpret_cast< QFileInfo *>( pValue );
+ QObject *pObj = *((QObject **)pValue);
- return QVariant::fromValue<QFileInfo*>( pInfo );
+ return QVariant::fromValue<QObject*>( pObj );
}
- // -=>NOTE: Default to being a QObject or derivative...
- // Will CRASH if NOT derived from QObject!!!
-
- QObject *pObjResult = reinterpret_cast< QObject *>( pValue );
-
- return QVariant::fromValue<QObject*>( pObjResult );
+ return QVariant( nType, pValue );
}
+
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
-void* Service::ConvertToParameterPtr( const QString &sParamType,
+void* Service::ConvertToParameterPtr( int nTypeId,
+ const QString &sParamType,
+ void* pParam,
const QString &sValue )
{
// -=>NOTE: Only intrinsic or Qt type conversions should be here
// All others should be added to overridden implementation.
- if (sParamType == "QString")
- return new QString( sValue );
-
- if (sParamType == "QDateTime")
+ switch( nTypeId )
{
- if ( sValue.isEmpty())
- return new QDateTime();
+ case QMetaType::Bool : *(( bool *)pParam) = ToBool( sValue ); break;
- return new QDateTime( QDateTime::fromString( sValue, Qt::ISODate ));
- }
+ case QMetaType::Char : *(( char *)pParam) = ( sValue.length() > 0) ? sValue.at( 0 ).toAscii() : 0; break;
+ case QMetaType::UChar : *(( unsigned char *)pParam) = ( sValue.length() > 0) ? sValue.at( 0 ).toAscii() : 0; break;
+ case QMetaType::QChar : *(( QChar *)pParam) = ( sValue.length() > 0) ? sValue.at( 0 ) : 0; break;
- if (sParamType == "int")
- return new int( sValue.toInt() );
+ case QMetaType::Short : *(( short *)pParam) = sValue.toShort (); break;
+ case QMetaType::UShort : *(( ushort *)pParam) = sValue.toUShort (); break;
- if (sParamType == "bool")
- return new bool( ToBool( sValue ));
+ case QMetaType::Int : *(( int *)pParam) = sValue.toInt (); break;
+ case QMetaType::UInt : *(( uint *)pParam) = sValue.toUInt (); break;
+
+ case QMetaType::Long : *(( long *)pParam) = sValue.toLong (); break;
+ case QMetaType::ULong : *(( ulong *)pParam) = sValue.toULong (); break;
+
+ case QMetaType::LongLong : *(( qlonglong *)pParam) = sValue.toLongLong (); break;
+ case QMetaType::ULongLong : *(( qulonglong *)pParam) = sValue.toULongLong (); break;
+
+ case QMetaType::Double : *(( double *)pParam) = sValue.toDouble (); break;
+ case QMetaType::Float : *(( float *)pParam) = sValue.toFloat (); break;
+
+ case QMetaType::QString : *(( QString *)pParam) = sValue; break;
+ case QMetaType::QByteArray : *(( QByteArray *)pParam) = sValue.toUtf8 (); break;
+
+ case QMetaType::QDateTime : *(( QDateTime *)pParam) = QDateTime::fromString( sValue, Qt::ISODate ); break;
+ }
- return NULL;
+ return pParam;
}
//////////////////////////////////////////////////////////////////////////////
View
16 mythtv/libs/libmythservicecontracts/service.h
@@ -56,17 +56,26 @@ class SERVICE_PUBLIC Service : public QObject
public:
+ Service( QObject *parent = 0 ) : QObject( parent )
+ {
+ qRegisterMetaType< QFileInfo >();
+ }
+
+ public:
+
/////////////////////////////////////////////////////////////////////
// This method should be overridden to handle non-QObject based custom types
/////////////////////////////////////////////////////////////////////
- virtual QVariant ConvertToVariant ( const QString &sTypeName,
- void *pValue );
+ virtual QVariant ConvertToVariant ( int nType, void *pValue );
- virtual void* ConvertToParameterPtr( const QString &sParamType,
+ virtual void* ConvertToParameterPtr( int nTypeId,
+ const QString &sParamType,
+ void* pParam,
const QString &sValue );
static bool ToBool( const QString &sVal );
+
};
//////////////////////////////////////////////////////////////////////////////
@@ -74,6 +83,5 @@ class SERVICE_PUBLIC Service : public QObject
//////////////////////////////////////////////////////////////////////////////
Q_DECLARE_METATYPE( QFileInfo )
-Q_DECLARE_METATYPE( QFileInfo* )
#endif
View
27 mythtv/libs/libmythservicecontracts/services/contentServices.h
@@ -25,9 +25,9 @@
#define CONTENTSERVICES_H_
#include <QFileInfo>
+#include <QStringList>
#include "service.h"
-#include "datacontracts/stringList.h"
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
@@ -50,28 +50,37 @@ class SERVICE_PUBLIC ContentServices : public Service //, public QScriptable ??
Q_OBJECT
Q_CLASSINFO( "version" , "1.0" );
+ public:
+
+ // Must call InitializeCustomTypes for each unique Custom Type used
+ // in public slots below.
+
+ ContentServices( QObject *parent = 0 ) : Service( parent )
+ {
+ }
+
public slots:
- virtual QFileInfo* GetFile ( const QString &StorageGroup,
+ virtual QFileInfo GetFile ( const QString &StorageGroup,
const QString &FileName ) = 0;
- virtual DTC::StringList* GetFileList ( const QString &StorageGroup ) = 0;
+ virtual QStringList GetFileList ( const QString &StorageGroup ) = 0;
- virtual QFileInfo* GetVideoArt ( int Id ) = 0;
+ virtual QFileInfo GetVideoArt ( int Id ) = 0;
- virtual QFileInfo* GetAlbumArt ( int Id, int Width, int Height ) = 0;
+ virtual QFileInfo GetAlbumArt ( int Id, int Width, int Height ) = 0;
- virtual QFileInfo* GetPreviewImage ( int ChanId,
+ virtual QFileInfo GetPreviewImage ( int ChanId,
const QDateTime &StartTime,
int Width,
int Height,
int SecsIn ) = 0;
- virtual QFileInfo* GetRecording ( int ChanId,
+ virtual QFileInfo GetRecording ( int ChanId,
const QDateTime &StartTime ) = 0;
- virtual QFileInfo* GetMusic ( int Id ) = 0;
- virtual QFileInfo* GetVideo ( int Id ) = 0;
+ virtual QFileInfo GetMusic ( int Id ) = 0;
+ virtual QFileInfo GetVideo ( int Id ) = 0;
};
#endif
View
10 mythtv/libs/libmythservicecontracts/services/dvrServices.h
@@ -50,6 +50,16 @@ class SERVICE_PUBLIC DvrServices : public Service //, public QScriptable ???
Q_OBJECT
Q_CLASSINFO( "version" , "1.0" );
+ public:
+
+ // Must call InitializeCustomTypes for each unique Custom Type used
+ // in public slots below.
+
+ DvrServices( QObject *parent = 0 ) : Service( parent )
+ {
+ DTC::ProgramList::InitializeCustomTypes();
+ DTC::EncoderList::InitializeCustomTypes();
+ }
public slots:
View
13 mythtv/libs/libmythservicecontracts/services/guideServices.h
@@ -51,6 +51,17 @@ class SERVICE_PUBLIC GuideServices : public Service //, public QScriptable ???
Q_OBJECT
Q_CLASSINFO( "version" , "1.0" );
+ public:
+
+ // Must call InitializeCustomTypes for each unique Custom Type used
+ // in public slots below.
+
+ GuideServices( QObject *parent = 0 ) : Service( parent )
+ {
+ DTC::ProgramGuide::InitializeCustomTypes();
+ DTC::Program ::InitializeCustomTypes();
+ }
+
public slots:
virtual DTC::ProgramGuide* GetProgramGuide ( const QDateTime &StartTime ,
@@ -62,7 +73,7 @@ class SERVICE_PUBLIC GuideServices : public Service //, public QScriptable ???
virtual DTC::Program* GetProgramDetails ( int ChanId,
const QDateTime &StartTime ) = 0;
- virtual QFileInfo* GetChannelIcon ( int ChanId,
+ virtual QFileInfo GetChannelIcon ( int ChanId,
int Width ,
int Height ) = 0;
};
View
32 mythtv/libs/libmythservicecontracts/services/mythServices.h
@@ -28,12 +28,9 @@
#include "service.h"
#include "datacontracts/connectionInfo.h"
-#include "datacontracts/stringList.h"
#include "datacontracts/settingList.h"
-#include "datacontracts/successFail.h"
#include "datacontracts/storageGroupDirList.h"
-
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
@@ -58,32 +55,45 @@ class SERVICE_PUBLIC MythServices : public Service //, public QScriptable ???
Q_CLASSINFO( "AddStorageGroupDir_Method", "POST" )
Q_CLASSINFO( "RemoveStorageGroupDir_Method", "POST" )
+ public:
+
+ // Must call InitializeCustomTypes for each unique Custom Type used
+ // in public slots below.
+
+ MythServices( QObject *parent = 0 ) : Service( parent )
+ {
+ DTC::ConnectionInfo ::InitializeCustomTypes();
+ DTC::SettingList ::InitializeCustomTypes();
+ DTC::StorageGroupDirList::InitializeCustomTypes();
+ }
+
public slots:
virtual DTC::ConnectionInfo* GetConnectionInfo ( const QString &Pin ) = 0;
- virtual DTC::StringList* GetHostName ( ) = 0;
- virtual DTC::StringList* GetHosts ( ) = 0;
- virtual DTC::StringList* GetKeys ( ) = 0;
+ virtual QString GetHostName ( ) = 0;
+ virtual QStringList GetHosts ( ) = 0;
+ virtual QStringList GetKeys ( ) = 0;
virtual DTC::StorageGroupDirList* GetStorageGroupDirs ( const QString &GroupName,
const QString &HostName ) = 0;
- virtual DTC::SuccessFail* AddStorageGroupDir ( const QString &GroupName,
+ virtual bool AddStorageGroupDir ( const QString &GroupName,
const QString &DirName,
const QString &HostName ) = 0;
- virtual DTC::SuccessFail* RemoveStorageGroupDir ( const QString &GroupName,
- const QString &DirName,
- const QString &HostName ) = 0;
+ virtual bool RemoveStorageGroupDir( const QString &GroupName,
+ const QString &DirName,
+ const QString &HostName ) = 0;
virtual DTC::SettingList* GetSetting ( const QString &HostName,
const QString &Key,
const QString &Default ) = 0;
- virtual DTC::SuccessFail* PutSetting ( const QString &HostName,
+ virtual bool PutSetting ( const QString &HostName,
const QString &Key,
const QString &Value ) = 0;
+
};
#endif
View
36 mythtv/libs/libmythupnp/htmlserver.cpp
@@ -91,7 +91,14 @@ bool HtmlServerExtension::ProcessRequest( HttpWorkerThread *, HTTPRequest *pRequ
QFileInfo oInfo( m_sAbsoluteSharePath + pRequest->m_sResourceUrl );
if (oInfo.isDir())
- oInfo.setFile( oInfo.filePath() + "/index.html" );
+ {
+ QString sIndexFileName = oInfo.filePath() + "/index.qsp";
+
+ if (QFile::exists( sIndexFileName ))
+ oInfo.setFile( sIndexFileName );
+ else
+ oInfo.setFile( oInfo.filePath() + "/index.html" );
+ }
if (oInfo.exists() == true )
{
@@ -108,9 +115,30 @@ bool HtmlServerExtension::ProcessRequest( HttpWorkerThread *, HTTPRequest *pRequ
if (oInfo.exists())
{
if (oInfo.isSymLink())
- pRequest->FormatFileResponse( oInfo.symLinkTarget() );
- else
- pRequest->FormatFileResponse( sResName );
+ sResName = oInfo.symLinkTarget();
+
+ // ------------------------------------------------------
+ // Is this a Qt Server Page (File contains script)...
+ // ------------------------------------------------------
+
+ if (oInfo.suffix().compare( "qsp", Qt::CaseInsensitive ) == 0)
+ {
+
+ pRequest->m_eResponseType = ResponseTypeHTML;
+
+ QTextStream stream( &pRequest->m_response );
+
+ m_Scripting.EvaluatePage( &stream, sResName );
+
+ return true;
+
+ }
+
+ // ------------------------------------------------------
+ // Return the file.
+ // ------------------------------------------------------
+
+ pRequest->FormatFileResponse( sResName );
return true;
}
View
10 mythtv/libs/libmythupnp/htmlserver.h
@@ -25,6 +25,7 @@
#define __HTMLSERVER_H__
#include "httpserver.h"
+#include "serverSideScripting.h"
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
@@ -38,13 +39,20 @@ class UPNP_PUBLIC HtmlServerExtension : public HttpServerExtension
{
private:
- QString m_sAbsoluteSharePath;
+ QString m_sAbsoluteSharePath;
+ ServerSideScripting m_Scripting;
public:
HtmlServerExtension( const QString sSharePath);
virtual ~HtmlServerExtension( );
bool ProcessRequest( HttpWorkerThread *pThread, HTTPRequest *pRequest );
+
+ QScriptEngine* ScriptEngine()
+ {
+ return &(m_Scripting.m_engine);
+ }
+
};
#endif
View
6 mythtv/libs/libmythupnp/httprequest.cpp
@@ -1297,6 +1297,8 @@ bool HTTPRequest::ProcessSOAPPayload( const QString &sSOAPAction )
// XML Document Loaded... now parse it
// --------------------------------------------------------------
+ QString sService;
+
if (sSOAPAction.contains( '#' ))
{
m_sNameSpace = sSOAPAction.section( '#', 0, 0).remove( 0, 1);
@@ -1308,6 +1310,10 @@ bool HTTPRequest::ProcessSOAPPayload( const QString &sSOAPAction )
int nPos = sSOAPAction.lastIndexOf( '/' );
m_sNameSpace = sSOAPAction.mid( 1, nPos );
m_sMethod = sSOAPAction.mid( nPos + 1, sSOAPAction.length() - nPos - 2 );
+
+ nPos = m_sNameSpace.lastIndexOf( '/', -2);
+ sService = m_sNameSpace.mid( nPos + 1, m_sNameSpace.length() - nPos - 2 );
+ m_sNameSpace = m_sNameSpace.mid( 0, nPos );
}
else
{
View
37 mythtv/libs/libmythupnp/httprequest.h
@@ -256,4 +256,41 @@ class BufferedSocketDeviceRequest : public HTTPRequest
};
+/////////////////////////////////////////////////////////////////////////////
+//
+/////////////////////////////////////////////////////////////////////////////
+
+class UPNP_PUBLIC HttpException
+{
+ public:
+ int code;
+ QString msg;
+
+ HttpException( int nCode = -1, const QString &sMsg = "")
+ : code( nCode ), msg ( sMsg )
+ {}
+
+ // Needed to force a v-table.
+ virtual ~HttpException()
+ {}
+};
+
+class UPNP_PUBLIC HttpRedirectException : public HttpException
+{
+ public:
+
+ QString hostName;
+ //int port;
+
+ HttpRedirectException( const QString &sHostName = "",
+ int nCode = -1,
+ const QString &sMsg = "" )
+ : HttpException( nCode, sMsg ), hostName( sHostName )
+ {}
+
+ virtual ~HttpRedirectException()
+ {}
+
+};
+
#endif
View
9 mythtv/libs/libmythupnp/httpserver.cpp
@@ -116,6 +116,15 @@ HttpServer::~HttpServer()
//
/////////////////////////////////////////////////////////////////////////////
+QScriptEngine* HttpServer::ScriptEngine()
+{
+ return ((HtmlServerExtension *)m_pHtmlServer)->ScriptEngine();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+/////////////////////////////////////////////////////////////////////////////
+
WorkerThread *HttpServer::CreateWorkerThread( ThreadPool * /*pThreadPool */,
const QString &sName )
{
View
4 mythtv/libs/libmythupnp/httpserver.h
@@ -36,6 +36,7 @@
#include <QThread>
#include <QTcpServer>
#include <QReadWriteLock>
+#include <QScriptEngine>
// MythTV headers
#include "upnputil.h"
@@ -77,6 +78,7 @@ class UPNP_PUBLIC HttpServerExtension : public QObject
virtual bool ProcessRequest( HttpWorkerThread *pThread,
HTTPRequest *pRequest ) = 0;
// virtual bool Uninitialize ( ) = 0;
+
};
typedef QList<QPointer<HttpServerExtension> > HttpServerExtensionList;
@@ -120,6 +122,8 @@ class UPNP_PUBLIC HttpServer : public QTcpServer,
void DelegateRequest ( HttpWorkerThread *pThread,
HTTPRequest *pRequest );
+ QScriptEngine* ScriptEngine();
+
};
/////////////////////////////////////////////////////////////////////////////
View
8 mythtv/libs/libmythupnp/libmythupnp.pro
@@ -23,7 +23,7 @@ HEADERS += httpserver.h upnpcds.h upnpcdsobjects.h bufferedsocketdevice.h upnpms
HEADERS += eventing.h upnpcmgr.h upnptaskevent.h upnptaskcache.h ssdpcache.h
HEADERS += upnpimpl.h multicast.h broadcast.h configuration.h
HEADERS += soapclient.h mythxmlclient.h mmembuf.h upnpexp.h
-HEADERS += servicehost.h wsdl.h htmlserver.h
+HEADERS += servicehost.h wsdl.h htmlserver.h serverSideScripting.h
HEADERS += serializers/serializer.h serializers/xmlSerializer.h
HEADERS += serializers/jsonSerializer.h serializers/soapSerializer.h
@@ -33,7 +33,7 @@ SOURCES += upnpdevice.cpp upnptasknotify.cpp upnptasksearch.cpp threadpool.cpp
SOURCES += httpserver.cpp upnpcds.cpp upnpcdsobjects.cpp bufferedsocketdevice.cpp
SOURCES += eventing.cpp upnpcmgr.cpp upnpmsrr.cpp upnptaskevent.cpp ssdpcache.cpp
SOURCES += configuration.cpp soapclient.cpp mythxmlclient.cpp mmembuf.cpp
-SOURCES += multicast.cpp htmlserver.cpp
+SOURCES += multicast.cpp htmlserver.cpp serverSideScripting.cpp
SOURCES += servicehost.cpp wsdl.cpp
SOURCES += serializers/serializer.cpp serializers/xmlSerializer.cpp
@@ -61,7 +61,7 @@ inc.files += httpserver.h httpstatus.h upnpcds.h upnpcdsobjects.h
inc.files += eventing.h upnpcmgr.h upnptaskevent.h upnptaskcache.h ssdpcache.h
inc.files += upnpimpl.h multicast.h broadcast.h configuration.h
inc.files += soapclient.h mythxmlclient.h mmembuf.h
-inc.files += servicehost.h wsdl.h htmlserver.h
+inc.files += servicehost.h wsdl.h htmlserver.h serverSideScripting.h
inc.files += serializers/serializer.h serializers/xmlSerializer.h
inc.files += serializers/jsonSerializer.h serializers/soapSerializer.h
@@ -73,7 +73,7 @@ macx {
QMAKE_LFLAGS_SHLIB += -flat_namespace
}
-QT += network xml sql
+QT += network xml sql script
use_hidesyms {
QMAKE_CXXFLAGS += -fvisibility=hidden
View
7 mythtv/libs/libmythupnp/serializers/jsonSerializer.cpp
@@ -57,7 +57,7 @@ QString JSONSerializer::GetContentType()
//
//////////////////////////////////////////////////////////////////////////////
-void JSONSerializer::BeginSerialize()
+void JSONSerializer::BeginSerialize( QString &sName )
{
m_bCommaNeeded = false;
@@ -104,7 +104,10 @@ void JSONSerializer::EndObject ( const QString &sName, const QObject *pObject
//
//////////////////////////////////////////////////////////////////////////////
-void JSONSerializer::AddProperty( const QString &sName, const QVariant &vValue )
+void JSONSerializer::AddProperty( const QString &sName,
+ const QVariant &vValue,
+ const QMetaObject *pMetaParent,
+ const QMetaProperty *pMetaProp )
{
if (m_bCommaNeeded)
m_Stream << ", ";
View
8 mythtv/libs/libmythupnp/serializers/jsonSerializer.h
@@ -47,12 +47,16 @@ class UPNP_PUBLIC JSONSerializer : public Serializer
QTextStream m_Stream;
bool m_bCommaNeeded;
- virtual void BeginSerialize();
+ virtual void BeginSerialize( QString &sName );
virtual void EndSerialize ();
virtual void BeginObject( const QString &sName, const QObject *pObject );
virtual void EndObject ( const QString &sName, const QObject *pObject );
- virtual void AddProperty( const QString &sName, const QVariant &vValue );
+
+ virtual void AddProperty( const QString &sName,
+ const QVariant &vValue,
+ const QMetaObject *pMetaParent,
+ const QMetaProperty *pMetaProp );
void RenderValue ( const QVariant &vValue );
View
11 mythtv/libs/libmythupnp/serializers/serializer.cpp
@@ -56,7 +56,7 @@ void Serializer::Serialize( const QObject *pObject, const QString &_sName )
// ---------------------------------------------------------------
- BeginSerialize();
+ BeginSerialize( sName );
SerializeObject( pObject, sName );
@@ -67,11 +67,12 @@ void Serializer::Serialize( const QObject *pObject, const QString &_sName )
//
//////////////////////////////////////////////////////////////////////////////
-void Serializer::Serialize( const QVariant &vValue, const QString &sName )
+void Serializer::Serialize( const QVariant &vValue, const QString &_sName )
{
- BeginSerialize();
+ QString sName( _sName );
+ BeginSerialize( sName );
- AddProperty( sName, vValue );
+ AddProperty( sName, vValue, NULL, NULL );
EndSerialize();
}
@@ -115,7 +116,7 @@ void Serializer::SerializeObjectProperties( const QObject *pObject )
QVariant value( pObject->property( pszPropName ) );
- AddProperty( sPropName, value );
+ AddProperty( sPropName, value, pMetaObject, &metaProperty );
}
}
}
View
12 mythtv/libs/libmythupnp/serializers/serializer.h
@@ -42,12 +42,16 @@ class UPNP_PUBLIC Serializer
{
protected:
- virtual void BeginSerialize() {}
+ virtual void BeginSerialize( QString &sName ) {}
virtual void EndSerialize () {}
virtual void BeginObject( const QString &sName, const QObject *pObject ) = 0;
virtual void EndObject ( const QString &sName, const QObject *pObject ) = 0;
- virtual void AddProperty( const QString &sName, const QVariant &vValue ) = 0;
+
+ virtual void AddProperty( const QString &sName,
+ const QVariant &vValue,
+ const QMetaObject *pMetaParent,
+ const QMetaProperty *pMetaProp ) = 0;
//////////////////////////////////////////////////////////////////////
@@ -56,8 +60,8 @@ class UPNP_PUBLIC Serializer
public:
- void Serialize( const QObject *pObject, const QString &_sName = QString() );
- void Serialize( const QVariant &vValue, const QString &sName );
+ virtual void Serialize( const QObject *pObject, const QString &_sName = QString() );
+ virtual void Serialize( const QVariant &vValue, const QString &sName );
//////////////////////////////////////////////////////////////////////
// Helper Methods
View
6 mythtv/libs/libmythupnp/serializers/soapSerializer.h
@@ -60,6 +60,7 @@ class UPNP_PUBLIC SoapSerializer : public XmlSerializer
headers.insert( "EXT", "" );
}
+
protected:
QString m_sNamespace;
@@ -68,18 +69,19 @@ class UPNP_PUBLIC SoapSerializer : public XmlSerializer
//
// ------------------------------------------------------------------
- virtual void BeginSerialize()
+ virtual void BeginSerialize( QString &sName)
{
m_pXmlWriter->writeStartDocument( "1.0" );
m_pXmlWriter->writeStartElement("http://schemas.xmlsoap.org/soap/envelope/", "Envelope" );
- m_pXmlWriter->writeAttribute( "encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/" );
+ // m_pXmlWriter->writeAttribute( "encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/" );
m_pXmlWriter->writeStartElement( "http://schemas.xmlsoap.org/soap/envelope/", "Body" );
m_pXmlWriter->writeStartElement( m_sRequestName + "Response" );
m_pXmlWriter->writeAttribute( "xmlns", m_sNamespace );
+ sName = m_sRequestName + "Result";
}
};
View
63 mythtv/libs/libmythupnp/serializers/xmlSerializer.cpp
@@ -25,6 +25,13 @@
#include <QMetaClassInfo>
+// --------------------------------------------------------------------------
+// This version should be bumped if the serializer code is changed in a way
+// that changes the schema layout of the rendered XML.
+// --------------------------------------------------------------------------
+
+#define XML_SERIALIZER_VERSION "1.1"
+
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
@@ -62,7 +69,7 @@ QString XmlSerializer::GetContentType()
//
//////////////////////////////////////////////////////////////////////////////
-void XmlSerializer::BeginSerialize()
+void XmlSerializer::BeginSerialize( QString &sName )
{
m_pXmlWriter->writeStartDocument( "1.0" );
// m_pXmlWriter->writeStartElement( m_sRequestName + "Response" );
@@ -91,6 +98,9 @@ void XmlSerializer::BeginObject( const QString &sName, const QObject *pObject )
if (nIdx >=0)
m_pXmlWriter->writeAttribute( "version", pMeta->classInfo( nIdx ).value() );
+
+ m_pXmlWriter->writeAttribute( "serializerVersion", XML_SERIALIZER_VERSION );
+
}
//////////////////////////////////////////////////////////////////////////////
@@ -106,13 +116,16 @@ void XmlSerializer::EndObject ( const QString &sName, const QObject *pObject )
//
//////////////////////////////////////////////////////////////////////////////
-void XmlSerializer::AddProperty( const QString &sName, const QVariant &vValue )
+void XmlSerializer::AddProperty( const QString &sName,
+ const QVariant &vValue,
+ const QMetaObject *pMetaParent,
+ const QMetaProperty *pMetaProp )
{
if (sName != "Description")
{
m_pXmlWriter->writeStartElement( sName );
- RenderValue( sName, vValue );
+ RenderValue( GetContentName( sName, pMetaParent, pMetaProp ), vValue );
m_pXmlWriter->writeEndElement();
}
@@ -128,7 +141,7 @@ void XmlSerializer::RenderValue( const QString &sName, const QVariant &vValue )
{
// -----------------------------------------------------------------------
- // See if this value is actually a child object
+ // See if this value is actually a QObject
// -----------------------------------------------------------------------
if ( vValue.canConvert< QObject* >())
@@ -139,7 +152,6 @@ void XmlSerializer::RenderValue( const QString &sName, const QVariant &vValue )
return;
}
-
// -----------------------------------------------------------------------
// Handle QVariant special cases...
// -----------------------------------------------------------------------
@@ -179,14 +191,19 @@ void XmlSerializer::RenderValue( const QString &sName, const QVariant &vValue )
void XmlSerializer::RenderList( const QString &sName, const QVariantList &list )
{
- QString sItemName = GetItemName( sName );
+// QString sItemName;
QListIterator< QVariant > it( list );
while (it.hasNext())
{
- m_pXmlWriter->writeStartElement( sItemName );
- RenderValue( sName, it.next() );
+ QVariant vValue = it.next();
+
+// if (sItemName.isEmpty())
+// sItemName = GetItemName( QMetaType::typeName( vValue.userType() ) );
+
+ m_pXmlWriter->writeStartElement( sName );
+ RenderValue( sName, vValue );
m_pXmlWriter->writeEndElement();
}
}
@@ -203,7 +220,7 @@ void XmlSerializer::RenderStringList( const QString &sName, const QStringList &l
while (it.hasNext())
{
- m_pXmlWriter->writeStartElement( sItemName );
+ m_pXmlWriter->writeStartElement( "String" );
m_pXmlWriter->writeCharacters ( it.next() );
m_pXmlWriter->writeEndElement();
}
@@ -238,9 +255,31 @@ void XmlSerializer::RenderMap( const QString &sName, const QVariantMap &map )
QString XmlSerializer::GetItemName( const QString &sName )
{
- if (sName.endsWith( "s" ))
- return sName.left( sName.length() - 1);
+ QString sTypeName( sName );
+
+ if (sName.at(0) == 'Q')
+ sTypeName = sName.mid( 1 );
+
+ sTypeName.remove( "DTC::" );
+ sTypeName.remove( QChar('*') );
- return "Value";
+ return sTypeName;
}
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+QString XmlSerializer::GetContentName( const QString &sName,
+ const QMetaObject *pMetaObject,
+ const QMetaProperty *pMetaProp )
+{
+ QString sMethodClassInfo = sName + "_type";
+
+ int nClassIdx = pMetaObject->indexOfClassInfo( sMethodClassInfo.toAscii() );
+
+ if (nClassIdx >=0)
+ return GetItemName( pMetaObject->classInfo( nClassIdx ).value() );
+
+ return sName;
+}
View
10 mythtv/libs/libmythupnp/serializers/xmlSerializer.h
@@ -48,13 +48,16 @@ class UPNP_PUBLIC XmlSerializer : public Serializer
QXmlStreamWriter *m_pXmlWriter;
QString m_sRequestName;
- virtual void BeginSerialize();
+ virtual void BeginSerialize( QString &sName );
virtual void EndSerialize ();
virtual void BeginObject( const QString &sName, const QObject *pObject );
virtual void EndObject ( const QString &sName, const QObject *pObject );
- virtual void AddProperty( const QString &sName, const QVariant &vValue );
+ virtual void AddProperty( const QString &sName,
+ const QVariant &vValue,
+ const QMetaObject *pMetaParent,
+ const QMetaProperty *pMetaProp );
void RenderValue ( const QString &sName, const QVariant &vValue );
@@ -64,6 +67,9 @@ class UPNP_PUBLIC XmlSerializer : public Serializer
QString GetItemName ( const QString &sName );
+ QString GetContentName ( const QString &sName,
+ const QMetaObject *pMetaObject,
+ const QMetaProperty *pMetaProp );
public:
View
297 mythtv/libs/libmythupnp/serverSideScripting.cpp
@@ -0,0 +1,297 @@
+//////////////////////////////////////////////////////////////////////////////
+// Program Name: serverSideScripting.cpp
+// Created : Mar. 22, 2011
+//
+// Purpose : Server Side Scripting support for Html Server
+//
+// Copyright (c) 2011 David Blain <dblain@mythtv.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or at your option any later version of the LGPL.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library. If not, see <http://www.gnu.org/licenses/>.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <QFile>
+#include <QFileInfo>
+
+#include "serverSideScripting.h"
+#include "mythverbose.h"
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+ServerSideScripting::ServerSideScripting()
+{
+
+ // ----------------------------------------------------------------------
+ // Add Scriptable Objects
+ // ----------------------------------------------------------------------
+
+ // Q_SCRIPT_DECLARE_QMETAOBJECT( DTC::MythService, QObject*)
+ // QScriptValue oClass = engine.scriptValueFromQMetaObject< DTC::MythService >();
+ // engine.globalObject().setProperty("Myth", oClass);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+ServerSideScripting::~ServerSideScripting()
+{
+ Lock();
+
+ QMap<QString, ScriptInfo*>::iterator it = m_mapScripts.begin();
+
+ for (; it != m_mapScripts.end(); ++it)
+ {
+ if (*it)
+ delete (*it);
+ }
+
+ m_mapScripts.clear();
+ Unlock();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+void ServerSideScripting::RegisterMetaObjectType( const QString &sName,
+ const QMetaObject *pMetaObject,
+ QScriptEngine::FunctionSignature pFunction)
+{
+ QScriptValue ctor = m_engine.newFunction( pFunction );
+
+ QScriptValue metaObject = m_engine.newQMetaObject( pMetaObject, ctor );
+ m_engine.globalObject().setProperty( sName, metaObject );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+bool ServerSideScripting::EvaluatePage( QTextStream *pOutStream, const QString &sFileName )
+{
+ try
+ {
+ bool bFound( false );
+ ScriptInfo *pInfo = NULL;
+
+ // ------------------------------------------------------------------
+ // See if page has already been loaded
+ // ------------------------------------------------------------------
+
+ Lock();
+
+ if ( (bFound = m_mapScripts.contains( sFileName )) == true )
+ pInfo = m_mapScripts[ sFileName ];
+
+ Unlock();
+
+ // ------------------------------------------------------------------
+ // Load Script File and Create Function
+ // ------------------------------------------------------------------
+
+ QFileInfo fileInfo ( sFileName );
+ QDateTime dtLastModified = fileInfo.lastModified();
+
+ if ((pInfo == NULL) || (pInfo->m_dtTimeStamp != dtLastModified ))
+ {
+ QString sCode = CreateMethodFromFile( sFileName );
+
+ QScriptValue func = m_engine.evaluate( sCode, sFileName );
+
+ if ( m_engine.hasUncaughtException() )
+ {
+ VERBOSE( VB_IMPORTANT, QString( "Error Loading QSP File: %1 - (%2)%3" )
+ .arg( sFileName )
+ .arg( m_engine.uncaughtExceptionLineNumber() )
+ .arg( m_engine.uncaughtException().toString() ));
+
+ return false;
+ }
+
+ if (pInfo != NULL)
+ {
+ pInfo->m_oFunc = func;
+ pInfo->m_dtTimeStamp = dtLastModified;
+ }
+ else
+ {
+ pInfo = new ScriptInfo( func, dtLastModified );
+ Lock();
+ m_mapScripts[ sFileName ] = pInfo;
+ Unlock();
+ }
+ }
+
+ // ------------------------------------------------------------------
+ // Execute function to render output
+ // ------------------------------------------------------------------
+
+ OutputStream outStream( pOutStream );
+
+ QScriptValueList args;
+ args << m_engine.newQObject( &outStream );
+
+ pInfo->m_oFunc.call( QScriptValue(), args );
+
+ if (m_engine.hasUncaughtException())
+ {
+ VERBOSE( VB_IMPORTANT, QString( "Error calling QSP File: %1 - %2" )
+ .arg( sFileName )
+ .arg( m_engine.uncaughtException().toString() ));
+ return false;
+ }
+
+ }
+ catch( ... )
+ {
+ VERBOSE( VB_IMPORTANT, QString( "Exception while evaluating QSP File: %1" )
+ .arg( sFileName ));
+
+ return false;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+QString ServerSideScripting::CreateMethodFromFile( const QString &sFileName )
+{
+ bool bInCode = false;
+ QString sBuffer;
+ QTextStream sCode( &sBuffer );
+
+ QFile scriptFile( sFileName );
+
+ if (!scriptFile.open( QIODevice::ReadOnly ))
+ throw "Unable to open file";
+
+ try
+ {
+ QTextStream stream( &scriptFile );
+
+ sCode << "(function( os ) {\n";
+
+ while( !stream.atEnd() )
+ {
+ QString sLine = stream.readLine();
+
+ bInCode = ProcessLine( sCode, sLine, bInCode );
+ }
+
+ sCode << "})";
+ }
+ catch( ... )
+ {
+ VERBOSE( VB_IMPORTANT, QString( "Exception while reading QSP File: %1" )
+ .arg( sFileName ));
+ }
+
+ scriptFile.close();
+
+ sCode.flush();
+
+ return sBuffer;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+bool ServerSideScripting::ProcessLine( QTextStream &sCode,
+ QString &sLine,
+ bool bInCode )
+{
+ int nStartPos = 0;
+ int nEndPos = 0;
+ int nMatchPos = 0;
+ bool bMatchFound = false;
+
+ sLine = sLine.trimmed();
+
+ QString sExpecting = bInCode ? &qu