You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tellico/src/translators/gcfilmsimporter.cpp

274 lines
9.5 KiB

/***************************************************************************
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 <kapplication.h>
#include <kstandarddirs.h>
#include <tqtextcodec.h>
#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<TQString, Data::BorrowerPtr> 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("<qt>The file is not a valid GCstar data file.</qt>"));
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<TQString, Data::BorrowerPtr>::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("<qt>The file is not a valid GCstar data file.</qt>"));
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"