Mercurial > hg > classical
diff utilities/composer/composer.cpp @ 20:c4cb65c436ef classical-rdf
* Simple query utility
author | Chris Cannam |
---|---|
date | Tue, 23 Feb 2010 16:37:49 +0000 |
parents | |
children | ea477e4cc75c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/composer/composer.cpp Tue Feb 23 16:37:49 2010 +0000 @@ -0,0 +1,287 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#include "Objects.h" +#include "TypeRegistrar.h" + +#include <dataquay/BasicStore.h> +#include <dataquay/RDFException.h> +#include <dataquay/objectmapper/ObjectMapper.h> +#include <dataquay/Debug.h> + +#include <QMultiMap> +#include <QFileInfo> + +#include <iostream> + +using namespace Dataquay; +using namespace ClassicalData; +using namespace std; + +ostream &operator<<(ostream &target, const QString &str) +{ + return target << str.toLocal8Bit().data(); +} + +ostream &operator<<(ostream &target, const QUrl &u) +{ + return target << "<" << u.toString() << ">"; +} + + +bool +load(BasicStore *store, QString fileName) +{ + QUrl url = QUrl::fromLocalFile(fileName); + + cerr << "Importing from URL " << url << " ..."; + try { + store->import(url, BasicStore::ImportIgnoreDuplicates, "ntriples"); + } catch (RDFException e) { + cerr << "failed" << endl; + cerr << "Import failed: " << e.what() << endl; + return false; + } + + cerr << " done" << endl; + return true; +} + +void +usage(char *name) +{ + int s = 0; + for (int i = 0; name[i]; ++i) if (name[i] == '/') s = i + 1; + name = name + s; + cerr << "Usage: " << name << " <input-rdf-file> list" << endl; + cerr << "Usage: " << name << " <input-rdf-file> list-uris" << endl; + cerr << "Usage: " << name << " <input-rdf-file> show <uri> [<uri> ...]" << endl; + cerr << "Usage: " << name << " <input-rdf-file> search <text>" << endl; + cerr << "Usage: " << name << " <input-rdf-file> match <text>" << endl; + exit(-1); +} + +static QList<Composer *> allComposers; +static QMap<Composer *, QSet<Work *> > worksMap; + +void +show(Composer *c) +{ + cout << c->property("uri").value<Uri>() << endl; + cout << c->getSortName(true); + QString d = c->getDisplayDates(); + if (d != "") cout << " (" << d << ")"; + if (!c->nationality().empty() || c->period() != "") { + cout << " ["; + bool first = true; + foreach (QString n, c->nationality()) { + if (!first) cout << "/"; + cout << n; + first = false; + } + if (c->period() != "") { + if (!first) cout << ", "; + cout << c->period(); + } + cout << "]"; + } + if (c->gender() != "") { + cout << " *" << c->gender(); + } + if (!worksMap[c].empty()) { + cout << " [" << worksMap[c].size() << " work(s)]"; + } + cout << endl; + foreach (QString a, c->aliases()) { + cout << " - " << a << endl; + } + if (c->remarks() != "") { + cout << " " << c->remarks() << endl; + } + foreach (Document *d, c->pages()) { + cout << " " << d->siteName() << " -> " << d->uri() << endl; + } +} + +void +showBrief(Composer *c) +{ + cout << c->property("uri").value<Uri>() << endl; + cout << c->getSortName(false); + QString d = c->getDisplayDates(); + if (d != "") cout << " (" << d << ")"; + if (!c->nationality().empty() || c->period() != "") { + cout << " ["; + bool first = true; + foreach (QString n, c->nationality()) { + if (!first) cout << "/"; + cout << n; + first = false; + } + if (c->period() != "") { + if (!first) cout << " "; + cout << c->period(); + } + cout << "]"; + } + if (c->gender() != "") { + cout << " *" << c->gender(); + } + if (!worksMap[c].empty()) { + cout << " [" << worksMap[c].size() << " work(s)]"; + } + cout << endl; +} + +void +listBrief(QList<Composer *> composers) +{ + QMultiMap<QString, Composer *> sorted; + foreach (Composer *c, composers) { + sorted.insert(c->getSortName(false), c); + } + foreach (Composer *c, sorted) { + showBrief(c); + } +} + +void +listUris(QList<Composer *> composers) +{ + QMultiMap<Uri, Composer *> sorted; + foreach (Composer *c, composers) { + sorted.insert(c->property("uri").value<Uri>(), c); + } + foreach (Uri uri, sorted.keys()) { + cout << uri << endl; + } +} + +void +showSearchResults(QMultiMap<float, Composer *> matches, int count) +{ + int n = 0; + for (QMultiMap<float, Composer *>::const_iterator i = matches.end(); + i != matches.begin(); ) { + --i; + if (i.key() <= 0) continue; + cout << endl; + if (n == 0) { + cout << "Best match:" << endl; + } else if (n == 1) { + cout << "Other candidate(s):" << endl; + } + cout << "[" << i.key() << "] "; + if (n == 0) show(i.value()); + else showBrief(i.value()); + if (++n > count) break; + } + if (n == 0) cout << "No matches" << endl; + cout << endl; +} + +void +search(QString typing) +{ + cout << "Searching for: " << typing << endl; + QMultiMap<float, Composer *> matches; + foreach (Composer *c, allComposers) { + float value = c->matchTyping(typing); + matches.insert(value, c); + } + showSearchResults(matches, 5); +} + +void +match(QString text) +{ + cout << "Matching: " << text << endl; + QMultiMap<float, Composer *> matches; + QRegExp sre("[\\., -]+"); + QStringList elements = text.toLower().split(sre, QString::SkipEmptyParts); + foreach (Composer *c, allComposers) { + float value = c->matchFuzzyName(elements); + matches.insert(value, c); + } + showSearchResults(matches, 5); +} + +void +showWildcard(QString text) +{ + cout << "Showing URI or wildcard: " << text << endl; + QRegExp re(text, Qt::CaseInsensitive, QRegExp::Wildcard); + foreach (Composer *c, allComposers) { + if (re.exactMatch(c->property("uri").value<Uri>().toString())) { + cout << endl; + show(c); + } + } + cout << endl; +} + +int +main(int argc, char **argv) +{ + if (argc < 3) usage(argv[0]); + QString inFileName = argv[1]; + QString command = argv[2]; + QStringList args; + for (int i = 3; i < argc; ++i) { + args.push_back(argv[i]); + } + + BasicStore *store = new BasicStore(); + store->setBaseUri(Uri("http://dbtune.org/classical/resource/")); + ObjectMapper *mapper = new ObjectMapper(store); + + TypeRegistrar::addMappings(store, mapper); + + if (!load(store, inFileName)) { + cerr << "Failed to load data source" << endl; + return 1; + } + + cerr << "Imported RDF data, mapping to objects..."; + QObject *root = mapper->loadAllObjects(0); + cerr << " done" << endl; + + delete mapper; + delete store; + + allComposers = root->findChildren<Composer *>(); + + QList<Work *> works = root->findChildren<Work *>(); + foreach (Work *w, works) { + Composition *c = w->composition(); + if (c) { + Composer *cp = c->composer(); + if (cp) worksMap[cp].insert(w); + } + } + + if (command == "list") { + listBrief(allComposers); + } else if (command == "list-uris") { + listUris(allComposers); + } else { + if (args.empty()) usage(argv[0]); + if (command == "show") { + foreach (QString s, args) { + if (!s.contains('/') && !s.contains('*')) { + s = "*" + s + "*"; + } + showWildcard(s); + } + } else if (command == "search") { + foreach (QString s, args) { + search(s); + } + } else if (command == "match") { + foreach (QString s, args) { + match(s); + } + } + } + +} +