annotate utilities/composer/composer.cpp @ 22:9abc896958cf classical-rdf

* Fixes for static initialiser ordering (etc)
author Chris Cannam
date Thu, 25 Feb 2010 22:34:11 +0000
parents ea477e4cc75c
children 2b574b88778e
rev   line source
Chris@20 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@20 2
Chris@20 3 #include "Objects.h"
Chris@20 4 #include "TypeRegistrar.h"
Chris@20 5
Chris@20 6 #include <dataquay/BasicStore.h>
Chris@20 7 #include <dataquay/RDFException.h>
Chris@20 8 #include <dataquay/objectmapper/ObjectMapper.h>
Chris@20 9 #include <dataquay/Debug.h>
Chris@20 10
Chris@20 11 #include <QMultiMap>
Chris@20 12 #include <QFileInfo>
Chris@20 13
Chris@20 14 #include <iostream>
Chris@20 15
Chris@20 16 using namespace Dataquay;
Chris@20 17 using namespace ClassicalData;
Chris@20 18 using namespace std;
Chris@20 19
Chris@20 20 ostream &operator<<(ostream &target, const QString &str)
Chris@20 21 {
Chris@20 22 return target << str.toLocal8Bit().data();
Chris@20 23 }
Chris@20 24
Chris@20 25 ostream &operator<<(ostream &target, const QUrl &u)
Chris@20 26 {
Chris@20 27 return target << "<" << u.toString() << ">";
Chris@20 28 }
Chris@20 29
Chris@20 30
Chris@20 31 bool
Chris@20 32 load(BasicStore *store, QString fileName)
Chris@20 33 {
Chris@20 34 QUrl url = QUrl::fromLocalFile(fileName);
Chris@20 35
Chris@20 36 cerr << "Importing from URL " << url << " ...";
Chris@20 37 try {
Chris@21 38 store->import(url, BasicStore::ImportPermitDuplicates, "ntriples");
Chris@20 39 } catch (RDFException e) {
Chris@20 40 cerr << "failed" << endl;
Chris@20 41 cerr << "Import failed: " << e.what() << endl;
Chris@20 42 return false;
Chris@20 43 }
Chris@20 44
Chris@20 45 cerr << " done" << endl;
Chris@20 46 return true;
Chris@20 47 }
Chris@20 48
Chris@20 49 void
Chris@20 50 usage(char *name)
Chris@20 51 {
Chris@20 52 int s = 0;
Chris@20 53 for (int i = 0; name[i]; ++i) if (name[i] == '/') s = i + 1;
Chris@20 54 name = name + s;
Chris@20 55 cerr << "Usage: " << name << " <input-rdf-file> list" << endl;
Chris@20 56 cerr << "Usage: " << name << " <input-rdf-file> list-uris" << endl;
Chris@20 57 cerr << "Usage: " << name << " <input-rdf-file> show <uri> [<uri> ...]" << endl;
Chris@20 58 cerr << "Usage: " << name << " <input-rdf-file> search <text>" << endl;
Chris@20 59 cerr << "Usage: " << name << " <input-rdf-file> match <text>" << endl;
Chris@20 60 exit(-1);
Chris@20 61 }
Chris@20 62
Chris@20 63 static QList<Composer *> allComposers;
Chris@20 64 static QMap<Composer *, QSet<Work *> > worksMap;
Chris@20 65
Chris@20 66 void
Chris@20 67 show(Composer *c)
Chris@20 68 {
Chris@20 69 cout << c->property("uri").value<Uri>() << endl;
Chris@20 70 cout << c->getSortName(true);
Chris@20 71 QString d = c->getDisplayDates();
Chris@20 72 if (d != "") cout << " (" << d << ")";
Chris@20 73 if (!c->nationality().empty() || c->period() != "") {
Chris@20 74 cout << " [";
Chris@20 75 bool first = true;
Chris@20 76 foreach (QString n, c->nationality()) {
Chris@20 77 if (!first) cout << "/";
Chris@20 78 cout << n;
Chris@20 79 first = false;
Chris@20 80 }
Chris@20 81 if (c->period() != "") {
Chris@20 82 if (!first) cout << ", ";
Chris@20 83 cout << c->period();
Chris@20 84 }
Chris@20 85 cout << "]";
Chris@20 86 }
Chris@20 87 if (c->gender() != "") {
Chris@20 88 cout << " *" << c->gender();
Chris@20 89 }
Chris@20 90 if (!worksMap[c].empty()) {
Chris@20 91 cout << " [" << worksMap[c].size() << " work(s)]";
Chris@20 92 }
Chris@20 93 cout << endl;
Chris@20 94 foreach (QString a, c->aliases()) {
Chris@20 95 cout << " - " << a << endl;
Chris@20 96 }
Chris@20 97 if (c->remarks() != "") {
Chris@20 98 cout << " " << c->remarks() << endl;
Chris@20 99 }
Chris@20 100 foreach (Document *d, c->pages()) {
Chris@20 101 cout << " " << d->siteName() << " -> " << d->uri() << endl;
Chris@20 102 }
Chris@20 103 }
Chris@20 104
Chris@20 105 void
Chris@20 106 showBrief(Composer *c)
Chris@20 107 {
Chris@20 108 cout << c->property("uri").value<Uri>() << endl;
Chris@20 109 cout << c->getSortName(false);
Chris@20 110 QString d = c->getDisplayDates();
Chris@20 111 if (d != "") cout << " (" << d << ")";
Chris@20 112 if (!c->nationality().empty() || c->period() != "") {
Chris@20 113 cout << " [";
Chris@20 114 bool first = true;
Chris@20 115 foreach (QString n, c->nationality()) {
Chris@20 116 if (!first) cout << "/";
Chris@20 117 cout << n;
Chris@20 118 first = false;
Chris@20 119 }
Chris@20 120 if (c->period() != "") {
Chris@20 121 if (!first) cout << " ";
Chris@20 122 cout << c->period();
Chris@20 123 }
Chris@20 124 cout << "]";
Chris@20 125 }
Chris@20 126 if (c->gender() != "") {
Chris@20 127 cout << " *" << c->gender();
Chris@20 128 }
Chris@20 129 if (!worksMap[c].empty()) {
Chris@20 130 cout << " [" << worksMap[c].size() << " work(s)]";
Chris@20 131 }
Chris@20 132 cout << endl;
Chris@20 133 }
Chris@20 134
Chris@20 135 void
Chris@20 136 listBrief(QList<Composer *> composers)
Chris@20 137 {
Chris@20 138 QMultiMap<QString, Composer *> sorted;
Chris@20 139 foreach (Composer *c, composers) {
Chris@20 140 sorted.insert(c->getSortName(false), c);
Chris@20 141 }
Chris@20 142 foreach (Composer *c, sorted) {
Chris@20 143 showBrief(c);
Chris@20 144 }
Chris@20 145 }
Chris@20 146
Chris@20 147 void
Chris@20 148 listUris(QList<Composer *> composers)
Chris@20 149 {
Chris@20 150 QMultiMap<Uri, Composer *> sorted;
Chris@20 151 foreach (Composer *c, composers) {
Chris@20 152 sorted.insert(c->property("uri").value<Uri>(), c);
Chris@20 153 }
Chris@20 154 foreach (Uri uri, sorted.keys()) {
Chris@20 155 cout << uri << endl;
Chris@20 156 }
Chris@20 157 }
Chris@20 158
Chris@20 159 void
Chris@20 160 showSearchResults(QMultiMap<float, Composer *> matches, int count)
Chris@20 161 {
Chris@20 162 int n = 0;
Chris@20 163 for (QMultiMap<float, Composer *>::const_iterator i = matches.end();
Chris@20 164 i != matches.begin(); ) {
Chris@20 165 --i;
Chris@20 166 if (i.key() <= 0) continue;
Chris@20 167 cout << endl;
Chris@20 168 if (n == 0) {
Chris@20 169 cout << "Best match:" << endl;
Chris@20 170 } else if (n == 1) {
Chris@20 171 cout << "Other candidate(s):" << endl;
Chris@20 172 }
Chris@20 173 cout << "[" << i.key() << "] ";
Chris@20 174 if (n == 0) show(i.value());
Chris@20 175 else showBrief(i.value());
Chris@20 176 if (++n > count) break;
Chris@20 177 }
Chris@20 178 if (n == 0) cout << "No matches" << endl;
Chris@20 179 cout << endl;
Chris@20 180 }
Chris@20 181
Chris@20 182 void
Chris@20 183 search(QString typing)
Chris@20 184 {
Chris@20 185 cout << "Searching for: " << typing << endl;
Chris@20 186 QMultiMap<float, Composer *> matches;
Chris@20 187 foreach (Composer *c, allComposers) {
Chris@20 188 float value = c->matchTyping(typing);
Chris@20 189 matches.insert(value, c);
Chris@20 190 }
Chris@20 191 showSearchResults(matches, 5);
Chris@20 192 }
Chris@20 193
Chris@20 194 void
Chris@20 195 match(QString text)
Chris@20 196 {
Chris@20 197 cout << "Matching: " << text << endl;
Chris@20 198 QMultiMap<float, Composer *> matches;
Chris@20 199 QRegExp sre("[\\., -]+");
Chris@20 200 QStringList elements = text.toLower().split(sre, QString::SkipEmptyParts);
Chris@20 201 foreach (Composer *c, allComposers) {
Chris@20 202 float value = c->matchFuzzyName(elements);
Chris@20 203 matches.insert(value, c);
Chris@20 204 }
Chris@20 205 showSearchResults(matches, 5);
Chris@20 206 }
Chris@20 207
Chris@20 208 void
Chris@20 209 showWildcard(QString text)
Chris@20 210 {
Chris@20 211 cout << "Showing URI or wildcard: " << text << endl;
Chris@20 212 QRegExp re(text, Qt::CaseInsensitive, QRegExp::Wildcard);
Chris@20 213 foreach (Composer *c, allComposers) {
Chris@20 214 if (re.exactMatch(c->property("uri").value<Uri>().toString())) {
Chris@20 215 cout << endl;
Chris@20 216 show(c);
Chris@20 217 }
Chris@20 218 }
Chris@20 219 cout << endl;
Chris@20 220 }
Chris@20 221
Chris@20 222 int
Chris@20 223 main(int argc, char **argv)
Chris@20 224 {
Chris@20 225 if (argc < 3) usage(argv[0]);
Chris@20 226 QString inFileName = argv[1];
Chris@20 227 QString command = argv[2];
Chris@20 228 QStringList args;
Chris@20 229 for (int i = 3; i < argc; ++i) {
Chris@20 230 args.push_back(argv[i]);
Chris@20 231 }
Chris@20 232
Chris@20 233 BasicStore *store = new BasicStore();
Chris@20 234 store->setBaseUri(Uri("http://dbtune.org/classical/resource/"));
Chris@20 235 ObjectMapper *mapper = new ObjectMapper(store);
Chris@20 236
Chris@22 237 TypeRegistrar::registerTypes();
Chris@20 238 TypeRegistrar::addMappings(store, mapper);
Chris@20 239
Chris@20 240 if (!load(store, inFileName)) {
Chris@20 241 cerr << "Failed to load data source" << endl;
Chris@20 242 return 1;
Chris@20 243 }
Chris@20 244
Chris@20 245 cerr << "Imported RDF data, mapping to objects...";
Chris@20 246 QObject *root = mapper->loadAllObjects(0);
Chris@20 247 cerr << " done" << endl;
Chris@20 248
Chris@20 249 delete mapper;
Chris@20 250 delete store;
Chris@20 251
Chris@20 252 allComposers = root->findChildren<Composer *>();
Chris@20 253
Chris@20 254 QList<Work *> works = root->findChildren<Work *>();
Chris@20 255 foreach (Work *w, works) {
Chris@20 256 Composition *c = w->composition();
Chris@20 257 if (c) {
Chris@20 258 Composer *cp = c->composer();
Chris@20 259 if (cp) worksMap[cp].insert(w);
Chris@20 260 }
Chris@20 261 }
Chris@20 262
Chris@20 263 if (command == "list") {
Chris@22 264 if (!args.empty()) usage(argv[0]);
Chris@20 265 listBrief(allComposers);
Chris@20 266 } else if (command == "list-uris") {
Chris@22 267 if (!args.empty()) usage(argv[0]);
Chris@20 268 listUris(allComposers);
Chris@20 269 } else {
Chris@20 270 if (args.empty()) usage(argv[0]);
Chris@20 271 if (command == "show") {
Chris@20 272 foreach (QString s, args) {
Chris@20 273 if (!s.contains('/') && !s.contains('*')) {
Chris@20 274 s = "*" + s + "*";
Chris@20 275 }
Chris@20 276 showWildcard(s);
Chris@20 277 }
Chris@20 278 } else if (command == "search") {
Chris@20 279 foreach (QString s, args) {
Chris@20 280 search(s);
Chris@20 281 }
Chris@20 282 } else if (command == "match") {
Chris@20 283 foreach (QString s, args) {
Chris@20 284 match(s);
Chris@20 285 }
Chris@20 286 }
Chris@20 287 }
Chris@20 288
Chris@20 289 }
Chris@20 290