00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "commentsmodel.h"
00021 #include <player/lib/atticamanager.h>
00022 #include <core/gluonobject.h>
00023 #include <core/gdlhandler.h>
00024 #include <core/gluon_global.h>
00025
00026 #include <attica/comment.h>
00027 #include <attica/listjob.h>
00028
00029 #include <QDebug>
00030 #include <QFile>
00031 #include <QDir>
00032
00033 using namespace GluonCore;
00034 using namespace GluonPlayer;
00035
00036 static const char serviceURI[] = "gamingfreedom.org";
00037
00038 CommentsModel::CommentsModel( QString gameId, QObject* parent )
00039 : QAbstractItemModel( parent )
00040 , rootNode( new GluonObject( "Comment" ) )
00041 , m_isOnline( false )
00042 , m_gameId(gameId)
00043 {
00044 m_columnNames << "Author" << "Title" << "Body" << "DateTime" << "Rating";
00045
00046 loadData();
00047 updateData();
00048 }
00049
00050 void CommentsModel::updateData()
00051 {
00052 if( AtticaManager::instance()->isProviderValid() )
00053 {
00054 providersUpdated();
00055 }
00056 else
00057 {
00058 connect( AtticaManager::instance(), SIGNAL( gotProvider() ), SLOT( providersUpdated() ) );
00059 }
00060 }
00061
00062 void CommentsModel::providersUpdated()
00063 {
00064 if( AtticaManager::instance()->isProviderValid() )
00065 {
00066 Attica::ListJob<Attica::Comment> *job =
00067 AtticaManager::instance()->provider().requestComments( Attica::Comment::ContentComment,
00068 m_gameId, "0", 0, 100 );
00069 connect( job, SIGNAL( finished( Attica::BaseJob* ) ), SLOT( processFetchedComments( Attica::BaseJob* ) ) );
00070 job->start();
00071 }
00072 else
00073 {
00074 qDebug() << "No providers found.";
00075 }
00076 }
00077
00078 void CommentsModel::processFetchedComments( Attica::BaseJob* job )
00079 {
00080 qDebug() << "Comments Successfully Fetched from the server";
00081
00082 Attica::ListJob<Attica::Comment> *commentsJob = static_cast<Attica::ListJob<Attica::Comment> *>( job );
00083 if( commentsJob->metadata().error() == Attica::Metadata::NoError )
00084 {
00085
00086
00087
00088 if( rootNode )
00089 {
00090 qDeleteAll( rootNode->children() );
00091 }
00092
00093 for( int i = 0; i < commentsJob->itemList().count(); ++i )
00094 {
00095 Attica::Comment p( commentsJob->itemList().at( i ) );
00096 addComment( p, rootNode );
00097 }
00098
00099 m_isOnline = true;
00100 reset();
00101 }
00102 else
00103 {
00104 qDebug() << "Could not fetch information";
00105 }
00106 }
00107
00108 void CommentsModel::addCommentFinished( Attica::BaseJob* job )
00109 {
00110 Attica::ListJob<Attica::Comment> *commentsJob = static_cast<Attica::ListJob<Attica::Comment>*>( job );
00111 if( commentsJob->metadata().error() == Attica::Metadata::NoError )
00112 {
00113 updateData();
00114 }
00115 else
00116 {
00117 emit addCommentFailed();
00118 }
00119 }
00120
00121 GluonObject* CommentsModel::addComment( Attica::Comment comment, GluonObject* parent )
00122 {
00123 GluonObject* newComment = new GluonObject( comment.id(), parent );
00124 newComment->setProperty( "Author", comment.user() );
00125 newComment->setProperty( "Title", comment.subject() );
00126 newComment->setProperty( "Body", comment.text() );
00127 newComment->setProperty( "DateTime", comment.date().toString() );
00128 newComment->setProperty( "Rating", comment.score() );
00129
00130 foreach( Attica::Comment child, comment.children() )
00131 {
00132 addComment( child, newComment );
00133 }
00134
00135 return newComment;
00136 }
00137
00138
00139 void CommentsModel::loadData()
00140 {
00141 QDir gluonDir = QDir::home();
00142 gluonDir.mkpath( ".gluon/" + QString( serviceURI ) );
00143 gluonDir.cd( ".gluon/" + QString( serviceURI ) );
00144 QString filename = gluonDir.absoluteFilePath( "comments.gdl" );
00145
00146 QFile dataFile( filename );
00147 while( 1 )
00148 {
00149 if( !dataFile.open( QIODevice::ReadOnly ) )
00150 {
00151 if( !QFile::exists( filename ) )
00152 {
00153 qDebug() << "Cannot find the file " << filename << ", creating new";
00154 dataFile.close();
00155 saveData();
00156 continue;
00157 }
00158 else
00159 {
00160 qDebug() << "Cannot open the file " << filename;
00161 return;
00162 }
00163 }
00164 else
00165 {
00166 break;
00167 }
00168 }
00169
00170 QTextStream commentReader( &dataFile );
00171 QString fileContents = commentReader.readAll();
00172 dataFile.close();
00173
00174 if( fileContents.isEmpty() )
00175 qDebug() << "Something is wrong with the comments file";
00176
00177 QList<GluonObject*> comments = GluonCore::GDLHandler::instance()->parseGDL( fileContents, 0 );
00178 rootNode = comments.at( 0 );
00179 }
00180
00181 void CommentsModel::saveData()
00182 {
00183 qDebug() << "Saving Data";
00184 QDir gluonDir = QDir::home();
00185 gluonDir.mkpath( ".gluon/" + QString( serviceURI ) );
00186 gluonDir.cd( ".gluon/" + QString( serviceURI ) );
00187 QString filename = gluonDir.absoluteFilePath( "comments.gdl" );
00188
00189 QFile dataFile( filename );
00190 if( !dataFile.open( QIODevice::WriteOnly ) )
00191 qDebug() << "Cannot open the comments file";
00192
00193 QList<const GluonObject*> comments;
00194 comments.append( rootNode );
00195 QTextStream dataWriter( &dataFile );
00196 dataWriter << GluonCore::GDLHandler::instance()->serializeGDL( comments );
00197 dataFile.close();
00198 qDebug() << "Saved";
00199 }
00200
00201 CommentsModel::~CommentsModel()
00202 {
00203 saveData();
00204 delete rootNode;
00205 }
00206
00207 QVariant CommentsModel::data( const QModelIndex& index, int role ) const
00208 {
00209 if( role == Qt::DisplayRole || role == Qt::EditRole )
00210 {
00211 GluonObject* node;
00212 node = static_cast<GluonObject*>( index.internalPointer() );
00213
00214 return node->property( columnName( Column( index.column() ) ).toUtf8() );
00215 }
00216 return QVariant();
00217 }
00218
00219 int CommentsModel::columnCount( const QModelIndex& parent ) const
00220 {
00221 Q_UNUSED( parent );
00222 return 5;
00223 }
00224
00225 int CommentsModel::rowCount( const QModelIndex& parent ) const
00226 {
00227 GluonObject* parentItem;
00228 if( parent.column() > 0 )
00229 return 0;
00230
00231 if( !parent.isValid() )
00232 parentItem = rootNode;
00233 else
00234 parentItem = static_cast<GluonObject*>( parent.internalPointer() );
00235
00236 return parentItem->children().count();
00237 }
00238
00239 QModelIndex CommentsModel::parent( const QModelIndex& child ) const
00240 {
00241 if( !child.isValid() )
00242 return QModelIndex();
00243
00244 GluonObject* childItem = static_cast<GluonObject*>( child.internalPointer() );
00245 GluonObject* parentItem = qobject_cast<GluonObject*> ( childItem->parent() );
00246
00247 if( parentItem == rootNode )
00248 return QModelIndex();
00249
00250 GluonObject* grandParentItem = qobject_cast<GluonObject*>( parentItem->parent() );
00251 if( !grandParentItem )
00252 return QModelIndex();
00253
00254 return createIndex( grandParentItem->children().indexOf( parentItem ), 0, parentItem );
00255 }
00256
00257 QModelIndex CommentsModel::index( int row, int column, const QModelIndex& parent ) const
00258 {
00259 if( !hasIndex( row, column, parent ) )
00260 return QModelIndex();
00261
00262 GluonObject* parentItem;
00263
00264 if( !parent.isValid() )
00265 parentItem = rootNode;
00266 else
00267 parentItem = static_cast<GluonObject*>( parent.internalPointer() );
00268
00269 GluonObject* childItem = parentItem->child( row );
00270 if( childItem )
00271 return createIndex( row, column, childItem );
00272 else
00273 return QModelIndex();
00274 }
00275
00276 QVariant CommentsModel::headerData( int section, Qt::Orientation orientation, int role ) const
00277 {
00278 if( orientation == Qt::Horizontal && role == Qt::DisplayRole )
00279 return columnName( Column( section ) );
00280
00281 return QVariant();
00282 }
00283
00284 Qt::ItemFlags CommentsModel::flags( const QModelIndex& index ) const
00285 {
00286 if( !index.isValid() )
00287 return Qt::ItemIsEnabled;
00288
00289 return QAbstractItemModel::flags( index );
00290 }
00291
00292 bool CommentsModel::setData( const QModelIndex& index, const QVariant& value, int role )
00293 {
00294 if( index.isValid() && role == Qt::EditRole )
00295 {
00296 GluonObject* node;
00297 node = static_cast<GluonObject*>( index.internalPointer() );
00298
00299 node->setProperty( columnName( Column( index.column() ) ).toUtf8(), value );
00300 emit dataChanged( index, index );
00301 return true;
00302 }
00303
00304 return false;
00305 }
00306
00307 bool CommentsModel::insertRows( int row, int count, const QModelIndex& parent )
00308 {
00309 if( count != 1 )
00310 {
00311 qDebug() << "Can insert only one comment at a time";
00312 return false;
00313 }
00314 if( row != rowCount( parent ) )
00315 {
00316 qDebug() << "Can only add a comment to the end of existing comments";
00317 return false;
00318 }
00319
00320 beginInsertRows( parent, row, row );
00321 GluonObject* parentNode;
00322 parentNode = static_cast<GluonObject*>( parent.internalPointer() );
00323
00324 GluonObject* newNode = new GluonObject( "Comment", parentNode );
00325 parentNode->addChild( newNode );
00326 endInsertRows();
00327
00328 return true;
00329 }
00330
00331 QString CommentsModel::columnName( const Column col ) const
00332 {
00333 return m_columnNames.at( col );
00334 }
00335
00336 bool CommentsModel::isOnline()
00337 {
00338 return m_isOnline;
00339 }
00340
00341 void CommentsModel::uploadComment( const QModelIndex& parentIndex, const QString& subject, const QString& message )
00342 {
00343 GluonObject* parentNode = static_cast<GluonObject*>( parentIndex.internalPointer() );
00344 Attica::PostJob* job =
00345 AtticaManager::instance()->provider().addNewComment( Attica::Comment::ContentComment,
00346 "128637", "0", parentNode->name(), subject,
00347 message );
00348 connect( job, SIGNAL( finished( Attica::BaseJob* ) ), SLOT( addCommentFinished( Attica::BaseJob* ) ) );
00349 job->start();
00350 }
00351
00352
00353 #include "commentsmodel.moc"