stylegetter.cpp 7.56 KB
Newer Older
Mehrdad Momeny's avatar
Mehrdad Momeny committed
1 2 3 4 5 6 7 8 9
/*
    This file is part of Blogilo, A KDE Blogging Client

    It is a modified version of "weblogstylegetter.h" from
    KBlogger project. it has been modified for use in Blogilo, at
    February 2009.

    Copyright (C) 2007-2008-2008 by Christian Weilbach <christian_weilbach@web.de>
    Copyright (C) 2007-2008 Antonio Aloisio <gnuton@gnuton.org>
10 11
    Copyright (C) 2008-2010 Mehrdad Momeny <mehrdad.momeny@gmail.com>
    Copyright (C) 2008-2010 Golnaz Nilieh <g382nilieh@gmail.com>
Mehrdad Momeny's avatar
Mehrdad Momeny committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

    This program 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) version 3 or any later version
    accepted by the membership of KDE e.V. (or its successor approved
    by the membership of KDE e.V.), which shall act as a proxy
    defined in Section 14 of version 3 of the license.

    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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, see http://www.gnu.org/licenses/
*/
29 30

#include "stylegetter.h"
Laurent Montel's avatar
Laurent Montel committed
31 32 33 34
#include "bilbopost.h"
#include "bilboblog.h"
#include "backend.h"
#include "dbman.h"
35 36

#include <kio/job.h>
Laurent Montel's avatar
Laurent Montel committed
37

38 39
#include <kmessagebox.h>
#include <klocalizedstring.h>
Laurent Montel's avatar
Laurent Montel committed
40
#include "blogilo_debug.h"
41

Daniel Vrátil's avatar
Daniel Vrátil committed
42
#include <QUrl>
43
#include <QFile>
44
#include <QDateTime>
Laurent Montel's avatar
Laurent Montel committed
45
#include <QStandardPaths>
46 47 48 49

static const char POST_TITLE[] = "Temporary-Post-Used-For-Style-Detection-Title-";
static const char  POST_CONTENT[] = "Temporary-Post-Used-For-Style-Detection-Content-";

Laurent Montel's avatar
Laurent Montel committed
50
StyleGetter::StyleGetter(const int blogid, QObject *parent)
Laurent Montel's avatar
Laurent Montel committed
51 52 53 54
    : QObject(parent),
      mTempPost(Q_NULLPTR),
      mParent(Q_NULLPTR),
      b(Q_NULLPTR)
55
{
Laurent Montel's avatar
Laurent Montel committed
56 57 58 59
    BilboBlog *tempBlog = DBMan::self()->blog(blogid);
    if (tempBlog->isError()) {
        KMessageBox::detailedError(mParent, i18n("Cannot fetch the selected blog style."),
                                   DBMan::self()->lastErrorText());
60 61
        return;
    }
Laurent Montel's avatar
Laurent Montel committed
62
    QString url = QStringLiteral("blogilo/%1/").arg(blogid);
Laurent Montel's avatar
Laurent Montel committed
63
    mCachePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + url;
64
    generateRandomPostStrings();
Laurent Montel's avatar
Laurent Montel committed
65 66
    mParent = qobject_cast< QWidget * >(parent);
    Q_ASSERT(mParent);
67 68 69 70

    // create temp post

    mTempPost = new BilboPost();
Laurent Montel's avatar
Laurent Montel committed
71 72 73
    mTempPost->setTitle(mPostTitle);
    mTempPost->setContent(mPostContent);
    mTempPost->setPrivate(false);
74

Laurent Montel's avatar
Laurent Montel committed
75 76
    if ((tempBlog->api() == BilboBlog::MOVABLETYPE_API) ||
            (tempBlog->api() == BilboBlog::WORDPRESSBUGGY_API)) {
77
        mTempPost->setCreationDateTime(QDateTime(QDate(2000, 1, 1), QTime(0, 0), Qt::UTC));
78 79
    }

Laurent Montel's avatar
Laurent Montel committed
80
    b = new Backend(blogid);
Laurent Montel's avatar
Laurent Montel committed
81 82
    connect(b, &Backend::sigPostPublished, this,
            &StyleGetter::slotTempPostPublished);
Laurent Montel's avatar
Laurent Montel committed
83
    connect(b, &Backend::sigError, this, &StyleGetter::slotError);
84

Laurent Montel's avatar
Laurent Montel committed
85
    Q_EMIT sigGetStyleProgress(10);
86

Laurent Montel's avatar
Laurent Montel committed
87
    b->publishPost(mTempPost);
88 89 90 91 92 93
}

StyleGetter::~StyleGetter()
{
}

Laurent Montel's avatar
Laurent Montel committed
94 95 96
QString StyleGetter::styledHtml(const int blogid,
                                const QString &title,
                                const QString &content)
97
{
Laurent Montel's avatar
Laurent Montel committed
98
    QString url = QStringLiteral("blogilo/%1/").arg(blogid);
Laurent Montel's avatar
Laurent Montel committed
99
    url = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + url;
Daniel Vrátil's avatar
Daniel Vrátil committed
100 101
    QUrl dest(url);
    dest.setPath(dest.path() + QStringLiteral("/style.html"));
Laurent Montel's avatar
Laurent Montel committed
102
    dest.setScheme(QStringLiteral("file"));
103

Laurent Montel's avatar
Laurent Montel committed
104
    if (!dest.isValid()) {
105
        return QLatin1String("<html><body><h2 align='center'>") + title + QLatin1String("</h2><br>") + content + QLatin1String("</html>");
106
    }
Daniel Vrátil's avatar
Daniel Vrátil committed
107
    QFile file(dest.toLocalFile());
Laurent Montel's avatar
Laurent Montel committed
108
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
109
        return QLatin1String("<html><body><h2 align='center'>") + title + QLatin1String("</h2><br>") + content + QLatin1String("</html>");
110
    }
Laurent Montel's avatar
Cleanup  
Laurent Montel committed
111 112

    QString buffer;
Laurent Montel's avatar
Laurent Montel committed
113
    while (!file.atEnd()) {
114
        QByteArray line = file.readLine();
Laurent Montel's avatar
Laurent Montel committed
115
        buffer.append(QString::fromUtf8(line));
116 117
    }

118
    QRegExp typeRx(QStringLiteral("(TYPE[^>]+>)"));
Laurent Montel's avatar
Laurent Montel committed
119
    buffer.remove(typeRx);
120

Laurent Montel's avatar
Laurent Montel committed
121 122
    QRegExp titleRx(QStringLiteral("%1[\\d]*").arg(QLatin1String(POST_TITLE)));
    QRegExp contentRx(QStringLiteral("%1[\\d]*").arg(QLatin1String(POST_CONTENT)));
123

Laurent Montel's avatar
Laurent Montel committed
124 125
    buffer.replace(titleRx, title);
    buffer.replace(contentRx, content);
126 127 128 129

    return buffer;
}

Laurent Montel's avatar
Laurent Montel committed
130
void StyleGetter::slotTempPostPublished(int blogId, BilboPost *post)
131 132
{

Daniel Vrátil's avatar
Daniel Vrátil committed
133
    QUrl postUrl;
134 135
//     postUrl = post->permaLink();
    postUrl = post->link();
Laurent Montel's avatar
Laurent Montel committed
136
    if (postUrl.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
137
        qCDebug(BLOGILO_LOG) << "link was empty";
138 139
//         postUrl = post->link();
        postUrl = post->permaLink();
Laurent Montel's avatar
Laurent Montel committed
140
        if (postUrl.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
141
            qCDebug(BLOGILO_LOG) << "permaLink was empty";
Daniel Vrátil's avatar
Daniel Vrátil committed
142
            postUrl = QUrl(DBMan::self()->blog(blogId)->blogUrl());
143 144 145
        }
    }

Laurent Montel's avatar
Laurent Montel committed
146
    Q_EMIT sigGetStyleProgress(30);
147 148

    mTempPost = post;
Laurent Montel's avatar
Laurent Montel committed
149
    KIO::StoredTransferJob *job = KIO::storedGet(postUrl, KIO::NoReload, KIO::HideProgressInfo);
Laurent Montel's avatar
Laurent Montel committed
150 151
    connect(job, &KJob::result,
            this, &StyleGetter::slotHtmlCopied);
152

153 154
}

Laurent Montel's avatar
Laurent Montel committed
155
void StyleGetter::slotHtmlCopied(KJob *job)
156
{
Laurent Montel's avatar
Laurent Montel committed
157 158 159
    if (job->error()) {
        KMessageBox::detailedError(mParent, i18n("Cannot get html file."),
                                   job->errorString());
160 161 162 163
        sender()->deleteLater();
        return;
    }

Laurent Montel's avatar
Laurent Montel committed
164
    Q_EMIT sigGetStyleProgress(50);
165

Laurent Montel's avatar
Laurent Montel committed
166
    QByteArray httpData(qobject_cast<KIO::StoredTransferJob *>(job)->data());
167

Laurent Montel's avatar
Laurent Montel committed
168 169 170 171
    QString href(mTempPost->permaLink().url());
    int filenameOffset = href.lastIndexOf(QLatin1String("/"));
    href = href.remove(filenameOffset + 1, 255);
    QString base(QLatin1String("<base href=\"") + href + QLatin1String("\"/>"));
172

173
    QRegExp rxBase(QStringLiteral("(<base\\shref=[^>]+>)"));
Laurent Montel's avatar
Laurent Montel committed
174 175 176 177 178
    if (rxBase.indexIn(QLatin1String(httpData)) != -1) {
        httpData.replace(rxBase.cap(1).toLatin1(), base.toLatin1());
    } else {
        int headOffset = httpData.indexOf("<head>");
        httpData.insert(headOffset + 6, base.toLatin1());
179 180
    }

Laurent Montel's avatar
Laurent Montel committed
181
    QFile file(mCachePath + QLatin1String("style.html"));
182
//     Q_ASSERT( dest.isValid() );
Laurent Montel's avatar
Laurent Montel committed
183
    if (file.exists()) {
184 185
        file.remove();
    }
Laurent Montel's avatar
Laurent Montel committed
186 187 188
    if (!file.open(QIODevice::WriteOnly)) {
        KMessageBox::error(mParent,
                           i18n("Cannot write data to file %1", file.fileName()));
189 190
        return;
    }
Laurent Montel's avatar
Laurent Montel committed
191 192 193
    if (file.write(httpData) == -1) {
        KMessageBox::error(mParent,
                           i18n("Cannot write data to file %1", file.fileName()));
194 195 196 197 198

        file.close();
        return;
    }
    file.close();
Laurent Montel's avatar
Laurent Montel committed
199
    Q_EMIT sigGetStyleProgress(70);
200 201 202
//     Q_EMIT sigStyleFetched();

    //Remove temp post from the server.
203 204
    connect(b, &Backend::sigPostRemoved, this,
            &StyleGetter::slotTempPostRemoved);
Laurent Montel's avatar
Laurent Montel committed
205
    b->removePost(mTempPost);
206 207
}

Laurent Montel's avatar
Laurent Montel committed
208
void StyleGetter::slotTempPostRemoved(int blog_id, const BilboPost &post)
209
{
Laurent Montel's avatar
Laurent Montel committed
210 211
    Q_UNUSED(blog_id);
    Q_UNUSED(post);
212 213 214 215

    delete mTempPost;
    b->deleteLater();

Laurent Montel's avatar
Laurent Montel committed
216
    Q_EMIT sigGetStyleProgress(100);
217 218 219 220 221
    Q_EMIT sigStyleFetched();
}

void StyleGetter::generateRandomPostStrings()
{
Laurent Montel's avatar
Laurent Montel committed
222
    srand(time(Q_NULLPTR));
223
    int postRandomNumber = rand();
Laurent Montel's avatar
Laurent Montel committed
224 225
    mPostTitle = QStringLiteral("%1%2").arg(QLatin1String(POST_TITLE)).arg(postRandomNumber);
    mPostContent = QStringLiteral("%1%2").arg(QLatin1String(POST_CONTENT)).arg(postRandomNumber);
226 227
}

Laurent Montel's avatar
Laurent Montel committed
228
void StyleGetter::slotError(const QString &errMsg)
229
{
Laurent Montel's avatar
Laurent Montel committed
230
    KMessageBox::detailedError(mParent, i18n("An error occurred in the latest transaction."), errMsg);
231 232 233
    b->deleteLater();
}