1
/****************************************************************************************
2
 * Copyright (c) 2008 Nikolaj Hald Nielsen <nhn@kde.org>                                *
3
 * Copyright (c) 2009 Bart Cerneels <bart.cerneels@kde.org>                             *
4
 *                                                                                      *
5
 * This program is free software; you can redistribute it and/or modify it under        *
6
 * the terms of the GNU General Public License as published by the Free Software        *
7
 * Foundation; either version 2 of the License, or (at your option) any later           *
8
 * version.                                                                             *
9
 *                                                                                      *
10
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
11
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
12
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
13
 *                                                                                      *
14
 * You should have received a copy of the GNU General Public License along with         *
15
 * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
16
 ****************************************************************************************/
17
18
#include "OpmlParser.h"
19
20
#include "core/support/Amarok.h"
21
#include "core/support/Debug.h"
22
23
#include <QDomDocument>
24
#include <QFile>
25
26
#include <KLocale>
27
#include <threadweaver/Job.h>
28
29
const QString OpmlParser::OPML_MIME = "text/x-opml+xml";
30
31
OpmlParser::OpmlParser( const QString &filename )
32
        : ThreadWeaver::Job()
33
{
34
    DEBUG_BLOCK
35
    m_sFileName = filename;
36
    connect( this, SIGNAL( done( ThreadWeaver::Job* ) ), SIGNAL( doneParsing() ) );
37
}
38
39
OpmlParser::~OpmlParser()
40
{
41
    DEBUG_BLOCK
42
}
43
44
void
45
OpmlParser::run()
46
{
47
    readConfigFile( m_sFileName );
48
}
49
50
void
51
OpmlParser::readConfigFile( const QString &filename )
52
{
53
    DEBUG_BLOCK
54
55
    QDomDocument doc( "opml" );
56
57
    if ( !QFile::exists( filename ) )
58
    {
59
        debug() << "Opml file does not exist";
60
        return;
61
    }
62
63
    QFile file( filename );
64
    if ( !file.open( QIODevice::ReadOnly ) ) {
65
        debug() << "OpmlParser::readConfigFile error reading file";
66
        return ;
67
    }
68
    if ( !doc.setContent( &file ) )
69
    {
70
        debug() << "OpmlParser::readConfigFile error parsing file";
71
        file.close();
72
        return ;
73
    }
74
    file.close();
75
76
    //run through all the elements
77
    QDomElement docElem = doc.documentElement();
78
79
    QDomNode bodyNode = docElem.namedItem( "body" );
80
    if( bodyNode.isNull() || !bodyNode.isElement() )
81
        return; //TODO: emit parsing element
82
83
    debug() << "begin parsing content";
84
    parseOpmlBody( bodyNode.toElement() );
85
    debug() << "finishing transaction";
86
87
    emit( doneParsing() );
88
}
89
90
void
91
OpmlParser::parseOpmlBody( const QDomElement &e )
92
{
93
    if( e.tagName() != "body" )
94
        return; //TODO: emit parsing element
95
96
    QDomElement node = e.firstChildElement( "outline" );
97
    while( !node.isNull() )
98
    {
99
        OpmlOutline *outline = parseOutlineElement( node );
100
        m_rootOutlines << outline;
101
        node = node.nextSiblingElement( "outline" );
102
    }
103
}
104
105
OpmlOutline*
106
OpmlParser::parseOutlineElement( const QDomElement &e )
107
{
108
    if( e.tagName() != "outline" )
109
        return 0;
110
111
    OpmlOutline *outline = new OpmlOutline();
112
113
    QDomNamedNodeMap attributes = e.attributes();
114
    for( unsigned int i = 0; i < attributes.length(); i++ )
115
    {
116
        QDomAttr attribute = attributes.item( i ).toAttr();
117
        outline->addAttribute( attribute.name(), attribute.value() );
118
    }
119
    outline->setHasChildren( e.hasChildNodes() );
120
121
    emit( outlineParsed( outline ) );
122
123
    QDomNodeList childNodes = e.childNodes();
124
    for( int i = 0; i < childNodes.count(); i++ )
125
    {
126
        QDomNode node = childNodes.item( i );
127
        if( !node.isElement() )
128
            continue;
129
        const QDomElement &element = node.toElement();
130
        outline->addChild( parseOutlineElement( element ) );
131
    }
132
133
    return outline;
134
}