CookieJar.cpp | 69 +++++++++++++++++++++++++++++++++++++++++ CookieJar.hpp | 13 ++++++++ CutyCapt.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- CutyCapt.hpp | 21 +++++++++---- CutyCapt.pro | 8 ++--- 5 files changed, 188 insertions(+), 22 deletions(-) diff --git a/CookieJar.cpp b/CookieJar.cpp new file mode 100644 index 0000000..da943cf --- /dev/null +++ b/CookieJar.cpp @@ -0,0 +1,69 @@ +#include "CookieJar.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_LINE_LENGTH 4096 + +bool CookieJar::serialize(const QString& path) { + FILE* f = fopen(path.toUtf8(), "w"); + if(f == NULL) { + perror("fopen"); + return false; + } + + bool success = true; + QList cookies = allCookies(); + + for(QList::const_iterator itr = cookies.begin(); itr != cookies.end(); itr++) { + int ret = fprintf(f, "%s\n", itr->toRawForm().constData()); + + if(ret < 0) { + perror("fprintf"); + success = false; + } + } + + fclose(f); + return success; +} + +bool CookieJar::deserialize(const QString& path) { + FILE* f = fopen(path.toUtf8(), "r"); + if(f == NULL) { + return true; // cookie jar file didn't exist - do nothing + } + + QList cookies; + char line[MAX_LINE_LENGTH + 1]; + + while(fgets(line, MAX_LINE_LENGTH, f) != NULL) { + QList tmp = QNetworkCookie::parseCookies(line); + + if(tmp.size() == 0) { + continue; + } + + if(tmp.size() > 1) { + fprintf(stderr, "warning: cookie jar contains multiple cookies on a single line. We are only taking the first.\n"); + fprintf(stderr, "%s\n", line); + } + + cookies.push_back(tmp.first()); + } + + if(errno != 0) { + perror("fgets"); + } + + setAllCookies(cookies); + fclose(f); + + return true; +} diff --git a/CookieJar.hpp b/CookieJar.hpp new file mode 100644 index 0000000..2a255d7 --- /dev/null +++ b/CookieJar.hpp @@ -0,0 +1,13 @@ +#ifndef COOKIEJAR_H +#define COOKIEJAR_H + +#include +#include + +class CookieJar : public QNetworkCookieJar { + public: + bool serialize(const QString& path); + bool deserialize(const QString& path); +}; + +#endif diff --git a/CutyCapt.cpp b/CutyCapt.cpp index c732cb9..3aa40b3 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -19,12 +19,19 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // -// $Id$ +// $Id: CutyCapt.cpp 10 2013-07-14 21:57:37Z hoehrmann $ // //////////////////////////////////////////////////////////////////// #include #include +#include +#include + +#if QT_VERSION >= 0x050000 +#include ` +#endif + #include #include @@ -37,6 +44,8 @@ #include #include #include "CutyCapt.hpp" +#include +#include "CookieJar.hpp" #if QT_VERSION >= 0x040600 && 0 #define CUTYCAPT_SCRIPT 1 @@ -159,10 +168,9 @@ CutyPage::setAttribute(QWebSettings::WebAttribute option, } // TODO: Consider merging some of main() and CutyCap - CutyCapt::CutyCapt(CutyPage* page, const QString& output, int delay, OutputFormat format, - const QString& scriptProp, const QString& scriptCode, bool insecure, - bool smooth) { + const QString& scriptProp, const QString& scriptCode, const QString& cookieJarPath,bool insecure, bool smooth, +QPrinter::Orientation orientation, QPrinter::PaperSize paperSize) { mPage = page; mOutput = output; mDelay = delay; @@ -173,19 +181,39 @@ CutyCapt::CutyCapt(CutyPage* page, const QString& output, int delay, OutputForma mFormat = format; mScriptProp = scriptProp; mScriptCode = scriptCode; + mCookieJarPath = cookieJarPath; mScriptObj = new QObject(); + mOrientation = orientation; + mPaperSize = paperSize; + printf("orientation=%d, paper size=%d\n", orientation, paperSize); // This is not really nice, but some restructuring work is // needed anyway, so this should not be that bad for now. mPage->setCutyCapt(this); } +CutyCapt::~CutyCapt() { + delete mScriptObj; +} + + + void CutyCapt::InitialLayoutCompleted() { mSawInitialLayout = true; if (mSawInitialLayout && mSawDocumentComplete) TryDelayedRender(); + + if(!mCookieJarPath.isEmpty()) { + CookieJar* cookieJar = static_cast(mPage->networkAccessManager()->cookieJar()); + bool success = cookieJar->serialize(mCookieJarPath); + + if(!success) { + fprintf(stderr, "fatal: unable to serialize cookies to cookie jar path\n"); + exit(1); + } + } } void @@ -283,7 +311,8 @@ CutyCapt::saveSnapshot() { case PdfFormat: case PsFormat: { QPrinter printer; - printer.setPageSize(QPrinter::A4); + printer.setPageSize(mPaperSize); + printer.setOrientation(mOrientation); printer.setOutputFileName(mOutput); // TODO: change quality here? mainFrame->print(&printer); @@ -360,7 +389,12 @@ CaptHelp(void) { " --private-browsing= Private browsing (default: unknown) \n" " --auto-load-images= Automatic image loading (default: on) \n" " --js-can-open-windows= Script can open windows? (default: unknown) \n" + " --orientation= Page orientation (default: portrait) \n" + " --page-size= Page size (default: A4) \n" " --js-can-access-clipboard= Script clipboard privs (default: unknown)\n" + " --cookie-jar= The path to the cookie jar to use when making\n" + " requests. Cookies will be read from this file\n" + " and saved back to it after the request. \n" #if QT_VERSION >= 0x040500 " --print-backgrounds= Backgrounds in PDF/PS output (default: off) \n" " --zoom-factor= Page zoom factor (default: no zooming) \n" @@ -427,6 +461,10 @@ main(int argc, char *argv[]) { QByteArray body; QNetworkRequest req; QNetworkAccessManager manager; + QString cookieJarPath = ""; + CookieJar cookieJar; + QPrinter::Orientation orientation = QPrinter::Portrait; + QPrinter::PaperSize paperSize = QPrinter::A4; // Parse command line parameters for (int ax = 1; ax < argc; ++ax) { @@ -460,10 +498,10 @@ main(int argc, char *argv[]) { #if CUTYCAPT_SCRIPT } else if (strcmp("--debug-print-alerts", s) == 0) { - page.setPrintAlerts(true); + page.setPrintAlerts(true); continue; #endif - } + } value = strchr(s, '='); @@ -502,7 +540,6 @@ main(int argc, char *argv[]) { for (int ix = 0; CutyExtMap[ix].id != CutyCapt::OtherFormat; ++ix) if (argOut.endsWith(CutyExtMap[ix].extension)) format = CutyExtMap[ix].id; //, break; - } else if (strncmp("--user-styles", s, nlen) == 0) { // This option is provided for backwards-compatibility only argUserStyle = value; @@ -543,6 +580,43 @@ main(int argc, char *argv[]) { } else if (strncmp("--links-included-in-focus-chain", s, nlen) == 0) { page.setAttribute(QWebSettings::LinksIncludedInFocusChain, value); + } else if (strncmp("--orientation", s, nlen) == 0) { + if (strcasecmp(value, "landscape") == 0) { + orientation = QPrinter::Landscape; + } else if (strcasecmp(value, "portrait") == 0) { + orientation = QPrinter::Portrait; + } else { + argHelp = 1; + break; + } + } else if (strncmp("--paper-size", s, nlen) == 0) { + if (strcasecmp(value, "A4") == 0) { + paperSize = QPrinter::A4; + } else if (strcasecmp(value, "A3") == 0) { + paperSize = QPrinter::A3; + } else if (strcasecmp(value, "Letter") == 0) { + paperSize = QPrinter::Letter; + } else if (strcasecmp(value, "Legal") == 0) { + paperSize = QPrinter::Legal; + } else if (strcasecmp(value, "Tabloid") == 0) { + paperSize = QPrinter::Tabloid; + } else { + argHelp = 1; + break; + } + } + else if (strncmp("--cookie-jar", s, nlen) == 0) { + cookieJarPath = value; + bool success = cookieJar.deserialize(cookieJarPath); + + if(!success) { + fprintf(stderr, "fatal: unable to deserialize cookies from cookie jar path\n"); + exit(1); + } + + manager.setCookieJar(&cookieJar); + page.setNetworkAccessManager(&manager); + #if QT_VERSION >= 0x040500 } else if (strncmp("--print-backgrounds", s, nlen) == 0) { page.setAttribute(QWebSettings::PrintElementBackgrounds, value); @@ -618,7 +692,7 @@ main(int argc, char *argv[]) { method = QNetworkAccessManager::PostOperation; else if (strcmp("value", "head") == 0) method = QNetworkAccessManager::HeadOperation; - else + else (void)0; // TODO: ... } else { @@ -650,8 +724,8 @@ main(int argc, char *argv[]) { } } - CutyCapt main(&page, argOut, argDelay, format, scriptProp, scriptCode, - !!argInsecure, !!argSmooth); + CutyCapt main(&page, argOut, argDelay, format, scriptProp, scriptCode, cookieJarPath,!!argInsecure, !!argSmooth,orientation,paperSize); + app.connect(&page, SIGNAL(loadFinished(bool)), @@ -715,5 +789,6 @@ main(int argc, char *argv[]) { else page.mainFrame()->load(req, method); - return app.exec(); + int status = app.exec(); + return status; } diff --git a/CutyCapt.hpp b/CutyCapt.hpp index 15f3864..73dc075 100755 --- a/CutyCapt.hpp +++ b/CutyCapt.hpp @@ -1,3 +1,4 @@ +#include #include #if QT_VERSION >= 0x050000 @@ -39,14 +40,19 @@ public: RenderTreeFormat, PngFormat, JpegFormat, MngFormat, TiffFormat, GifFormat, BmpFormat, PpmFormat, XbmFormat, XpmFormat, OtherFormat }; - CutyCapt(CutyPage* page, - const QString& output, - int delay, - OutputFormat format, - const QString& scriptProp, +CutyCapt(CutyPage* page, + const QString& output, + int delay, + OutputFormat format, + const QString& scriptProp, const QString& scriptCode, + const QString& cookieJarPath, bool insecure, - bool smooth); + bool smooth, + QPrinter::Orientation orientation, + QPrinter::PaperSize paperSize); + + ~CutyCapt(); private slots: void DocumentComplete(bool ok); @@ -70,6 +76,9 @@ protected: QObject* mScriptObj; QString mScriptProp; QString mScriptCode; + QString mCookieJarPath; bool mInsecure; bool mSmooth; + QPrinter::Orientation mOrientation; + QPrinter::PaperSize mPaperSize; }; diff --git a/CutyCapt.pro b/CutyCapt.pro index 10dda79..1f2b14e 100755 --- a/CutyCapt.pro +++ b/CutyCapt.pro @@ -1,14 +1,14 @@ QT += webkit svg network -SOURCES = CutyCapt.cpp -HEADERS = CutyCapt.hpp -CONFIG += qt console +SOURCES = CutyCapt.cpp CookieJar.cpp +HEADERS = CutyCapt.hpp CookieJar.hpp +CONFIG += qt console debug greaterThan(QT_MAJOR_VERSION, 4): { QT += webkitwidgets + QT += printsupport } contains(CONFIG, static): { QTPLUGIN += qjpeg qgif qsvg qmng qico qtiff DEFINES += STATIC_PLUGINS } -