|
|
|
//Olivier Goffart <ogoffart @ kde.org>
|
|
|
|
// 2003 06 26
|
|
|
|
|
|
|
|
#include "historyplugin.h" //just needed because we are a member of this class
|
|
|
|
// we don't use any history function here
|
|
|
|
|
|
|
|
/**-----------------------------------------------------------
|
|
|
|
* CONVERTER from the old kopete history.
|
|
|
|
* it port history from kopete 0.6, 0.5 and above the actual
|
|
|
|
* this should be placed in a perl script handled by KConf_update
|
|
|
|
* but i need to acess to some info i don't have with perl, like
|
|
|
|
* the accountId, to know each protocol id, and more
|
|
|
|
*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include "kopetepluginmanager.h"
|
|
|
|
#include "kopeteaccount.h"
|
|
|
|
#include "kopeteaccountmanager.h"
|
|
|
|
#include "kopetecontact.h"
|
|
|
|
#include "kopetemessage.h"
|
|
|
|
#include "kopeteprotocol.h"
|
|
|
|
#include "kopeteuiglobal.h"
|
|
|
|
|
|
|
|
#include <kconfig.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <kprogress.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <ksavefile.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqdom.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
|
|
|
|
#define CBUFLENGTH 512 // buffer length for fgets()
|
|
|
|
|
|
|
|
void HistoryPlugin::convertOldHistory()
|
|
|
|
{
|
|
|
|
bool deleteFiles= KMessageBox::questionYesNo( Kopete::UI::Global::mainWidget(),
|
|
|
|
i18n( "Would you like to remove old history files?" ) , i18n( "History Converter" ), KStdGuiItem::del(), i18n("Keep") ) == KMessageBox::Yes;
|
|
|
|
|
|
|
|
KProgressDialog *progressDlg=new KProgressDialog(Kopete::UI::Global::mainWidget() , "history_progress_dlg" , i18n( "History converter" ) ,
|
|
|
|
TQString() , true); //modal to make sure the user will not doing stupid things (we have a kapp->processEvents())
|
|
|
|
progressDlg->setAllowCancel(false); //because i am too lazy to allow to cancel
|
|
|
|
|
|
|
|
|
|
|
|
TQString kopetedir=locateLocal( "data", TQString::tqfromLatin1( "kopete"));
|
|
|
|
TQDir d( kopetedir ); //d should point to ~/.kde/share/apps/kopete/
|
|
|
|
|
|
|
|
d.setFilter( TQDir::Dirs );
|
|
|
|
|
|
|
|
const TQFileInfoList *list = d.entryInfoList();
|
|
|
|
TQFileInfoListIterator it( *list );
|
|
|
|
TQFileInfo *fi;
|
|
|
|
while ( (fi = it.current()) != 0 )
|
|
|
|
{
|
|
|
|
TQString protocolId;
|
|
|
|
TQString accountId;
|
|
|
|
|
|
|
|
if( Kopete::Protocol *p = dynamic_cast<Kopete::Protocol *>( Kopete::PluginManager::self()->plugin( fi->fileName() ) ) )
|
|
|
|
{
|
|
|
|
protocolId=p->pluginId();
|
|
|
|
TQDictIterator<Kopete::Account> it(Kopete::AccountManager::self()->accounts(p));
|
|
|
|
Kopete::Account *a = it.current();
|
|
|
|
if(a)
|
|
|
|
accountId=a->accountId();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(accountId.isNull() || protocolId.isNull())
|
|
|
|
{
|
|
|
|
if(fi->fileName() == "MSNProtocol" || fi->fileName() == "msn_logs" )
|
|
|
|
{
|
|
|
|
protocolId="MSNProtocol";
|
|
|
|
KGlobal::config()->setGroup("MSN");
|
|
|
|
accountId=KGlobal::config()->readEntry( "UserID" );
|
|
|
|
}
|
|
|
|
else if(fi->fileName() == "ICTQProtocol" || fi->fileName() == "icq_logs" )
|
|
|
|
{
|
|
|
|
protocolId="ICTQProtocol";
|
|
|
|
KGlobal::config()->setGroup("ICQ");
|
|
|
|
accountId=KGlobal::config()->readEntry( "UIN" );
|
|
|
|
}
|
|
|
|
else if(fi->fileName() == "AIMProtocol" || fi->fileName() == "aim_logs" )
|
|
|
|
{
|
|
|
|
protocolId="AIMProtocol";
|
|
|
|
KGlobal::config()->setGroup("AIM");
|
|
|
|
accountId=KGlobal::config()->readEntry( "UserID" );
|
|
|
|
}
|
|
|
|
else if(fi->fileName() == "OscarProtocol" )
|
|
|
|
{
|
|
|
|
protocolId="AIMProtocol";
|
|
|
|
KGlobal::config()->setGroup("OSCAR");
|
|
|
|
accountId=KGlobal::config()->readEntry( "UserID" );
|
|
|
|
}
|
|
|
|
else if(fi->fileName() == "JabberProtocol" || fi->fileName() == "jabber_logs")
|
|
|
|
{
|
|
|
|
protocolId="JabberProtocol";
|
|
|
|
KGlobal::config()->setGroup("Jabber");
|
|
|
|
accountId=KGlobal::config()->readEntry( "UserID" );
|
|
|
|
}
|
|
|
|
//TODO: gadu, wp
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!protocolId.isEmpty() || !accountId.isEmpty())
|
|
|
|
{
|
|
|
|
TQDir d2( fi->absFilePath() );
|
|
|
|
d2.setFilter( TQDir::Files );
|
|
|
|
d2.setNameFilter("*.log");
|
|
|
|
const TQFileInfoList *list = d2.entryInfoList();
|
|
|
|
TQFileInfoListIterator it2( *list );
|
|
|
|
TQFileInfo *fi2;
|
|
|
|
|
|
|
|
progressDlg->progressBar()->reset();
|
|
|
|
progressDlg->progressBar()->setTotalSteps(d2.count());
|
|
|
|
progressDlg->setLabel(i18n("Parsing old history in %1").tqarg(fi->fileName()));
|
|
|
|
progressDlg->show(); //if it was not already showed...
|
|
|
|
|
|
|
|
while ( (fi2 = it2.current()) != 0 )
|
|
|
|
{
|
|
|
|
//we assume that all "-" are dots. (like in hotmail.com)
|
|
|
|
TQString contactId=fi2->fileName().replace(".log" , TQString()).replace("-" , ".");
|
|
|
|
|
|
|
|
if(!contactId.isEmpty() )
|
|
|
|
{
|
|
|
|
progressDlg->setLabel(i18n("Parsing old history in %1:\n%2").tqarg(fi->fileName()).tqarg(contactId));
|
|
|
|
kapp->processEvents(0); //make sure the text is updated in the progressDlg
|
|
|
|
|
|
|
|
int month=0;
|
|
|
|
int year=0;
|
|
|
|
TQDomDocument doc;
|
|
|
|
TQDomElement docElem;
|
|
|
|
|
|
|
|
TQDomElement msgelement;
|
|
|
|
TQDomNode node;
|
|
|
|
TQDomDocument xmllist;
|
|
|
|
Kopete::Message::MessageDirection dir;
|
|
|
|
TQString body, date, nick;
|
|
|
|
TQString buffer, msgBlock;
|
|
|
|
char cbuf[CBUFLENGTH]; // buffer for the log file
|
|
|
|
|
|
|
|
TQString logFileName = fi2->absFilePath();
|
|
|
|
|
|
|
|
// open the file
|
|
|
|
FILE *f = fopen(TQFile::encodeName(logFileName), "r");
|
|
|
|
|
|
|
|
// create a new <message> block
|
|
|
|
while ( ! feof( f ) )
|
|
|
|
{
|
|
|
|
fgets(cbuf, CBUFLENGTH, f);
|
|
|
|
buffer = TQString::fromUtf8(cbuf);
|
|
|
|
|
|
|
|
while ( strchr(cbuf, '\n') == NULL && !feof(f) )
|
|
|
|
{
|
|
|
|
fgets( cbuf, CBUFLENGTH, f );
|
|
|
|
buffer += TQString::fromUtf8(cbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( buffer.startsWith( TQString::tqfromLatin1( "<message " ) ) )
|
|
|
|
{
|
|
|
|
msgBlock = buffer;
|
|
|
|
|
|
|
|
// find the end of the message block
|
|
|
|
while( !feof( f ) && buffer != TQString::tqfromLatin1( "</message>\n" ) /*strcmp("</message>\n", cbuf )*/ )
|
|
|
|
{
|
|
|
|
fgets(cbuf, CBUFLENGTH, f);
|
|
|
|
buffer = TQString::fromUtf8(cbuf);
|
|
|
|
|
|
|
|
while ( strchr(cbuf, '\n') == NULL && !feof(f) )
|
|
|
|
{
|
|
|
|
fgets( cbuf, CBUFLENGTH, f );
|
|
|
|
buffer += TQString::fromUtf8(cbuf);
|
|
|
|
}
|
|
|
|
msgBlock.append(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
// now let's work on this new block
|
|
|
|
xmllist.setContent(msgBlock, false);
|
|
|
|
msgelement = xmllist.documentElement();
|
|
|
|
node = msgelement.firstChild();
|
|
|
|
|
|
|
|
if( msgelement.attribute( TQString::tqfromLatin1( "direction" ) ) == TQString::tqfromLatin1( "inbound" ) )
|
|
|
|
dir = Kopete::Message::Inbound;
|
|
|
|
else
|
|
|
|
dir = Kopete::Message::Outbound;
|
|
|
|
|
|
|
|
// Read all the elements.
|
|
|
|
TQString tagname;
|
|
|
|
TQDomElement element;
|
|
|
|
|
|
|
|
while ( ! node.isNull() )
|
|
|
|
{
|
|
|
|
if ( node.isElement() )
|
|
|
|
{
|
|
|
|
element = node.toElement();
|
|
|
|
tagname = element.tagName();
|
|
|
|
|
|
|
|
if( tagname == TQString::tqfromLatin1( "srcnick" ) )
|
|
|
|
nick = element.text();
|
|
|
|
|
|
|
|
else if( tagname == TQString::tqfromLatin1( "date" ) )
|
|
|
|
date = element.text();
|
|
|
|
else if( tagname == TQString::tqfromLatin1( "body" ) )
|
|
|
|
body = element.text().stripWhiteSpace();
|
|
|
|
}
|
|
|
|
|
|
|
|
node = node.nextSibling();
|
|
|
|
}
|
|
|
|
//FIXME!! The date in logs writed with kopete running with QT 3.0 is Localised.
|
|
|
|
// so QT can't parse it correctly.
|
|
|
|
TQDateTime dt=TQDateTime::fromString(date);
|
|
|
|
if(dt.date().month() != month || dt.date().year() != year)
|
|
|
|
{
|
|
|
|
if(!docElem.isNull())
|
|
|
|
{
|
|
|
|
TQDate date(year,month,1);
|
|
|
|
TQString name = protocolId.replace( TQRegExp( TQString::tqfromLatin1( "[./~?*]" ) ), TQString::tqfromLatin1( "-" ) ) +
|
|
|
|
TQString::tqfromLatin1( "/" ) +
|
|
|
|
contactId.replace( TQRegExp( TQString::tqfromLatin1( "[./~?*]" ) ), TQString::tqfromLatin1( "-" ) ) +
|
|
|
|
date.toString(".yyyyMM");
|
|
|
|
KSaveFile file( locateLocal( "data", TQString::tqfromLatin1( "kopete/logs/" ) + name+ TQString::tqfromLatin1( ".xml" ) ) );
|
|
|
|
if( file.status() == 0 )
|
|
|
|
{
|
|
|
|
TQTextStream *stream = file.textStream();
|
|
|
|
//stream->setEncoding( TQTextStream::UnicodeUTF8 ); //???? oui ou non?
|
|
|
|
doc.save( *stream , 1 );
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
month=dt.date().month();
|
|
|
|
year=dt.date().year();
|
|
|
|
docElem=TQDomElement();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(docElem.isNull())
|
|
|
|
{
|
|
|
|
doc=TQDomDocument("Kopete-History");
|
|
|
|
docElem= doc.createElement( "kopete-history" );
|
|
|
|
docElem.setAttribute ( "version" , "0.7" );
|
|
|
|
doc.appendChild( docElem );
|
|
|
|
TQDomElement headElem = doc.createElement( "head" );
|
|
|
|
docElem.appendChild( headElem );
|
|
|
|
TQDomElement dateElem = doc.createElement( "date" );
|
|
|
|
dateElem.setAttribute( "year", TQString::number(year) );
|
|
|
|
dateElem.setAttribute( "month", TQString::number(month) );
|
|
|
|
headElem.appendChild(dateElem);
|
|
|
|
TQDomElement myselfElem = doc.createElement( "contact" );
|
|
|
|
myselfElem.setAttribute( "type", "myself" );
|
|
|
|
myselfElem.setAttribute( "contactId", accountId );
|
|
|
|
headElem.appendChild(myselfElem);
|
|
|
|
TQDomElement contactElem = doc.createElement( "contact" );
|
|
|
|
contactElem.setAttribute( "contactId", contactId );
|
|
|
|
headElem.appendChild(contactElem);
|
|
|
|
TQDomElement importElem = doc.createElement( "imported" );
|
|
|
|
importElem.setAttribute( "from", fi->fileName() );
|
|
|
|
importElem.setAttribute( "date", TQDateTime::tqcurrentDateTime().toString() );
|
|
|
|
headElem.appendChild(importElem);
|
|
|
|
}
|
|
|
|
TQDomElement msgElem = doc.createElement( "msg" );
|
|
|
|
msgElem.setAttribute( "in", dir==Kopete::Message::Outbound ? "0" : "1" );
|
|
|
|
msgElem.setAttribute( "from", dir==Kopete::Message::Outbound ? accountId : contactId );
|
|
|
|
msgElem.setAttribute( "nick", nick ); //do we have to set this?
|
|
|
|
msgElem.setAttribute( "time", TQString::number(dt.date().day()) + " " + TQString::number(dt.time().hour()) + ":" + TQString::number(dt.time().minute()) );
|
|
|
|
TQDomText msgNode = doc.createTextNode( body.stripWhiteSpace() );
|
|
|
|
docElem.appendChild( msgElem );
|
|
|
|
msgElem.appendChild( msgNode );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose( f );
|
|
|
|
if(deleteFiles)
|
|
|
|
d2.remove(fi2->fileName() , false);
|
|
|
|
|
|
|
|
if(!docElem.isNull())
|
|
|
|
{
|
|
|
|
TQDate date(year,month,1);
|
|
|
|
TQString name = protocolId.replace( TQRegExp( TQString::tqfromLatin1( "[./~?*]" ) ), TQString::tqfromLatin1( "-" ) ) +
|
|
|
|
TQString::tqfromLatin1( "/" ) +
|
|
|
|
contactId.replace( TQRegExp( TQString::tqfromLatin1( "[./~?*]" ) ), TQString::tqfromLatin1( "-" ) ) +
|
|
|
|
date.toString(".yyyyMM");
|
|
|
|
KSaveFile file( locateLocal( "data", TQString::tqfromLatin1( "kopete/logs/" ) + name+ TQString::tqfromLatin1( ".xml" ) ) );
|
|
|
|
if( file.status() == 0 )
|
|
|
|
{
|
|
|
|
TQTextStream *stream = file.textStream();
|
|
|
|
//stream->setEncoding( TQTextStream::UnicodeUTF8 ); //???? oui ou non?
|
|
|
|
doc.save( *stream ,1 );
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
progressDlg->progressBar()->setProgress(progressDlg->progressBar()->progress()+1);
|
|
|
|
++it2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
delete progressDlg;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool HistoryPlugin::detectOldHistory()
|
|
|
|
{
|
|
|
|
KGlobal::config()->setGroup("History Plugin");
|
|
|
|
TQString version=KGlobal::config()->readEntry( "Version" ,"0.6" );
|
|
|
|
|
|
|
|
if(version != "0.6")
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
TQDir d( locateLocal( "data", TQString::tqfromLatin1( "kopete/logs")) );
|
|
|
|
d.setFilter( TQDir::Dirs );
|
|
|
|
if(d.count() >= 3) // '.' and '..' are included
|
|
|
|
return false; //the new history already exists
|
|
|
|
|
|
|
|
TQDir d2( locateLocal( "data", TQString::tqfromLatin1( "kopete")) );
|
|
|
|
d2.setFilter( TQDir::Dirs );
|
|
|
|
const TQFileInfoList *list = d2.entryInfoList();
|
|
|
|
TQFileInfoListIterator it( *list );
|
|
|
|
TQFileInfo *fi;
|
|
|
|
while ( (fi = it.current()) != 0 )
|
|
|
|
{
|
|
|
|
if( dynamic_cast<Kopete::Protocol *>( Kopete::PluginManager::self()->plugin( fi->fileName() ) ) )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if(fi->fileName() == "MSNProtocol" || fi->fileName() == "msn_logs" )
|
|
|
|
return true;
|
|
|
|
else if(fi->fileName() == "ICTQProtocol" || fi->fileName() == "icq_logs" )
|
|
|
|
return true;
|
|
|
|
else if(fi->fileName() == "AIMProtocol" || fi->fileName() == "aim_logs" )
|
|
|
|
return true;
|
|
|
|
else if(fi->fileName() == "OscarProtocol" )
|
|
|
|
return true;
|
|
|
|
else if(fi->fileName() == "JabberProtocol" || fi->fileName() == "jabber_logs")
|
|
|
|
return true;
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|