/* * Copyright (C) 2010 Ixonos Plc. * Copyright (C) 2011-2017 Philipp Spitzer, gregor herrmann, Stefan Stahl * * This file is part of ConfClerk. * * ConfClerk is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * ConfClerk is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * ConfClerk. If not, see . */ #include #include #include #include "schedulexmlparser.h" #include "sqlengine.h" #include "../gui/errormessage.h" #include ScheduleXmlParser::ScheduleXmlParser(SqlEngine* sqlEngine, QObject *aParent): QObject(aParent),sqlEngine(sqlEngine) { } class ParseException: public std::runtime_error { public: ParseException(const QString& message): std::runtime_error(message.toStdString()) {} }; void checkEvent(QHash& event) { QString event_id = event["id"]; if (event_id.trimmed().isEmpty()) throw ParseException(QObject::tr("The ID of event '%1' is missing.").arg(event["title"])); bool ok; event_id.toInt(&ok); if (!ok) throw ParseException(QObject::tr("The ID '%2' of event '%1' is not numeric.").arg(event["title"]).arg(event_id)); } void ScheduleXmlParser::parseDataImpl(const QByteArray &aData, const QString& url, int conferenceId) { QDomDocument document; QString xml_error; int xml_error_line; int xml_error_column; if (!document.setContent(aData, false, &xml_error, &xml_error_line, &xml_error_column)) { throw ParseException("Could not parse schedule: " + xml_error + " at line " + QString("%1").arg(xml_error_line) + " column " + QString("%1").arg(xml_error_column)); } QDomElement scheduleElement = document.firstChildElement("schedule"); TransactionRaii transaction(*sqlEngine); // begins the transaction QString conference_title; if (!scheduleElement.isNull()) { QDomElement conferenceElement = scheduleElement.firstChildElement("conference"); QTime conference_day_change; if (!conferenceElement.isNull()) { emit(parsingScheduleBegin()); QHash conference; conference["id"] = QString::number(conferenceId); // conference ID is assigned automatically if 0 conference["title"] = conferenceElement.firstChildElement("title").text(); conference["subtitle"] = conferenceElement.firstChildElement("subtitle").text(); conference["venue"] = conferenceElement.firstChildElement("venue").text(); conference["city"] = conferenceElement.firstChildElement("city").text(); conference["start"] = conferenceElement.firstChildElement("start").text(); // date conference["end"] = conferenceElement.firstChildElement("end").text(); // date QString conferenceDayChangeStr = conferenceElement.firstChildElement("day_change").text(); // time, e.g. "04:00:00" if (conferenceDayChangeStr.isEmpty()) conferenceDayChangeStr = "04:00:00"; conference["day_change"] = conferenceDayChangeStr; conference["timeslot_duration"] = conferenceElement.firstChildElement("timeslot_duration").text(); // time conference["url"] = url; sqlEngine->addConferenceToDB(conference, conferenceId); conferenceId = conference["id"].toInt(); conference_title = conference["title"]; conference_day_change = QTime(0, 0).addSecs(conference["day_change"].toInt()); } // we need to get count of all events in order to emit 'progressStatus' signal int totalEventsCount = scheduleElement.elementsByTagName("event").count(); // parsing day elements int currentEvent = 0; // hold global idx of processed event QDomNodeList dayList = scheduleElement.elementsByTagName("day"); for (int i=0; i room; room["name"] = roomElement.attribute("name"); room["event_id"] = eventElement.attribute("id"); room["conference_id"] = QString::number(conferenceId,10); sqlEngine->addRoomToDB(room); // process event's nodes QHash event; event["id"] = eventElement.attribute("id"); event["conference_id"] = QString::number(conferenceId, 10); QTime event_start = QTime::fromString(eventElement.firstChildElement("start").text(), sqlEngine->TIME_FORMAT); event["start"] = event_start.toString(sqlEngine->TIME_FORMAT); // time eg. 10:00 QDate event_date; QDomElement eventDateElement = eventElement.firstChildElement("date"); if (!eventDateElement.isNull()) { QString date_str = eventDateElement.text(); // date eg. 2009-02-07T10:00:00+00:00 event_date = QDate::fromString(date_str.left(sqlEngine->DATE_FORMAT.size()), sqlEngine->DATE_FORMAT); } else { event_date = QDate::fromString(dayElement.attribute("date"),sqlEngine->DATE_FORMAT); // date eg. 2009-02-07 if (event_start < conference_day_change) event_date = event_date.addDays(1); } event["date"] = event_date.toString(sqlEngine->DATE_FORMAT); // date eg. 2009-02-07 event["duration"] = eventElement.firstChildElement("duration").text(); // time eg. 00:30 event["room_name"] = eventElement.firstChildElement("room").text(); // string eg. "Janson" event["tag"] = eventElement.firstChildElement("tag").text(); // string eg. "welcome" event["title"] = eventElement.firstChildElement("title").text(); // string eg. "Welcome" event["subtitle"] = eventElement.firstChildElement("subtitle").text(); // string event["track"] = eventElement.firstChildElement("track").text(); // string eg. "Keynotes" event["type"] = eventElement.firstChildElement("type").text(); // string eg. "Podium" event["language"] = eventElement.firstChildElement("language").text(); // language eg. "English" event["abstract"] = eventElement.firstChildElement("abstract").text(); // string event["description"] = eventElement.firstChildElement("description").text(); // string checkEvent(event); sqlEngine->addEventToDB(event); // process persons' nodes QDomElement personsElement = eventElement.firstChildElement("persons"); QDomNodeList personList = personsElement.elementsByTagName("person"); for(int i = 0;i < personList.count();i++){ QHash person; person["id"] = personList.at(i).toElement().attribute("id"); person["name"] = personList.at(i).toElement().text(); person["event_id"] = eventElement.attribute("id"); person["conference_id"] = QString::number(conferenceId, 10); sqlEngine->addPersonToDB(person); } // process links' nodes QDomElement linksElement = eventElement.firstChildElement("links"); QDomNodeList linkList = linksElement.elementsByTagName("link"); for(int i = 0;i < linkList.count();i++){ QHash link; link["name"] = linkList.at(i).toElement().text(); link["url"] = linkList.at(i).toElement().attribute("href"); link["event_id"] = eventElement.attribute("id"); link["conference_id"] = QString::number(conferenceId, 10); sqlEngine->addLinkToDB(link); } // emit signal to inform the user about the current status (how many events are parsed so far - expressed in %) int status = currentEvent * 100 / totalEventsCount; progressStatus(status); } // parsing event elements } } // parsing room elements } // parsing day elements } // schedule element if (conference_title.isNull()) throw ParseException("Could not parse schedule"); transaction.commit(); emit parsingScheduleEnd(conferenceId); } void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url, int conferenceId) { try { parseDataImpl(aData, url, conferenceId); } catch (ParseException& e) { error_message(e.what()); } }