|
MythTV
0.26-pre
|
00001 // Qt headers 00002 #include <QByteArray> 00003 #include <QDir> 00004 #include <QFileInfo> 00005 #include <QTextStream> 00006 #include <QUrl> 00007 00008 // MythTV headers 00009 #include "httpconfig.h" 00010 #include "backendutil.h" 00011 #include "mythcontext.h" 00012 #include "mythdb.h" 00013 #include "mythdirs.h" 00014 #include "storagegroup.h" 00015 #include "mythdownloadmanager.h" 00016 #include "mythcoreutil.h" 00017 00018 HttpConfig::HttpConfig() : HttpServerExtension("HttpConfig", QString()) 00019 { 00020 } 00021 00022 HttpConfig::~HttpConfig() 00023 { 00024 } 00025 00026 QStringList HttpConfig::GetBasePaths() 00027 { 00028 QStringList paths; 00029 paths << "/Config"; 00030 paths << "/Config/Database"; 00031 paths << "/Config/General"; 00032 return paths; 00033 } 00034 00035 bool HttpConfig::ProcessRequest(HTTPRequest *request) 00036 { 00037 if (!request) 00038 return false; 00039 00040 LOG(VB_UPNP, LOG_INFO, 00041 QString("HttpConfig::ProcessRequest(): m_sBaseURL: '%1'," 00042 "m_sMethod: '%2'") 00043 .arg(request->m_sBaseUrl).arg(request->m_sMethod)); 00044 if (!request->m_sBaseUrl.startsWith("/Config")) 00045 { 00046 return false; 00047 } 00048 00049 bool handled = false; 00050 if (request->m_sMethod == "Save") 00051 { 00052 { 00053 // DISABLE HTML SETUP SAVING 00054 // DISABLE HTML SETUP SAVING 00055 QTextStream os(&request->m_response); 00056 os << "<html>\r\n" 00057 " <head>\r\n" 00058 " <title>Saving is Disabled</title>\r\n" 00059 " </head>\r\n" 00060 " <body>\r\n" 00061 " <b>Saving is Disabled</b><br>\r\n" 00062 " </body>\r\n" 00063 "</html>\r\n"; 00064 00065 request->m_eResponseType = ResponseTypeHTML; 00066 request->m_mapRespHeaders[ "Cache-Control" ] = 00067 "no-cache=\"Ext\", max-age = 0"; 00068 00069 return true; 00070 // DISABLE HTML SETUP SAVING 00071 // DISABLE HTML SETUP SAVING 00072 } 00073 00074 // FIXME, this is always false, what's it for 00075 if (request->m_sBaseUrl.right(7) == "config" && 00076 !database_settings.empty()) 00077 { 00078 QString checkResult; 00079 PrintHeader(request->m_response, "/Config/Database"); 00080 check_settings(database_settings, request->m_mapParams, 00081 checkResult); 00082 load_settings(database_settings, ""); 00083 PrintSettings(request->m_response, database_settings); 00084 PrintFooter(request->m_response); 00085 handled = true; 00086 } 00087 else 00088 { 00089 bool okToSave = false; 00090 QString checkResult; 00091 QString fn = GetShareDir() + "backend-config/"; 00092 00093 if (request->m_sBaseUrl == "/Config/Database") 00094 { 00095 if (check_settings(database_settings, request->m_mapParams, 00096 checkResult)) 00097 okToSave = true; 00098 } 00099 else if (request->m_sBaseUrl == "/Config/General") 00100 { 00101 if (check_settings(general_settings, request->m_mapParams, 00102 checkResult)) 00103 okToSave = true; 00104 } 00105 00106 if (okToSave) 00107 LOG(VB_UPNP, LOG_INFO, "HTTP method 'Save' called, but not handled"); 00108 #if 0 00109 QTextStream os(&request->m_response); 00110 os << "<html><body><h3>The Save function for this screen is " 00111 << "not hooked up yet</h3><dl>"; 00112 QStringMap::const_iterator it = request->m_mapParams.begin(); 00113 for (; it!=request->m_mapParams.end(); ++it) 00114 { 00115 if (it.key() == "__group__") 00116 continue; 00117 00118 os << "<dt>"<<it.key()<<"</dt><dd>" 00119 <<*it<<"</dd>\r\n"; 00120 } 00121 os << "</dl></body></html>"; 00122 handled = true; 00123 #else 00124 QTextStream os(&request->m_response); 00125 os << checkResult; 00126 request->m_eResponseType = ResponseTypeOther; 00127 request->m_sResponseTypeText = "application/json"; 00128 request->m_mapRespHeaders[ "Cache-Control" ] = 00129 "no-cache=\"Ext\", max-age = 0"; 00130 00131 return true; 00132 #endif 00133 } 00134 } 00135 else if (request->m_sMethod == "Settings") 00136 { 00137 QString result = "{ \"Error\": \"Unknown Settings List\" }"; 00138 QString fn = GetShareDir() + "backend-config/"; 00139 00140 if (request->m_sBaseUrl == "/Config/Database") 00141 { 00142 fn += "config_backend_database.xml"; 00143 parse_settings(database_settings, fn); 00144 result = StringMapToJSON( 00145 GetSettingsMap(database_settings, gCoreContext->GetHostName())); 00146 } 00147 else if (request->m_sBaseUrl == "/Config/General") 00148 { 00149 fn += "config_backend_general.xml"; 00150 parse_settings(general_settings, fn); 00151 result = StringMapToJSON( 00152 GetSettingsMap(general_settings, gCoreContext->GetHostName())); 00153 } 00154 00155 QTextStream os(&request->m_response); 00156 os << result; 00157 request->m_eResponseType = ResponseTypeOther; 00158 request->m_sResponseTypeText = "application/json"; 00159 request->m_mapRespHeaders[ "Cache-Control" ] = 00160 "no-cache=\"Ext\", max-age = 0"; 00161 00162 return true; 00163 } 00164 else if (request->m_sMethod == "XML") 00165 { 00166 QString fn = GetShareDir() + "backend-config/"; 00167 00168 if (request->m_sBaseUrl == "/Config/Database") 00169 fn += "config_backend_database.xml"; 00170 else if (request->m_sBaseUrl == "/Config/General") 00171 fn += "config_backend_general.xml"; 00172 00173 request->FormatFileResponse(fn); 00174 return true; 00175 } 00176 else if ((request->m_sMethod == "InstallPackage") && 00177 (request->m_mapParams.contains("package"))) 00178 { 00179 QString package = QUrl::fromPercentEncoding(request->m_mapParams["package"].toUtf8()); 00180 QString url = QString("http://www.mythtv.org/ftp/3rdParty/%1").arg(package); 00181 StorageGroup tmpGroup("Temp", gCoreContext->GetHostName()); 00182 QString tmpFile = tmpGroup.GetFirstDir(true) + "package.zip"; 00183 StorageGroup destGroup("3rdParty", gCoreContext->GetHostName()); 00184 QString outDir = destGroup.GetFirstDir(); 00185 00186 QString result = "false"; 00187 if ((GetMythDownloadManager()->download(url, tmpFile)) && 00188 (extractZIP(tmpFile, outDir))) 00189 { 00190 result = "true"; 00191 } 00192 00193 QTextStream os(&request->m_response); 00194 os << StringListToJSON("Result", QStringList(result)); 00195 00196 request->m_eResponseType = ResponseTypeOther; 00197 request->m_sResponseTypeText = "application/json"; 00198 request->m_mapRespHeaders[ "Cache-Control" ] = 00199 "no-cache=\"Ext\", max-age = 0"; 00200 00201 return true; 00202 } 00203 else if ((request->m_sMethod == "FileBrowser") && 00204 (request->m_mapParams.contains("dir"))) 00205 { 00206 QString startingDir = QUrl::fromPercentEncoding(request->m_mapParams["dir"].toUtf8()); 00207 if (startingDir.startsWith("myth://")) 00208 { 00209 QUrl qurl(startingDir); 00210 QString dir; 00211 00212 QString host = qurl.host(); 00213 int port = qurl.port(); 00214 00215 dir = qurl.path(); 00216 00217 QString storageGroup = qurl.userName(); 00218 00219 StorageGroup sgroup(storageGroup); 00220 QStringList entries = sgroup.GetFileInfoList(dir); 00221 00222 if ((entries.size() == 1) && 00223 (entries[0].startsWith("sgdir::"))) 00224 { 00225 QStringList parts = entries[0].split("::"); 00226 entries = sgroup.GetFileInfoList(parts[1]); 00227 } 00228 00229 if (entries.size()) 00230 { 00231 QTextStream os(&request->m_response); 00232 os << "<ul class=\"jqueryFileTree\" style=\"display: none;\">\r\n"; 00233 00234 for (QStringList::iterator it = entries.begin(); 00235 it != entries.end(); ++it) 00236 { 00237 QString entry = *it; 00238 QStringList parts = entry.split("::"); 00239 QFileInfo fi(parts[1]); 00240 if (dir == "/") 00241 dir = ""; 00242 QString path = 00243 gCoreContext->GenMythURL(host, 00244 port, 00245 dir + parts[1], 00246 storageGroup); 00247 if (entry.startsWith("sgdir::")) 00248 { 00249 os << " <li class=\"directory collapsed\"><a href=\"#\" rel=\"" 00250 << path << "/\">" << parts[1] << "</a></li>\r\n"; 00251 } 00252 else if (entry.startsWith("dir::")) 00253 { 00254 os << " <li class=\"directory collapsed\"><a href=\"#\" rel=\"" 00255 << path << "/\">" << fi.fileName() << "</a></li>\r\n"; 00256 } 00257 else if (entry.startsWith("file::")) 00258 { 00259 os << " <li class=\"file ext_" << fi.suffix() << "\"><a href=\"#\" rel=\"" 00260 << parts[3] << "\">" << fi.fileName() << "</a></li>\r\n"; 00261 } 00262 } 00263 os << "</ul>\r\n"; 00264 00265 handled = true; 00266 } 00267 } else { 00268 QDir dir(startingDir); 00269 if (dir.exists()) 00270 { 00271 QTextStream os(&request->m_response); 00272 os << "<ul class=\"jqueryFileTree\" style=\"display: none;\">\r\n"; 00273 00274 QFileInfoList infoList = dir.entryInfoList(); 00275 for (QFileInfoList::iterator it = infoList.begin(); 00276 it != infoList.end(); 00277 ++it ) 00278 { 00279 QFileInfo &fi = *it; 00280 if (!fi.isDir()) 00281 continue; 00282 if (fi.fileName().startsWith(".")) 00283 continue; 00284 00285 os << " <li class=\"directory collapsed\"><a href=\"#\" rel=\"" 00286 << fi.absoluteFilePath() << "/\">" << fi.fileName() << "</a></li>\r\n"; 00287 } 00288 00289 bool dirsOnly = true; 00290 if (request->m_mapParams.contains("dirsOnly")) 00291 dirsOnly = request->m_mapParams["dirsOnly"].toInt(); 00292 00293 if (!dirsOnly) 00294 { 00295 for (QFileInfoList::iterator it = infoList.begin(); 00296 it != infoList.end(); 00297 ++it ) 00298 { 00299 QFileInfo &fi = *it; 00300 if (fi.isDir()) 00301 continue; 00302 if (fi.fileName().startsWith(".")) 00303 continue; 00304 00305 os << " <li class=\"file ext_" << fi.suffix() << "\"><a href=\"#\" rel=\"" 00306 << fi.absoluteFilePath() << "\">" << fi.fileName() << "</a></li>\r\n"; 00307 } 00308 } 00309 os << "</ul>\r\n"; 00310 00311 handled = true; 00312 } 00313 } 00314 } 00315 else if ((request->m_sMethod == "GetValueList") && 00316 (request->m_mapParams.contains("List"))) 00317 { 00318 QString key = request->m_mapParams["List"]; 00319 QStringList sList = GetSettingValueList(key); 00320 QTextStream os(&request->m_response); 00321 os << StringListToJSON(key, sList); 00322 00323 request->m_eResponseType = ResponseTypeOther; 00324 request->m_sResponseTypeText = "application/json"; 00325 request->m_mapRespHeaders[ "Cache-Control" ] = 00326 "no-cache=\"Ext\", max-age = 0"; 00327 00328 return true; 00329 } 00330 else if ((request->m_sMethod == "Database") || (NULL == gContext)) 00331 { 00332 QString fn = GetShareDir() + "backend-config/" 00333 "config_backend_database.xml"; 00334 QString group; 00335 QString form("/Config/Database/Save"); 00336 00337 if (request->m_mapParams.contains("__group__")) 00338 group = request->m_mapParams["__group__"]; 00339 00340 if (group.isEmpty()) 00341 PrintHeader(request->m_response, form); 00342 else 00343 OpenForm(request->m_response, form, group); 00344 00345 parse_settings(general_settings, fn, group); 00346 load_settings(general_settings, gCoreContext->GetHostName()); 00347 PrintSettings(request->m_response, general_settings); 00348 00349 if (group.isEmpty()) 00350 PrintFooter(request->m_response); 00351 else 00352 CloseForm(request->m_response, group); 00353 00354 handled = true; 00355 } 00356 else if (request->m_sMethod == "General") 00357 { 00358 QString fn = GetShareDir() + "backend-config/" 00359 "config_backend_general.xml"; 00360 QString group; 00361 QString form("/Config/General/Save"); 00362 00363 if (request->m_mapParams.contains("__group__")) 00364 group = request->m_mapParams["__group__"]; 00365 00366 if (group.isEmpty()) 00367 PrintHeader(request->m_response, form); 00368 else 00369 OpenForm(request->m_response, form, group); 00370 00371 parse_settings(general_settings, fn, group); 00372 load_settings(general_settings, gCoreContext->GetHostName()); 00373 PrintSettings(request->m_response, general_settings); 00374 00375 if (group.isEmpty()) 00376 PrintFooter(request->m_response); 00377 else 00378 CloseForm(request->m_response, group); 00379 00380 handled = true; 00381 } 00382 00383 if (handled) 00384 { 00385 request->m_eResponseType = ResponseTypeHTML; 00386 request->m_mapRespHeaders[ "Cache-Control" ] = 00387 "no-cache=\"Ext\", max-age = 0"; 00388 } 00389 00390 return handled; 00391 } 00392 00393 void HttpConfig::PrintHeader(QBuffer &buffer, const QString &form, 00394 const QString &group) 00395 { 00396 QTextStream os(&buffer); 00397 00398 os.setCodec("UTF-8"); 00399 00400 os << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " 00401 << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n" 00402 << "<html xmlns=\"http://www.w3.org/1999/xhtml\"" 00403 << " xml:lang=\"en\" lang=\"en\">\r\n" 00404 << "<head>\r\n" 00405 << " <meta http-equiv=\"Content-Type\"\r\n" 00406 << " content=\"text/html; charset=UTF-8\" />\r\n" 00407 << " <link rel=\"stylesheet\" href=\"/setup/css/Config.css\" type=\"text/css\">\r\n" 00408 << " <title>MythTV Config</title>" 00409 << "</head>\r\n" 00410 << "<body>\r\n\r\n" 00411 << "<div class=\"config\">\r\n" 00412 << " <h1 class=\"config\">MythTV Configuration</h1>\r\n"; 00413 00414 OpenForm(buffer, form, group); 00415 } 00416 00417 void HttpConfig::OpenForm(QBuffer &buffer, const QString &form, 00418 const QString &group) 00419 { 00420 QTextStream os(&buffer); 00421 00422 os.setCodec("UTF-8"); 00423 00424 os << " <form id=\"config_form_" << group << "\">\r\n" 00425 << " <input type=\"hidden\" id=\"__config_form_action__\" value=\"" << form << "\" />\r\n" 00426 << " <input type=\"hidden\" id=\"__group__\" value=\"" << group << "\" />\r\n"; 00427 } 00428 00429 void HttpConfig::CloseForm(QBuffer &buffer, const QString &group) 00430 { 00431 QTextStream os(&buffer); 00432 00433 // os << " <div class=\"config_form_submit\"\r\n" 00434 // << " id=\"config_form_submit\">\r\n"; 00435 os << " <input type=\"button\" value=\"Save Changes\" onClick=\"javascript:submitConfigForm('" << group << "')\" />\r\n" 00436 // << " </div>\r\n" 00437 << " </form>\r\n"; 00438 } 00439 00440 void HttpConfig::PrintFooter(QBuffer &buffer, const QString &group) 00441 { 00442 CloseForm(buffer, group); 00443 00444 QTextStream os(&buffer); 00445 00446 os << "</div>\r\n" 00447 << "</body>\r\n" 00448 << "</html>\r\n"; 00449 } 00450 00451 void HttpConfig::PrintSettings(QBuffer &buffer, const MythSettingList &settings) 00452 { 00453 QTextStream os(&buffer); 00454 00455 MythSettingList::const_iterator it = settings.begin(); 00456 for (; it != settings.end(); ++it) 00457 os << (*it)->ToHTML(1); 00458 }
1.7.6.1