added: properly use default scraper in http api function
[xbmc:xbmc-antiquated.git] / xbmc / lib / libGoAhead / XBMChttp.cpp
1
2 /******************************** Description *********************************/
3
4 /*
5  *  This module provides an API over HTTP between the web server and XBMC
6  *
7  *            heavily based on XBMCweb.cpp
8  */
9
10 /********************************* Includes ***********************************/
11
12 #include "stdafx.h"
13 #include "WebServer.h"
14 #include "XBMChttp.h"
15 #include "includes.h"
16
17 #include "../../PlayListFactory.h"
18 #include "../../Application.h"
19 #include "../../Util.h"
20 #include "../../PlayListPlayer.h"
21 #include "../../FileSystem/HDDirectory.h" 
22 #include "../../FileSystem/CDDADirectory.h"
23 #include "../../VideoDatabase.h"
24 #include "GUIButtonControl.h"
25 #include "../../utils/GUIInfoManager.h"
26 #include "../../Picture.h"
27 #include "../../musicInfoTagLoaderFactory.h"
28 #include "../../utils/MusicInfoScraper.h"
29 #include "../../MusicDatabase.h"
30 #include "../../GUIWindowSlideShow.h"
31 #include "../../GUIMediaWindow.h"
32 #include "../../GUIWindowFileManager.h"
33 #include "GUIButtonScroller.h"
34 #include "../../FileSystem/FactoryDirectory.h"
35 #include "../../FileSystem/VirtualDirectory.h"
36 #include "../../utils/UdpClient.h"
37 #include "../../xbox/XKHDD.h"
38 #include "../../PictureInfoTag.h"
39 #include "../../MusicInfoTag.h"
40
41 using namespace std;
42 using namespace MUSIC_GRABBER;
43 using namespace XFILE;
44 using namespace DIRECTORY;
45 using namespace PLAYLIST;
46 using namespace MUSIC_INFO;
47
48 #define XML_MAX_INNERTEXT_SIZE 256
49 #define MAX_PARAS 20
50 #define NO_EID -1
51
52 CXbmcHttp* m_pXbmcHttp;
53 CXbmcHttpShim* pXbmcHttpShim;
54
55
56 CUdpBroadcast::CUdpBroadcast() : CUdpClient()
57 {
58   Create();
59 }
60
61 CUdpBroadcast::~CUdpBroadcast()
62 {
63   Destroy();
64 }
65
66 bool CUdpBroadcast::broadcast(CStdString message, int port)
67 {
68   if (port>0)
69     return Broadcast(port, message);
70   else
71     return false;
72 }
73
74
75 CXbmcHttp::CXbmcHttp()
76 {
77   resetTags();
78   CKey temp;
79   key = temp;
80   lastKey = temp;
81   lastThumbFn="";
82   repeatKeyRate=0;
83   MarkTime=0;
84   pUdpBroadcast=NULL;
85   shuttingDown=false;
86   autoGetPictureThumbs=true;
87 }
88
89 CXbmcHttp::~CXbmcHttp()
90 {
91   if (pUdpBroadcast)
92   {
93     delete pUdpBroadcast;
94     pUdpBroadcast=NULL;
95   }
96   CLog::Log(LOGDEBUG, "xbmcHttp ends");
97 }
98
99 /*
100 ** encode
101 **
102 ** base64 encode a stream adding padding and line breaks as per spec.
103 */
104 CStdString CXbmcHttp::encodeFileToBase64( CStdString inFilename, int linesize )
105 {
106   unsigned char in[3];//, out[4];
107   int i, len, blocksout = 0;
108   CStdString strBase64="";
109   FILE *infile;
110
111 //  Translation Table as described in RFC1113
112   static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
113
114   infile = fopen( inFilename.c_str(), "rb" );
115   bool bOutput=false;
116   if (infile != 0) 
117   {
118     while( !feof( infile ) ) 
119     {
120       len = 0;
121       for( i = 0; i < 3; i++ ) 
122       {
123         in[i] = (unsigned char) getc( infile );
124         if( !feof( infile ) ) 
125           len++;
126         else 
127           in[i] = 0;
128       }
129       if( len ) 
130       {
131                 strBase64 += cb64[ in[0] >> 2 ];
132         strBase64 += cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
133         strBase64 += (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
134         strBase64 += (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
135         blocksout++;
136       }
137       if(linesize == 0 && feof(infile))
138         bOutput=true;
139       else if ((linesize > 0) && (blocksout >= (linesize/4) || (feof(infile))))
140         bOutput=true;
141       if (bOutput)
142       {
143         if( blocksout && linesize > 0 )
144           strBase64 += "\r";
145         if( blocksout )
146           strBase64 += closeTag ;
147         blocksout = 0;
148         bOutput=false;
149       }
150     }
151     fclose(infile);
152   }
153   return strBase64;
154 }
155
156 /*
157 ** decode
158 **
159 ** decode a base64 encoded stream discarding padding, line breaks and noise
160 */
161 bool CXbmcHttp::decodeBase64ToFile( const CStdString &inString, const CStdString &outfilename, bool append)
162 {
163   unsigned char in[4], v; //out[3];
164   bool ret=true;
165   int i, len ;
166   unsigned int ptr=0;
167   FILE *outfile;
168
169 // Translation Table to decode
170   static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
171
172   try
173   {
174     if (append)
175           outfile = fopen( outfilename.c_str(), "ab" );
176         else
177       outfile = fopen( outfilename.c_str(), "wb" );
178     while( ptr < inString.length() )
179     {
180       for( len = 0, i = 0; i < 4 && ptr < inString.length(); i++ ) 
181       {
182         v = 0;
183         while( ptr < inString.length() && v == 0 ) 
184         {
185           v = (unsigned char) inString[ptr];
186           ptr++;
187           v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
188           if( v )
189             v = (unsigned char) ((v == '$') ? 0 : v - 61);
190         }
191         if( ptr < inString.length() ) {
192           len++;
193           if( v ) 
194             in[ i ] = (unsigned char) (v - 1);
195         }
196         else 
197           in[i] = 0;
198       }
199       if( len ) 
200       {
201                 putc((unsigned char ) ((in[0] << 2 | in[1] >> 4) & 255), outfile );
202         putc((unsigned char ) ((in[1] << 4 | in[2] >> 2) & 255), outfile );
203         putc((unsigned char ) ((in[2] << 6) & 0xc0) | in[3], outfile );
204       }
205     }
206     fclose(outfile);
207   }
208   catch (...)
209   {
210     ret=false;
211   }
212   return ret;
213 }
214
215 __int64 CXbmcHttp::fileSize(const CStdString &filename)
216 {
217   if (CFile::Exists(filename))
218   {
219     struct __stat64 s64;
220     if (CFile::Stat(filename, &s64) == 0)
221       return s64.st_size;
222     else
223       return -1;
224   }
225   else
226     return -1;
227 }
228
229 void CXbmcHttp::resetTags()
230 {
231   openTag="<li>"; 
232   closeTag="\n";
233   userHeader="";
234   userFooter="";
235   openRecordSet="";
236   closeRecordSet="";
237   openRecord="";
238   closeRecord="";
239   openField="<field>";
240   closeField="</field>";
241   openBroadcast="<b>";
242   closeBroadcast="</b>";
243   incWebHeader=true;
244   incWebFooter=true;
245   closeFinalTag=false;
246 }
247
248 CStdString CXbmcHttp::procMask(CStdString mask)
249 {
250   mask=mask.ToLower();
251   if(mask=="[music]")
252     return g_stSettings.m_musicExtensions;
253   if(mask=="[video]")
254     return g_stSettings.m_videoExtensions;
255   if(mask=="[pictures]")
256     return g_stSettings.m_pictureExtensions;
257   if(mask=="[files]")
258     return "";
259   return mask;
260 }
261
262 int CXbmcHttp::splitParameter(const CStdString &parameter, CStdString& command, CStdString paras[], const CStdString &sep)
263 //returns -1 if no command, -2 if too many parameters else the number of parameters
264 //assumption: sep.length()==1
265 {
266   unsigned int num=0, p;
267   CStdString empty="";
268
269   paras[0]="";
270   for (p=0; p<parameter.length(); p++)
271   {
272     if (parameter.Mid(p,1)==sep)
273     {
274       if (p<parameter.length()-1)
275       {
276         if (parameter.Mid(p+1,1)==sep)
277         {
278           paras[num]+=sep;
279           p+=1;
280         }
281         else
282         {
283           if (command!="")
284           {
285             paras[num]=paras[num].Trim();
286             num++;
287                         if (num==MAX_PARAS)
288                       return -2;
289           }
290           else
291           {
292             command=paras[0];
293             paras[0]=empty;
294             p++; //the ";" after the command is always followed by a space which we can jump over
295           }
296         }
297       }
298       else
299       {
300         if (command!="")
301         {
302           paras[num]=paras[num].Trim();
303           num++;
304                   if (num==MAX_PARAS)
305                     return -2;
306         }
307         else
308         {
309           command=paras[0];
310           paras[0]=empty;
311         }
312       }
313     }
314     else
315     {
316       paras[num]+=parameter.Mid(p,1);
317     }
318   }
319   if (command=="")
320     if (paras[0]!="")
321     {
322       command=paras[0];
323       return 0;
324     }
325     else
326       return -1;
327   else
328   {
329     paras[num]=paras[num].Trim();
330     return num+1;
331   }
332 }
333
334
335 bool CXbmcHttp::playableFile(const CStdString &filename)
336 {
337   CFileItem item(filename, false);  
338   return item.IsInternetStream() || CFile::Exists(filename);
339 }
340
341 int CXbmcHttp::SetResponse(const CStdString &response)
342 {
343   if (response.length()>=closeTag.length())
344   {
345     if ((response.Right(closeTag.length())!=closeTag) && closeFinalTag) 
346       return g_applicationMessenger.SetResponse(response+closeTag);
347   }
348   else 
349     if (closeFinalTag)
350       return g_applicationMessenger.SetResponse(response+closeTag);
351   return g_applicationMessenger.SetResponse(response);
352 }
353
354 int CXbmcHttp::displayDir(int numParas, CStdString paras[]) 
355 {
356   //mask = ".mp3|.wma" or one of "[music]", "[video]", "[pictures]", "[files]"-> matching files
357   //mask = "*" or "/" -> just folders
358   //mask = "" -> all files and folder
359   //option = "1" -> append date&time to file name
360
361   CFileItemList dirItems;
362   CStdString output="";
363
364   CStdString  folder, mask="", option="";
365
366   if (numParas==0)
367   {
368     return SetResponse(openTag+"Error:Missing folder");
369   }
370   folder=paras[0];
371   if (folder.length()<1)
372   {
373     return SetResponse(openTag+"Error:Missing folder");
374   }
375   if (numParas>1)
376     mask=procMask(paras[1]);
377   if (numParas>2)
378     option=paras[2];
379   IDirectory *pDirectory = CFactoryDirectory::Create(folder);
380   if (!pDirectory) 
381   {
382     return SetResponse(openTag+"Error");  
383   }
384   pDirectory->SetMask(mask);
385   if (!pDirectory->GetDirectory(folder,dirItems))
386   {
387     return SetResponse(openTag+"Error:Not folder");
388   }
389   dirItems.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC);
390   CStdString aLine="";
391   for (int i=0; i<dirItems.Size(); ++i)
392   {
393     CFileItem *itm = dirItems[i];
394     if (mask=="*" || mask=="/" || (mask =="" && itm->m_bIsFolder))
395       if (!CUtil::HasSlashAtEnd(itm->m_strPath))
396         aLine=closeTag+openTag + itm->m_strPath + "\\" ;
397       else
398         aLine=closeTag+openTag + itm->m_strPath ;
399     else
400       if (!itm->m_bIsFolder)
401         aLine=closeTag+openTag + itm->m_strPath;
402     if (aLine!="")
403     {
404       if (option=="1") {
405         output+=aLine+"  ;" + itm->m_dateTime.GetAsLocalizedDateTime();
406       }
407       else
408         output+=aLine;
409       aLine="";
410     }
411   }
412   return SetResponse(output);
413 }
414
415 void CXbmcHttp::SetCurrentMediaItem(CFileItem& newItem)
416 {
417   //  No audio file, we are finished here
418   if (!newItem.IsAudio() )
419     return;
420
421   //  we have a audio file.
422   //  Look if we have this file in database...
423   bool bFound=false;
424   CMusicDatabase musicdatabase;
425   if (musicdatabase.Open())
426   {
427     CSong song;
428     bFound=musicdatabase.GetSongByFileName(newItem.m_strPath, song);
429     newItem.GetMusicInfoTag()->SetSong(song);
430     musicdatabase.Close();
431   }
432   if (!bFound && g_guiSettings.GetBool("musicfiles.usetags"))
433   {
434     //  ...no, try to load the tag of the file.
435     auto_ptr<IMusicInfoTagLoader> pLoader(CMusicInfoTagLoaderFactory::CreateLoader(newItem.m_strPath));
436     //  Do we have a tag loader for this file type?
437     if (pLoader.get() != NULL)
438       pLoader->Load(newItem.m_strPath,*newItem.GetMusicInfoTag());
439   }
440
441   //  If we have tag information, ...
442   if (newItem.HasMusicInfoTag() && newItem.GetMusicInfoTag()->Loaded())
443   {
444     g_infoManager.SetCurrentSongTag(*newItem.GetMusicInfoTag());
445   }
446 }
447
448 void CXbmcHttp::AddItemToPlayList(const CFileItem* pItem, int playList, int sortMethod, CStdString mask, bool recursive)
449 //if playlist==-1 then use slideshow
450 {
451   if (pItem->m_bIsFolder)
452   {
453     // recursive
454     if (pItem->IsParentFolder()) return;
455     CStdString strDirectory=pItem->m_strPath;
456     CFileItemList items;
457     IDirectory *pDirectory = CFactoryDirectory::Create(strDirectory);
458     if (mask!="")
459       pDirectory->SetMask(mask);
460     pDirectory->GetDirectory(strDirectory, items);
461     items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC);
462     for (int i=0; i < items.Size(); ++i)
463           if (!(CFileItem*)items[i]->m_bIsFolder || recursive)
464         AddItemToPlayList(items[i], playList, sortMethod, mask, recursive);
465   }
466   else
467   {
468     //selected item is a file, add it to playlist
469     if (playList==-1)
470     {
471       CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
472       if (!pSlideShow)
473         return ;
474       pSlideShow->Add(pItem);
475     }
476     else
477       g_playlistPlayer.Add(playList, (CFileItem*)pItem);
478   }
479 }
480
481 void CXbmcHttp::LoadPlayListOld(const CStdString& strPlayList, int playList)
482 {
483   // load a playlist like .m3u, .pls
484   // first get correct factory to load playlist
485   auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(strPlayList));
486   if ( NULL != pPlayList.get())
487   {
488     if (!pPlayList->Load(strPlayList))
489       return; 
490     g_playlistPlayer.ClearPlaylist(playList);
491     g_playlistPlayer.Reset();
492     g_playlistPlayer.Add(playList, *pPlayList);
493     g_playlistPlayer.SetCurrentPlaylist(playList);
494     g_applicationMessenger.PlayListPlayerPlay();
495     
496     // set current file item
497     CPlayList& playlist = g_playlistPlayer.GetPlaylist(playList);
498     CFileItem item(playlist[0].GetDescription());
499     item.m_strPath = playlist[0].GetFileName();
500     SetCurrentMediaItem(item);
501   }
502 }
503
504 bool CXbmcHttp::LoadPlayList(CStdString strPath, int iPlaylist, bool clearList, bool autoStart)
505 {
506   //CStdString strPath = item.m_strPath;
507   CFileItem *item = new CFileItem(CUtil::GetFileName(strPath));
508   item->m_strPath=strPath;
509
510   auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(*item));
511   if ( NULL == pPlayList.get())
512     return false;
513   if (!pPlayList->Load(item->m_strPath))
514     return false;
515
516   CPlayList& playlist = (*pPlayList);
517
518   if (playlist.size() == 0)
519     return false;
520
521   // first item of the list, used to determine the intent
522   CPlayList::CPlayListItem playlistItem = playlist[0];
523
524   if ((playlist.size() == 1) && (autoStart))
525   {
526     // just 1 song? then play it (no need to have a playlist of 1 song)
527     g_applicationMessenger.MediaPlay(CFileItem(playlistItem).m_strPath);
528     return true;
529   }
530
531   if (clearList)
532     g_playlistPlayer.ClearPlaylist(iPlaylist);
533
534   g_playlistPlayer.Add(iPlaylist, *pPlayList);
535
536   if (autoStart)
537     if (g_playlistPlayer.GetPlaylist( iPlaylist ).size() )
538     {
539       g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
540       g_playlistPlayer.Reset();
541       g_applicationMessenger.PlayListPlayerPlay();
542       return true;
543     } 
544     else
545       return false;
546   else
547     return true;
548   return false;
549 }
550
551 void CXbmcHttp::copyThumb(CStdString srcFn, CStdString destFn)
552 //Copies src file to dest, unless src=="" or src doesn't exist in which case dest is deleted
553 {
554
555   if (destFn=="")
556     return;
557   if (srcFn=="")
558   {
559     try
560         {
561           if (CFile::Exists(destFn))
562             CFile::Delete(destFn);
563           lastThumbFn=srcFn;
564         }
565     catch (...)
566     {
567     }
568   }
569   else
570     if (srcFn!=lastThumbFn)
571           try
572           {
573             lastThumbFn=srcFn;
574             if (CFile::Exists(srcFn))
575           CFile::Cache(srcFn, destFn);
576             else
577             {
578               CPicture pic;
579           pic.CacheSkinImage(srcFn, destFn);
580             }
581       }
582       catch (...)
583       {
584         return;
585       }
586 }
587
588 int CXbmcHttp::xbmcGetMediaLocation(int numParas, CStdString paras[])
589 {
590   // getmediadirectory&parameter=type;location;options
591   // options = showdate, pathsonly
592   // returns a listing of
593   // <li>label;path;0|1=folder;date
594
595   int iType = -1;
596   CStdString strType;
597   CStdString strMask;
598   CStdString strLocation;
599   CStdString strOutput;
600
601   if (numParas < 1)
602     return SetResponse(openTag+"Error: must supply media type at minimum");
603   else
604   {
605     if (paras[0].Equals("music"))
606       iType = 0;
607     else if (paras[0].Equals("video"))
608       iType = 1;
609     else if (paras[0].Equals("pictures"))
610       iType = 2;
611     else if (paras[0].Equals("files"))
612       iType = 3;
613     if (iType < 0)
614       return SetResponse(openTag+"Error: invalid media type; valid options are music, video, pictures");
615
616     strType = paras[0].ToLower();
617     if (numParas > 1)
618       strLocation = paras[1];
619   }
620
621   // handle options
622   bool bShowDate = false;
623   bool bPathsOnly = false;
624   if (numParas > 2)
625   {
626     for (int i = 2; i < numParas; ++i)
627     {
628       if (paras[i].Equals("showdate"))
629         bShowDate = true;
630       else if (paras[i].Equals("pathsonly"))
631         bPathsOnly = true;
632     }
633     // pathsonly and showdate are mutually exclusive, pathsonly wins
634     if (bPathsOnly)
635       bShowDate = false;
636   }
637
638   VECSHARES *pShares = NULL;
639   enum SHARETYPES { MUSIC, VIDEO, PICTURES, FILES };
640   switch(iType)
641   {
642   case MUSIC:
643     {
644       pShares = &g_settings.m_musicSources;
645       strMask = g_stSettings.m_musicExtensions;
646     }
647     break;
648   case VIDEO:
649     {
650       pShares = &g_settings.m_videoSources;
651       strMask = g_stSettings.m_videoExtensions;
652     }
653     break;
654   case PICTURES:
655     {
656       pShares = &g_settings.m_pictureSources;
657       strMask = g_stSettings.m_pictureExtensions;
658     }
659     break;
660   case FILES:
661     {
662       pShares = &g_settings.m_fileSources;
663       strMask = "";
664     }
665     break;
666   }
667
668   if (!pShares)
669     return SetResponse(openTag+"Error");
670
671   // TODO: Why are we insisting the passed path has anything to do with
672   //       the shares in question??
673   //       Surely we should just grab the directory regardless??
674         // 
675         // kraqh3d's response:
676         //      When I added this function, it was meant to behave more like Xbmc internally.
677         //      This code emulates the CVirtualDirectory class which does not allow arbitrary
678         //      fetching of directories. (nor does ActivateWindow for that matter.)
679         //      You can still use the older "getDirectory" command which is unnounded and will
680         //      fetch any old folder.
681
682   // special locations
683   bool bSpecial = false;
684   CURL url(strLocation);
685   if (url.GetProtocol() == "rar" || url.GetProtocol() == "zip")
686     bSpecial = true;
687   if (strType.Equals("music"))
688   {
689     if (url.GetProtocol() == "musicdb")
690       bSpecial = true;
691     else if (strLocation.Equals("$playlists"))
692     {
693       strLocation = "special://musicplaylists/";
694       bSpecial = true;
695     }
696   }
697   else if (strType.Equals("video"))
698   {
699     if (strLocation.Equals("$playlists"))
700     {
701       strLocation = "special://videoplaylists/";
702       bSpecial = true;
703     }
704   }
705
706   if (!strLocation.IsEmpty() && !bSpecial)
707   {
708     VECSHARES vecShares = *pShares;
709     bool bIsShareName = false;
710     int iIndex = CUtil::GetMatchingShare(strLocation, vecShares, bIsShareName);
711     if (iIndex < 0)
712     {
713       CStdString strError = "Error: invalid location, " + strLocation;
714       return SetResponse(openTag+strError);
715     }
716     if (bIsShareName)
717       strLocation = vecShares[iIndex].strPath;
718   }
719
720   CFileItemList items;
721   if (strLocation.IsEmpty())
722   {
723     CStdString params[2];
724     params[0] = strType;
725     params[1] = "appendone";
726     if (bPathsOnly)
727       params[1] = "pathsonly";
728     return xbmcGetShares(2, params);
729   }
730   else if (!CDirectory::GetDirectory(strLocation, items, strMask))
731   {
732     CStdString strError = "Error: could not get location, " + strLocation;
733     return SetResponse(openTag+strError);
734   }
735
736   items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC);
737   CStdString strLine;
738   for (int i = 0; i < items.Size(); ++i)
739   {
740     CFileItem *item = items[i];
741     CStdString strLabel = item->GetLabel();
742     strLabel.Replace(";",";;");
743     CStdString strPath = item->m_strPath;
744     strPath.Replace(";",";;");
745     CStdString strFolder = "0";
746     if (item->m_bIsFolder)
747     {
748       if (!item->IsFileFolder() && !CUtil::HasSlashAtEnd(strPath))
749         CUtil::AddSlashAtEnd(strPath);
750       strFolder = "1";
751     }
752     strLine = openTag;
753     if (!bPathsOnly)
754       strLine += strLabel + ";";
755     strLine += strPath;
756     if (!bPathsOnly)
757       strLine += ";" + strFolder;
758     if (bShowDate)
759     {
760       strLine += ";" + item->m_dateTime.GetAsLocalizedDateTime();
761     }
762     strLine += closeTag;
763     strOutput += strLine;
764   }
765   return SetResponse(strOutput);
766 }
767
768 int CXbmcHttp::xbmcGetXBEID(int numParas, CStdString paras[])
769 {
770   if (numParas==0) {
771     return SetResponse(openTag+"Error:Missing Parameter");
772   }
773   CStdString tmp;
774   if (CFile::Exists(paras[0].c_str()))
775   {
776     tmp.Format("%09x",CUtil::GetXbeID(paras[0]));
777     return SetResponse(openTag + tmp);
778   }
779   else
780   {
781      return SetResponse(openTag+"Error:xbe doesn't exist");
782   }
783
784 }
785
786 int CXbmcHttp::xbmcGetXBETitle(int numParas, CStdString paras[])
787 {
788   CStdString xbeinfo;
789   if (numParas==0) {
790     return SetResponse(openTag+"Error:Missing Parameter");
791   }
792   CStdString tmp;
793   if (CUtil::GetXBEDescription(paras[0],xbeinfo))
794   {
795     tmp.Format("%s",xbeinfo);
796     return SetResponse(openTag + tmp);
797   }
798   else
799   {
800      return SetResponse(openTag+"Error:Failed to getxbetitle");
801   }
802 }
803
804 int CXbmcHttp::xbmcGetShares(int numParas, CStdString paras[])
805 {
806   // returns the share listing in this format:
807   // <li>type;name;path
808   // literal semicolons are translated into ;;
809   // options include the type, and pathsonly boolean
810
811   int iStart = 0;
812   int iEnd   = 4;
813   bool bShowType = true;
814   bool bShowName = true;
815
816   if (numParas > 0)
817   {
818     if (paras[0].Equals("music"))
819     {
820       iStart = 0;
821       iEnd   = 1;
822       bShowType = false;
823     }
824     else if (paras[0].Equals("video"))
825     {
826       iStart = 1;
827       iEnd   = 2;
828       bShowType = false;
829     }
830     else if (paras[0].Equals("pictures"))
831     {
832       iStart = 2;
833       iEnd   = 3;
834       bShowType = false;
835     }
836     else if (paras[0].Equals("files"))
837     {
838       iStart = 3;
839       iEnd   = 4;
840       bShowType = false;
841     }
842     else
843       numParas = 0;
844   }
845
846   bool bAppendOne = false;
847   if (numParas > 1)
848   {
849     // special case where getmedialocation calls getshares
850     if (paras[1].Equals("appendone"))
851       bAppendOne = true;
852     else if (paras[1].Equals("pathsonly"))
853       bShowName = false;
854   }
855
856   CStdString strOutput;
857   enum SHARETYPES { MUSIC, VIDEO, PICTURES, FILES };
858   for (int i = iStart; i < iEnd; ++i)
859   {
860     CStdString strType;
861     VECSHARES *pShares = NULL;
862     switch(i)
863     {
864     case MUSIC:
865       {
866         strType = "music";
867         pShares = &g_settings.m_musicSources;
868       }
869       break;
870     case VIDEO:
871       {
872         strType = "video";
873         pShares = &g_settings.m_videoSources;
874       }
875       break;
876     case PICTURES:
877       {
878         strType = "pictures";
879         pShares = &g_settings.m_pictureSources;
880       }
881       break;
882     case FILES:
883       {
884         strType = "files";
885         pShares = &g_settings.m_fileSources;
886       }
887       break;
888     }
889
890     if (!pShares)
891       return SetResponse(openTag+"Error");
892     
893     VECSHARES vecShares = *pShares;
894     for (int j = 0; j < (int)vecShares.size(); ++j)
895     {
896       CShare share = vecShares.at(j);
897       CStdString strName = share.strName;
898       strName.Replace(";", ";;");
899       CStdString strPath = share.strPath;
900       strPath.Replace(";", ";;");
901       if (!CUtil::HasSlashAtEnd(strPath))
902         CUtil::AddSlashAtEnd(strPath);
903       CStdString strLine = openTag;
904       if (bShowType)
905         strLine += strType + ";";
906       if (bShowName)
907         strLine += strName + ";";
908       strLine += strPath;
909       if (bAppendOne)
910         strLine += ";1";
911       strLine += closeTag;
912       strOutput += strLine;
913     }
914   }
915   return SetResponse(strOutput);
916 }
917
918 int CXbmcHttp::xbmcQueryMusicDataBase(int numParas, CStdString paras[])
919 {
920   if (numParas==0)
921     return SetResponse(openTag+"Error:Missing Parameter");
922   else
923   {
924         CMusicDatabase musicdatabase;
925         if (musicdatabase.Open())
926         {
927           CStdString result;
928       if (musicdatabase.GetArbitraryQuery(paras[0], openRecordSet, closeRecordSet, openRecord, closeRecord, openField, closeField, result))
929                 return SetResponse(result);
930           else
931                   return SetResponse(openTag+"Error:"+result);
932           musicdatabase.Close();
933         }
934         else
935           return SetResponse(openTag+"Error:Could not open database");
936   }
937   return true;
938 }
939
940 int CXbmcHttp::xbmcQueryVideoDataBase(int numParas, CStdString paras[])
941 {
942   if (numParas==0)
943     return SetResponse(openTag+"Error:Missing Parameter");
944   else
945   {
946         CVideoDatabase videodatabase;
947         if (videodatabase.Open())
948         {
949           CStdString result;
950       if (videodatabase.GetArbitraryQuery(paras[0], openRecordSet, closeRecordSet, openRecord, closeRecord, openField, closeField, result))
951                 return SetResponse(result);
952           else
953                   return SetResponse(openTag+"Error:"+result);
954           videodatabase.Close();
955         }
956         else
957           return SetResponse(openTag+"Error:Could not open database");
958   }
959   return true;
960 }
961
962 int CXbmcHttp::xbmcAddToPlayList(int numParas, CStdString paras[])
963 {
964   //parameters=playList;mask;recursive
965   CStdString strFileName, mask="";
966   bool changed=false, recursive=true;
967   int playList ;
968
969   if (numParas==0)
970     return SetResponse(openTag+"Error:Missing Parameter");
971   else
972   {
973     if (numParas==1) //no playlist and no mask
974       playList=g_playlistPlayer.GetCurrentPlaylist();
975     else
976     {
977       playList=atoi(paras[1]);
978       if (playList==-1)
979         playList=g_playlistPlayer.GetCurrentPlaylist();
980       if(numParas>2) //includes mask
981         mask=procMask(paras[2]);
982           if (numParas>3) //recursive
983             recursive=(paras[3]=="1");
984     }
985     strFileName=paras[0] ;
986     CFileItem *pItem = new CFileItem(strFileName);
987     pItem->m_strPath=strFileName.c_str();
988     if (pItem->IsPlayList())
989       changed=LoadPlayList(pItem->m_strPath, playList, false, false);
990     else
991     {      
992       bool bResult = CDirectory::Exists(pItem->m_strPath);
993       pItem->m_bIsFolder=bResult;
994       pItem->m_bIsShareOrDrive=false;
995       if (bResult || CFile::Exists(pItem->m_strPath))
996       {
997         AddItemToPlayList(pItem, playList, 0, mask, recursive);
998         changed=true;
999       }
1000     }
1001     delete pItem;
1002     if (changed)
1003     {
1004       g_playlistPlayer.HasChanged();
1005       return SetResponse(openTag+"OK");
1006     }
1007     else
1008       return SetResponse(openTag+"Error");
1009   }
1010 }
1011
1012 int CXbmcHttp::xbmcGetTagFromFilename(int numParas, CStdString paras[]) 
1013 {
1014   CStdString strFileName;
1015   if (numParas==0) {
1016     return SetResponse(openTag+"Error:Missing Parameter");
1017   }
1018   strFileName=CUtil::GetFileName(paras[0]);
1019   CFileItem *pItem = new CFileItem(strFileName);
1020   pItem->m_strPath=paras[0].c_str();
1021   if (!pItem->IsAudio())
1022   {
1023     delete pItem;
1024     return SetResponse(openTag+"Error:Not Audio");
1025   }
1026
1027   CMusicInfoTag* tag=pItem->GetMusicInfoTag();
1028   bool bFound=false;
1029   CSong song;
1030   CMusicDatabase musicdatabase;
1031   if (musicdatabase.Open())
1032   {
1033     bFound=musicdatabase.GetSongByFileName(pItem->m_strPath, song);
1034     musicdatabase.Close();
1035   }
1036   if (bFound)
1037   {
1038     SYSTEMTIME systime;
1039     systime.wYear=song.iYear;
1040     tag->SetReleaseDate(systime);
1041     tag->SetTrackNumber(song.iTrack);
1042     tag->SetAlbum(song.strAlbum);
1043     tag->SetArtist(song.strArtist);
1044     tag->SetGenre(song.strGenre);
1045     tag->SetTitle(song.strTitle);
1046     tag->SetDuration(song.iDuration);
1047     tag->SetLoaded(true);
1048   }
1049   else
1050     if (g_guiSettings.GetBool("musicfiles.usetags"))
1051     {
1052       // get correct tag parser
1053       auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(pItem->m_strPath));
1054       if (NULL != pLoader.get())
1055       {            
1056         // get id3tag
1057         if ( !pLoader->Load(pItem->m_strPath,*tag))
1058           tag->SetLoaded(false);
1059       }
1060       else
1061       {
1062         return SetResponse(openTag+"Error:Could not load TagLoader");
1063       }
1064     }
1065     else
1066     {
1067       return SetResponse(openTag+"Error:System not set to use tags");
1068     }
1069   if (tag->Loaded())
1070   {
1071     CStdString output, tmp;
1072
1073     output = openTag+"Artist:" + tag->GetArtist();
1074     output += closeTag+openTag+"Album:" + tag->GetAlbum();
1075     output += closeTag+openTag+"Title:" + tag->GetTitle();
1076     tmp.Format("%i", tag->GetTrackNumber());
1077     output += closeTag+openTag+"Track number:" + tmp;
1078     tmp.Format("%i", tag->GetDuration());
1079     output += closeTag+openTag+"Duration:" + tmp;
1080     output += closeTag+openTag+"Genre:" + tag->GetGenre();
1081     SYSTEMTIME stTime;
1082     tag->GetReleaseDate(stTime);
1083     tmp.Format("%i", stTime.wYear);
1084     output += closeTag+openTag+"Release year:" + tmp;
1085     pItem->SetMusicThumb();
1086     if (pItem->HasThumbnail())
1087       output += closeTag+openTag+"Thumb:" + pItem->GetThumbnailImage() ;
1088     else {
1089       output += closeTag+openTag+"Thumb:[None]";
1090     }
1091     delete pItem;
1092     return SetResponse(output);
1093   }
1094   else
1095   {
1096     delete pItem;
1097     return SetResponse(openTag+"Error:No tag info");
1098   }
1099 }
1100
1101 int CXbmcHttp::xbmcClearPlayList(int numParas, CStdString paras[])
1102 {
1103   int playList ;
1104   if (numParas==0)
1105     playList = g_playlistPlayer.GetCurrentPlaylist() ;
1106   else
1107     playList=atoi(paras[0]) ;
1108   g_playlistPlayer.ClearPlaylist( playList );
1109   return SetResponse(openTag+"OK");
1110 }
1111
1112 int CXbmcHttp::xbmcGetDirectory(int numParas, CStdString paras[])
1113 {
1114   if (numParas>0)
1115     return displayDir(numParas, paras);
1116   else
1117     return SetResponse(openTag+"Error:No path") ;
1118 }
1119
1120 int CXbmcHttp::xbmcGetMovieDetails(int numParas, CStdString paras[])
1121 {
1122   if (numParas>0)
1123   {
1124     CFileItem *item = new CFileItem(paras[0]);
1125     item->m_strPath = paras[0].c_str() ;
1126     if (item->IsVideo()) {
1127       CVideoDatabase m_database;
1128       CVideoInfoTag aMovieRec;
1129       m_database.Open();
1130       if (m_database.HasMovieInfo(paras[0].c_str()))
1131       {
1132         CStdString thumb, output, tmp;
1133         m_database.GetMovieInfo(paras[0].c_str(),aMovieRec);
1134         tmp.Format("%i", aMovieRec.m_iYear);
1135         output = closeTag+openTag+"Year:" + tmp;
1136         output += closeTag+openTag+"Director:" + aMovieRec.m_strDirector;
1137         output += closeTag+openTag+"Title:" + aMovieRec.m_strTitle;
1138         output += closeTag+openTag+"Plot:" + aMovieRec.m_strPlot;
1139         output += closeTag+openTag+"Genre:" + aMovieRec.m_strGenre;
1140         CStdString strRating;
1141         strRating.Format("%3.3f", aMovieRec.m_fRating);
1142         if (strRating=="") strRating="0.0";
1143         output += closeTag+openTag+"Rating:" + strRating;
1144         CStdString cast = aMovieRec.GetCast(true);
1145         /*for (CVideoInfoTag::iCast it = aMovieRec.m_cast.begin(); it != aMovieRec.m_cast.end(); ++it)
1146         {
1147           CStdString character;
1148           character.Format("%s %s %s\n", it->first.c_str(), g_localizeStrings.Get(20347).c_str(), it->second.c_str());
1149           cast += character;
1150         }*/
1151         output += closeTag+openTag+"Cast:" + cast;
1152         item->SetVideoThumb();
1153         if (!item->HasThumbnail())
1154           thumb = "[None]";
1155         else
1156           thumb = item->GetCachedVideoThumb();
1157         output += closeTag+openTag+"Thumb:" + thumb;
1158         m_database.Close();
1159         delete item;
1160         return SetResponse(output);
1161       }
1162       else
1163       {
1164         m_database.Close();
1165         delete item;
1166         return SetResponse(openTag+"Error:Not found");
1167       }
1168     }
1169     else
1170     {
1171       delete item;
1172       return SetResponse(openTag+"Error:Not a video") ;
1173     }
1174   }
1175   else
1176     return SetResponse(openTag+"Error:No file name") ;
1177 }
1178
1179 int CXbmcHttp::xbmcGetCurrentlyPlaying(int numParas, CStdString paras[])
1180 {
1181   CStdString output="", tmp="", tag="", thumbFn="", thumbNothingPlaying="", thumb="";
1182   if (numParas>0)
1183     thumbFn=paras[0];
1184   if (numParas>1)
1185     thumbNothingPlaying=paras[1];
1186   CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1187   if (m_gWindowManager.GetActiveWindow() == WINDOW_SLIDESHOW && pSlideShow)
1188   {
1189     const CFileItem *slide = pSlideShow->GetCurrentSlide();
1190     output=openTag+"Filename:"+slide->m_strPath;
1191     output+=closeTag+openTag+"Type:Picture" ;
1192     CStdString resolution = "0x0";
1193     if (slide && slide->HasPictureInfoTag() && slide->GetPictureInfoTag()->Loaded())
1194       resolution = slide->GetPictureInfoTag()->GetInfo(SLIDE_RESOLUTION);
1195     output+=closeTag+openTag+"Resolution:" + resolution;
1196     CFileItem item(*slide);
1197     item.SetCachedPictureThumb();
1198     if (autoGetPictureThumbs && !item.HasThumbnail())
1199     {
1200       CPicture pic;
1201       pic.DoCreateThumbnail(item.m_strPath, item.GetCachedPictureThumb());
1202       item.SetCachedPictureThumb();
1203     }
1204     thumb = item.GetCachedPictureThumb();
1205     if (!item.HasThumbnail())
1206         {
1207       thumb = "[None] " + thumb;
1208           copyThumb("defaultPictureBig.png",thumbFn);
1209         }
1210         else
1211       copyThumb(thumb,thumbFn);
1212     output+=closeTag+openTag+"Thumb:"+thumb;
1213     return SetResponse(output);
1214   }
1215
1216   CFileItem &fileItem = g_application.CurrentFileItem();
1217   if (fileItem.m_strPath.IsEmpty())
1218   {
1219     output=openTag+"Filename:[Nothing Playing]";
1220         copyThumb(thumbNothingPlaying,thumbFn);
1221   }
1222   else
1223   {
1224     output = openTag + "Filename:" + fileItem.m_strPath;  // currently playing item filename
1225     if (g_application.IsPlayingVideo())
1226     { // Video information
1227       tmp.Format("%i",g_playlistPlayer.GetCurrentSong());
1228       output+=closeTag+openTag+"VideoNo:"+tmp;  // current item # in playlist
1229       output+=closeTag+openTag+"Type"+tag+":Video" ;
1230       const CVideoInfoTag* tagVal=g_infoManager.GetCurrentMovieTag();
1231       if (tagVal)
1232       {
1233         if (!tagVal->m_strShowTitle.IsEmpty())
1234           output+=closeTag+openTag+"Show Title"+tag+":"+tagVal->m_strShowTitle ;
1235         if (!tagVal->m_strTitle.IsEmpty())
1236           output+=closeTag+openTag+"Title"+tag+":"+tagVal->m_strTitle ;
1237         if (!tagVal->m_strGenre.IsEmpty())
1238           output+=closeTag+openTag+"Genre"+tag+":"+tagVal->m_strGenre;
1239         if (!tagVal->m_strStudio.IsEmpty())
1240           output+=closeTag+openTag+"Studio"+tag+":"+tagVal->m_strStudio;
1241         if (tagVal && !tagVal->m_strDirector.IsEmpty())
1242           output+=closeTag+openTag+"Director"+tag+":"+tagVal->m_strDirector;
1243         if (!tagVal->m_strWritingCredits.IsEmpty())
1244           output+=closeTag+openTag+"Writer"+tag+":"+tagVal->m_strWritingCredits;
1245         if (!tagVal->m_strTagLine.IsEmpty())
1246           output+=closeTag+openTag+"Tagline"+tag+":"+tagVal->m_strTagLine;
1247         if (!tagVal->m_strPlotOutline.IsEmpty())
1248           output+=closeTag+openTag+"Plotoutline"+tag+":"+tagVal->m_strPlotOutline;
1249         if (!tagVal->m_strPlot.IsEmpty())
1250           output+=closeTag+openTag+"Plot"+tag+":"+tagVal->m_strPlot;    
1251         if (tagVal->m_fRating != 0.0f)  // only non-zero ratings are of interest
1252           output.Format("%s%03.1f (%s %s)",output+closeTag+openTag+"Rating"+tag+":",tagVal->m_fRating, tagVal->m_strVotes, g_localizeStrings.Get(20350));
1253         if (!tagVal->m_strOriginalTitle.IsEmpty())
1254           output+=closeTag+openTag+"Original Title"+tag+":"+tagVal->m_strOriginalTitle;
1255         if (!tagVal->m_strPremiered.IsEmpty())
1256           output+=closeTag+openTag+"Premiered"+tag+":"+tagVal->m_strPremiered;
1257         if (!tagVal->m_strStatus.IsEmpty())
1258           output+=closeTag+openTag+"Status"+tag+":"+tagVal->m_strStatus;
1259         if (!tagVal->m_strProductionCode.IsEmpty())
1260           output+=closeTag+openTag+"Production Code"+tag+":"+tagVal->m_strProductionCode;
1261         if (!tagVal->m_strFirstAired.IsEmpty())
1262           output+=closeTag+openTag+"First Aired"+tag+":"+tagVal->m_strFirstAired;
1263         if (tagVal->m_iYear != 0)
1264           output.Format("%s%i",output+closeTag+openTag+"Year"+tag+":",tagVal->m_iYear);
1265         if (tagVal->m_iSeason != -1)
1266           output.Format("%s%i",output+closeTag+openTag+"Season"+tag+":",tagVal->m_iSeason);
1267         if (tagVal->m_iEpisode != -1)
1268           output.Format("%s%i",output+closeTag+openTag+"Episode"+tag+":",tagVal->m_iEpisode);
1269           }
1270           thumb=g_infoManager.GetImage(VIDEOPLAYER_COVER, -1);
1271                 
1272                 //CPicture pic;
1273         //pic.CacheSkinImage("defaultAlbumCover.png", cachedThumb);
1274
1275           copyThumb(thumb,thumbFn);
1276           output+=closeTag+openTag+"Thumb"+tag+":"+thumb;
1277     }
1278     else if (g_application.IsPlayingAudio())
1279     { // Audio information
1280       tmp.Format("%i",g_playlistPlayer.GetCurrentSong());        
1281       output+=closeTag+openTag+"SongNo:"+tmp;  // current item # in playlist
1282       output+=closeTag+openTag+"Type"+tag+":Audio";
1283       const CMusicInfoTag* tagVal=g_infoManager.GetCurrentSongTag();
1284       if (tagVal && !tagVal->GetTitle().IsEmpty())
1285         output+=closeTag+openTag+"Title"+tag+":"+tagVal->GetTitle();
1286       if (tagVal && tagVal->GetTrackNumber())
1287           {
1288             CStdString tmp;
1289                 tmp.Format("%i",(int)tagVal->GetTrackNumber());
1290         output+=closeTag+openTag+"Track"+tag+":"+tmp;
1291           }
1292       if (tagVal && !tagVal->GetArtist().IsEmpty())
1293         output+=closeTag+openTag+"Artist"+tag+":"+tagVal->GetArtist();
1294       if (tagVal && !tagVal->GetAlbum().IsEmpty())
1295         output+=closeTag+openTag+"Album"+tag+":"+tagVal->GetAlbum();
1296       if (tagVal && !tagVal->GetGenre().IsEmpty())
1297         output+=closeTag+openTag+"Genre"+tag+":"+tagVal->GetGenre();
1298       if (tagVal && tagVal->GetYear())
1299         output+=closeTag+openTag+"Year"+tag+":"+tagVal->GetYearString();
1300       if (tagVal && tagVal->GetURL())
1301         output+=closeTag+openTag+"URL"+tag+":"+tagVal->GetURL();
1302       if (tagVal && g_infoManager.GetMusicLabel(MUSICPLAYER_LYRICS))
1303         output+=closeTag+openTag+"Lyrics"+tag+":"+g_infoManager.GetMusicLabel(MUSICPLAYER_LYRICS);
1304
1305       // TODO: Should this be a tagitem member?? (wouldn't have vbr updates though)
1306       CStdString bitRate(g_infoManager.GetMusicLabel(MUSICPLAYER_BITRATE)); 
1307       // TODO: This should be a static tag item
1308       CStdString sampleRate(g_infoManager.GetMusicLabel(MUSICPLAYER_SAMPLERATE));
1309       if (!bitRate.IsEmpty())
1310         output+=closeTag+openTag+"Bitrate"+tag+":"+bitRate;  
1311       if (!sampleRate.IsEmpty())
1312         output+=closeTag+openTag+"Samplerate"+tag+":"+sampleRate;  
1313           thumb=g_infoManager.GetImage(MUSICPLAYER_COVER, -1);
1314       copyThumb(thumb,thumbFn);
1315           output+=closeTag+openTag+"Thumb"+tag+":"+thumb;
1316     }
1317         if (g_application.IsPlaying())
1318           if (!g_application.m_pPlayer->IsPaused()) 
1319                 output+=closeTag+openTag+"PlayStatus:Playing";
1320       else
1321         output+=closeTag+openTag+"PlayStatus:Paused";
1322         else
1323                 output+=closeTag+openTag+"PlayStatus:Stopped";
1324     output+=closeTag+openTag+"Time:"+g_infoManager.GetCurrentPlayTime();
1325     output+=closeTag+openTag+"Duration:";
1326     if (g_application.IsPlayingVideo())
1327       output += g_infoManager.GetDuration();
1328     else
1329       output += g_infoManager.GetDuration();
1330     tmp.Format("%i",(int)g_application.GetPercentage());
1331     output+=closeTag+openTag+"Percentage:"+tmp;
1332     // file size
1333     if (!fileItem.m_dwSize)
1334       fileItem.m_dwSize = fileSize(fileItem.m_strPath);
1335     if (fileItem.m_dwSize)
1336     {
1337       tmp.Format("%I64d",fileItem.m_dwSize);
1338       output+=closeTag+openTag+"File size:"+tmp;
1339     }
1340   }
1341   return SetResponse(output);
1342 }
1343
1344 int CXbmcHttp::xbmcGetMusicLabel(int numParas, CStdString paras[])
1345 {
1346   if (numParas<1)
1347     return SetResponse(openTag+"Error:Missing Parameter");
1348   else
1349   {
1350         int item=(int)atoi(paras[0].c_str());
1351     return SetResponse(openTag+g_infoManager.GetMusicLabel(item));
1352   }
1353 }
1354
1355 int CXbmcHttp::xbmcGetVideoLabel(int numParas, CStdString paras[])
1356 {
1357   if (numParas<1)
1358     return SetResponse(openTag+"Error:Missing Parameter");
1359   else
1360   {
1361         int item=(int)atoi(paras[0].c_str());
1362     return SetResponse(openTag+g_infoManager.GetVideoLabel(item));
1363   }
1364 }
1365
1366 int CXbmcHttp::xbmcGetPercentage()
1367 {
1368   if (g_application.m_pPlayer)
1369   {
1370     CStdString tmp;
1371     tmp.Format("%i",(int)g_application.GetPercentage());
1372     return SetResponse(openTag + tmp ) ;
1373   }
1374   else
1375     return SetResponse(openTag+"Error");
1376 }
1377
1378 int CXbmcHttp::xbmcSeekPercentage(int numParas, CStdString paras[], bool relative)
1379 {
1380   if (numParas<1)
1381     return SetResponse(openTag+"Error:Missing Parameter");
1382   else
1383   {
1384     if (g_application.m_pPlayer)
1385     {
1386       float percent=(float)atof(paras[0].c_str());
1387       if (relative)
1388       {
1389         double newPos = g_application.GetTime() + percent * 0.01 * g_application.GetTotalTime();
1390         if ((newPos>=0) && (newPos/1000<=g_infoManager.GetTotalPlayTime()))
1391         {
1392           g_application.SeekTime(newPos);
1393           return SetResponse(openTag+"OK");
1394         }
1395         else
1396           return SetResponse(openTag+"Error:Out of range");
1397       }
1398       else
1399       {
1400         g_application.SeekPercentage(percent);
1401         return SetResponse(openTag+"OK");
1402       }
1403     }
1404     else
1405       return SetResponse(openTag+"Error:Loading mPlayer");
1406   }
1407 }
1408
1409 int CXbmcHttp::xbmcMute()
1410 {
1411         g_application.Mute();
1412     return SetResponse(openTag+"OK");
1413 }
1414
1415 int CXbmcHttp::xbmcSetVolume(int numParas, CStdString paras[])
1416 {
1417   if (numParas<1)
1418     return SetResponse(openTag+"Error:Missing Parameter");
1419   else
1420   {
1421     int iPercent = atoi(paras[0].c_str());
1422     g_application.SetVolume(iPercent);
1423     return SetResponse(openTag+"OK");
1424   }
1425 }
1426
1427 int CXbmcHttp::xbmcGetVolume()
1428 {
1429   CStdString tmp;
1430   tmp.Format("%i",g_application.GetVolume());
1431   return SetResponse(openTag + tmp);
1432 }
1433
1434 int CXbmcHttp::xbmcClearSlideshow()
1435 {
1436   CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1437   if (!pSlideShow)
1438     return SetResponse(openTag+"Error:Could not create slideshow");
1439   else
1440   {
1441     pSlideShow->Reset();
1442     return SetResponse(openTag+"OK");
1443   }
1444 }
1445
1446 int CXbmcHttp::xbmcPlaySlideshow(int numParas, CStdString paras[] )
1447 { // (filename(;1)) -> 1 indicates recursive
1448     int recursive;
1449     if (numParas>1)
1450       recursive=atoi(paras[1].c_str());
1451     else
1452       recursive=0;
1453     CGUIMessage msg( GUI_MSG_START_SLIDESHOW, 0, 0, recursive, 0, 0);
1454     if (numParas==0)
1455       msg.SetStringParam("");
1456     else
1457       msg.SetStringParam(paras[0]);
1458     CGUIWindow *pWindow = m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1459     if (pWindow) pWindow->OnMessage(msg);
1460     return SetResponse(openTag+"OK");
1461 }
1462
1463 int CXbmcHttp::xbmcSlideshowSelect(int numParas, CStdString paras[])
1464 {
1465   if (numParas<1)
1466     return SetResponse(openTag+"Error:Missing filename");
1467   else
1468   {
1469     CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1470     if (!pSlideShow)
1471       return SetResponse(openTag+"Error:Could not create slideshow");
1472     else
1473     {
1474       pSlideShow->Select(paras[0]);
1475       return SetResponse(openTag+"OK");
1476     }
1477   }
1478 }
1479
1480 int CXbmcHttp::xbmcAddToSlideshow(int numParas, CStdString paras[])
1481 //filename (;mask)
1482 {
1483   CStdString mask="";
1484   bool recursive=true;
1485   if (numParas<1)
1486     return SetResponse(openTag+"Error:Missing parameter");
1487   else
1488   {
1489     if (numParas>1)
1490       mask=procMask(paras[1]);
1491         if (numParas>2)
1492           recursive=paras[2]=="1";
1493     CFileItem *pItem = new CFileItem(paras[0]);
1494     pItem->m_strPath=paras[0].c_str();
1495     IDirectory *pDirectory = CFactoryDirectory::Create(pItem->m_strPath);
1496     if (mask!="")
1497       pDirectory->SetMask(mask);
1498     bool bResult=pDirectory->Exists(pItem->m_strPath);
1499     pItem->m_bIsFolder=bResult;
1500     pItem->m_bIsShareOrDrive=false;
1501     AddItemToPlayList(pItem, -1, 0, mask, recursive); //add to slideshow
1502     delete pItem;
1503     return SetResponse(openTag+"OK");
1504   }
1505 }
1506
1507 int CXbmcHttp::xbmcSetPlaySpeed(int numParas, CStdString paras[])
1508 {
1509   if (numParas>0) {
1510     g_application.SetPlaySpeed(atoi(paras[0]));
1511     return SetResponse(openTag+"OK");
1512   }
1513   else
1514     return SetResponse(openTag+"Error:Missing parameter");
1515 }
1516
1517 int CXbmcHttp::xbmcGetPlaySpeed()
1518 {
1519   CStdString strSpeed;
1520   strSpeed.Format("%i", g_application.GetPlaySpeed());
1521   return SetResponse(openTag + strSpeed );
1522 }
1523
1524 int CXbmcHttp::xbmcGetGUIDescription()
1525 {
1526   CStdString strWidth, strHeight;
1527   strWidth.Format("%i", g_graphicsContext.GetWidth());
1528   strHeight.Format("%i", g_graphicsContext.GetHeight());
1529   return SetResponse(openTag+"Width:" + strWidth + closeTag+openTag+"Height:" + strHeight  );
1530 }
1531
1532 int CXbmcHttp::xbmcGetGUIStatus()
1533 {
1534   CStdString output, tmp, strTmp;
1535   CGUIMediaWindow *mediaWindow = (CGUIMediaWindow *)m_gWindowManager.GetWindow(WINDOW_MUSIC_FILES);
1536   if (mediaWindow)
1537     output = closeTag+openTag+"MusicPath:" + mediaWindow->CurrentDirectory().m_strPath;
1538   mediaWindow = (CGUIMediaWindow *)m_gWindowManager.GetWindow(WINDOW_VIDEO_FILES);
1539   if (mediaWindow)
1540     output += closeTag+openTag+"VideoPath:" + mediaWindow->CurrentDirectory().m_strPath;
1541   mediaWindow = (CGUIMediaWindow *)m_gWindowManager.GetWindow(WINDOW_PICTURES);
1542   if (mediaWindow)
1543     output += closeTag+openTag+"PicturePath:" + mediaWindow->CurrentDirectory().m_strPath;
1544   mediaWindow = (CGUIMediaWindow *)m_gWindowManager.GetWindow(WINDOW_PROGRAMS);
1545   if (mediaWindow)
1546     output += closeTag+openTag+"ProgramsPath:" + mediaWindow->CurrentDirectory().m_strPath;
1547   CGUIWindowFileManager *fileManager = (CGUIWindowFileManager *)m_gWindowManager.GetWindow(WINDOW_FILES);
1548   if (fileManager)
1549   {
1550     output += closeTag+openTag+"FilesPath1:" + fileManager->CurrentDirectory(0).m_strPath;
1551     output += closeTag+openTag+"FilesPath2:" + fileManager->CurrentDirectory(1).m_strPath;
1552   }
1553   int iWin=m_gWindowManager.GetActiveWindow();
1554   CGUIWindow* pWindow=m_gWindowManager.GetWindow(iWin);  
1555   tmp.Format("%i", iWin);
1556   output += openTag+"ActiveWindow:" + tmp;
1557   if (pWindow)
1558   {
1559     output += closeTag+openTag+"ActiveWindowName:" + g_localizeStrings.Get(iWin) ; 
1560     CGUIControl* pControl=pWindow->GetFocusedControl();
1561     if (pControl)
1562     {
1563       CStdString id;
1564       id.Format("%d",(int)pControl->GetID());
1565       output += closeTag+openTag+"ControlId:" + id;
1566       strTmp = pControl->GetDescription();
1567       if (pControl->GetControlType() == CGUIControl::GUICONTROL_BUTTON)
1568       {
1569         output += closeTag+openTag+"Type:Button";
1570         if (strTmp!="")
1571           output += closeTag+openTag+"Description:" + strTmp;
1572         CStdStringArray actions = ((CGUIButtonControl *)pControl)->GetClickActions();
1573         if (actions.size())
1574           output += closeTag+openTag+"Execution:" + actions[0];
1575       }
1576       else if (pControl->GetControlType() == CGUIControl::GUICONTROL_BUTTONBAR)
1577       {
1578         output += closeTag+openTag+"Type:ButtonBar"+closeTag+openTag+"Description:" + strTmp;
1579         CStdString button;
1580         button.Format("%d",((CGUIButtonScroller *)pControl)->GetActiveButton());
1581         output += closeTag+openTag+"ActiveButton:" + button;
1582       }
1583       else if (pControl->GetControlType() == CGUIControl::GUICONTROL_SPIN)
1584       {
1585         output += closeTag+openTag+"Type:Spin"+closeTag+openTag+"Description:" + strTmp;
1586       }
1587       else if (pControl->GetControlType() == CGUIControl::GUICONTROL_THUMBNAIL)
1588       {
1589         output += closeTag+openTag+"Type:ThumbNail"+closeTag+openTag+"Description:" + strTmp;
1590       }
1591       else if (pControl->GetControlType() == CGUIControl::GUICONTROL_LIST)
1592       {
1593         output += closeTag+openTag+"Type:List"+closeTag+openTag+"Description:" + strTmp;
1594       }
1595     }
1596   }
1597   return SetResponse(output);
1598 }
1599
1600 int CXbmcHttp::xbmcGetThumb(int numParas, CStdString paras[], bool bGetThumb)
1601 {
1602   CStdString thumb="";
1603   int linesize=80;
1604   if (numParas<1)
1605     return SetResponse(openTag+"Error:Missing parameter");
1606   bool bImgTag=false;
1607   // only allow the old GetThumb command to accept "imgtag"
1608   if (bGetThumb && numParas==2 && paras[1].Equals("imgtag"))
1609   {
1610     bImgTag=true;
1611     thumb="<img src=\"data:image/jpg;base64,";
1612     linesize=0;
1613   }
1614   if (CUtil::IsRemote(paras[0]))
1615   {
1616     CStdString strDest="Z:\\xbmcDownloadFile.tmp";
1617     CFile::Cache(paras[0], strDest.c_str(),NULL,NULL) ;
1618     if (CFile::Exists(strDest))
1619     {
1620       thumb+=encodeFileToBase64(strDest,linesize);
1621       ::DeleteFile(strDest.c_str());
1622     }
1623     else
1624     {
1625       return SetResponse(openTag+"Error");
1626     }
1627   }
1628   else
1629     thumb+=encodeFileToBase64(paras[0],linesize);
1630
1631   if (bImgTag)
1632   {
1633     thumb+="\" alt=\"Your browser doesnt support this\" title=\"";
1634     thumb+=paras[0];
1635     thumb+="\">";
1636   }
1637   return SetResponse(thumb) ;
1638 }
1639
1640 int CXbmcHttp::xbmcGetThumbFilename(int numParas, CStdString paras[])
1641 {
1642   CStdString thumbFilename="";
1643
1644   if (numParas>1)
1645   {
1646     thumbFilename = CUtil::GetCachedAlbumThumb(paras[0], paras[1]);
1647     return SetResponse(openTag+thumbFilename ) ;
1648   }
1649   else
1650     return SetResponse(openTag+"Error:Missing parameter (album;artist)") ;
1651 }
1652
1653 int CXbmcHttp::xbmcPlayerPlayFile(int numParas, CStdString paras[])
1654 {
1655   int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
1656   // file
1657   if (numParas<1)
1658     return SetResponse(openTag+"Error:Missing file parameter");
1659   // get playlist
1660   if (numParas>1)
1661     iPlaylist = atoi(paras[1]);
1662   // test file parameter
1663   CFileItem item(paras[0], FALSE);
1664   if (item.IsPlayList())
1665   {
1666     // if no playlist, set the playlist to PLAYLIST_MUSIC_TEMP like playmedia
1667     if (iPlaylist == PLAYLIST_NONE)
1668       iPlaylist = PLAYLIST_MUSIC;
1669     LoadPlayList(paras[0], iPlaylist, true, true);
1670     CStdString strPlaylist;
1671     strPlaylist.Format("%i", iPlaylist);
1672     return SetResponse(openTag+"OK:Playlist="+strPlaylist);
1673   }
1674   else
1675   {
1676     g_applicationMessenger.MediaPlay(paras[0]);
1677     if(g_application.IsPlaying())
1678       return SetResponse(openTag+"OK");
1679   }
1680   return SetResponse(openTag+"Error:Could not play file");
1681 }
1682
1683 int CXbmcHttp::xbmcGetCurrentPlayList()
1684 {
1685   CStdString tmp;
1686   tmp.Format("%i", g_playlistPlayer.GetCurrentPlaylist());
1687   return SetResponse(openTag + tmp  );
1688 }
1689
1690 int CXbmcHttp::xbmcSetCurrentPlayList(int numParas, CStdString paras[])
1691 {
1692   if (numParas<1) 
1693     return SetResponse(openTag+"Error:Missing playlist") ;
1694   else {
1695     g_playlistPlayer.SetCurrentPlaylist(atoi(paras[0].c_str()));
1696     return SetResponse(openTag+"OK") ;
1697   }
1698 }
1699
1700 int CXbmcHttp::xbmcGetPlayListContents(int numParas, CStdString paras[])
1701 {
1702   CStdString list="";
1703   int playList;
1704
1705   if (numParas<1) 
1706     playList=g_playlistPlayer.GetCurrentPlaylist();
1707   else
1708     playList=atoi(paras[0]);
1709   CPlayList& thePlayList = g_playlistPlayer.GetPlaylist(playList);
1710   if (thePlayList.size()==0)
1711     list=openTag+"[Empty]" ;
1712   else
1713     if (g_application.IsPlayingAudio())
1714         {
1715           for (int i=0; i< thePlayList.size(); i++) {
1716         const CPlayList::CPlayListItem& item=thePlayList[i];
1717                 const CMusicInfoTag* tagVal=item.GetMusicTag();
1718             if (tagVal && tagVal->GetURL()!="")
1719           list += closeTag+openTag + tagVal->GetURL();
1720                 else
1721           list += closeTag+openTag + item.GetFileName();
1722       }
1723         }
1724         else
1725           for (int i=0; i< thePlayList.size(); i++) {
1726         const CPlayList::CPlayListItem& item=thePlayList[i];
1727         list += closeTag+openTag + item.GetFileName();
1728       }
1729   return SetResponse(list) ;
1730 }
1731
1732 int CXbmcHttp::xbmcGetPlayListLength(int numParas, CStdString paras[])
1733 {
1734   int playList;
1735
1736   if (numParas<1) 
1737     playList=g_playlistPlayer.GetCurrentPlaylist();
1738   else
1739     playList=atoi(paras[0]);
1740   CPlayList& thePlayList = g_playlistPlayer.GetPlaylist(playList);
1741
1742   CStdString tmp;
1743   tmp.Format("%i", thePlayList.size());
1744   return SetResponse(openTag + tmp );
1745 }
1746
1747 int CXbmcHttp::xbmcGetSlideshowContents()
1748 {
1749   CStdString list="";
1750   CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1751   if (!pSlideShow)
1752     return SetResponse(openTag+"Error");
1753   else
1754   {
1755     const CFileItemList &slideshowContents = pSlideShow->GetSlideShowContents();
1756     if (slideshowContents.Size()==0)
1757       list=openTag+"[Empty]" ;
1758     else
1759     for (int i = 0; i < slideshowContents.Size(); ++i)
1760       list += closeTag+openTag + slideshowContents[i]->m_strPath;
1761     return SetResponse(list) ;
1762   }
1763 }
1764
1765 int CXbmcHttp::xbmcGetPlayListSong(int numParas, CStdString paras[])
1766 {
1767   CStdString Filename;
1768   int iSong;
1769
1770   if (numParas<1) 
1771   {
1772     CStdString tmp;
1773     tmp.Format("%i", g_playlistPlayer.GetCurrentSong());
1774     return SetResponse(openTag + tmp );
1775   }
1776   else {
1777     CPlayList thePlayList;
1778     iSong=atoi(paras[0]);  
1779     if (iSong!=-1){
1780       thePlayList=g_playlistPlayer.GetPlaylist( g_playlistPlayer.GetCurrentPlaylist() );
1781       if (thePlayList.size()>iSong) {
1782         Filename=thePlayList[iSong].GetFileName();
1783         return SetResponse(openTag + Filename );
1784       }
1785     }
1786   }
1787   return SetResponse(openTag+"Error");
1788 }
1789
1790 int CXbmcHttp::xbmcSetPlayListSong(int numParas, CStdString paras[])
1791 {
1792   if (numParas<1)
1793     return SetResponse(openTag+"Error:Missing song number");
1794   else
1795   {
1796     g_playlistPlayer.Play(atoi(paras[0].c_str()));
1797     return SetResponse(openTag+"OK");
1798   }
1799 }
1800
1801 int CXbmcHttp::xbmcPlayListNext()
1802 {
1803   g_playlistPlayer.PlayNext();
1804   return SetResponse(openTag+"OK");
1805 }
1806
1807 int CXbmcHttp::xbmcPlayListPrev()
1808 {
1809   g_playlistPlayer.PlayPrevious();
1810   return SetResponse(openTag+"OK");
1811 }
1812
1813 int CXbmcHttp::xbmcRemoveFromPlayList(int numParas, CStdString paras[])
1814 {
1815   if (numParas>0)
1816   {
1817     if (numParas==1)
1818       g_playlistPlayer.GetPlaylist(g_playlistPlayer.GetCurrentPlaylist()).Remove(paras[0]) ;
1819     else
1820       g_playlistPlayer.GetPlaylist(atoi(paras[1])).Remove(paras[0]) ;
1821     return SetResponse(openTag+"OK");
1822   }
1823   else
1824     return SetResponse(openTag+"Error:Missing parameter");
1825 }
1826
1827 CStdString CXbmcHttp::GetOpenTag()
1828 {
1829   return openTag;
1830 }
1831
1832 CStdString CXbmcHttp::GetCloseTag()
1833 {
1834   return closeTag;
1835 }
1836
1837 CKey CXbmcHttp::GetKey()
1838 {
1839   if (repeatKeyRate!=0)
1840     if (GetTickCount() >= MarkTime + repeatKeyRate)
1841         {
1842           MarkTime=GetTickCount();
1843           key=lastKey;
1844         }
1845   return key;
1846 }
1847
1848 void CXbmcHttp::ResetKey()
1849 {
1850   CKey newKey;
1851   key = newKey;
1852 }
1853
1854 int CXbmcHttp::xbmcSetKey(int numParas, CStdString paras[])
1855 {
1856   DWORD dwButtonCode=0;
1857   BYTE bLeftTrigger=0, bRightTrigger=0;
1858   float fLeftThumbX=0.0f, fLeftThumbY=0.0f, fRightThumbX=0.0f, fRightThumbY=0.0f ;
1859   if (numParas<1)
1860     return SetResponse(openTag+"Error:Missing parameters");
1861     
1862   else
1863   {
1864     dwButtonCode=(DWORD) atoi(paras[0]);
1865     if (numParas>1) {
1866       bLeftTrigger=(BYTE) atoi(paras[1]) ;
1867       if (numParas>2) {
1868         bRightTrigger=(BYTE) atoi(paras[2]) ;
1869         if (numParas>3) {
1870           fLeftThumbX=(float) atof(paras[3]) ;
1871           if (numParas>4) {
1872             fLeftThumbY=(float) atof(paras[4]) ;
1873             if (numParas>5) {
1874               fRightThumbX=(float) atof(paras[5]) ;
1875               if (numParas>6)
1876                 fRightThumbY=(float) atof(paras[6]) ;
1877             }
1878           }
1879         }
1880       }
1881     }
1882     CKey tempKey(dwButtonCode, bLeftTrigger, bRightTrigger, fLeftThumbX, fLeftThumbY, fRightThumbX, fRightThumbY) ;
1883         tempKey.SetFromHttpApi(true);
1884     key = tempKey;
1885         lastKey = key;
1886     return SetResponse(openTag+"OK");
1887   }
1888 }
1889
1890 int CXbmcHttp::xbmcSetKeyRepeat(int numParas, CStdString paras[])
1891 {
1892   if (numParas!=1)
1893     return SetResponse(openTag+"Error:Should be only one parameter");
1894   else
1895   {
1896     repeatKeyRate = atoi(paras[0]);
1897         return SetResponse(openTag+"OK");
1898   }
1899 }
1900
1901 int CXbmcHttp::xbmcAction(int numParas, CStdString paras[], int theAction)
1902 {
1903   bool showingSlideshow=(m_gWindowManager.GetActiveWindow() == WINDOW_SLIDESHOW);
1904
1905   switch(theAction)
1906   {
1907   case 1:
1908     if (showingSlideshow) {
1909       CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1910       if (pSlideShow) {
1911         CAction action;
1912         action.wID = ACTION_PAUSE;
1913         pSlideShow->OnAction(action);    
1914       }
1915     }
1916     else
1917       g_applicationMessenger.MediaPause();
1918     return SetResponse(openTag+"OK");
1919     break;
1920   case 2:
1921     if (showingSlideshow) {
1922       CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1923       if (pSlideShow) {
1924         CAction action;
1925         action.wID = ACTION_STOP;
1926         pSlideShow->OnAction(action);    
1927       }
1928     }
1929     else
1930       //g_application.StopPlaying();
1931       g_applicationMessenger.MediaStop();
1932     return SetResponse(openTag+"OK");
1933     break;
1934   case 3:
1935     if (showingSlideshow) {
1936       CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1937       if (pSlideShow) {
1938         CAction action;
1939         action.wID = ACTION_NEXT_PICTURE;
1940         pSlideShow->OnAction(action);
1941       }
1942     }
1943     else
1944       g_playlistPlayer.PlayNext();
1945     return SetResponse(openTag+"OK");
1946     break;
1947   case 4:
1948     if (showingSlideshow) {
1949       CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1950       if (pSlideShow) {
1951         CAction action;
1952         action.wID = ACTION_PREV_PICTURE;
1953         pSlideShow->OnAction(action);    
1954       }
1955     }
1956     else
1957       g_playlistPlayer.PlayPrevious();
1958     return SetResponse(openTag+"OK");
1959     break;
1960   case 5:
1961     if (showingSlideshow)
1962     {
1963       CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1964       if (pSlideShow) {
1965         CAction action;
1966         action.wID = ACTION_ROTATE_PICTURE;
1967         pSlideShow->OnAction(action);  
1968         return SetResponse(openTag+"OK");
1969       }
1970       else
1971         return SetResponse(openTag+"Error");
1972     }
1973     else
1974       return SetResponse(openTag+"Error");
1975     break;
1976   case 6:
1977     if (showingSlideshow)
1978     {
1979       CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
1980       if (pSlideShow) {
1981         if (numParas>1) {
1982           CAction action;
1983           action.wID = ACTION_ANALOG_MOVE;
1984           action.fAmount1=(float) atof(paras[0]);
1985           action.fAmount2=(float) atof(paras[1]);
1986           pSlideShow->OnAction(action);    
1987           return SetResponse(openTag+"OK");
1988         }
1989         else
1990           return SetResponse(openTag+"Error:Missing parameters");
1991       }
1992       else
1993         return SetResponse(openTag+"Error");
1994     }
1995     else
1996       return SetResponse(openTag+"Error");
1997     break;
1998   case 7:
1999     if (showingSlideshow)
2000     {
2001       CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
2002       if (pSlideShow) {
2003         if (numParas>0)
2004         {
2005           CAction action;
2006           action.wID = ACTION_ZOOM_LEVEL_NORMAL+atoi(paras[0]);
2007           pSlideShow->OnAction(action);    
2008           return SetResponse(openTag+"OK");
2009         }
2010         else
2011           return SetResponse(openTag+"Error:Missing parameters");
2012       }
2013       else
2014         return SetResponse(openTag+"Error");
2015     }
2016     else
2017       return SetResponse(openTag+"Error");
2018     break;
2019   default:
2020     return SetResponse(openTag+"Error");
2021   }
2022 }
2023
2024 int CXbmcHttp::xbmcExit(int theAction)
2025 {
2026   if (theAction>0 && theAction<6)
2027   {
2028     SetResponse(openTag+"OK");
2029         shuttingDown=true;
2030         return theAction;
2031   }
2032   else
2033     return SetResponse(openTag+"Error");
2034 }
2035
2036 int CXbmcHttp::xbmcLookupAlbum(int numParas, CStdString paras[])
2037 // paras: album
2038 //        album, artist
2039 //        album, artist, 1
2040 {
2041   CStdString albums="", album, artist="", tmp;
2042   double relevance;
2043   bool rel = false;
2044   SScraperInfo info;
2045   info.strContent = "albums";
2046   info.strPath = g_stSettings.m_defaultMusicScraper;
2047   CMusicInfoScraper scraper(info); 
2048
2049   if (numParas<1)
2050     return SetResponse(openTag+"Error:Missing album name");
2051   else
2052   {
2053     try
2054     {
2055       int cnt=0;
2056       album=paras[0];
2057       if (numParas>1)
2058       {
2059         artist = paras[1];
2060         scraper.FindAlbuminfo(album, artist);
2061         if (numParas>2)
2062           rel = (paras[2]=="1");
2063       }
2064       else
2065         scraper.FindAlbuminfo(album);
2066       //wait a max of 20s
2067       while (!scraper.Completed() && cnt++<200)
2068         Sleep(100);
2069       if (scraper.Successfull())
2070       {
2071         // did we find at least 1 album?
2072         int iAlbumCount=scraper.GetAlbumCount();
2073         if (iAlbumCount >=1)
2074         {
2075           for (int i=0; i < iAlbumCount; ++i)
2076           {
2077             CMusicAlbumInfo& info = scraper.GetAlbum(i);
2078             albums += closeTag+openTag + info.GetTitle2() + "<@@>" + info.GetAlbumURL().m_url[0].m_url;
2079             if (rel)
2080             {
2081               relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, album, info.GetAlbum().strArtist, artist);
2082               tmp.Format("%f",relevance);
2083               albums += "<@@@>"+tmp;
2084             }
2085           }
2086           return SetResponse(albums) ;
2087         }
2088         else
2089           return SetResponse(openTag+"Error:No albums found") ;
2090       }
2091       else
2092         return SetResponse(openTag+"Error:Scraping") ;
2093     }
2094     catch (...)
2095     {
2096       return SetResponse(openTag+"Error");
2097     }
2098   }
2099 }
2100
2101 int CXbmcHttp::xbmcChooseAlbum(int numParas, CStdString paras[])
2102 {
2103   CStdString output="";
2104
2105   if (numParas<1)
2106     return SetResponse(openTag+"Error:Missing album name");
2107   else
2108     try
2109     {
2110       CMusicAlbumInfo musicInfo;//("", "") ;
2111       CHTTP http;
2112       SScraperInfo info; // TODO - WTF is this code supposed to do?
2113       if (musicInfo.Load(http,info))
2114       {
2115         if (musicInfo.GetAlbum().thumbURL.m_url.size() > 0)
2116          output=openTag+"image:" + musicInfo.GetAlbum().thumbURL.m_url[0].m_url;
2117
2118         output+=closeTag+openTag+"review:" + musicInfo.GetAlbum().strReview;
2119         return SetResponse(output) ;
2120       }
2121       else
2122         return SetResponse(openTag+"Error:Loading musinInfo");
2123     }
2124     catch (...)
2125     {
2126       return SetResponse(openTag+"Error:Exception");
2127     }
2128 }
2129
2130 int CXbmcHttp::xbmcDownloadInternetFile(int numParas, CStdString paras[])
2131 {
2132   CStdString src, dest="";
2133
2134   if (numParas<1)
2135     return SetResponse(openTag+"Error:Missing parameter");
2136   else
2137   {
2138     src=paras[0];
2139     if (numParas>1)
2140       dest=paras[1];
2141     if (dest=="")
2142       dest="Z:\\xbmcDownloadInternetFile.tmp" ;
2143     if (src=="")
2144       return SetResponse(openTag+"Error:Missing parameter");
2145     else
2146     {
2147       try
2148       {
2149         CHTTP http;
2150         http.Download(src, dest);
2151         CStdString encoded="";
2152         encoded=encodeFileToBase64(dest, 80);
2153         if (encoded=="")
2154           return SetResponse(openTag+"Error:Nothing downloaded");
2155         {
2156           if (dest=="Z:\\xbmcDownloadInternetFile.tmp")
2157           ::DeleteFile(dest);
2158           return SetResponse(encoded) ;
2159         }
2160       }
2161       catch (...)
2162       {
2163         return SetResponse(openTag+"Error:Exception");
2164       }
2165     }
2166   }
2167 }
2168
2169 int CXbmcHttp::xbmcSetFile(int numParas, CStdString paras[])
2170 //parameter = destFilename ; base64String ; ( first | continue | last )
2171 {
2172   if (numParas<2)
2173     return SetResponse(openTag+"Error:Missing parameter");
2174   else
2175   {
2176     paras[1].Replace(" ","+");
2177         if (numParas>2)
2178           if (paras[2].ToLower() == "first")
2179                 decodeBase64ToFile(paras[1], "Z:\\xbmcTemp.tmp");
2180           else 
2181             if (paras[2].ToLower() == "continue")
2182                   decodeBase64ToFile(paras[1], "Z:\\xbmcTemp.tmp", true);
2183                 else
2184                   if (paras[2].ToLower() == "last")
2185                   {
2186                     decodeBase64ToFile(paras[1], "Z:\\xbmcTemp.tmp", true);
2187                         CFile::Cache("Z:\\xbmcTemp.tmp", paras[0].c_str(), NULL, NULL) ;
2188             ::DeleteFile("Z:\\xbmcTemp.tmp");
2189                   }
2190                   else
2191                     return  SetResponse(openTag+"Error:Unknown 2nd parameter");
2192         else
2193         {
2194       decodeBase64ToFile(paras[1], "Z:\\xbmcTemp.tmp");
2195       CFile::Cache("Z:\\xbmcTemp.tmp", paras[0].c_str(), NULL, NULL) ;
2196       ::DeleteFile("Z:\\xbmcTemp.tmp");
2197         }
2198     return SetResponse(openTag+"OK");
2199   }
2200 }
2201
2202 int CXbmcHttp::xbmcCopyFile(int numParas, CStdString paras[])
2203 //parameter = srcFilename ; destFilename
2204 // both file names are relative to the XBox not the calling client
2205 {
2206   if (numParas<2)
2207     return SetResponse(openTag+"Error:Missing parameter");
2208   else
2209   {
2210     if (CFile::Exists(paras[0].c_str()))
2211     {
2212       CFile::Cache(paras[0].c_str(), paras[1].c_str(), NULL, NULL) ;
2213       return SetResponse(openTag+"OK");
2214     }
2215     else
2216       return SetResponse(openTag+"Error:Source file not found");
2217   }
2218 }
2219
2220
2221 int CXbmcHttp::xbmcFileSize(int numParas, CStdString paras[])
2222 {
2223   if (numParas<1)
2224     return SetResponse(openTag+"Error:Missing parameter");
2225   else
2226   {
2227     __int64 filesize=fileSize(paras[0]);
2228     if (filesize>-1)
2229     {
2230       CStdString tmp;
2231       tmp.Format("%I64d",filesize);
2232       return SetResponse(openTag+tmp);
2233     }
2234     else
2235       return SetResponse(openTag+"Error:Source file not found");
2236   }
2237 }
2238
2239 int CXbmcHttp::xbmcDeleteFile(int numParas, CStdString paras[])
2240 {
2241   if (numParas<1) 
2242     return SetResponse(openTag+"Error:Missing parameter");
2243   else
2244   {
2245     try
2246     {
2247       if (CFile::Exists(paras[0].c_str()))
2248       {
2249         ::DeleteFile(paras[0].c_str());
2250         return SetResponse(openTag+"OK");
2251       }
2252       else
2253         return SetResponse(openTag+"Error:File not found");
2254     }
2255     catch (...)
2256     {
2257       return SetResponse(openTag+"Error");
2258     }
2259   }
2260 }
2261
2262 int CXbmcHttp::xbmcFileExists(int numParas, CStdString paras[])
2263 {
2264   if (numParas<1) 
2265     return SetResponse(openTag+"Error:Missing parameter");
2266   else
2267   {
2268     try
2269     {
2270       if (CFile::Exists(paras[0].c_str()))
2271       {
2272         return SetResponse(openTag+"True");
2273       }
2274       else
2275         return SetResponse(openTag+"False");
2276     }
2277     catch (...)
2278     {
2279       return SetResponse(openTag+"Error");
2280     }
2281   }
2282 }
2283
2284 int CXbmcHttp::xbmcShowPicture(int numParas, CStdString paras[])
2285 {
2286   if (numParas<1) 
2287     return SetResponse(openTag+"Error:Missing parameter");
2288   else
2289   {
2290     if (!playableFile(paras[0]))
2291       return SetResponse(openTag+"Error:Unable to open file");
2292     g_applicationMessenger.PictureShow(paras[0]);
2293     return SetResponse(openTag+"OK");
2294   }
2295 }
2296
2297 int CXbmcHttp::xbmcGetCurrentSlide()
2298 {
2299   CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)m_gWindowManager.GetWindow(WINDOW_SLIDESHOW);
2300   if (!pSlideShow)
2301     return SetResponse(openTag+"Error:Could not access slideshown");
2302   else
2303   {
2304     const CFileItem *slide=pSlideShow->GetCurrentSlide();
2305     if (!slide)
2306             return SetResponse(openTag + "[None]");
2307     return SetResponse(openTag + slide->m_strPath);
2308   }
2309 }
2310
2311 int CXbmcHttp::xbmcExecBuiltIn(int numParas, CStdString paras[])
2312 {
2313   if (numParas<1) 
2314     return SetResponse(openTag+"Error:Missing parameter");
2315   else
2316   {
2317     g_applicationMessenger.ExecBuiltIn(paras[0]);
2318     return SetResponse(openTag+"OK");
2319   }
2320 }
2321
2322 int CXbmcHttp::xbmcGUISetting(int numParas, CStdString paras[])
2323 //parameter=type;name(;value)
2324 //type=0->int, 1->bool, 2->float, 3->string
2325 {
2326   if (numParas<2)
2327     return SetResponse(openTag+"Error:Missing parameters");
2328   else
2329   {
2330     CStdString tmp;
2331     if (numParas<3)
2332       switch (atoi(paras[0])) 
2333       {
2334         case 0:  //  int
2335           tmp.Format("%i", g_guiSettings.GetInt(paras[1]));
2336           return SetResponse(openTag + tmp );
2337           break;
2338         case 1: // bool
2339           if (g_guiSettings.GetBool(paras[1])==0)
2340             return SetResponse(openTag+"False");
2341           else
2342             return SetResponse(openTag+"True");
2343           break;
2344         case 2: // float
2345           tmp.Format("%f", g_guiSettings.GetFloat(paras[1]));
2346           return SetResponse(openTag + tmp);
2347           break;
2348         case 3: // string
2349           tmp.Format("%s", g_guiSettings.GetString(paras[1]));
2350           return SetResponse(openTag + tmp);
2351           break;
2352         default:
2353           return SetResponse(openTag+"Error:Unknown type");
2354           break;
2355       }
2356     else
2357     {
2358       switch (atoi(paras[0])) 
2359       {
2360         case 0:  //  int
2361           g_guiSettings.SetInt(paras[1], atoi(paras[2]));
2362           return SetResponse(openTag+"OK");
2363           break;
2364         case 1: // bool
2365           g_guiSettings.SetBool(paras[1], (paras[2].ToLower()=="true"));
2366           return SetResponse(openTag+"OK");
2367           break;
2368         case 2: // float
2369           g_guiSettings.SetFloat(paras[1], (float)atof(paras[2]));
2370           return SetResponse(openTag+"OK");
2371           break;
2372         case 3: // string
2373           g_guiSettings.SetString(paras[1], paras[2]);
2374           return SetResponse(openTag+"OK");
2375           break;
2376         default:
2377           return SetResponse(openTag+"Error:Unknown type");
2378           break;
2379       }     
2380     }
2381   }
2382   return 0; // not reached
2383 }
2384
2385 int CXbmcHttp::xbmcConfig(int numParas, CStdString paras[])
2386 {
2387   int argc=0, ret=-1;
2388   char_t* argv[20]; 
2389   CStdString response="";
2390   
2391   if (numParas<1) {
2392     return SetResponse(openTag+"Error:Missing paramters");
2393   }
2394   if (numParas>1){
2395     for (argc=0; argc<numParas-1;argc++)
2396       argv[argc]=(char_t*)paras[argc+1].c_str();
2397   }
2398   argv[argc]=NULL;
2399   bool createdWebConfigObj=XbmcWebConfigInit();
2400   if (paras[0]=="bookmarksize")
2401   {
2402     ret=XbmcWebsHttpAPIConfigBookmarkSize(response, argc, argv);
2403     if (ret!=-1)
2404       ret=1;
2405   }
2406   else if (paras[0]=="getbookmark")
2407   {
2408     ret=XbmcWebsHttpAPIConfigGetBookmark(response, argc, argv);
2409     if (ret!=-1)
2410       ret=1;
2411   }
2412   else if (paras[0]=="addbookmark") 
2413     ret=XbmcWebsHttpAPIConfigAddBookmark(response, argc, argv);
2414   else if (paras[0]=="savebookmark")
2415     ret=XbmcWebsHttpAPIConfigSaveBookmark(response, argc, argv);
2416   else if (paras[0]=="removebookmark")
2417     ret=XbmcWebsHttpAPIConfigRemoveBookmark(response, argc, argv);
2418   else if (paras[0]=="saveconfiguration")
2419     ret=XbmcWebsHttpAPIConfigSaveConfiguration(response, argc, argv);
2420   else if (paras[0]=="getoption")
2421   {
2422     //getoption has been deprecated so the following is just to prevent (my) legacy client code breaking (to be removed later)
2423     if (paras[1]=="pictureextensions")
2424       response="<li>"+g_stSettings.m_pictureExtensions;
2425         else if (paras[1]=="videoextensions")
2426       response="<li>"+g_stSettings.m_videoExtensions;
2427         else if (paras[1]=="musicextensions")
2428       response="<li>"+g_stSettings.m_musicExtensions;
2429         else
2430           response="<li>Error:Function is deprecated";
2431     //ret=XbmcWebsHttpAPIConfigGetOption(response, argc, argv);
2432     //if (ret!=-1)
2433     ret=1;
2434   }
2435   else if (paras[0]=="setoption")
2436     ret=XbmcWebsHttpAPIConfigSetOption(response, argc, argv);
2437   else
2438   {
2439     return SetResponse(openTag+"Error:Unknown Config Command");
2440   }
2441   if (createdWebConfigObj)
2442           XbmcWebConfigRelease();
2443   if (ret==-1)
2444     return SetResponse(openTag+"Error:WebServer needs to be running - is it?");
2445   else
2446   {
2447         response.Replace("<li>",openTag);
2448     return SetResponse(response);
2449   }
2450 }
2451
2452 int CXbmcHttp::xbmcGetSystemInfo(int numParas, CStdString paras[])
2453 {
2454   if (numParas<1)
2455     return SetResponse(openTag+"Error:Missing Parameter");
2456   else
2457   {
2458     CStdString strInfo = "";
2459     int i;
2460     for (i=0; i<numParas; i++)
2461     {
2462       CStdString strTemp = (CStdString) g_infoManager.GetLabel(atoi(paras[i]));
2463       if (strTemp.IsEmpty())
2464         strTemp = "Error:No information retrieved for " + paras[i];
2465       strInfo += openTag + strTemp;
2466     }
2467     return SetResponse(strInfo);
2468   }
2469 }
2470
2471 int CXbmcHttp::xbmcGetSystemInfoByName(int numParas, CStdString paras[])
2472 {
2473   if (numParas<1)
2474     return SetResponse(openTag+"Error:Missing Parameter");
2475   else
2476   {
2477     CStdString strInfo = "";
2478     int i;
2479     for (i=0; i<numParas; i++)
2480     {
2481       CStdString strTemp = (CStdString) g_infoManager.GetLabel(g_infoManager.TranslateString(paras[i]));
2482       if (strTemp.IsEmpty())
2483         strTemp = "Error:No information retrieved for " + paras[i];
2484       strInfo += openTag + strTemp;
2485     }
2486     if(strInfo.Find("°") && strInfo.Find("Â"))
2487     {
2488       // The Charset Converter ToUtf8() will add. only in this case= "°" a char "°" during converting, 
2489       // which is the right value for the GUI!
2490       // A length depending fix in CCharsetConverter::stringCharsetToUtf8() will couse a wrong char in GUI. 
2491       // So just for http, we remove the "Â", to fix BUG ID:[1586251]
2492       strInfo.Replace("Â","");
2493     }
2494     return SetResponse(strInfo);
2495   }
2496 }
2497
2498 int CXbmcHttp::xbmcSpinDownHardDisk(int numParas, CStdString paras[])
2499 {
2500   if (numParas==1)
2501         if (paras[0].ToLower()=="false")
2502           if (g_application.m_dwSpinDownTime!=0)
2503             return SetResponse(openTag+"OK:Not spun down");
2504           else
2505           {
2506             #ifdef HAS_XBOX_HARDWARE
2507           XKHDD::SpindownHarddisk(false);
2508         #endif
2509         g_application.m_dwSpinDownTime = timeGetTime();
2510         return SetResponse(openTag+"OK");
2511           }
2512   if (g_application.m_dwSpinDownTime==0)
2513         return SetResponse(openTag+"OK:Already spun down");
2514   if (m_gWindowManager.HasModalDialog())
2515         return SetResponse(openTag+"Error:Can't spin down now (modal dialog)");
2516   if (g_application.MustBlockHDSpinDown())
2517         return SetResponse(openTag+"Error:Can't spin down now (must block)");
2518   if (g_application.IsPlaying() && g_application.CurrentFileItem().IsHD())
2519         return SetResponse(openTag+"Error:Can't spin down now (playing media on hard disk)");
2520   #ifdef HAS_XBOX_HARDWARE
2521     XKHDD::SpindownHarddisk();
2522   #endif
2523   g_application.m_dwSpinDownTime = 0;
2524   g_application.m_bSpinDown = true;
2525   return SetResponse(openTag+"OK");
2526 }
2527
2528 bool CXbmcHttp::xbmcBroadcast(CStdString message, int level)
2529 {
2530   if  (g_stSettings.m_HttpApiBroadcastLevel>=level)
2531   {
2532     if (!pUdpBroadcast)
2533           pUdpBroadcast = new CUdpBroadcast();
2534         CStdString msg;
2535     msg.Format(openBroadcast+message+";%i"+closeBroadcast, level);
2536         return pUdpBroadcast->broadcast(msg, g_stSettings.m_HttpApiBroadcastPort);
2537   }
2538   else
2539     return true;
2540 }
2541
2542 int CXbmcHttp::xbmcBroadcast(int numParas, CStdString paras[])
2543 {
2544   if (numParas>0)
2545   {
2546     if (!pUdpBroadcast)
2547                 pUdpBroadcast = new CUdpBroadcast();
2548         bool succ;
2549         if (numParas>1)
2550        succ=pUdpBroadcast->broadcast(paras[0], atoi(paras[1]));
2551         else
2552        succ=pUdpBroadcast->broadcast(paras[0], g_stSettings.m_HttpApiBroadcastPort);
2553         if (succ)
2554           return SetResponse(openTag+"OK");
2555         else
2556           return SetResponse(openTag+"Error: calling broadcast");
2557   }
2558   else
2559         return SetResponse(openTag+"Error:Wrong number of parameters");
2560 }
2561
2562 int CXbmcHttp::xbmcSetBroadcast(int numParas, CStdString paras[])
2563 {
2564   if (numParas>0)
2565   {
2566     g_stSettings.m_HttpApiBroadcastLevel=atoi(paras[0]);
2567         if (numParas>1)
2568            g_stSettings.m_HttpApiBroadcastPort=atoi(paras[1]);
2569         return SetResponse(openTag+"OK");
2570   }
2571   else
2572     return SetResponse(openTag+"Error:Wrong number of parameters");
2573 }
2574
2575 int CXbmcHttp::xbmcGetBroadcast()
2576 {
2577   CStdString tmp;
2578   tmp.Format("%i;%i", g_stSettings.m_HttpApiBroadcastLevel,g_stSettings.m_HttpApiBroadcastPort);
2579   return SetResponse(openTag+tmp);
2580 }
2581
2582 int CXbmcHttp::xbmcGetSkinSetting(int numParas, CStdString paras[])
2583 //parameter=type;name
2584 //type: 0=bool, 1=string
2585 {
2586   if (numParas<2)
2587     return SetResponse(openTag+"Error:Missing parameters");
2588   else
2589   {
2590     if (atoi(paras[0]) == 0)
2591     {
2592       int string = g_settings.TranslateSkinBool(paras[1]);
2593       bool value = g_settings.GetSkinBool(string);
2594       if (value==false)
2595         return SetResponse(openTag+"False");
2596       else
2597         return SetResponse(openTag+"True");
2598     }
2599     else
2600     {
2601       int string = g_settings.TranslateSkinString(paras[1]);
2602       CStdString value = g_settings.GetSkinString(string);
2603       return SetResponse(openTag+value);
2604     }
2605   }
2606 }
2607
2608 int CXbmcHttp::xbmcTakeScreenshot(int numParas, CStdString paras[])
2609 //no paras
2610 //filename, flash, rotation, width, height, quality
2611 //filename, flash, rotation, width, height, quality, download
2612 //filename, flash, rotation, width, height, quality, download, imgtag
2613 //filename can be blank
2614 {
2615   if (numParas<1)
2616     CUtil::TakeScreenshot();
2617   else
2618   {
2619     CStdString filepath, path, filename;
2620     if (paras[0]=="")
2621       filepath="Z:\\screenshot.jpg";
2622     else
2623       filepath=paras[0];
2624     // check we have a valid path
2625     filename = CUtil::GetFileName(filepath);
2626     if (!CUtil::GetParentPath(filepath, path) || !CDirectory::Exists(path))
2627     {
2628       CLog::Log(LOGERROR, "Invalid path in xbmcTakeScreenShot - saving to Z:");
2629       CUtil::AddFileToFolder("Z:", filename, filepath);
2630     }
2631     if (numParas>5)
2632     {
2633       CUtil::TakeScreenshot("Z:\\temp.bmp", paras[1].ToLower()=="true");
2634       int height, width;
2635       if (paras[4]=="")
2636         if (paras[3]=="")
2637         {
2638           return SetResponse(openTag+"Error:Both height and width parameters cannot be absent");
2639         }
2640         else
2641         {
2642           width=atoi(paras[3]);
2643           height=-1;
2644         }
2645       else
2646         if (paras[3]=="")
2647         {
2648           height=atoi(paras[4]);
2649           width=-1;
2650         }
2651         else
2652         {
2653           width=atoi(paras[3]);
2654           height=atoi(paras[4]);
2655         }
2656       CPicture pic;
2657       int ret;
2658       ret=pic.ConvertFile("Z:\\temp.bmp", filepath, (float) atof(paras[2]), width, height, atoi(paras[5]));
2659       if (ret==0)
2660       {
2661         ::DeleteFile("Z:\\temp.bmp");
2662         if (numParas>6)
2663           if (paras[6].ToLower()=="true")
2664           {
2665             CStdString b64="";
2666             int linesize=80;
2667             bool bImgTag=false;
2668             // only allow the old GetThumb command to accept "imgtag"
2669             if (numParas==8 && paras[7].Equals("imgtag"))
2670             {
2671               bImgTag=true;
2672               b64="<img src=\"data:image/jpg;base64,";
2673               linesize=0;
2674             }
2675             b64+=encodeFileToBase64(filepath,linesize);
2676             if (filepath=="Z:\\screenshot.jpg")
2677               ::DeleteFile(filepath.c_str());
2678             if (bImgTag)
2679             {
2680               b64+="\" alt=\"Your browser doesnt support this\" title=\"";
2681               b64+=paras[0];
2682               b64+="\">";
2683             }
2684             return SetResponse(b64) ;
2685           }
2686       }
2687       else
2688       {
2689         CStdString strInt;
2690         strInt.Format("%", ret);
2691         return SetResponse(openTag+"Error:Could not convert image, error: " + strInt );
2692       }
2693     }
2694     else
2695       return SetResponse(openTag+"Error:Missing parameters");
2696   }
2697   return SetResponse(openTag+"OK");
2698 }
2699
2700 int CXbmcHttp::xbmcAutoGetPictureThumbs(int numParas, CStdString paras[])
2701 {
2702   if (numParas<1)
2703     return SetResponse(openTag+"Error:Missing parameter");
2704   else
2705   {
2706     autoGetPictureThumbs = (paras[0].ToLower()=="true");
2707     return SetResponse(openTag+"OK");
2708   }
2709 }
2710
2711 int CXbmcHttp::xbmcOnAction(int numParas, CStdString paras[])
2712 {
2713   if (numParas!=1)
2714           return SetResponse(openTag+"Error:There must be one and only one parameter");
2715   else
2716   {
2717         CAction action;
2718     action.wID = atoi(paras[0]);
2719     g_application.OnAction(action);
2720     return SetResponse(openTag+"OK");
2721   }
2722 }
2723
2724 int CXbmcHttp::xbmcRecordStatus(int numParas, CStdString paras[])
2725 {
2726   if (numParas!=0)
2727     return SetResponse(openTag+"Error:Too many parameters");
2728   else
2729       if( g_application.IsPlaying() && g_application.m_pPlayer && g_application.m_pPlayer->CanRecord())
2730                 return SetResponse(g_application.m_pPlayer->IsRecording()?openTag+"Recording":openTag+"Not recording");
2731           else
2732         return SetResponse(openTag+"Can't record");
2733 }
2734
2735 int CXbmcHttp::xbmcGetLogLevel()
2736 {
2737   CStdString level;
2738   level.Format("%i", g_advancedSettings.m_logLevel);
2739   return SetResponse(openTag+level);
2740 }
2741
2742 int CXbmcHttp::xbmcSetLogLevel(int numParas, CStdString paras[])
2743 {
2744   if (numParas!=1)
2745     return SetResponse(openTag+"Error:Must have one parameter");
2746   else
2747   {
2748     g_advancedSettings.m_logLevel=atoi(paras[0]);
2749         return SetResponse(openTag+"OK");
2750   }
2751 }
2752
2753 int CXbmcHttp::xbmcWebServerStatus(int numParas, CStdString paras[])
2754 {
2755   if (numParas==0)
2756         if (g_application.m_pWebServer)
2757       return SetResponse(openTag+"On");
2758         else
2759       return SetResponse(openTag+"Off");
2760   else
2761         if (paras[0].ToLower().Equals("on"))
2762           if (g_application.m_pWebServer)
2763             return SetResponse(openTag+"Already on");
2764           else
2765           {
2766             g_application.StartWebServer();
2767             return SetResponse(openTag+"OK");
2768           }
2769         else
2770           if (paras[0].ToLower().Equals("off"))
2771             if (!g_application.m_pWebServer)
2772               return SetResponse(openTag+"Already off");
2773             else
2774             {
2775               g_application.StopWebServer();
2776               return SetResponse(openTag+"OK");
2777             }
2778           else
2779         return SetResponse(openTag+"Error:Unknown parameter");
2780 }
2781
2782 int CXbmcHttp::xbmcSetResponseFormat(int numParas, CStdString paras[])
2783 {
2784   if (numParas==0)
2785   {
2786     resetTags();
2787     return SetResponse(openTag+"OK");
2788   }
2789   else if ((numParas % 2)==1)
2790     return SetResponse(openTag+"Error:Missing parameter");
2791   else
2792   {
2793         CStdString para;
2794         for (int i=0; i<numParas; i+=2)
2795         {
2796       para=paras[i].ToLower();
2797       if (para=="webheader")
2798         incWebHeader=(paras[i+1].ToLower()=="true");
2799       else if (para=="webfooter")
2800         incWebFooter=(paras[i+1].ToLower()=="true");
2801       else if (para=="header")
2802         userHeader=paras[i+1];
2803       else if (para=="footer")
2804         userFooter=paras[i+1];
2805       else if (para=="opentag")
2806         openTag=paras[i+1];
2807       else if (para=="closetag")
2808         closeTag=paras[i+1];
2809       else if (para=="closefinaltag")
2810         closeFinalTag=(paras[i+1].ToLower()=="true");
2811       else if (para=="openrecordset")
2812         openRecordSet=paras[i+1]; 
2813           else if (para=="closerecordset")
2814         closeRecordSet=paras[i+1];
2815       else if (para=="openrecord")
2816         openRecord=paras[i+1];
2817           else if (para=="closerecord")
2818         closeRecord=paras[i+1];
2819           else if (para=="openfield")
2820         openField=paras[i+1];
2821           else if (para=="closefield")
2822         closeField=paras[i+1];
2823           else if (para=="openbroadcast")
2824         openBroadcast=paras[i+1];
2825           else if (para=="closebroadcast")
2826         closeBroadcast=paras[i+1];
2827           else
2828                   return SetResponse(openTag+"Error:Unknown parameter:"+para);
2829         }
2830     return SetResponse(openTag+"OK");
2831   }
2832 }
2833
2834
2835 int CXbmcHttp::xbmcHelp()
2836 {
2837   CStdString output;
2838   output="<p><b>XBMC HTTP API Commands</b></p><p><b>Syntax: http://xbox/xbmcCmds/xbmcHttp?command=</b>one_of_the_commands_in_the_list_below<b>&ampparameter=</b>first_parameter<b>;</b>second_parameter<b>;...</b></p><p>Note the use of the semi colon to separate multiple parameters</p><p>The commands are case insensitive.</p>";
2839
2840   output+= "<p>The full documentation can be found here: <a  href=\"http://www.xboxmediacenter.com/wiki/index.php?title=WebServerHTTP-API\">http://www.xboxmediacenter.com/wiki/index.php?title=WebServerHTTP-API</a></p><p>The following list of commands is not necessarily complete</p>";
2841
2842   output+= openTag+"clearplaylist"+closeTag+openTag+"addtoplaylist"+closeTag+openTag+"playfile"+closeTag+openTag+"pause"+closeTag+openTag+"stop"+closeTag+openTag+"restart"+closeTag+openTag+"shutdown"+closeTag+openTag+"exit"+closeTag+openTag+"reset"+closeTag+openTag+"restartapp"+closeTag+openTag+"getcurrentlyplaying"+closeTag+openTag+"getdirectory"+closeTag+openTag+"gettagfromfilename"+closeTag+openTag+"getcurrentplaylist"+closeTag+openTag+"setcurrentplaylist"+closeTag+openTag+"getplaylistcontents"+closeTag+openTag+"removefromplaylist"+closeTag+openTag+"setplaylistsong"+closeTag+openTag+"getplaylistsong"+closeTag+openTag+"playlistnext"+closeTag+openTag+"playlistprev"+closeTag+openTag+"getpercentage"+closeTag+openTag+"seekpercentage"+closeTag+openTag+"seekpercentagerelative"+closeTag+openTag+"setvolume"+closeTag+openTag+"getvolume"+closeTag+openTag+"getthumbfilename"+closeTag+openTag+"lookupalbum"+closeTag+openTag+"choosealbum"+closeTag+openTag+"downloadinternetfile"+closeTag+openTag+"getmoviedetails"+closeTag+openTag+"showpicture"+closeTag+openTag+"sendkey"+closeTag+openTag+"filedelete"+closeTag+openTag+"filecopy"+closeTag+openTag+"fileexists"+closeTag+openTag+"fileupload"+closeTag+openTag+"getguistatus"+closeTag+openTag+"execbuiltin"+closeTag+openTag+"config"+closeTag+openTag+"getsysteminfo"+closeTag+openTag+"getsysteminfobyname"+closeTag+openTag+"guisetting"+closeTag+openTag+"addtoslideshow"+closeTag+openTag+"clearslideshow"+closeTag+openTag+"playslideshow"+closeTag+openTag+"getslideshowcontents"+closeTag+openTag+"slideshowselect"+closeTag+openTag+"getcurrentslide"+closeTag+openTag+"rotate"+closeTag+openTag+"move"+closeTag+openTag+"zoom"+closeTag+openTag+"playnext"+closeTag+openTag+"playprev"+closeTag+openTag+"TakeScreenShot"+closeTag+openTag+"GetGUIDescription"+closeTag+openTag+"GetPlaySpeed"+closeTag+openTag+"SetPlaySpeed"+closeTag+openTag+"SetResponseFormat"+closeTag+openTag+"Help";
2843
2844   return SetResponse(output);
2845 }
2846
2847
2848 int CXbmcHttp::xbmcCommand(const CStdString &parameter)
2849 {
2850   if (shuttingDown)
2851     return -1;
2852   int numParas, retVal=false;
2853   CStdString command, paras[MAX_PARAS];
2854   numParas = splitParameter(parameter, command, paras, ";");
2855   if (parameter.length()<300)
2856     CLog::Log(LOGDEBUG, "HttpApi Start command: %s  paras: %s", command.c_str(), parameter.c_str());
2857   else
2858     CLog::Log(LOGDEBUG, "HttpApi Start command: %s  paras: [not recorded]", command.c_str());
2859   command=command.ToLower();
2860   if (numParas>=0)
2861   {
2862     if (command == "clearplaylist")                   retVal = xbmcClearPlayList(numParas, paras);  
2863       else if (command == "addtoplaylist")            retVal = xbmcAddToPlayList(numParas, paras);  
2864       else if (command == "playfile")                 retVal = xbmcPlayerPlayFile(numParas, paras); 
2865       else if (command == "pause")                    retVal = xbmcAction(numParas, paras,1);
2866       else if (command == "stop")                     retVal = xbmcAction(numParas, paras,2);
2867       else if (command == "playnext")                 retVal = xbmcAction(numParas, paras,3);
2868       else if (command == "playprev")                 retVal = xbmcAction(numParas, paras,4);
2869       else if (command == "rotate")                   retVal = xbmcAction(numParas, paras,5);
2870       else if (command == "move")                     retVal = xbmcAction(numParas, paras,6);
2871       else if (command == "zoom")                     retVal = xbmcAction(numParas, paras,7);
2872       else if (command == "restart")                  retVal = xbmcExit(1);
2873       else if (command == "shutdown")                 retVal = xbmcExit(2);
2874       else if (command == "exit")                     retVal = xbmcExit(3);
2875       else if (command == "reset")                    retVal = xbmcExit(4);
2876       else if (command == "restartapp")               retVal = xbmcExit(5);