Skip to content

Commit

Permalink
Server Side Scripting added along with other changes.
Browse files Browse the repository at this point in the history
  * 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
dblain committed Mar 24, 2011
1 parent 0b33d93 commit 2575589
Show file tree
Hide file tree
Showing 62 changed files with 1,964 additions and 489 deletions.
2 changes: 1 addition & 1 deletion mythtv/html/html.pro
Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions mythtv/html/index.html
Expand Up @@ -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>
Expand Down
39 changes: 39 additions & 0 deletions 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;
}
148 changes: 148 additions & 0 deletions 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>
91 changes: 91 additions & 0 deletions 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>
8 changes: 4 additions & 4 deletions mythtv/html/setup/js/storagegroups.js
Expand Up @@ -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");
});
Expand All @@ -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");
});
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmyth/libmyth.pro
Expand Up @@ -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)

Expand Down
18 changes: 0 additions & 18 deletions mythtv/libs/libmythservicecontracts/datacontracthelper.h
Expand Up @@ -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: \
Expand Down
Expand Up @@ -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 )
Expand All @@ -42,6 +43,17 @@ class SERVICE_PUBLIC ConnectionInfo : public QObject
PROPERTYIMP_PTR( DatabaseInfo, Database )
PROPERTYIMP_PTR( WOLInfo , WOL )

public:

static void InitializeCustomTypes()
{
qRegisterMetaType< ConnectionInfo >();
qRegisterMetaType< ConnectionInfo* >();

DatabaseInfo::InitializeCustomTypes();
WOLInfo ::InitializeCustomTypes();
}

public:

ConnectionInfo(QObject *parent = 0)
Expand Down Expand Up @@ -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

0 comments on commit 2575589

Please sign in to comment.