MythTV  master
mythfexml.cpp
Go to the documentation of this file.
1 // Program Name: MythFE.cpp
3 //
4 // Purpose - Frontend Html & XML status HttpServerExtension
5 //
7 
8 #include "mythfexml.h"
9 
10 #include "mythcorecontext.h"
11 #include "mythdate.h"
12 #include "mythdbcon.h"
13 
14 #include "mythmainwindow.h"
15 
16 #include <QTextStream>
17 #include <QCoreApplication>
18 #include <QTextStream>
19 #include <QDir>
20 #include <QFile>
21 #include <QRegExp>
22 #include <QBuffer>
23 #include <QKeyEvent>
24 
25 #include "../../config.h"
26 
27 #include "keybindings.h"
28 
29 #include "services/frontend.h"
30 
32 //
34 
35 MythFEXML::MythFEXML( UPnpDevice *pDevice , const QString &sSharePath)
36  : Eventing( "MythFEXML", "MYTHTV_Event", sSharePath)
37 {
38 
39  QString sUPnpDescPath =
40  UPnp::GetConfiguration()->GetValue( "UPnP/DescXmlPath", m_sSharePath );
41 
42  m_sServiceDescFileName = sUPnpDescPath + "MFEXML_scpd.xml";
43  m_sControlUrl = "/MythFE";
44 
45  // Add our Service Definition to the device.
46 
47  RegisterService( pDevice );
48 }
49 
51 //
53 
55 {
56  if (sURI == "GetServDesc") return MFEXML_GetServiceDescription;
57  if (sURI == "GetScreenShot") return MFEXML_GetScreenShot;
58  if (sURI == "GetActionTest") return MFEXML_ActionListTest;
59  if (sURI == "GetRemote") return MFEXML_GetRemote;
60 
61  return( MFEXML_Unknown );
62 }
63 
65 //
67 
69 {
71 }
72 
74 //
76 
78 {
79  if (!pRequest)
80  return false;
81 
82  if (pRequest->m_sBaseUrl != m_sControlUrl)
83  return false;
84 
85  LOG(VB_UPNP, LOG_INFO, QString("MythFEXML::ProcessRequest: %1 : %2")
86  .arg(pRequest->m_sMethod).arg(pRequest->m_sRawRequest));
87 
88  switch(GetMethod(pRequest->m_sMethod))
89  {
92  break;
94  GetScreenShot(pRequest);
95  break;
97  GetActionListTest(pRequest);
98  break;
99  case MFEXML_GetRemote:
100  GetRemote(pRequest);
101  break;
102  default:
104  }
105  return true;
106 }
107 
108 // ==========================================================================
109 // Request handler Methods
110 // ==========================================================================
111 
113 //
115 
117 {
118  pRequest->m_eResponseType = ResponseTypeFile;
119 
120  // Optional Parameters
121  int nWidth = pRequest->m_mapParams[ "width" ].toInt();
122  int nHeight = pRequest->m_mapParams[ "height" ].toInt();
123  QString sFormat = pRequest->m_mapParams[ "format" ];
124 
125  if (sFormat.isEmpty())
126  sFormat = "png";
127 
128  if (sFormat != "jpg" && sFormat != "png")
129  {
130  LOG(VB_GENERAL, LOG_ERR, "Invalid screen shot format: " + sFormat);
131  return;
132  }
133 
134  LOG(VB_GENERAL, LOG_INFO,
135  QString("Screen shot requested (%1x%2), format %3")
136  .arg(nWidth).arg(nHeight).arg(sFormat));
137 
138  QString sFileName = QString("/%1/myth-screenshot-XML.%2")
139  .arg(gCoreContext->GetSetting("ScreenShotPath","/tmp"))
140  .arg(sFormat);
141 
142  MythMainWindow *window = GetMythMainWindow();
143  window->RemoteScreenShot(sFileName, nWidth, nHeight);
144 
145  pRequest->m_sFileName = sFileName;
146 }
147 
148 static const QString PROCESS_ACTION =
149  " <script type =\"text/javascript\">\n"
150  " function postaction(action) {\n"
151  " var myForm = document.createElement(\"form\");\n"
152  " myForm.method =\"Post\";\n"
153  " myForm.action =\"../Frontend/SendAction?\";\n"
154  " myForm.target =\"post_target\";\n"
155  " var myInput = document.createElement(\"input\");\n"
156  " myInput.setAttribute(\"name\", \"Action\");\n"
157  " myInput.setAttribute(\"value\", action);\n"
158  " myForm.appendChild(myInput);\n"
159  " document.body.appendChild(myForm);\n"
160  " myForm.submit();\n"
161  " document.body.removeChild(myForm);\n"
162  " }\n"
163  " </script>\n";
164 
165 static const QString HIDDEN_IFRAME =
166  " <iframe id=\"hidden_target\" name=\"post_target\" src=\"\""
167  " style=\"width:0;height:0;border:0px solid #fff;\"></iframe>\n";
168 
170 {
172 
173  pRequest->m_eResponseType = ResponseTypeHTML;
174  pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000";
175 
176  QTextStream stream( &pRequest->m_response );
177 
178  stream <<
179  "<html>\n" << PROCESS_ACTION <<
180  " <body>\n" << HIDDEN_IFRAME;
181 
182  QHashIterator<QString,QStringList> contexts(Frontend::gActionDescriptions);
183  while (contexts.hasNext())
184  {
185  contexts.next();
186  QStringList actions = contexts.value();
187  foreach (QString action, actions)
188  {
189  QStringList split = action.split(",");
190  if (split.size() == 2)
191  {
192  stream <<
193  QString(" <div>%1&nbsp;<input type=\"button\" value=\"%2\" onClick=\"postaction('%2');\"></input>&nbsp;%3</div>\n")
194  .arg(contexts.key()).arg(split[0]).arg(split[1]);
195  }
196  }
197  }
198 
199  stream <<
200  " </body>\n"
201  "</html>\n";
202 
203 }
204 
205 #define BUTTON(action,desc) \
206  QString(" <input class=\"bigb\" type=\"button\" value=\"%1\" onClick=\"postaction('%2');\"></input>\r\n").arg(action).arg(desc)
207 
209 {
210  pRequest->m_eResponseType = ResponseTypeHTML;
211  pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000";
212 
213  QTextStream stream( &pRequest->m_response );
214 
215  stream <<
216  "<html>\n" << PROCESS_ACTION <<
217  " <style type=\"text/css\" title=\"Default\" media=\"all\">\r\n"
218  " <!--\r\n"
219  " body {\r\n"
220  " margin: 0px;\r\n"
221  " width : 310px;\r\n"
222  " }\r\n"
223  " -->\r\n"
224  " .bigb {\r\n"
225  " width : 100px;\r\n"
226  " height: 50px;\r\n"
227  " margin: 0px;\r\n"
228  " text-align: center;\r\n"
229  " }\r\n"
230  " </style>\r\n"
231  " <title>MythFrontend Control</title>\r\n" <<
232  " <body>\n" << HIDDEN_IFRAME;
233 
234  stream <<
235  " <div>\r\n" <<
236  BUTTON("1","1") << BUTTON("2","2") << BUTTON("3","3") <<
237  " </div>\r\n" <<
238  " <div>\r\n" <<
239  BUTTON("4","4") << BUTTON("5","5") << BUTTON("6","6") <<
240  " </div>\r\n" <<
241  " <div>\r\n" <<
242  BUTTON("7","7") << BUTTON("8","8") << BUTTON("9","9") <<
243  " </div>\r\n" <<
244  " <div>\r\n" <<
245  BUTTON("MENU","MENU") << BUTTON("0","0") << BUTTON("INFO","INFO") <<
246  " </div>\r\n" <<
247  " <div>\r\n" <<
248  BUTTON("Back","ESCAPE") << BUTTON("^","UP") << BUTTON("MUTE","MUTE") <<
249  " </div>\r\n" <<
250  " <div>\r\n" <<
251  BUTTON("<","LEFT") << BUTTON("Enter","SELECT") << BUTTON(">","RIGHT") <<
252  " </div>\r\n" <<
253  " <div>\r\n" <<
254  BUTTON("<<","JUMPRWND") << BUTTON("v","DOWN") << BUTTON(">>","JUMPFFWD") <<
255  " </div>\r\n";
256 
257  stream <<
258  " </body>\n"
259  "</html>\n";
260 }
QStringList GetBasePaths() override
Definition: eventing.cpp:135
virtual int GetValue(const QString &sSetting, int Default)=0
QString m_sBaseUrl
Definition: httprequest.h:123
QString m_sSharePath
Definition: httpserver.h:78
void RegisterService(UPnpDevice *device)
Creates a UPnpService and adds it to the UPnpDevice's list of services.
QString m_sMethod
Definition: httprequest.h:125
QStringMap m_mapRespHeaders
Definition: httprequest.h:149
QString m_sControlUrl
Definition: mythfexml.h:28
static QHash< QString, QStringList > gActionDescriptions
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
bool ProcessRequest(HTTPRequest *pRequest) override
Definition: mythfexml.cpp:77
static void FormatErrorResponse(HTTPRequest *pRequest, UPnPResultCode eCode, const QString &sMsg="")
Definition: upnp.cpp:268
static void InitialiseActions(void)
Definition: frontend.cpp:301
static const QString HIDDEN_IFRAME
Definition: mythfexml.cpp:165
QString m_sServiceDescFileName
Definition: mythfexml.h:29
QString m_sRawRequest
Definition: httprequest.h:119
QString GetSetting(const QString &key, const QString &defaultval="")
static const QString PROCESS_ACTION
Definition: mythfexml.cpp:148
#define BUTTON(action, desc)
Definition: mythfexml.cpp:205
QStringList GetBasePaths() override
Definition: mythfexml.cpp:68
QString m_sFileName
Definition: httprequest.h:151
static Configuration * GetConfiguration()
Definition: upnp.cpp:71
void RemoteScreenShot(QString filename, int x, int y)
QStringMap m_mapParams
Definition: httprequest.h:127
MythMainWindow * GetMythMainWindow(void)
MythFEXMLMethod
Definition: mythfexml.h:15
Main header for keybinding classes.
MythFEXML(UPnpDevice *pDevice, const QString &sSharePath)
Definition: mythfexml.cpp:35
void GetRemote(HTTPRequest *pRequest)
Definition: mythfexml.cpp:208
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
void GetActionListTest(HTTPRequest *pRequest)
Definition: mythfexml.cpp:169
QBuffer m_response
Definition: httprequest.h:153
HttpResponseType m_eResponseType
Definition: httprequest.h:145
void GetScreenShot(HTTPRequest *pRequest)
Definition: mythfexml.cpp:116
void FormatFileResponse(const QString &sFileName)
MythFEXMLMethod GetMethod(const QString &sURI)
Definition: mythfexml.cpp:54