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