Esempio n. 1
0
KoRdfLocation::KoRdfLocation(QObject *parent, const KoDocumentRdf *rdf, Soprano::QueryResultIterator &it, bool isGeo84)
    : KoRdfSemanticItem(parent, rdf, it)
{
    m_linkSubject = it.binding("geo");
    m_dlong = KoTextRdfCore::optionalBindingAsString(it, "long", "0").toDouble();
    m_dlat  = KoTextRdfCore::optionalBindingAsString(it, "lat",  "0").toDouble();
    m_name  = QString("%1,%2").arg(m_dlong).arg(m_dlat);
    m_joiner = it.binding("joiner");
    m_isGeo84 = isGeo84;
}
Esempio n. 2
0
KoRdfFoaF::KoRdfFoaF(QObject *parent, const KoDocumentRdf *rdf, Soprano::QueryResultIterator &it)
    : KoRdfSemanticItem(parent, rdf, it)
{
    m_uri      = it.binding("person").toString();
    m_name     = it.binding("name").toString();
    m_nick     = KoTextRdfCore::optionalBindingAsString(it, "nick");
    m_homePage = KoTextRdfCore::optionalBindingAsString(it, "homepage");
    m_imageUrl = KoTextRdfCore::optionalBindingAsString(it, "img");
    m_phone    = KoTextRdfCore::optionalBindingAsString(it, "phone");
    kDebug(30015) << "+++xmlid:" << it.binding("xmlid").toString();
}
Esempio n. 3
0
bool Nepomuk::Types::EntityPrivate::load()
{
    const QString query = QString::fromLatin1( "select ?p ?o where { "
                          "graph ?g { <%1> ?p ?o . } . "
                          "{ ?g a %2 . } UNION { ?g a %3 . } . }" )
                          .arg( QString::fromAscii( uri.toEncoded() ),
                                Soprano::Node::resourceToN3( Soprano::Vocabulary::NRL::Ontology() ),
                                Soprano::Node::resourceToN3( Soprano::Vocabulary::NRL::KnowledgeBase() ) );

    Soprano::QueryResultIterator it
        = ResourceManager::instance()->mainModel()->executeQuery( query, Soprano::Query::QueryLanguageSparql );
    while ( it.next() ) {
        QUrl property = it.binding( "p" ).uri();
        Soprano::Node value = it.binding( "o" );

        if ( property == Soprano::Vocabulary::RDFS::label() ) {
            if ( value.language().isEmpty() ) {
                label = value.toString();
            }
            else if( value.language() == KGlobal::locale()->language() ) {
                l10nLabel = value.toString();
            }
        }

        else if ( property == Soprano::Vocabulary::RDFS::comment() ) {
            if ( value.language().isEmpty() ) {
                comment = value.toString();
            }
            else if( value.language() == KGlobal::locale()->language() ) {
                l10nComment = value.toString();
            }
        }

        else if ( property == Soprano::Vocabulary::NAO::hasSymbol() ) {
            icon = KIcon( value.toString() );
        }

        else if ( property == Soprano::Vocabulary::NAO::userVisible() ) {
            userVisible = value.literal().toBool();
        }

        else {
            addProperty( property, value );
        }
    }

    return !it.lastError();
}
KoRdfBasicSemanticItem::KoRdfBasicSemanticItem(QObject *parent, const KoDocumentRdf *rdf, Soprano::QueryResultIterator &it)
    : QObject(parent)
    , m_rdf(rdf)
{
    m_context = it.binding("graph");
    kDebug(30015) << "KoRdfBasicSemanticItem() context:" << m_context.toString();
}
Esempio n. 5
0
void Nepomuk::ResourceCompletion::makeCompletion( const QString& string )
{
    kDebug() << string;

    if ( string.length() > 3 ) {
        Query::AndTerm term;
        term.addSubTerm( Query::LiteralTerm( string + '*' ) );
        if ( d->type.isValid() && d->type != Soprano::Vocabulary::RDFS::Resource() )
            term.addSubTerm( Query::ResourceTypeTerm( d->type ) );
        Query::Query query(term);
        query.setLimit( 10 );

        kDebug() << query.toSparqlQuery();

        Soprano::QueryResultIterator it
            = ResourceManager::instance()->mainModel()->executeQuery( query.toSparqlQuery(),
                                                                      Soprano::Query::QueryLanguageSparql );
        while ( it.next() ) {
            Resource res( it.binding( 0 ).uri() );
            double score = 1.0; //it[1].literal().toDouble();
            kDebug() << "Match for input" << string << res.uri();
            addCompletion( KCompletionItem( res.genericLabel(),
                                            QString( "%1 (%2)" ).arg( res.genericLabel() ).arg( Types::Class( res.type() ).label() ),
                                            res.genericDescription(),
                                            KIcon( res.genericIcon() ),
                                            score,
                                            res.resourceUri() ) );

        }
    }
}
Esempio n. 6
0
void moviemanager::queryTag(QString userTag)
{
    //This module is not working
    //get help from pnh for debugging
    //pnh code
    Nepomuk::Tag myTag;
    myTag.setLabel(userTag);
    QString query
       = QString("select distinct ?r where { ?r %1 %2 . ?r a %3 }")
         .arg( Soprano::Node::resourceToN3(Soprano::Vocabulary::NAO::hasTag()) )
         .arg( Soprano::Node::resourceToN3(myTag.resourceUri()) )
         .arg( Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NFO::Video()) );

    QList<Nepomuk::Resource> myResourceList;
    Soprano::Model *model = Nepomuk::ResourceManager::instance()->mainModel();

    Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparql );
    while( it.next() ) {
        qDebug() << "looping";
       myResourceList << Nepomuk::Resource( it.binding( "r" ).uri() );
    }

    Q_FOREACH (const Nepomuk::Resource& r, myResourceList)
    {
        mainMovieList->addItem(r.property(Nepomuk::Vocabulary::NFO::fileName()).toString());
        //if(r.tags().contains(new Nepomuk:Tag("video"))) newList.append(r)
    }
Esempio n. 7
0
void RemoveDuplicates::loadDuplicates()
{
    Soprano::Model* model = Nepomuk::ResourceManager::instance()->mainModel();
    QString query
       = QString( "select distinct ?u1 where { "
                 "?r1 a %1 . ?r2 a %1. ?r1 %2 ?h. ?r2 %2 ?h. "
                 "?r1 %3 ?u1. ?r2 %3 ?u2. filter(?r1!=?r2) . }order by ?h limit 50")
         .arg( Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NFO::FileDataObject()))
         .arg( Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NFO::hasHash()))
         .arg( Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NIE::url()));

    Soprano::QueryResultIterator it
       = model->executeQuery( query,
                              Soprano::Query::QueryLanguageSparql );
    Nepomuk::File tempRsc;
    while( it.next() ) {
        tempRsc = it.binding("u1").uri() ;
        QString usagecount = QString::number(tempRsc.usageCount());
        QListWidgetItem* item = new QListWidgetItem(tempRsc.genericLabel() + ":: Usage Count:" + usagecount,m_resourceList);
        item->setCheckState(Qt::Unchecked);
        item->setToolTip(tempRsc.url().path());
        qDebug()<<tempRsc.url().path();
    }

}
Esempio n. 8
0
void MainWindow::query()
{
  if (tag->text().isEmpty() && text->toPlainText().isEmpty())
    return;

  static Soprano::Model *model = Nepomuk2::ResourceManager::instance()->mainModel();

  Nepomuk2::Query::ComparisonTerm tag_term;
  Nepomuk2::Query::LiteralTerm text_term;
  if (!tag->text().isEmpty())
    tag_term = Nepomuk2::Query::ComparisonTerm(Soprano::Vocabulary::NAO::hasTag(), Nepomuk2::Query::LiteralTerm(tag->text()));
  if (!text->toPlainText().isEmpty())
    text_term = Nepomuk2::Query::LiteralTerm(text->toPlainText());

  Nepomuk2::Query::Query query(Nepomuk2::Query::AndTerm(tag_term, text_term));
  url->setText(query.toSearchUrl().url());

  Soprano::QueryResultIterator it = model->executeQuery(query.toSparqlQuery(), Soprano::Query::QueryLanguageSparql);
  QString text_result;
  while(it.next())
  {
    for (int i=0; i< it.bindingCount(); ++i)
    {
      text_result += it.binding(i).toString();
      text_result += "<br>";
    }
  }

  result->setText(text_result);
}
Esempio n. 9
0
bool Nepomuk::Types::EntityPrivate::loadAncestors()
{
    const QString query = QString::fromLatin1( "select ?s ?p where { "
                          "graph ?g { ?s ?p <%1> . } . "
                          "{ ?g a %2 . } UNION { ?g a %3 . } . }" )
                          .arg( QString::fromAscii( uri.toEncoded() ),
                                Soprano::Node::resourceToN3( Soprano::Vocabulary::NRL::Ontology() ),
                                Soprano::Node::resourceToN3( Soprano::Vocabulary::NRL::KnowledgeBase() ) );

    Soprano::QueryResultIterator it
        = ResourceManager::instance()->mainModel()->executeQuery( query, Soprano::Query::QueryLanguageSparql );
    while ( it.next() ) {
        addAncestorProperty( it.binding( "s" ).uri(), it.binding( "p" ).uri() );
    }

    return !it.lastError();
}
void KoEventSemanticItemFactory::updateSemanticItems(QList<hKoRdfBasicSemanticItem> &semanticItems, const KoDocumentRdf *rdf, QSharedPointer<Soprano::Model> m)
{
    const QString sparqlQuery = QLatin1String(
        " prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n"
        " prefix cal:  <http://www.w3.org/2002/12/cal/icaltzd#>  \n"
        " select distinct ?graph ?ev ?uid ?dtstart ?dtend ?summary ?location ?geo ?long ?lat \n"
        " where {  \n"
        "  GRAPH ?graph { \n"
        "    ?ev rdf:type cal:Vevent . \n"
        "    ?ev cal:uid      ?uid . \n"
        "    ?ev cal:dtstart  ?dtstart . \n"
        "    ?ev cal:dtend    ?dtend \n"
        "    OPTIONAL { ?ev cal:summary  ?summary  } \n"
        "    OPTIONAL { ?ev cal:location ?location } \n"
        "    OPTIONAL {  \n"
        "               ?ev cal:geo ?geo . \n"
        "               ?geo rdf:first ?lat . \n"
       "               ?geo rdf:rest ?joiner . \n"
       "               ?joiner rdf:first ?long \n"
       "              } \n"
       "    } \n"
       "  } \n");

    Soprano::QueryResultIterator it =
        m->executeQuery(sparqlQuery,
                        Soprano::Query::QueryLanguageSparql);

    QList<hKoRdfBasicSemanticItem> oldSemanticItems = semanticItems;
    // uniqfilter is needed because soprano is not honouring
    // the DISTINCT sparql keyword
    QSet<QString> uniqfilter;
    while (it.next()) {
        const QString name = it.binding("uid").toString();
        if (uniqfilter.contains(name)) {
            continue;
        }
        uniqfilter += name;

        hKoRdfBasicSemanticItem newSemanticItem(new KoRdfCalendarEvent(0, rdf, it));

        const QString newSemanticItemLinkingSubject = newSemanticItem->linkingSubject().toString();
        foreach (hKoRdfBasicSemanticItem semItem, oldSemanticItems) {
            if (newSemanticItemLinkingSubject == semItem->linkingSubject().toString()) {
                oldSemanticItems.removeAll(semItem);
                newSemanticItem = 0;
                break;
            }
        }

        if (newSemanticItem) {
            semanticItems << newSemanticItem;
        }
    }

    foreach (hKoRdfBasicSemanticItem semItem, oldSemanticItems) {
        semanticItems.removeAll(semItem);
    }
KoRdfCalendarEvent::KoRdfCalendarEvent(QObject *parent, const KoDocumentRdf *rdf, Soprano::QueryResultIterator &it)
    : KoRdfSemanticItem(parent, rdf, it)
{
    m_location = KoTextRdfCore::optionalBindingAsString(it, "location");
    m_summary = KoTextRdfCore::optionalBindingAsString(it, "summary");
    m_uid = KoTextRdfCore::optionalBindingAsString(it, "uid");
    m_linkSubject = it.binding("ev");
    // floating time is the default
    m_startTimespec = KSystemTimeZones::local();
    m_endTimespec = KSystemTimeZones::local();
    // check for timezones in the type of each date-time binding.
    m_startTimespec = toKTimeZone(it.binding("dtstart"));
    m_endTimespec = toKTimeZone(it.binding("dtend"));
    m_dtstart = VEventDateTimeToKDateTime(it.binding("dtstart").toString(),
                   m_startTimespec);
    m_dtend = VEventDateTimeToKDateTime(it.binding("dtend").toString(),
                                           m_endTimespec);
    kDebug(30015) << "KoRdfCalendarEvent() start:" << m_dtstart.toString()
        << " end:" << m_dtend.toString();
    kDebug(30015) << "KoRdfCalendarEvent() long:" << KoTextRdfCore::optionalBindingAsString(it, "long")
        << " lat:" << KoTextRdfCore::optionalBindingAsString(it, "lat");
    kDebug(30015) << "KoRdfCalendarEvent() context-direct:" << it.binding("graph").toString();
    kDebug(30015) << "KoRdfCalendarEvent() context():" << context().toString();
    kDebug(30015) << "m_startTimespec.offset:" << m_startTimespec.timeZone().currentOffset();
    kDebug(30015) << "dtstart:" << m_dtstart.date();
    kDebug(30015) << "dtstart:" << m_dtstart.time();
    kDebug(30015) << "dtend:" << m_dtend.date();
    kDebug(30015) << "dtend:" << m_dtend.time();
}
//TODO: next functions look like the ones from CAuSectionRdf. Maybe there is anyway to share code?
void CAuActorSemanticItemFactory::updateSemanticItems(
    QList<hKoRdfBasicSemanticItem> &semanticItems,
    const KoDocumentRdf *rdf,
    QSharedPointer<Soprano::Model> m)
{
    const QString sparqlQuery = CAuActorRdf::QUERY;

    Soprano::QueryResultIterator it = m->executeQuery(
        sparqlQuery,
        Soprano::Query::QueryLanguageSparql
    );

    QList<hKoRdfBasicSemanticItem> oldSemanticItems = semanticItems;

    // uniqfilter is needed because soprano is not honouring
    // the DISTINCT sparql keyword
    QSet<QString> uniqfilter;
    while (it.next()) {

        QString magicid = it.binding("magicid").toString();
        if (uniqfilter.contains(magicid)) {
            continue;
        }
        uniqfilter += magicid;

        hKoRdfBasicSemanticItem newSemanticItem(new CAuActorRdf(0, rdf, it));

        const QString newItemLs = newSemanticItem->linkingSubject().toString();
        foreach (hKoRdfBasicSemanticItem semItem, oldSemanticItems) {
            if (newItemLs == semItem->linkingSubject().toString()) {
                oldSemanticItems.removeAll(semItem);
                newSemanticItem = 0;
                break;
            }
        }

        if (newSemanticItem) {
            semanticItems << newSemanticItem;
        }
    }

    foreach (hKoRdfBasicSemanticItem semItem, oldSemanticItems) {
        semanticItems.removeAll(semItem);
    }
Esempio n. 13
0
void OntologyUpdater::start()
{
    QApplication::processEvents();
    Soprano::Model *m_mainModel;
    bool m_nepomukInited = Utilities::nepomukInited();
    if (m_nepomukInited) {
        m_mainModel = Nepomuk2::ResourceManager::instance()->mainModel();
    } else {
        return;
    }
    
    m_stopUpdate = false;
    
    MediaVocabulary mediaVocabulary;
    
    //Update audio
    QString queryPrefix = QString("PREFIX xesam: <%1> "
                    "PREFIX rdf: <%2> "
                    "PREFIX xls: <%3> "
                    "PREFIX nmm: <http://www.semanticdesktop.org/ontologies/nmm#> "
                    "PREFIX nie: <http://www.semanticdesktop.org/ontologies/2007/01/19/nie#> "
                    "PREFIX nfo: <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#> ")
                    .arg(Soprano::Vocabulary::Xesam::xesamNamespace().toString())
                    .arg(Soprano::Vocabulary::RDF::rdfNamespace().toString())
                    .arg(Soprano::Vocabulary::XMLSchema::xsdNamespace().toString());
    QString queryStr = queryPrefix + QString("SELECT ?r "
                       "WHERE { {?r rdf:type <http://www.semanticdesktop.org/ontologies/nfo#Audio>} "
                       "UNION "
                       "{?r rdf:type <http://www.semanticdesktop.org/ontologies/nmm#MusicPiece>} "
                       "UNION "
                       "{?r rdf:type <http://www.semanticdesktop.org/ontologies/nmm#DigitalRadio>} "
                       "UNION "
                       "{?r rdf:type <http://www.semanticdesktop.org/ontologies/nmm#MusicAlbum>} "
                       "UNION "
                       "{?r rdf:type <%1>} "
                       "UNION "
                       "{?r rdf:type <%2>} "
                       "UNION "
                       "{?r rdf:type <%3>} }")
                       .arg(mediaVocabulary.typeAudio().toString())
                       .arg(mediaVocabulary.typeAudioMusic().toString())
                       .arg(mediaVocabulary.typeMediaStream().toString());
    
    Soprano::QueryResultIterator it = m_mainModel->executeQuery(queryStr, Soprano::Query::QueryLanguageSparql);
    emit infoMessage(i18n("<b>Updating audio types and properties</b><br>0 items updated..."));
    QApplication::processEvents();
    int i = 0;
    while( it.next() && !m_stopUpdate) {
        QApplication::processEvents();
        i++;
        Nepomuk2::Resource resource = Nepomuk2::Resource(it.binding("r").uri());
        //Update types
        QUrl type = QUrl("http://www.semanticdesktop.org/ontologies/nfo#Audio");
        if (resource.hasType(type)) {
            removeType(resource, type);
            if (!resource.hasType(mediaVocabulary.typeAudio())) {
                resource.addType(mediaVocabulary.typeAudio());
            }
        }
        type = QUrl("http://www.semanticdesktop.org/ontologies/nmm#MusicPiece");
        if (resource.hasType(type)) {
            removeType(resource, type);
            if (!resource.hasType(mediaVocabulary.typeAudioMusic())) {
                resource.addType(mediaVocabulary.typeAudioMusic());
            }
            //Update properties
            QUrl property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#musicAlbum");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.musicAlbum(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#trackNumber");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.musicTrackNumber(), value);
            }
        }
        type = QUrl("http://www.semanticdesktop.org/ontologies/nmm#DigitalRadio");
        if (resource.hasType(type)) {
            removeType(resource, type);
            if (!resource.hasType(mediaVocabulary.typeMediaStream())) {
                resource.addType(mediaVocabulary.typeMediaStream());
            }
        }
        type = QUrl("http://www.semanticdesktop.org/ontologies/nmm#MusicAlbum");
        if (resource.hasType(type)) {
            removeType(resource, type);
            if (!resource.hasType(mediaVocabulary.typeMusicAlbum())) {
                resource.addType(mediaVocabulary.typeMusicAlbum());
            }
        }
        
        //Update common properties
        QUrl property = QUrl("http://www.semanticdesktop.org/ontologies/nfo#duration");
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.duration(), value);
        }
        property = Nepomuk2::Vocabulary::NMM::artwork();
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.artwork(), value);
        }
        property = Nepomuk2::Vocabulary::NIE::hasLogicalPart();
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            if (value.toResource().hasType(Nepomuk2::Vocabulary::NFO::Image())) {
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.artwork(), value);
            }
        }
        property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#genre");
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.genre(), value);
        }
        property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#releaseDate");
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.releaseDate(), value);
        }
        property = Soprano::Vocabulary::Xesam::useCount();
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.playCount(), value);
        }
        property = Soprano::Vocabulary::Xesam::lastUsed();
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.lastPlayed(), value);
        }
        emit infoMessage(i18n("<b>Updating audio types and properties</b><br>%1 audio items done...", i));
        QApplication::processEvents();
    }


    //Update video
    queryStr = queryPrefix + QString("SELECT ?r "
                       "WHERE { {?r rdf:type <http://www.semanticdesktop.org/ontologies/nfo#Video>} "
                       "UNION "
                       "{?r rdf:type <http://www.semanticdesktop.org/ontologies/nmm#Movie>} "
                       "UNION "
                       "{?r rdf:type <http://www.semanticdesktop.org/ontologies/nmm#TVShow>} "
                       "UNION "
                       "{?r rdf:type <http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#TVSeries>} "
                       "UNION "
                       "{?r rdf:type <%1>} "
                       "UNION "
                       "{?r rdf:type <%2>} "
                       "UNION "
                       "{?r rdf:type <%3>} }")
                       .arg(mediaVocabulary.typeVideo().toString())
                       .arg(mediaVocabulary.typeVideoMovie().toString())
                       .arg(mediaVocabulary.typeVideoTVShow().toString());

    
    it = m_mainModel->executeQuery(queryStr, Soprano::Query::QueryLanguageSparql);
    emit infoMessage(i18n("<b>Updating audio types and properties</b><br>0 items updated..."));
    QApplication::processEvents();
    i = 0;
    while( it.next() && !m_stopUpdate) {
        QApplication::processEvents();
        i++;
        Nepomuk2::Resource resource = Nepomuk2::Resource(it.binding("r").uri());
        //Update types
        QUrl type = QUrl("http://www.semanticdesktop.org/ontologies/nfo#Video");
        if (resource.hasType(type)) {
            removeType(resource, type);
            if (!resource.hasType(mediaVocabulary.typeVideo())) {
                resource.addType(mediaVocabulary.typeVideo());
            }
        }
        type = QUrl("http://www.semanticdesktop.org/ontologies/nmm#Movie");
        if (resource.hasType(type)) {
            removeType(resource, type);
            if (!resource.hasType(mediaVocabulary.typeVideoMovie())) {
                resource.addType(mediaVocabulary.typeVideoMovie());
            }
            //Update properties
            QUrl property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#synopsis");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoSynopsis(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#writer");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoWriter(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#actor");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoActor(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#director");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoDirector(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#producer");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoProducer(), value);
            }
        }
        type = QUrl("http://www.semanticdesktop.org/ontologies/nmm#TVShow");
        if (resource.hasType(type)) {
            removeType(resource, type);
            if (!resource.hasType(mediaVocabulary.typeVideoTVShow())) {
                resource.addType(mediaVocabulary.typeVideoTVShow());
            }
            //Update properties
            QUrl property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#series");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoSeries(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#synopsis");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoSynopsis(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#season");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoSeason(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#episodeNumber");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoEpisodeNumber(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#writer");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoWriter(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#actor");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoActor(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#director");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoDirector(), value);
            }
            property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#producer");
            if (resource.hasProperty(property)) {
                Nepomuk2::Variant value = resource.property(property);
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.videoProducer(), value);
            }
        }
        type = QUrl("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#TVSeries");
        if (resource.hasType(type)) {
            removeType(resource, type);
            if (!resource.hasType(mediaVocabulary.typeTVSeries())) {
                resource.addType(mediaVocabulary.typeTVSeries());
            }
        }
        
        //Update common properties
        QUrl property = QUrl("http://www.semanticdesktop.org/ontologies/nfo#duration");
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.duration(), value);
        }
        property = Nepomuk2::Vocabulary::NMM::artwork();
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.artwork(), value);
        }
        property = Nepomuk2::Vocabulary::NIE::hasLogicalPart();
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            if (value.toResource().hasType(Nepomuk2::Vocabulary::NFO::Image())) {
                resource.removeProperty(property);
                resource.setProperty(mediaVocabulary.artwork(), value);
            }
        }
        property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#genre");
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.genre(), value);
        }
        property = QUrl("http://www.semanticdesktop.org/ontologies/nmm#releaseDate");
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.releaseDate(), value);
        }
        property = Soprano::Vocabulary::Xesam::useCount();
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.playCount(), value);
        }
        property = Soprano::Vocabulary::Xesam::lastUsed();
        if (resource.hasProperty(property)) {
            Nepomuk2::Variant value = resource.property(property);
            resource.removeProperty(property);
            resource.setProperty(mediaVocabulary.lastPlayed(), value);
        }
        
        emit infoMessage(i18n("<b>Updating video types and properties</b><br>%1 video items done...", i));
        QApplication::processEvents();
    }


    //Fix screwed up properties
    MediaQuery query;
    QStringList bindings;
    bindings.append(mediaVocabulary.mediaResourceBinding());
    bindings.append(mediaVocabulary.ratingBinding());
    query.select(bindings, MediaQuery::Distinct);
    query.startWhere();
    query.addCondition(mediaVocabulary.hasTypeAnyAudio(MediaQuery::Required));
    query.addCondition(mediaVocabulary.hasRating(MediaQuery::Required, 10, MediaQuery::GreaterThan));
    query.endWhere();
    it = m_mainModel->executeQuery(query.query(), Soprano::Query::QueryLanguageSparql);
    emit infoMessage(i18n("<b>Updating audio types and properties</b><br>0 items updated..."));
    QApplication::processEvents();
    i = 0;
    while( it.next() && !m_stopUpdate) {
        QApplication::processEvents();
        i++;
        Nepomuk2::Resource resource = Nepomuk2::Resource(it.binding("r").uri());
        QUrl property = QUrl("http://www.semanticdesktop.org/ontologies/2007/08/15/nao#numericRating");
        if (resource.hasProperty(property)) {
            int rating = resource.property(property).toInt();
            if (rating > 10) {
                resource.removeProperty(property);
            }
        }
        emit infoMessage(i18n("<b>Cleaning up erroneous audio properties</b><br>%1 audio items done...", i));
        QApplication::processEvents();
    }

    MediaQuery query1;
    bindings.clear();
    bindings.append(mediaVocabulary.mediaResourceBinding());
    bindings.append(mediaVocabulary.ratingBinding());
    query1.select(bindings, MediaQuery::Distinct);
    query1.startWhere();
    query1.addCondition(mediaVocabulary.hasTypeAnyVideo(MediaQuery::Required));
    query1.addCondition(mediaVocabulary.hasRating(MediaQuery::Required, 10, MediaQuery::GreaterThan));
    query1.endWhere();
    it = m_mainModel->executeQuery(query.query(), Soprano::Query::QueryLanguageSparql);
    emit infoMessage(i18n("<b>Updating audio types and properties</b><br>0 items updated..."));
    QApplication::processEvents();
    i = 0;
    while( it.next() && !m_stopUpdate) {
        QApplication::processEvents();
        i++;
        Nepomuk2::Resource resource = Nepomuk2::Resource(it.binding("r").uri());
        QUrl property = QUrl("http://www.semanticdesktop.org/ontologies/2007/08/15/nao#numericRating");
        if (resource.hasProperty(property)) {
            int rating = resource.property(property).toInt();
            if (rating > 10) {
                resource.removeProperty(property);
            }
        }
        emit infoMessage(i18n("<b>Cleaning up erroneous video properties</b><br>%1 video items done...", i));
        QApplication::processEvents();
    }

    if (!m_stopUpdate) {
        emit infoMessage(i18n("<b>Update complete.</b>"));
    } else {
        emit infoMessage(i18n("<b>Update stopped.</b>"));
    }
    emit done();
}
void SemanticsListEngine::run()
{
    QThread::setTerminationEnabled(true);
    m_stop = false;

    if (m_updateSourceInfo || m_removeSourceInfo) {
        NepomukListEngine::run();
        return;
    }
    
    //Create media list based on engine argument and filter
    QList<MediaItem> mediaList;
    MediaVocabulary mediaVocabulary = MediaVocabulary();
    
    QString engineArg = m_mediaListProperties.engineArg();
    QString engineFilter = m_mediaListProperties.engineFilter();
    QStringList engineFilterList = m_mediaListProperties.engineFilterList();
    
    //Parse filter
    QString mediaType;
    QString groupByCategoryType;
    QString groupByField;
    QString limitFilter;
    int originalGenreLimit = 0;
    if (engineFilterList.count() != 0) {
        mediaType = engineFilterList.at(0);
        if (engineFilterList.filter("groupBy=").count() != 0) {
            QString groupByFilter = engineFilterList.filter("groupBy=").at(0);
            groupByField = groupByFilter.remove("groupBy=").trimmed();
            if (groupByField == "artist") {
                groupByCategoryType = "Artist";
            } else if (groupByField == "album") {
                groupByCategoryType = "Album";
            } else if (groupByField == "genre") {
                if (mediaType == "audio") {
                    groupByCategoryType = "AudioGenre";
                } else if (mediaType == "video") {
                    groupByCategoryType = "VideoGenre";
                }
            } else if (groupByField == "seriesName") {
                groupByCategoryType = "TV Series";
            } else if (groupByField == "actor") {
                groupByCategoryType = "Actor";
            } else if (groupByField == "director") {
                groupByCategoryType = "Director";
            } else if (groupByField == "tag") {
                if (mediaType == "audio") {
                    groupByCategoryType = "AudioTag";
                } else if (mediaType == "video") {
                    groupByCategoryType = "VideoTag";
                }
            }
        }
        if (engineFilterList.filter("limit=").count() !=0) {
            limitFilter = engineFilterList.filter("limit=").at(0);
            if (groupByField == "genre") {
                originalGenreLimit = m_mediaListProperties.filterValue(limitFilter).trimmed().toInt();
                int originalFilterIndex = engineFilterList.indexOf(limitFilter);
                limitFilter = QString("%1%2%3").arg(m_mediaListProperties.filterField(limitFilter))
                                               .arg(m_mediaListProperties.filterOperator(limitFilter))
                                               .arg(m_mediaListProperties.filterValue(limitFilter).trimmed().toInt()*3);
                engineFilterList.replace(originalFilterIndex, limitFilter);
            }
        }
    }
    
    if (m_nepomukInited) {
        if (engineArg.toLower() == "frequent") {
            mediaList.clear();
            if (mediaType == "audio" || mediaType == "video") {
                MediaQuery query;
                bool ignoreZeros = false;
                if (groupByCategoryType.isEmpty()) {
                    QStringList bindings;
                    bindings.append(mediaVocabulary.mediaResourceBinding());
                    bindings.append(mediaVocabulary.mediaResourceUrlBinding());
                    bindings.append(mediaVocabulary.playCountBinding());
                    query.select(bindings, MediaQuery::Distinct);
                    query.startWhere();
                    if (mediaType == "audio") {
                        query.addCondition(mediaVocabulary.hasTypeAnyAudio(MediaQuery::Required));
                    } else if (mediaType == "video") {
                        query.addCondition(mediaVocabulary.hasTypeAnyVideo(MediaQuery::Required));
                    }
                    query.addLRIFilterConditions(engineFilterList, mediaVocabulary);
                    if (m_mediaListProperties.filterForField("playCount").isEmpty()) {
                        query.addCondition(mediaVocabulary.hasPlayCount(MediaQuery::Required, 0, MediaQuery::GreaterThan));
                        ignoreZeros = true;
                    }
                    query.addCondition(mediaVocabulary.hasLastPlayed(MediaQuery::Optional));
                    query.endWhere();
                    QStringList orderByBindings;
                    QList<MediaQuery::Order> order;
                    orderByBindings.append(mediaVocabulary.playCountBinding());
                    order.append(MediaQuery::Descending);
                    orderByBindings.append(mediaVocabulary.lastPlayedBinding());
                    order.append(MediaQuery::Descending);
                    query.orderBy(orderByBindings, order);
                } else {
                    QStringList bindings;
                    //NOTE:query.addLRIFilterConditions will automatically add 
                    //the groupBy field name to the binding list.
                    QString groupByResourceBinding = MediaVocabulary::resourceBindingForCategory(groupByCategoryType);
                    if (!groupByResourceBinding.isEmpty()) {
                        bindings.append(groupByResourceBinding);
                    }
                    bindings.append(query.fieldBindingDictionary[groupByField]);
                    bindings.append(MediaQuery::aggregateBinding(mediaVocabulary.playCountBinding(), MediaQuery::Sum));
                    query.select(bindings, MediaQuery::Distinct);
                    query.startWhere();
                    MediaQuery subQuery;
                    QStringList subBindings;
                    subBindings.append(mediaVocabulary.playCountBinding());
                    subBindings.append(mediaVocabulary.mediaResourceBinding());
                    subQuery.select(subBindings, MediaQuery::Distinct);
                    subQuery.startWhere();
                    if (mediaType == "audio") {
                        subQuery.addCondition(mediaVocabulary.hasTypeAnyAudio(MediaQuery::Required));
                    } else if (mediaType == "video") {
                        subQuery.addCondition(mediaVocabulary.hasTypeAnyVideo(MediaQuery::Required));
                    }
                    if (m_mediaListProperties.filterForField("playCount").isEmpty()) {
                        subQuery.addCondition(mediaVocabulary.hasPlayCount(MediaQuery::Required, 0, MediaQuery::GreaterThan));
                        ignoreZeros = true;
                    }
                    QStringList subQueryLRIFilterList = engineFilterList;
                    subQueryLRIFilterList.removeAll(limitFilter);
                    subQuery.addLRIFilterConditions(subQueryLRIFilterList, mediaVocabulary);
                    subQuery.endWhere();
                    query.addSubQuery(subQuery);
                    query.endWhere();
                    query.addLRIFilterCondition(limitFilter,  mediaVocabulary);
                    QStringList orderByBindings;
                    QList<MediaQuery::Order> order;
                    orderByBindings.append(QString("%1_sum").arg(mediaVocabulary.playCountBinding()));
                    order.append(MediaQuery::Descending);
                    query.orderBy(orderByBindings, order);
                }

                Soprano::QueryResultIterator it = query.executeSelect(m_mainModel);
                
                //Build media list from results
                while( it.next() ) {
                    if (m_stop) {
                        return;
                    }
                    MediaItem mediaItem;
                    if (groupByCategoryType.isEmpty()) {
                        Nepomuk::Resource res = Nepomuk::Resource(it.binding(mediaVocabulary.mediaResourceBinding()).uri());
                        mediaItem = Utilities::mediaItemFromNepomuk(res, m_mediaListProperties.lri);
                        mediaItem.semanticComment = i18np("played once", "played %1 times", mediaItem.fields["playCount"].toInt());
                    } else {
                        mediaItem = Utilities::categoryMediaItemFromIterator(it, groupByCategoryType, m_mediaListProperties.lri);
                        int playCount = it.binding(QString("%1_sum").arg(mediaVocabulary.playCountBinding())).literal().toInt();
                        mediaItem.semanticComment = i18np("played once", "played %1 times", playCount);
                        mediaItem.fields["playCount"] = playCount;
                    }
                    if (!mediaItem.url.startsWith("nepomuk:/")) {
                        if ((ignoreZeros && mediaItem.fields["playCount"].toInt() > 0) ||
                            !ignoreZeros) {
                            if (groupByCategoryType == "AudioGenre") {
                                addUniqueGenreGroup("playCount", mediaItem, &mediaList, originalGenreLimit);
                            } else {
                                mediaList.append(mediaItem);
                            }
                        }
                    }
                }
                m_mediaListProperties.name = i18n("Frequently Played");
                m_mediaListProperties.type = QString("Sources");
            }
        }
        if (engineArg.toLower() == "recent") {
            mediaList.clear();
            if (!mediaType.isEmpty()) {
                MediaQuery query;
                QStringList bindings;
                if (groupByCategoryType.isEmpty()) {
                    bindings.append(mediaVocabulary.mediaResourceBinding());
                    bindings.append(mediaVocabulary.mediaResourceUrlBinding());
                    bindings.append(mediaVocabulary.lastPlayedBinding());
                } else {
                    //NOTE:query.addLRIFilterConditions will automatically add 
                    //the groupBy field name to the binding list.
                    QString groupByResourceBinding = MediaVocabulary::resourceBindingForCategory(groupByCategoryType);
                    if (!groupByResourceBinding.isEmpty()) {
                        bindings.append(groupByResourceBinding);
                    }
                    bindings.append(MediaQuery::aggregateBinding(mediaVocabulary.lastPlayedBinding(), MediaQuery::Max));
                } 
                query.select(bindings, MediaQuery::Distinct);
                query.startWhere();
                if (mediaType == "audio") {
                    query.addCondition(mediaVocabulary.hasTypeAnyAudio(MediaQuery::Required));
                } else if (mediaType == "video") {
                    query.addCondition(mediaVocabulary.hasTypeAnyVideo(MediaQuery::Required));
                }
                query.addLRIFilterConditions(engineFilterList, mediaVocabulary);
                query.addCondition(mediaVocabulary.hasLastPlayed(MediaQuery::Required));
                query.endWhere();
                QStringList orderByBindings;
                QList<MediaQuery::Order> order;
                if (groupByCategoryType.isEmpty()) {
                    orderByBindings.append(mediaVocabulary.lastPlayedBinding());
                } else {
                    orderByBindings.append(QString("%1_max").arg(mediaVocabulary.lastPlayedBinding()));
                }
                order.append(MediaQuery::Descending);
                query.orderBy(orderByBindings, order);
                
                Soprano::QueryResultIterator it = query.executeSelect(m_mainModel);
                
                //Build media list from results
                while( it.next() ) {
                    if (m_stop) {
                        return;
                    }
                    MediaItem mediaItem;
                    if (groupByCategoryType.isEmpty()) {
                        Nepomuk::Resource res = Nepomuk::Resource(it.binding(mediaVocabulary.mediaResourceBinding()).uri());
                        mediaItem = Utilities::mediaItemFromNepomuk(res, m_mediaListProperties.lri);
                        mediaItem.fields["lastPlayed"] = it.binding(mediaVocabulary.lastPlayedBinding()).literal().toDateTime();
                    } else {
                        mediaItem = Utilities::categoryMediaItemFromIterator(it, groupByCategoryType, m_mediaListProperties.lri);
                        mediaItem.fields["lastPlayed"] = it.binding(QString("%1_max").arg(mediaVocabulary.lastPlayedBinding())).literal().toDateTime();
                    }
                    mediaItem.semanticComment = Utilities::wordsForTimeSince(mediaItem.fields["lastPlayed"].toDateTime());
                    if (!mediaItem.url.startsWith("nepomuk:/")) {
                        if (groupByCategoryType == "AudioGenre") {
                            addUniqueGenreGroup("lastPlayed", mediaItem, &mediaList, originalGenreLimit);
                        } else {
                            mediaList.append(mediaItem);
                        }
                    }
                }
                m_mediaListProperties.name = i18n("Recently Played");
                m_mediaListProperties.type = QString("Sources");
            }
        }
        if (engineArg.toLower() == "highest") {
            mediaList.clear();
            if (!mediaType.isEmpty()) {
                bool ignoreZeros = false;
                MediaQuery query;
                QStringList bindings;
                if (groupByCategoryType.isEmpty()) {
                    bindings.append(mediaVocabulary.mediaResourceBinding());
                    bindings.append(mediaVocabulary.mediaResourceUrlBinding());
                    bindings.append(mediaVocabulary.ratingBinding());
                } else {
                    //NOTE:query.addLRIFilterConditions will automatically add 
                    //the groupBy field name to the binding list.
                    QString groupByResourceBinding = MediaVocabulary::resourceBindingForCategory(groupByCategoryType);
                    if (!groupByResourceBinding.isEmpty()) {
                        bindings.append(groupByResourceBinding);
                    }
                    bindings.append(MediaQuery::aggregateBinding(mediaVocabulary.ratingBinding(), MediaQuery::Sum));
                    bindings.append(MediaQuery::aggregateBinding(mediaVocabulary.ratingBinding(), MediaQuery::Count));
                } 
                query.select(bindings, MediaQuery::Distinct);
                query.startWhere();
                if (mediaType == "audio") {
                    query.addCondition(mediaVocabulary.hasTypeAnyAudio(MediaQuery::Required));
                } else if (mediaType == "video") {
                    query.addCondition(mediaVocabulary.hasTypeAnyVideo(MediaQuery::Required));
                }
                query.addLRIFilterConditions(engineFilterList, mediaVocabulary);
                if (m_mediaListProperties.filterForField("rating").isEmpty()) {
                    query.addCondition(mediaVocabulary.hasRating(MediaQuery::Required, 0, MediaQuery::GreaterThan));
                    ignoreZeros = true;
                }
                query.addCondition(mediaVocabulary.hasPlayCount(MediaQuery::Optional));
                query.endWhere();
                QStringList orderByBindings;
                QList<MediaQuery::Order> order;
                if (groupByCategoryType.isEmpty()) {
                    orderByBindings.append(mediaVocabulary.ratingBinding());
                    order.append(MediaQuery::Descending);
                    orderByBindings.append(mediaVocabulary.playCountBinding());
                    order.append(MediaQuery::Descending);
                } else {
                    orderByBindings.append(QString("%1_sum").arg(mediaVocabulary.ratingBinding()));
                    order.append(MediaQuery::Descending);
                    order.append(MediaQuery::Descending);
                }
                query.orderBy(orderByBindings, order);
                
                Soprano::QueryResultIterator it = query.executeSelect(m_mainModel);
                
                //Build media list from results
                while( it.next() ) {
                    if (m_stop) {
                        return;
                    }
                    MediaItem mediaItem;
                    if (groupByCategoryType.isEmpty()) {
                        Nepomuk::Resource res = Nepomuk::Resource(it.binding(mediaVocabulary.mediaResourceBinding()).uri());
                        mediaItem = Utilities::mediaItemFromNepomuk(res, m_mediaListProperties.lri);
                    } else {
                        mediaItem = Utilities::categoryMediaItemFromIterator(it, groupByCategoryType, m_mediaListProperties.lri);
                        int sum = it.binding(QString("%1_sum").arg(mediaVocabulary.ratingBinding())).literal().toInt();
                        int count = it.binding(QString("%1_count").arg(mediaVocabulary.ratingBinding())).literal().toInt();
                        int rating = sum/count;
                        mediaItem.fields["rating"] = rating;
                    }
                    if (!mediaItem.url.startsWith("nepomuk:/")) {
                        if ((ignoreZeros && mediaItem.fields["rating"].toInt() > 0) ||
                            !ignoreZeros) {
                            if (groupByCategoryType == "AudioGenre") {
                                addUniqueGenreGroup("rating", mediaItem, &mediaList, originalGenreLimit);
                            } else {
                                mediaList.append(mediaItem);
                            }
                        }
                    }
                }
                m_mediaListProperties.name = i18n("Highest Rated");
                m_mediaListProperties.type = QString("Sources");
            }
        }
        if (engineArg.toLower() == "recentlyadded") {
            mediaList.clear();
            if (!mediaType.isEmpty()) {
                MediaQuery query;
                QStringList bindings;
                bindings.append(mediaVocabulary.mediaResourceBinding());
                bindings.append("added");
                query.select(bindings, MediaQuery::Distinct);
                query.startWhere();
                query.addCondition("graph ?g { ");
                if (mediaType == "audio") {
                    query.addCondition(mediaVocabulary.hasTypeAnyAudio(MediaQuery::Required));
                } else if (mediaType == "video") {
                    query.addCondition(mediaVocabulary.hasTypeAnyVideo(MediaQuery::Required));
                }
                query.addLRIFilterConditions(engineFilterList, mediaVocabulary);
                query.addCondition("} ");
                query.addCondition("?g nao:created ?added . ");
                query.endWhere();
                QStringList orderByBindings;
                QList<MediaQuery::Order> order;
                orderByBindings.append("added");
                order.append(MediaQuery::Descending);
                query.orderBy(orderByBindings, order);

                Soprano::QueryResultIterator it = query.executeSelect(m_mainModel);

                //Build media list from results
                while( it.next() ) {
                    if (m_stop) {
                        return;
                    }
                    MediaItem mediaItem;
                    QDateTime added = it.binding("added").literal().toDateTime();
                    Nepomuk::Resource res = Nepomuk::Resource(it.binding(mediaVocabulary.mediaResourceBinding()).uri());
                    mediaItem = Utilities::mediaItemFromNepomuk(res, m_mediaListProperties.lri);
                    mediaItem.semanticComment = i18nc("for example, added 3 days ago", "added %1", Utilities::wordsForTimeSince(added));
                    if (!mediaItem.url.startsWith("nepomuk:/")) {
                        mediaList.append(mediaItem);
                    }
                }
                m_mediaListProperties.name = i18n("Recently Added");
                m_mediaListProperties.type = QString("Sources");
            }
        }
    }
    
    emit results(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
    
    //Check if MediaItems in mediaList exist
    QList<MediaItem> mediaItems = Utilities::mediaItemsDontExist(mediaList);
    if (mediaItems.count() > 0) {
        emit updateMediaItems(mediaItems);
    } else {
        //Get any remaining metadata for mediaItems
        if (mediaType == "video") {
            for (int i = 0; i < mediaList.count(); i++) {
                if (m_stop) {
                    return;
                }
                MediaItem mediaItem = Utilities::completeMediaItem(mediaList.at(i));
                emit updateMediaItem(mediaItem);
            }
        }
        
    }
    
    m_requestSignature = QString();
    m_subRequestSignature = QString();
}