Page MenuHomePhorge

fbdaemonconnection.cpp
No OneTemporary

Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None

fbdaemonconnection.cpp

/*
* Copyright (C) 2014 Sandro Knauß <knauss@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fbdaemonconnection.h"
#include "fbdaemonthread.h"
#include "fbgeneratorjob.h"
#include "fbgeneratorfolderjob.h"
#include "settings.h"
#include <xmlobject.h>
#include <kpimutils/email.h>
#include <kimap/rfccodecs.h>
#include <QRegExp>
#include <QStringList>
FbDaemonConnection::FbDaemonConnection(FbDaemonThread* parent)
: QObject(parent)
, job(0)
, defaultTimeslot(1000)
{
connect(parent, SIGNAL(newLine(const QByteArray&)), SLOT(onNewLine(const QByteArray&)));
}
FbDaemonConnection::~FbDaemonConnection()
{
setJob(0);
}
void FbDaemonConnection::setJob(KJob* j)
{
if (j == job) {
return;
}
if (job) {
emit job->kill();
}
job = j;
}
void FbDaemonConnection::generateForUser(const QStringList parameters)
{
QString user = parameters[0];
if (!validateGenerateForUser(user)) {
sendError("emailaddress not valid");
return;
}
SessionSettings settings = Settings::instance().getSessionSettings();
settings.userName = user;
FBGeneratorJob *generator = new FBGeneratorJob(settings, false, this);
foreach(QString parameter, parameters.mid(1)) {
if (parameter.startsWith("slot:")) {
if (!validateTimeslot(parameter)) {
sendError("malformed timeslot");
return;
}
Timeslot slot = parseTimeslot(parameter);
generator->setTimeFrame(slot.start, slot.end);
} else {
sendError("unknown parameter");
return;
}
}
connect(generator, SIGNAL(result(KJob*)), this, SLOT(onGenerateUserDone(KJob*)));
setJob(generator);
generator->start();
}
void FbDaemonConnection::generateForFolder(const QStringList parameters)
{
QString folder = parameters[0];
if (!validateGenerateForFolder(folder)) {
sendError("folder not valid");
return;
}
folder = KIMAP::decodeImapFolderName(folder);
SessionSettings settings = Settings::instance().getSessionSettings();
//Login as admin
settings.userName = settings.authorizationName;
settings.authorizationName = "";
FBGeneratorFolderJob *generator = new FBGeneratorFolderJob(settings, folder, this);
foreach(QString parameter, parameters.mid(1)) {
if (parameter.startsWith("slot:")) {
if (!validateTimeslot(parameter)) {
sendError("malformed timeslot");
return;
}
Timeslot slot = parseTimeslot(parameter);
generator->setTimeFrame(slot.start, slot.end);
} else {
sendError("unknown parameter");
return;
}
}
connect(generator, SIGNAL(result(KJob*)), this, SLOT(onGenerateFolderDone(KJob*)));
setJob(generator);
generator->start();
}
void FbDaemonConnection::onNewLine(const QByteArray& line)
{
if (job) {
sendError("Can only process one command after another");
return;
}
QStringList tokens;
QString token;
QRegExp rx("([ \n\"])");
int pos = 0, oldpos = 0;
bool insideString = false;
line.trimmed();
while ((pos = rx.indexIn(line, pos)) != -1) {
if (insideString) {
if (line[pos - 1] == '\\') { //escaped "
token += line.mid(oldpos, pos - oldpos - 1);
} else {
token += line.mid(oldpos, pos - oldpos);
if (rx.cap(1) == QString('"')) {
insideString = false;
token = token.mid(1, token.size() - 1);
}
}
} else {
if (oldpos > 0) {
oldpos += 1;
}
token = line.mid(oldpos, pos - oldpos);
if (rx.cap(1) == QString('"')) {
insideString = true;
}
}
if (!insideString && !token.trimmed().isEmpty()) {
tokens << token.trimmed();
}
oldpos = pos;
pos += 1;
}
if (insideString) {
sendError("no closing \" found");
return;
}
token = line.mid(oldpos + 1).trimmed();
if (!token.isEmpty()) {
tokens << token;
}
qDebug() << "tokens" << tokens;
if (tokens.size() < 3) {
sendError("command not valid");
return;
}
method = tokens[0].toAscii();
if (!validateMethod(method)) {
sendError("method not valid");
return;
}
QString submethod = tokens[1].toUpper();
QStringList parameters = tokens.mid(2);
if (submethod == "USER") {
generateForUser(parameters);
} else if (submethod == "FOLDER") {
generateForFolder(parameters);
} else {
sendError("unknown command: " + submethod.toAscii());
}
}
void FbDaemonConnection::sendError(const QByteArray& error)
{
qDebug() << "An error occured " << error;
emit sendData(createStatusLine("BAD", error));
setJob(0);
}
const QByteArray FbDaemonConnection::createStatusLine(const QByteArray &status, const QByteArray &additional)
{
QByteArray line;
line += status.toUpper();
if (!method.isEmpty()) {
line += " " + method;
}
line += " " + additional + "\r\n";
line += "\r\n";
return line;
}
bool FbDaemonConnection::validateGenerateForUser(const QString& user)
{
return KPIMUtils::isValidSimpleAddress(user);
}
bool FbDaemonConnection::validateGenerateForFolder(const QString& folder)
{
QRegExp utf7("^[A-Za-z0-9\\+,\\(\\)<>@,;:\"/\\[\\]?.= ]+$");
return utf7.exactMatch(folder);
}
bool FbDaemonConnection::validateMethod(const QByteArray& method)
{
return (method.toUpper() == "IFB");
}
Timeslot FbDaemonConnection::parseTimeslot(const QString& timeslot)
{
Timeslot slot;
QString start = "interval";
QString end = "interval";
if (!timeslot.isEmpty()) {
QRegExp reSlot("^slot:(interval|[0-9]+)-(interval|[0-9]+)$");
int pos = reSlot.indexIn(timeslot);
if (pos == -1) {
Q_ASSERT(pos);
}
start = reSlot.cap(1);
end = reSlot.cap(2);
}
if (start == "interval" && end == "interval") {
slot.start = KDateTime::currentUtcDateTime(); // $now
} else if (start != "interval") {
slot.start.setTime_t(start.toUInt());
}
if (end != "interval") {
slot.end.setTime_t(end.toUInt());
if (start == "interval") {
slot.start = slot.end.addDays(-Settings::instance().getTimeframe()); // $now - $defaultvalue
}
} else {
slot.end = slot.start.addDays(Settings::instance().getTimeframe()); // $now + $defaultvalue
}
return slot;
}
bool FbDaemonConnection::validateTimeslot(const QString& timeslot)
{
QRegExp reSlot("^slot:(interval|[0-9]+)-(interval|[0-9]+)$");
return reSlot.exactMatch(timeslot);
}
void FbDaemonConnection::onGenerateFolderDone(KJob* job)
{
if (job != this->job) {
qDebug() << "On other job emitted finished, that should not happen";
qDebug() << "job:" << job << " this->job:" << this->job;
sendError("Something stranged happend");
return;
}
if (job->error()) {
sendError(job->errorString().toAscii());
return;
}
FBGeneratorFolderJob *fbJob = qobject_cast<FBGeneratorFolderJob*>(job);
Q_ASSERT(fbJob);
onSendFbObject(fbJob->getFreebusy());
}
void FbDaemonConnection::onGenerateUserDone(KJob* job)
{
if (job != this->job) {
qDebug() << "On other job emitted finished, that should not happen";
qDebug() << "job:" << job << " this->job:" << this->job;
sendError("Something stranged happend");
return;
}
if (job->error()) {
sendError(job->errorString().toAscii());
return;
}
FBGeneratorJob *fbJob = qobject_cast<FBGeneratorJob*>(job);
Q_ASSERT(fbJob);
onSendFbObject(fbJob->getFreebusy());
}
void FbDaemonConnection::onSendFbObject(const Kolab::Freebusy &freebusy)
{
QByteArray block;
const std::string &v3String = Kolab::writeFreebusy(freebusy);
block = "* ({" + QByteArray::number((uint)v3String.length()) + "} \r\n";
block += v3String.c_str();
block += ")\r\n";
block += createStatusLine("OK", "completed");
emit sendData(block);
setJob(0);
}

File Metadata

Mime Type
text/x-c
Expires
Mon, Apr 6, 1:48 AM (6 d, 9 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18831883
Default Alt Text
fbdaemonconnection.cpp (8 KB)

Event Timeline