File indexing completed on 2024-04-28 04:50:22

0001 /*
0002     SPDX-FileCopyrightText: 2003 Christian Kvasny <chris@k3b.org>
0003     SPDX-FileCopyrightText: 2009 Sebastian Trueg <trueg@k3b.org>
0004     SPDX-FileCopyrightText: 2010 Michal Malek <michalm@jabster.pl>
0005     SPDX-FileCopyrightText: 1998-2010 Sebastian Trueg <trueg@k3b.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "k3bvideocdinfo.h"
0011 #include "k3bcore.h"
0012 #include "k3bprocess.h"
0013 #include "k3bexternalbinmanager.h"
0014 
0015 #include <KConfig>
0016 #include <KLocalizedString>
0017 
0018 #include <QDebug>
0019 #include <QDomDocument>
0020 #include <QDomElement>
0021 
0022 
0023 K3b::VideoCdInfo::VideoCdInfo( QObject* parent )
0024     : QObject( parent )
0025 {
0026     m_process = 0L;
0027     m_isXml = false;
0028 }
0029 
0030 
0031 K3b::VideoCdInfo::~VideoCdInfo()
0032 {
0033     delete m_process;
0034 }
0035 
0036 void K3b::VideoCdInfo::cancelAll()
0037 {
0038     if ( m_process->isRunning() ) {
0039         m_process->disconnect( this );
0040         m_process->kill();
0041     }
0042 }
0043 
0044 void K3b::VideoCdInfo::info( const QString& device )
0045 {
0046     if ( !k3bcore ->externalBinManager() ->foundBin( "vcdxrip" ) ) {
0047         qDebug() << "(K3b::VideoCdInfo::info) could not find vcdxrip executable";
0048         emit infoFinished( false );
0049         return ;
0050     }
0051 
0052     delete m_process;
0053     m_process = new K3b::Process();
0054 
0055     *m_process << k3bcore ->externalBinManager() ->binPath( "vcdxrip" );
0056 
0057     *m_process << "-q" << "--norip" << "-i" << device << "-o" << "-";
0058 
0059     m_process->setSplitStdout( true );
0060     m_process->setSuppressEmptyLines( false );
0061     connect( m_process, SIGNAL(stderrLine(QString)),
0062              this, SLOT(slotParseOutput(QString)) );
0063     connect( m_process, SIGNAL(stdoutLine(QString)),
0064              this, SLOT(slotParseOutput(QString)) );
0065     connect( m_process, SIGNAL(finished(int,QProcess::ExitStatus)),
0066              this, SLOT(slotInfoFinished(int,QProcess::ExitStatus)) );
0067 
0068     if ( !m_process->start( KProcess::SeparateChannels ) ) {
0069         qDebug() << "(K3b::VideoCdInfo::info) could not start vcdxrip";
0070         cancelAll();
0071         emit infoFinished( false );
0072     }
0073 }
0074 
0075 void K3b::VideoCdInfo::slotParseOutput( const QString& inp )
0076 {
0077     if ( inp.contains( "<?xml" ) )
0078         m_isXml = true;
0079 
0080     if ( m_isXml )
0081         m_xmlData += inp;
0082     else
0083         qDebug() << "(K3b::VideoCdInfo::slotParseOutput) " << inp;
0084 
0085     if ( inp.contains( "</videocd>" ) )
0086         m_isXml = false;
0087 }
0088 
0089 void K3b::VideoCdInfo::slotInfoFinished( int exitCode, QProcess::ExitStatus exitStatus )
0090 {
0091     if ( exitStatus == QProcess::NormalExit ) {
0092         // TODO: check the process' exitStatus()
0093         switch ( exitCode ) {
0094             case 0:
0095                 break;
0096             default:
0097                 cancelAll();
0098                 qDebug() << "vcdxrip finished with exit code" << exitCode;
0099                 emit infoFinished( false );
0100                 return ;
0101         }
0102     } else {
0103         cancelAll();
0104         qDebug() << "vcdxrip crashed!";
0105         emit infoFinished( false );
0106         return ;
0107     }
0108 
0109     if ( m_xmlData.isEmpty() ) {
0110         qDebug() << "XML data empty!";
0111         emit infoFinished( false );
0112         return ;
0113     }
0114 
0115     parseXmlData();
0116     emit infoFinished( true );
0117 }
0118 
0119 void K3b::VideoCdInfo::parseXmlData()
0120 {
0121     QDomDocument xml_doc;
0122     QDomElement xml_root;
0123 
0124     m_Result.xmlData = m_xmlData;
0125 
0126     xml_doc.setContent( m_xmlData );
0127     xml_root = xml_doc.documentElement();
0128 
0129     m_Result.type = xml_root.attribute( "class" );
0130     m_Result.version = xml_root.attribute( "version" );
0131 
0132     for ( QDomNode node = xml_root.firstChild(); !node.isNull(); node = node.nextSibling() ) {
0133         QDomElement el = node.toElement();
0134         QString tagName = el.tagName().toLower();
0135 
0136         if ( tagName == "pvd" ) {
0137             for ( QDomNode snode = node.firstChild(); !snode.isNull(); snode = snode.nextSibling() ) {
0138                 QDomElement sel = snode.toElement();
0139                 QString pvdElement = sel.tagName().toLower();
0140                 QString pvdElementText = sel.text();
0141                 if ( pvdElement == "volume-id" )
0142                     m_Result.volumeId = pvdElementText;
0143             }
0144 
0145         } else if ( tagName == "sequence-items" ) {
0146             for ( QDomNode snode = node.firstChild(); !snode.isNull(); snode = snode.nextSibling() ) {
0147                 QDomElement sel = snode.toElement();
0148                 m_Result.addEntry( K3b::VideoCdInfoResultEntry(
0149                                        sel.attribute( "src" ),
0150                                        sel.attribute( "id" ) ),
0151                                    K3b::VideoCdInfoResult::SEQUENCE
0152                                  );
0153             }
0154         } else if ( tagName == "segment-items" ) {
0155             for ( QDomNode snode = node.firstChild(); !snode.isNull(); snode = snode.nextSibling() ) {
0156                 QDomElement sel = snode.toElement();
0157                 m_Result.addEntry( K3b::VideoCdInfoResultEntry(
0158                                        sel.attribute( "src" ),
0159                                        sel.attribute( "id" ) ),
0160                                    K3b::VideoCdInfoResult::SEGMENT
0161                                  );
0162             }
0163         } else {
0164             qDebug() << QString( "(K3b::VideoCdInfo::parseXmlData) tagName '%1' not used" ).arg( tagName );
0165         }
0166     }
0167 }
0168 
0169 const K3b::VideoCdInfoResult& K3b::VideoCdInfo::result() const
0170 {
0171     return m_Result;
0172 }
0173 
0174 const K3b::VideoCdInfoResultEntry& K3b::VideoCdInfoResult::entry( int number, int type ) const
0175 {
0176     switch ( type ) {
0177         case K3b::VideoCdInfoResult::FILE:
0178             if ( number >= m_fileEntry.count() )
0179                 return m_emptyEntry;
0180             return m_fileEntry[ number ];
0181         case K3b::VideoCdInfoResult::SEGMENT:
0182             if ( number >= m_segmentEntry.count() )
0183                 return m_emptyEntry;
0184             return m_segmentEntry[ number ];
0185         case K3b::VideoCdInfoResult::SEQUENCE:
0186             if ( number >= m_sequenceEntry.count() )
0187                 return m_emptyEntry;
0188             return m_sequenceEntry[ number ];
0189         default:
0190             qDebug() << "(K3b::VideoCdInfoResult::entry) not supported entrytype.";
0191     }
0192 
0193     return m_emptyEntry;
0194 
0195 }
0196 
0197 
0198 void K3b::VideoCdInfoResult::addEntry( const K3b::VideoCdInfoResultEntry& entry, int type )
0199 {
0200     switch ( type ) {
0201         case K3b::VideoCdInfoResult::FILE:
0202             m_fileEntry.append( entry );
0203             break;
0204         case K3b::VideoCdInfoResult::SEGMENT:
0205             m_segmentEntry.append( entry );
0206             break;
0207         case K3b::VideoCdInfoResult::SEQUENCE:
0208             m_sequenceEntry.append( entry );
0209             break;
0210         default:
0211             qDebug() << "(K3b::VideoCdInfoResult::addEntry) not supported entrytype.";
0212     }
0213 }
0214 
0215 int K3b::VideoCdInfoResult::foundEntries( int type ) const
0216 {
0217     switch ( type ) {
0218         case K3b::VideoCdInfoResult::FILE:
0219             return m_fileEntry.count();
0220         case K3b::VideoCdInfoResult::SEGMENT:
0221             return m_segmentEntry.count();
0222         case K3b::VideoCdInfoResult::SEQUENCE:
0223             return m_sequenceEntry.count();
0224         default:
0225             qDebug() << "(K3b::VideoCdInfoResult::addEntry) not supported entrytype.";
0226     }
0227     return 0;
0228 }
0229 
0230 #include "moc_k3bvideocdinfo.cpp"