/*************************************************************************** copyright : (C) 2005-2006 by Robby Stephenson email : robby@periapsis.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of version 2 of the GNU General Public License as * * published by the Free Software Foundation; * * * ***************************************************************************/ #include "gcfilmsimporter.h" #include "../collections/videocollection.h" #include "../latin1literal.h" #include "../tellico_utils.h" #include "../imagefactory.h" #include "../borrower.h" #include "../progressmanager.h" #include "xslthandler.h" #include "tellicoimporter.h" #include #include #include #define CHECKLIMITS(n) if(values.count() <= n) continue using Tellico::Import::GCfilmsImporter; GCfilmsImporter::GCfilmsImporter(const KURL& url_) : TextImporter(url_), m_coll(0), m_cancelled(false) { } bool GCfilmsImporter::canImport(int type) const { return type == Data::Collection::Video || type == Data::Collection::Book || type == Data::Collection::Album || type == Data::Collection::Game || type == Data::Collection::Wine || type == Data::Collection::Coin; } Tellico::Data::CollPtr GCfilmsImporter::collection() { if(m_coll) { return m_coll; } ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true); item.setTotalSteps(100); connect(&item, TQT_SIGNAL(signalCancelled(ProgressItem*)), TQT_SLOT(slotCancel())); ProgressItem::Done done(this); TQString str = text(); TQTextIStream t(&str); TQString line = t.readLine(); if(line.startsWith(TQString::tqfromLatin1("GCfilms"))) { readGCfilms(str); } else { // need to reparse the string if it's in utf-8 if(line.lower().find(TQString::tqfromLatin1("utf-8")) > 0) { str = TQString::fromUtf8(str.local8Bit()); } readGCstar(str); } return m_coll; } void GCfilmsImporter::readGCfilms(const TQString& text_) { m_coll = new Data::VideoCollection(true); bool hasURL = false; if(m_coll->hasField(TQString::tqfromLatin1("url"))) { hasURL = m_coll->fieldByName(TQString::tqfromLatin1("url"))->type() == Data::Field::URL; } else { Data::FieldPtr field = new Data::Field(TQString::tqfromLatin1("url"), i18n("URL"), Data::Field::URL); field->setCategory(i18n("General")); m_coll->addField(field); hasURL = true; } bool convertUTF8 = false; TQMap borrowers; const TQRegExp rx(TQString::tqfromLatin1("\\s*,\\s*")); TQRegExp year(TQString::tqfromLatin1("\\d{4}")); TQRegExp runTimeHr(TQString::tqfromLatin1("(\\d+)\\s?hr?")); TQRegExp runTimeMin(TQString::tqfromLatin1("(\\d+)\\s?mi?n?")); bool gotFirstLine = false; uint total = 0; TQTextIStream t(&text_); const uint length = text_.length(); const uint stepSize = TQMAX(s_stepSize, length/100); const bool showProgress = options() & ImportProgress; ProgressManager::self()->setTotalSteps(this, length); uint j = 0; for(TQString line = t.readLine(); !m_cancelled && !line.isNull(); line = t.readLine(), j += line.length()) { // string was wrongly converted TQStringList values = TQStringList::split('|', (convertUTF8 ? TQString::fromUtf8(line.local8Bit()) : line), true); if(values.empty()) { continue; } if(!gotFirstLine) { if(values[0] != Latin1Literal("GCfilms")) { setStatusMessage(i18n("The file is not a valid GCstar data file.")); m_coll = 0; return; } total = Tellico::toUInt(values[1], 0)+1; // number of lines really if(values.size() > 2 && values[2] == Latin1Literal("UTF8")) { // if locale encoding isn't utf8, need to do a reconversion TQTextCodec* codec = TQTextCodec::codecForLocale(); if(TQCString(codec->name()).find("utf-8", 0, false) == -1) { convertUTF8 = true; } } gotFirstLine = true; continue; } bool ok; Data::EntryPtr entry = new Data::Entry(m_coll); entry->setId(Tellico::toUInt(values[0], &ok)); entry->setField(TQString::tqfromLatin1("title"), values[1]); if(year.search(values[2]) > -1) { entry->setField(TQString::tqfromLatin1("year"), year.cap()); } uint time = 0; if(runTimeHr.search(values[3]) > -1) { time = Tellico::toUInt(runTimeHr.cap(1), &ok) * 60; } if(runTimeMin.search(values[3]) > -1) { time += Tellico::toUInt(runTimeMin.cap(1), &ok); } if(time > 0) { entry->setField(TQString::tqfromLatin1("running-time"), TQString::number(time)); } entry->setField(TQString::tqfromLatin1("director"), splitJoin(rx, values[4])); entry->setField(TQString::tqfromLatin1("nationality"), splitJoin(rx, values[5])); entry->setField(TQString::tqfromLatin1("genre"), splitJoin(rx, values[6])); KURL u = KURL::fromPathOrURL(values[7]); if(!u.isEmpty()) { TQString id = ImageFactory::addImage(u, true /* quiet */); if(!id.isEmpty()) { entry->setField(TQString::tqfromLatin1("cover"), id); } } entry->setField(TQString::tqfromLatin1("cast"), splitJoin(rx, values[8])); // values[9] is the original title entry->setField(TQString::tqfromLatin1("plot"), values[10]); if(hasURL) { entry->setField(TQString::tqfromLatin1("url"), values[11]); } CHECKLIMITS(12); // values[12] is whether the film has been viewed or not entry->setField(TQString::tqfromLatin1("medium"), values[13]); // values[14] is number of DVDS? // values[15] is place? // gcfilms's ratings go 0-10, just divide by two entry->setField(TQString::tqfromLatin1("rating"), TQString::number(int(Tellico::toUInt(values[16], &ok)/2))); entry->setField(TQString::tqfromLatin1("comments"), values[17]); CHECKLIMITS(18); TQStringList s = TQStringList::split(',', values[18]); TQStringList tracks, langs; for(TQStringList::ConstIterator it = s.begin(); it != s.end(); ++it) { langs << (*it).section(';', 0, 0); tracks << (*it).section(';', 1, 1); } entry->setField(TQString::tqfromLatin1("language"), langs.join(TQString::tqfromLatin1("; "))); entry->setField(TQString::tqfromLatin1("audio-track"), tracks.join(TQString::tqfromLatin1("; "))); entry->setField(TQString::tqfromLatin1("subtitle"), splitJoin(rx, values[19])); CHECKLIMITS(20); // values[20] is borrower name if(!values[20].isEmpty()) { TQString tmp = values[20]; Data::BorrowerPtr b = borrowers[tmp]; if(!b) { b = new Data::Borrower(tmp, TQString()); borrowers.insert(tmp, b); } // values[21] is loan date if(!values[21].isEmpty()) { tmp = values[21]; // assume date is dd/mm/yyyy int d = Tellico::toUInt(tmp.section('/', 0, 0), &ok); int m = Tellico::toUInt(tmp.section('/', 1, 1), &ok); int y = Tellico::toUInt(tmp.section('/', 2, 2), &ok); b->addLoan(new Data::Loan(entry, TQDate(y, m, d), TQDate(), TQString())); entry->setField(TQString::tqfromLatin1("loaned"), TQString::tqfromLatin1("true")); } } // values[22] is history ? // for certification, only thing we can do is assume default american ratings // they're not translated one for one CHECKLIMITS(23); int age = Tellico::toUInt(values[23], &ok); if(age < 2) { entry->setField(TQString::tqfromLatin1("certification"), TQString::tqfromLatin1("U (USA)")); } else if(age < 3) { entry->setField(TQString::tqfromLatin1("certification"), TQString::tqfromLatin1("G (USA)")); } else if(age < 6) { entry->setField(TQString::tqfromLatin1("certification"), TQString::tqfromLatin1("PG (USA)")); } else if(age < 14) { entry->setField(TQString::tqfromLatin1("certification"), TQString::tqfromLatin1("PG-13 (USA)")); } else { entry->setField(TQString::tqfromLatin1("certification"), TQString::tqfromLatin1("R (USA)")); } m_coll->addEntries(entry); if(showProgress && j%stepSize == 0) { ProgressManager::self()->setProgress(this, j); kapp->processEvents(); } } if(m_cancelled) { m_coll = 0; return; } for(TQMap::Iterator it = borrowers.begin(); it != borrowers.end(); ++it) { if(!it.data()->isEmpty()) { m_coll->addBorrower(it.data()); } } } void GCfilmsImporter::readGCstar(const TQString& text_) { TQString xsltFile = locate("appdata", TQString::tqfromLatin1("gcstar2tellico.xsl")); XSLTHandler handler(xsltFile); if(!handler.isValid()) { setStatusMessage(i18n("Tellico encountered an error in XSLT processing.")); return; } TQString str = handler.applyStylesheet(text_); if(str.isEmpty()) { setStatusMessage(i18n("The file is not a valid GCstar data file.")); return; } Import::TellicoImporter imp(str); m_coll = imp.collection(); setStatusMessage(imp.statusMessage()); } inline TQString GCfilmsImporter::splitJoin(const TQRegExp& rx, const TQString& s) { return TQStringList::split(rx, s, false).join(TQString::tqfromLatin1("; ")); } void GCfilmsImporter::slotCancel() { m_cancelled = true; } #undef CHECKLIMITS #include "gcfilmsimporter.moc"