/*
* Copyright (C) 2005-2008 Team XBMC
* http://www.xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "tinyXML/tinyxml.h"
#include "PlayListXML.h"
#include "FileSystem/File.h"
#include "Util.h"
#include "utils/URIUtils.h"
#include "utils/RegExp.h"
#include "utils/log.h"
#include "XMLUtils.h"
#ifndef _LINUX
#include "cores/dllloader/exports/emu_msvcrt.h"
#endif
#include "Settings.h"
#include "MusicInfoTag.h"
using namespace PLAYLIST;
using namespace XFILE;
/*
Playlist example (must be stored with .pxml extension):
mms://stream02.rambler.ru/eurosport
Евроспорт
LIVETV
RU
1
123
mms://video.rfn.ru/vesti_24
Вести 24
LIVETV
RU
2
*/
CPlayListXML::CPlayListXML(void)
{}
CPlayListXML::~CPlayListXML(void)
{}
static inline CStdString GetString( const TiXmlElement* pRootElement, const char *tagName )
{
CStdString strValue;
if ( XMLUtils::GetString(pRootElement, tagName, strValue) )
return strValue;
return "";
}
bool CPlayListXML::Load( const CStdString& strFileName )
{
TiXmlDocument xmlDoc;
m_strPlayListName = URIUtils::GetFileName(strFileName);
URIUtils::GetParentPath(strFileName, m_strBasePath);
Clear();
// Try to load the file as XML. If it does not load, return an error.
if ( !xmlDoc.LoadFile( strFileName ) )
{
CLog::Log(LOGERROR, "Playlist %s has invalid format/malformed xml", strFileName.c_str());
return false;
}
TiXmlElement *pRootElement = xmlDoc.RootElement();
// If the stream does not contain "streams", still ok. Not an error.
if ( !pRootElement || stricmp( pRootElement->Value(), "streams" ) )
{
CLog::Log(LOGERROR, "Playlist %s has no root", strFileName.c_str());
return false;
}
TiXmlElement* pSet = pRootElement->FirstChildElement("stream");
while ( pSet )
{
// Get parameters
CStdString url = GetString( pSet, "url" );
CStdString name = GetString( pSet, "name" );
CStdString category = GetString( pSet, "category" );
CStdString lang = GetString( pSet, "lang" );
CStdString channel = GetString( pSet, "channel" );
CStdString lockpass = GetString( pSet, "lockpassword" );
// If url is empty, it doesn't make any sense
if ( !url.IsEmpty() )
{
// If the name is empty, use url
if ( name.IsEmpty() )
name = url;
// Append language to the name, and also set as metadata
if ( !lang.IsEmpty() )
name += " [" + lang + "]";
CStdString info = name;
CFileItemPtr newItem( new CFileItem(info) );
newItem->SetPath(url);
// Set language as metadata
if ( !lang.IsEmpty() )
newItem->SetProperty("language", lang );
// Set category as metadata
if ( !category.IsEmpty() )
newItem->SetProperty("category", category );
// Set channel as extra info and as metadata
if ( !channel.IsEmpty() )
{
newItem->SetProperty("remotechannel", channel );
newItem->SetExtraInfo( "Channel: " + channel );
}
if ( !lockpass.IsEmpty() )
{
newItem->m_strLockCode = lockpass;
newItem->m_iHasLock = 2;
newItem->m_iLockMode = LOCK_MODE_NUMERIC;
}
Add(newItem);
}
else
CLog::Log(LOGERROR, "Playlist entry %s in file %s has missing tag", name.c_str(), strFileName.c_str());
pSet = pSet->NextSiblingElement("stream");
}
return true;
}
void CPlayListXML::Save(const CStdString& strFileName) const
{
if (!m_vecItems.size()) return ;
CStdString strPlaylist = CUtil::MakeLegalPath(strFileName);
CFile file;
if (!file.OpenForWrite(strPlaylist, true))
{
CLog::Log(LOGERROR, "Could not save WPL playlist: [%s]", strPlaylist.c_str());
return ;
}
CStdString write;
write.AppendFormat("\n");
write.AppendFormat("\n");
for (int i = 0; i < (int)m_vecItems.size(); ++i)
{
CFileItemPtr item = m_vecItems[i];
write.AppendFormat(" \n" );
write.AppendFormat(" %s", item->GetPath().c_str() );
write.AppendFormat(" %s", item->GetLabel().c_str() );
if ( !item->GetProperty("language").IsEmpty() )
write.AppendFormat(" %s", item->GetProperty("language").c_str() );
if ( !item->GetProperty("category").IsEmpty() )
write.AppendFormat(" %s", item->GetProperty("category").c_str() );
if ( !item->GetProperty("remotechannel").IsEmpty() )
write.AppendFormat(" %s", item->GetProperty("remotechannel").c_str() );
if ( item->m_iHasLock > 0 )
write.AppendFormat(" %s", item->m_strLockCode.c_str() );
write.AppendFormat(" \n\n" );
}
write.AppendFormat("\n");
file.Write(write.c_str(), write.size());
file.Close();
}