<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 <NAME> <<EMAIL>>
 * Copyright (C) 2010 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "commentsmodel.h"

#include <player/lib/atticamanager.h>
#include <core/gluonobject.h>
#include <core/gdlhandler.h>
#include <core/gluon_global.h>

#include <attica/comment.h>
#include <attica/listjob.h>

#include <QDebug>
#include <QFile>
#include <QDir>

using namespace GluonCore;
using namespace GluonPlayer;

static const char serviceURI[] = "gamingfreedom.org";

CommentsModel::CommentsModel( QString gameId, QObject* parent )
    : QAbstractItemModel( parent )
    , rootNode( new GluonObject( "Comment" ) )
    , m_isOnline( false )
    , m_gameId( gameId )
{
    m_columnNames << "Author" << "Title" << "Body" << "DateTime" << "Rating";

    loadData();     // Load comments stored locally
    updateData();   // Fetch latest comments from the web service
}

void CommentsModel::updateData()
{
    if( AtticaManager::instance()->isProviderValid() )
    {
        providersUpdated();
    }
    else
    {
        connect( AtticaManager::instance(), SIGNAL( gotProvider() ), SLOT( providersUpdated() ) );
    }
}

void CommentsModel::providersUpdated()
{
    if( AtticaManager::instance()->isProviderValid() )
    {
        Attica::ListJob<Attica::Comment> *job =
            AtticaManager::instance()->provider().requestComments( Attica::Comment::ContentComment,
                    m_gameId, "0", 0, 100 );
        connect( job, SIGNAL( finished( Attica::BaseJob* ) ), SLOT( processFetchedComments( Attica::BaseJob* ) ) );
        job->start();
    }
    else
    {
        qDebug() << "No providers found.";
    }
}

void CommentsModel::processFetchedComments( Attica::BaseJob* job )
{
    qDebug() << "Comments Successfully Fetched from the server";

    Attica::ListJob<Attica::Comment> *commentsJob = static_cast<Attica::ListJob<Attica::Comment> *>( job );
    if( commentsJob->metadata().error() == Attica::Metadata::NoError )
    {
        //No error, try to remove exising comments (if any)
        //and add new comments

        if( rootNode )
        {
            qDeleteAll( rootNode->children() );
        }

        for( int i = 0; i < commentsJob->itemList().count(); ++i )
        {
            Attica::Comment p( commentsJob->itemList().at( i ) );
            addComment( p, rootNode );
        }

        m_isOnline = true;
        reset();    //Reset the model to notify views to reload comments
    }
    else
    {
        qDebug() << "Could not fetch information";
    }
}

void CommentsModel::addCommentFinished( Attica::BaseJob* job )
{
    Attica::ListJob<Attica::Comment> *commentsJob = static_cast<Attica::ListJob<Attica::Comment>*>( job );
    if( commentsJob->metadata().error() == Attica::Metadata::NoError )
    {
        updateData();
    }
    else
    {
        emit addCommentFailed();
    }
}

GluonObject* CommentsModel::addComment( Attica::Comment comment, GluonObject* parent )
{
    GluonObject* newComment = new GluonObject( comment.id(), parent );
    newComment->setProperty( "Author", comment.user() );
    newComment->setProperty( "Title", comment.subject() );
    newComment->setProperty( "Body", comment.text() );
    newComment->setProperty( "DateTime", comment.date().toString() );
    newComment->setProperty( "Rating", comment.score() );

    foreach( const Attica::Comment& child, comment.children() )
    {
        addComment( child, newComment );
    }

    return newComment;
}


void CommentsModel::loadData()
{
    QDir gluonDir = QDir::home();
    gluonDir.mkpath( ".gluon/" + QString( serviceURI ) );
    gluonDir.cd( ".gluon/" + QString( serviceURI ) );
    QString filename = gluonDir.absoluteFilePath( "comments.gdl" );

    QFile dataFile( filename );
    while( 1 )
    {
        if( !dataFile.open( QIODevice::ReadOnly ) )
        {
            if( !QFile::exists( filename ) )
            {
                qDebug() << "Cannot find the file " << filename << ", creating new";
                dataFile.close();
                saveData();         //Create a blank file if it doesn't exist
                continue;       //Try to open again
            }
            else
            {
                qDebug() << "Cannot open the file " << filename;
                return;     //return from loadData()
            }
        }
        else
        {
            break;      //File opened successfully
        }
    }

    QTextStream commentReader( &dataFile );
    QString fileContents = commentReader.readAll();
    dataFile.close();

    if( fileContents.isEmpty() )
        qDebug() << "Something is wrong with the comments file";

    QList<GluonObject*> comments = GluonCore::GDLHandler::instance()->parseGDL( fileContents, 0, 0 );
    rootNode = comments.at( 0 );
}

void CommentsModel::saveData()
{
    qDebug() << "Saving Data";
    QDir gluonDir = QDir::home();
    gluonDir.mkpath( ".gluon/" + QString( serviceURI ) );
    gluonDir.cd( ".gluon/" + QString( serviceURI ) );
    QString filename = gluonDir.absoluteFilePath( "comments.gdl" );

    QFile dataFile( filename );
    if( !dataFile.open( QIODevice::WriteOnly ) )
        qDebug() << "Cannot open the comments file";

    QList<const GluonObject*> comments;
    comments.append( rootNode );
    QTextStream dataWriter( &dataFile );
    dataWriter << GluonCore::GDLHandler::instance()->serializeGDL( comments );<commit_msg>Simplify the commentsmodel code radically with the new parseGDL interface.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 <NAME> <<EMAIL>>
 * Copyright (C) 2010 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "commentsmodel.h"

#include <player/lib/atticamanager.h>
#include <core/gluonobject.h>
#include <core/gdlhandler.h>
#include <core/gluon_global.h>

#include <attica/comment.h>
#include <attica/listjob.h>

#include <QDebug>
#include <QFile>
#include <QDir>

using namespace GluonCore;
using namespace GluonPlayer;

static const char serviceURI[] = "gamingfreedom.org";

CommentsModel::CommentsModel( QString gameId, QObject* parent )
    : QAbstractItemModel( parent )
    , rootNode( new GluonObject( "Comment" ) )
    , m_isOnline( false )
    , m_gameId( gameId )
{
    m_columnNames << "Author" << "Title" << "Body" << "DateTime" << "Rating";

    loadData();     // Load comments stored locally
    updateData();   // Fetch latest comments from the web service
}

void CommentsModel::updateData()
{
    if( AtticaManager::instance()->isProviderValid() )
    {
        providersUpdated();
    }
    else
    {
        connect( AtticaManager::instance(), SIGNAL( gotProvider() ), SLOT( providersUpdated() ) );
    }
}

void CommentsModel::providersUpdated()
{
    if( AtticaManager::instance()->isProviderValid() )
    {
        Attica::ListJob<Attica::Comment> *job =
            AtticaManager::instance()->provider().requestComments( Attica::Comment::ContentComment,
                    m_gameId, "0", 0, 100 );
        connect( job, SIGNAL( finished( Attica::BaseJob* ) ), SLOT( processFetchedComments( Attica::BaseJob* ) ) );
        job->start();
    }
    else
    {
        qDebug() << "No providers found.";
    }
}

void CommentsModel::processFetchedComments( Attica::BaseJob* job )
{
    qDebug() << "Comments Successfully Fetched from the server";

    Attica::ListJob<Attica::Comment> *commentsJob = static_cast<Attica::ListJob<Attica::Comment> *>( job );
    if( commentsJob->metadata().error() == Attica::Metadata::NoError )
    {
        //No error, try to remove exising comments (if any)
        //and add new comments

        if( rootNode )
        {
            qDeleteAll( rootNode->children() );
        }

        for( int i = 0; i < commentsJob->itemList().count(); ++i )
        {
            Attica::Comment p( commentsJob->itemList().at( i ) );
            addComment( p, rootNode );
        }

        m_isOnline = true;
        reset();    //Reset the model to notify views to reload comments
    }
    else
    {
        qDebug() << "Could not fetch information";
    }
}

void CommentsModel::addCommentFinished( Attica::BaseJob* job )
{
    Attica::ListJob<Attica::Comment> *commentsJob = static_cast<Attica::ListJob<Attica::Comment>*>( job );
    if( commentsJob->metadata().error() == Attica::Metadata::NoError )
    {
        updateData();
    }
    else
    {
        emit addCommentFailed();
    }
}

GluonObject* CommentsModel::addComment( Attica::Comment comment, GluonObject* parent )
{
    GluonObject* newComment = new GluonObject( comment.id(), parent );
    newComment->setProperty( "Author", comment.user() );
    newComment->setProperty( "Title", comment.subject() );
    newComment->setProperty( "Body", comment.text() );
    newComment->setProperty( "DateTime", comment.date().toString() );
    newComment->setProperty( "Rating", comment.score() );

    foreach( const Attica::Comment& child, comment.children() )
    {
        addComment( child, newComment );
    }

    return newComment;
}


void CommentsModel::loadData()
{
    QDir gluonDir = QDir::home();
    gluonDir.mkpath( ".gluon/" + QString( serviceURI ) );
    gluonDir.cd( ".gluon/" + QString( serviceURI ) );
    QString filename = gluonDir.absoluteFilePath( "comments.gdl" );

    rootNode = GluonCore::GDLHandler::instance()->parseGDL( filename ).at(0);
}

void CommentsModel::saveData()
{
    qDebug() << "Saving Data";
    QDir gluonDir = QDir::home();
    gluonDir.mkpath( ".gluon/" + QString( serviceURI ) );
    gluonDir.cd( ".gluon/" + QString( serviceURI ) );
    QString filename = gluonDir.absoluteFilePath( "comments.gdl" );

    QFile dataFile( filename );
    if( !dataFile.open( QIODevice::WriteOnly ) )
        qDebug() << "Cannot open the comments file";

    QList<const GluonObject*> comments;
    comments.append( rootNode );
    QTextStream dataWriter( &dataFile );
    dataWriter << GluonCore::GDLHandler::instance()->serializeGDL( comments );
{'fraction_non_alphanumeric': 0.14450867052023122, 'fraction_numerical': 0.005090156155637995, 'mean_word_length': 3.1593110871905274, 'pattern_counts': {'":': 0, '<': 108, '<?xml version=': 0, '>': 82, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1340731', 'n_tokens_mistral': 3487, 'n_tokens_neox': 3338, 'n_words': 929}