Skip to content

Commit

Permalink
Frontend Services: Move action handling from MythFEXML to service.
Browse files Browse the repository at this point in the history
- The 'helper' method GetActionTest remains in MythFEXML.
- Arguments are now capitalised for consistency with the rest of the
services API.
- the Frontend Remote Control is modified for the new urls and methods.

Old methods:

http://frontend-ip:6547/MythFE/SendAction?action=UP
http://frontend-

New methods:

http://frontend-ip:6547/Frontend/SendAction?Action=UP
http://frontend-
  • Loading branch information
Mark Kendall committed Nov 11, 2011
1 parent 3f57e79 commit 9a90d31
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 152 deletions.
@@ -0,0 +1,47 @@
#ifndef FRONTENDACTIONLIST_H
#define FRONTENDACTIONLIST_H

#include "serviceexp.h"
#include "datacontracthelper.h"

namespace DTC
{
class SERVICE_PUBLIC FrontendActionList : public QObject
{
Q_OBJECT
Q_CLASSINFO("version", "1.0");

Q_CLASSINFO("ActionList_type", "Action"); // is this legal?

Q_PROPERTY(QVariantMap ActionList READ ActionList DESIGNABLE true)

PROPERTYIMP_RO_REF(QVariantMap, ActionList)

public:
static void InitializeCustomTypes()
{
qRegisterMetaType<FrontendActionList>();
qRegisterMetaType<FrontendActionList*>();
}

public:
FrontendActionList(QObject *parent = 0) : QObject(parent)
{
}

FrontendActionList(const FrontendActionList &src)
{
Copy(src);
}

void Copy(const FrontendActionList &src)
{
m_ActionList = src.m_ActionList;
}
};
};

Q_DECLARE_METATYPE(DTC::FrontendActionList)
Q_DECLARE_METATYPE(DTC::FrontendActionList*)

#endif // FRONTENDACTIONLIST_H
Expand Up @@ -36,6 +36,7 @@ HEADERS += datacontracts/lineup.h datacontracts/captureCard.h
HEADERS += datacontracts/captureCardList.h datacontracts/recRule.h
HEADERS += datacontracts/recRuleList.h
HEADERS += datacontracts/frontendStatus.h
HEADERS += datacontracts/frontendActionList.h

SOURCES += service.cpp

Expand Down Expand Up @@ -71,6 +72,7 @@ incDatacontracts.files += datacontracts/versionInfo.h datacontracts/line
incDatacontracts.files += datacontracts/captureCard.h datacontracts/captureCardList.h
incDatacontracts.files += datacontracts/recRule.h datacontracts/recRuleList.h
incDatacontracts.files += datacontracts/frontendStatus.h
incDatacontracts.files += datacontracts/frontendActionList.h

INSTALLS += inc incServices incDatacontracts

Expand Down
Expand Up @@ -3,6 +3,7 @@

#include "service.h"
#include "datacontracts/frontendStatus.h"
#include "datacontracts/frontendActionList.h"

class SERVICE_PUBLIC FrontendServices : public Service
{
Expand All @@ -13,11 +14,16 @@ class SERVICE_PUBLIC FrontendServices : public Service
FrontendServices(QObject *parent = 0) : Service(parent)
{
DTC::FrontendStatus::InitializeCustomTypes();
DTC::FrontendActionList::InitializeCustomTypes();
}

public slots:
virtual DTC::FrontendStatus* GetStatus(void) = 0;
virtual bool SendMessage(const QString &Message) = 0;
virtual bool SendAction(const QString &Action,
const QString &File,
uint Width, uint Height) = 0;
virtual DTC::FrontendActionList* GetActionList(void) = 0;
};

#endif // FRONTENDSERVICES_H
139 changes: 6 additions & 133 deletions mythtv/programs/mythfrontend/mythfexml.cpp
Expand Up @@ -26,6 +26,8 @@

#include "keybindings.h"

#include "services/frontend.h"

/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -61,8 +63,6 @@ MythFEXMLMethod MythFEXML::GetMethod(const QString &sURI)
{
if (sURI == "GetServDesc") return MFEXML_GetServiceDescription;
if (sURI == "GetScreenShot") return MFEXML_GetScreenShot;
if (sURI == "SendAction") return MFEXML_Action;
if (sURI == "GetActionList") return MFEXML_ActionList;
if (sURI == "GetActionTest") return MFEXML_ActionListTest;
if (sURI == "GetRemote") return MFEXML_GetRemote;

Expand Down Expand Up @@ -101,12 +101,6 @@ bool MythFEXML::ProcessRequest( HTTPRequest *pRequest )
case MFEXML_GetScreenShot:
GetScreenShot(pRequest);
break;
case MFEXML_Action:
SendAction(pRequest);
break;
case MFEXML_ActionList:
GetActionList(pRequest);
break;
case MFEXML_ActionListTest:
GetActionListTest(pRequest);
break;
Expand Down Expand Up @@ -159,59 +153,15 @@ void MythFEXML::GetScreenShot(HTTPRequest *pRequest)
pRequest->m_sFileName = sFileName;
}

void MythFEXML::SendAction(HTTPRequest *pRequest)
{
QStringMap* map = &pRequest->m_mapParams;
pRequest->m_eResponseType = ResponseTypeHTML;
QString sText = map->value("action");
uint pcount = map->size();

LOG(VB_UPNP, LOG_INFO, QString("UPNP Action: %1 (total %2 params)")
.arg(sText).arg(pcount));

if (!IsValidAction(sText))
return;

if (pcount > 1)
{
bool valid = false;
QStringList args;
if (ACTION_SCREENSHOT == sText && 3 == pcount)
{
args << map->value("width");
args << map->value("height");
valid = true;
}
else if (ACTION_HANDLEMEDIA == sText && 2 == pcount)
{
args << map->value("file");
valid = true;
}

if (valid)
{
MythEvent* me = new MythEvent(sText, args);
qApp->postEvent(GetMythMainWindow(), me);
return;
}

LOG(VB_UPNP, LOG_WARNING,
"Failed to validate extra paramaters - ignoring");
}

QKeyEvent* ke = new QKeyEvent(QEvent::KeyPress, 0, Qt::NoModifier, sText);
qApp->postEvent(GetMythMainWindow(), (QEvent*)ke);
}

static const QString PROCESS_ACTION =
" <script type =\"text/javascript\">\n"
" function postaction(action) {\n"
" var myForm = document.createElement(\"form\");\n"
" myForm.method =\"Post\";\n"
" myForm.action =\"SendAction?\";\n"
" myForm.action =\"../Frontend/SendAction?\";\n"
" myForm.target =\"post_target\";\n"
" var myInput = document.createElement(\"input\");\n"
" myInput.setAttribute(\"name\", \"action\");\n"
" myInput.setAttribute(\"name\", \"Action\");\n"
" myInput.setAttribute(\"value\", action);\n"
" myForm.appendChild(myInput);\n"
" document.body.appendChild(myForm);\n"
Expand All @@ -226,7 +176,7 @@ static const QString HIDDEN_IFRAME =

void MythFEXML::GetActionListTest(HTTPRequest *pRequest)
{
InitActions();
Frontend::InitialiseActions();

pRequest->m_eResponseType = ResponseTypeHTML;
pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000";
Expand All @@ -237,7 +187,7 @@ void MythFEXML::GetActionListTest(HTTPRequest *pRequest)
"<html>\n" << PROCESS_ACTION <<
" <body>\n" << HIDDEN_IFRAME;

QHashIterator<QString,QStringList> contexts(m_actionDescriptions);
QHashIterator<QString,QStringList> contexts(Frontend::gActionDescriptions);
while (contexts.hasNext())
{
contexts.next();
Expand All @@ -260,46 +210,11 @@ void MythFEXML::GetActionListTest(HTTPRequest *pRequest)

}

void MythFEXML::GetActionList(HTTPRequest *pRequest)
{
InitActions();

pRequest->m_eResponseType = ResponseTypeXML;
pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000";

QTextStream stream( &pRequest->m_response );

stream << "<mythactions version=\"1\">";

QHashIterator<QString,QStringList> contexts(m_actionDescriptions);
while (contexts.hasNext())
{
contexts.next();
stream << QString("<context name=\"%1\">")
.arg(contexts.key());
QStringList actions = contexts.value();
foreach (QString action, actions)
{
QStringList split = action.split(",");
if (split.size() == 2)
{
stream <<
QString("<action name=\"%1\">%2</action>")
.arg(split[0]).arg(split[1]);
}
}
stream << "</context>";
}
stream << "</mythactions>";
}

#define BUTTON(action,desc) \
QString(" <input class=\"bigb\" type=\"button\" value=\"%1\" onClick=\"postaction('%2');\"></input>\r\n").arg(action).arg(desc)

void MythFEXML::GetRemote(HTTPRequest *pRequest)
{
InitActions();

pRequest->m_eResponseType = ResponseTypeHTML;
pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000";

Expand Down Expand Up @@ -351,45 +266,3 @@ void MythFEXML::GetRemote(HTTPRequest *pRequest)
" </body>\n"
"</html>\n";
}

bool MythFEXML::IsValidAction(const QString &action)
{
InitActions();
if (m_actionList.contains(action))
return true;
LOG(VB_GENERAL, LOG_ERR, QString("UPNP Action: %1 is invalid").arg(action));
return false;
}

void MythFEXML::InitActions(void)
{
static bool initialised = false;
if (initialised)
return;

initialised = true;
KeyBindings *bindings = new KeyBindings(gCoreContext->GetHostName());
if (bindings)
{
QStringList contexts = bindings->GetContexts();
contexts.sort();
foreach (QString context, contexts)
{
m_actionDescriptions[context] = QStringList();
QStringList ctx_actions = bindings->GetActions(context);
ctx_actions.sort();
m_actionList += ctx_actions;
foreach (QString actions, ctx_actions)
{
QString desc = actions + "," +
bindings->GetActionDescription(context, actions);
m_actionDescriptions[context].append(desc);
}
}
}
m_actionList.removeDuplicates();
m_actionList.sort();

foreach (QString actions, m_actionList)
LOG(VB_UPNP, LOG_INFO, QString("MythFEXML Action: %1").arg(actions));
}
19 changes: 0 additions & 19 deletions mythtv/programs/mythfrontend/mythfexml.h
Expand Up @@ -17,8 +17,6 @@ typedef enum
MFEXML_Unknown = 0,
MFEXML_GetServiceDescription,
MFEXML_GetScreenShot,
MFEXML_Action,
MFEXML_ActionList,
MFEXML_ActionListTest,
MFEXML_GetRemote,
} MythFEXMLMethod;
Expand All @@ -30,9 +28,6 @@ class MythFEXML : public Eventing
QString m_sControlUrl;
QString m_sServiceDescFileName;

QStringList m_actionList;
QHash<QString,QStringList> m_actionDescriptions;

protected:

// Implement UPnpServiceImpl methods that we can
Expand All @@ -47,12 +42,8 @@ class MythFEXML : public Eventing
MythFEXMLMethod GetMethod( const QString &sURI );

void GetScreenShot ( HTTPRequest *pRequest );
void SendAction ( HTTPRequest *pRequest );
void GetActionList ( HTTPRequest *pRequest );
void GetActionListTest( HTTPRequest *pRequest );
void GetRemote ( HTTPRequest *pRequest );
bool IsValidAction ( const QString &action );
void InitActions ( void );

public:
MythFEXML( UPnpDevice *pDevice , const QString sSharePath);
Expand All @@ -61,18 +52,8 @@ class MythFEXML : public Eventing
virtual QStringList GetBasePaths();

bool ProcessRequest( HTTPRequest *pRequest );

// Static methods shared with HttpStatus

};

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
#endif


0 comments on commit 9a90d31

Please sign in to comment.