MythTV  0.26-pre
mythfexml.cpp
Go to the documentation of this file.
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&nbsp;<input type=\"button\" value=\"%2\" onClick=\"postaction('%2');\"></input>&nbsp;%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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends