|
MythTV
0.26-pre
|
00001 00002 // Program Name: MythFE.cpp 00003 // 00004 // Purpose - Frontend Html & XML status HttpServerExtension 00005 // 00007 00008 #include "mythfexml.h" 00009 00010 #include "mythcorecontext.h" 00011 #include "mythmiscutil.h" 00012 #include "mythdbcon.h" 00013 00014 #include "mythmainwindow.h" 00015 00016 #include <QTextStream> 00017 #include <QCoreApplication> 00018 #include <QTextStream> 00019 #include <QDir> 00020 #include <QFile> 00021 #include <QRegExp> 00022 #include <QBuffer> 00023 #include <QKeyEvent> 00024 00025 #include "../../config.h" 00026 00027 #include "keybindings.h" 00028 00029 #include "services/frontend.h" 00030 00032 // 00034 00035 MythFEXML::MythFEXML( UPnpDevice *pDevice , const QString sSharePath) 00036 : Eventing( "MythFEXML", "MYTHTV_Event", sSharePath) 00037 { 00038 00039 QString sUPnpDescPath = 00040 UPnp::GetConfiguration()->GetValue( "UPnP/DescXmlPath", m_sSharePath ); 00041 00042 m_sServiceDescFileName = sUPnpDescPath + "MFEXML_scpd.xml"; 00043 m_sControlUrl = "/MythFE"; 00044 00045 // Add our Service Definition to the device. 00046 00047 RegisterService( pDevice ); 00048 } 00049 00051 // 00053 00054 MythFEXML::~MythFEXML() 00055 { 00056 } 00057 00059 // 00061 00062 MythFEXMLMethod MythFEXML::GetMethod(const QString &sURI) 00063 { 00064 if (sURI == "GetServDesc") return MFEXML_GetServiceDescription; 00065 if (sURI == "GetScreenShot") return MFEXML_GetScreenShot; 00066 if (sURI == "GetActionTest") return MFEXML_ActionListTest; 00067 if (sURI == "GetRemote") return MFEXML_GetRemote; 00068 00069 return( MFEXML_Unknown ); 00070 } 00071 00073 // 00075 00076 QStringList MythFEXML::GetBasePaths() 00077 { 00078 return Eventing::GetBasePaths() << m_sControlUrl; 00079 } 00080 00082 // 00084 00085 bool MythFEXML::ProcessRequest( HTTPRequest *pRequest ) 00086 { 00087 if (!pRequest) 00088 return false; 00089 00090 if (pRequest->m_sBaseUrl != m_sControlUrl) 00091 return false; 00092 00093 LOG(VB_UPNP, LOG_INFO, QString("MythFEXML::ProcessRequest: %1 : %2") 00094 .arg(pRequest->m_sMethod).arg(pRequest->m_sRawRequest)); 00095 00096 switch(GetMethod(pRequest->m_sMethod)) 00097 { 00098 case MFEXML_GetServiceDescription: 00099 pRequest->FormatFileResponse(m_sServiceDescFileName); 00100 break; 00101 case MFEXML_GetScreenShot: 00102 GetScreenShot(pRequest); 00103 break; 00104 case MFEXML_ActionListTest: 00105 GetActionListTest(pRequest); 00106 break; 00107 case MFEXML_GetRemote: 00108 GetRemote(pRequest); 00109 break; 00110 default: 00111 UPnp::FormatErrorResponse(pRequest, UPnPResult_InvalidAction); 00112 } 00113 return true; 00114 } 00115 00116 // ========================================================================== 00117 // Request handler Methods 00118 // ========================================================================== 00119 00121 // 00123 00124 void MythFEXML::GetScreenShot(HTTPRequest *pRequest) 00125 { 00126 pRequest->m_eResponseType = ResponseTypeFile; 00127 00128 // Optional Parameters 00129 int nWidth = pRequest->m_mapParams[ "width" ].toInt(); 00130 int nHeight = pRequest->m_mapParams[ "height" ].toInt(); 00131 QString sFormat = pRequest->m_mapParams[ "format" ]; 00132 00133 if (sFormat.isEmpty()) 00134 sFormat = "png"; 00135 00136 if (sFormat != "jpg" && sFormat != "png") 00137 { 00138 LOG(VB_GENERAL, LOG_ERR, "Invalid screen shot format: " + sFormat); 00139 return; 00140 } 00141 00142 LOG(VB_GENERAL, LOG_INFO, 00143 QString("Screen shot requested (%1x%2), format %3") 00144 .arg(nWidth).arg(nHeight).arg(sFormat)); 00145 00146 QString sFileName = QString("/%1/myth-screenshot-XML.%2") 00147 .arg(gCoreContext->GetSetting("ScreenShotPath","/tmp")) 00148 .arg(sFormat); 00149 00150 MythMainWindow *window = GetMythMainWindow(); 00151 window->RemoteScreenShot(sFileName, nWidth, nHeight); 00152 00153 pRequest->m_sFileName = sFileName; 00154 } 00155 00156 static const QString PROCESS_ACTION = 00157 " <script type =\"text/javascript\">\n" 00158 " function postaction(action) {\n" 00159 " var myForm = document.createElement(\"form\");\n" 00160 " myForm.method =\"Post\";\n" 00161 " myForm.action =\"../Frontend/SendAction?\";\n" 00162 " myForm.target =\"post_target\";\n" 00163 " var myInput = document.createElement(\"input\");\n" 00164 " myInput.setAttribute(\"name\", \"Action\");\n" 00165 " myInput.setAttribute(\"value\", action);\n" 00166 " myForm.appendChild(myInput);\n" 00167 " document.body.appendChild(myForm);\n" 00168 " myForm.submit();\n" 00169 " document.body.removeChild(myForm);\n" 00170 " }\n" 00171 " </script>\n"; 00172 00173 static const QString HIDDEN_IFRAME = 00174 " <iframe id=\"hidden_target\" name=\"post_target\" src=\"\"" 00175 " style=\"width:0;height:0;border:0px solid #fff;\"></iframe>\n"; 00176 00177 void MythFEXML::GetActionListTest(HTTPRequest *pRequest) 00178 { 00179 Frontend::InitialiseActions(); 00180 00181 pRequest->m_eResponseType = ResponseTypeHTML; 00182 pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000"; 00183 00184 QTextStream stream( &pRequest->m_response ); 00185 00186 stream << 00187 "<html>\n" << PROCESS_ACTION << 00188 " <body>\n" << HIDDEN_IFRAME; 00189 00190 QHashIterator<QString,QStringList> contexts(Frontend::gActionDescriptions); 00191 while (contexts.hasNext()) 00192 { 00193 contexts.next(); 00194 QStringList actions = contexts.value(); 00195 foreach (QString action, actions) 00196 { 00197 QStringList split = action.split(","); 00198 if (split.size() == 2) 00199 { 00200 stream << 00201 QString(" <div>%1 <input type=\"button\" value=\"%2\" onClick=\"postaction('%2');\"></input> %3</div>\n") 00202 .arg(contexts.key()).arg(split[0]).arg(split[1]); 00203 } 00204 } 00205 } 00206 00207 stream << 00208 " </body>\n" 00209 "</html>\n"; 00210 00211 } 00212 00213 #define BUTTON(action,desc) \ 00214 QString(" <input class=\"bigb\" type=\"button\" value=\"%1\" onClick=\"postaction('%2');\"></input>\r\n").arg(action).arg(desc) 00215 00216 void MythFEXML::GetRemote(HTTPRequest *pRequest) 00217 { 00218 pRequest->m_eResponseType = ResponseTypeHTML; 00219 pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000"; 00220 00221 QTextStream stream( &pRequest->m_response ); 00222 00223 stream << 00224 "<html>\n" << PROCESS_ACTION << 00225 " <style type=\"text/css\" title=\"Default\" media=\"all\">\r\n" 00226 " <!--\r\n" 00227 " body {\r\n" 00228 " margin: 0px;\r\n" 00229 " width : 310px;\r\n" 00230 " }\r\n" 00231 " -->\r\n" 00232 " .bigb {\r\n" 00233 " width : 100px;\r\n" 00234 " height: 50px;\r\n" 00235 " margin: 0px;\r\n" 00236 " text-align: center;\r\n" 00237 " }\r\n" 00238 " </style>\r\n" 00239 " <title>MythFrontend Control</title>\r\n" << 00240 " <body>\n" << HIDDEN_IFRAME; 00241 00242 stream << 00243 " <div>\r\n" << 00244 BUTTON("1","1") << BUTTON("2","2") << BUTTON("3","3") << 00245 " </div>\r\n" << 00246 " <div>\r\n" << 00247 BUTTON("4","4") << BUTTON("5","5") << BUTTON("6","6") << 00248 " </div>\r\n" << 00249 " <div>\r\n" << 00250 BUTTON("7","7") << BUTTON("8","8") << BUTTON("9","9") << 00251 " </div>\r\n" << 00252 " <div>\r\n" << 00253 BUTTON("MENU","MENU") << BUTTON("0","0") << BUTTON("INFO","INFO") << 00254 " </div>\r\n" << 00255 " <div>\r\n" << 00256 BUTTON("Back","ESCAPE") << BUTTON("^","UP") << BUTTON("MUTE","MUTE") << 00257 " </div>\r\n" << 00258 " <div>\r\n" << 00259 BUTTON("<","LEFT") << BUTTON("Enter","SELECT") << BUTTON(">","RIGHT") << 00260 " </div>\r\n" << 00261 " <div>\r\n" << 00262 BUTTON("<<","JUMPRWND") << BUTTON("v","DOWN") << BUTTON(">>","JUMPFFWD") << 00263 " </div>\r\n"; 00264 00265 stream << 00266 " </body>\n" 00267 "</html>\n"; 00268 }
1.7.6.1