LeechCraft 0.6.70-17335-ge406ffdcaf
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
ljutils.cpp
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#include "ljutils.h"
10
11#include <QCoreApplication>
12#include <QDomDocument>
13#include <QNetworkAccessManager>
15#include <util/sll/either.h>
16#include <util/sll/qtutil.h>
17#include <util/threads/coro.h>
19
20namespace LC::Util::LJ
21{
22 namespace
23 {
24 QByteArray GetChallengeRequestBody ()
25 {
26 return R"(<?xml version="1.0"?>
27<methodCall>
28 <methodName>LJ.XMLRPC.getchallenge</methodName>
29</methodCall>
30)";
31 }
32
33 std::optional<QString> GetChallenge (const QDomDocument& doc)
34 {
35 const auto& replyStruct = doc.documentElement ()
36 .firstChildElement ("params"_qs)
37 .firstChildElement ("param"_qs)
38 .firstChildElement ("value"_qs)
39 .firstChildElement ("struct"_qs);
40 for (const auto& member : Util::DomChildren (replyStruct, "member"_qs))
41 if (member.firstChildElement ("name"_qs).text () == "challenge")
42 return member
43 .firstChildElement ("value"_qs)
44 .firstChildElement ("string"_qs)
45 .text ();
46
47 return {};
48 }
49
50 struct Tr
51 {
52 Q_DECLARE_TR_FUNCTIONS ("LC::Util::LJ")
53 };
54 }
55
57 {
58 QNetworkRequest request { QUrl { "http://www.livejournal.com/interface/xmlrpc"_qs } };
59 request.setRawHeader ("User-Agent", config.UserAgent_);
60 request.setHeader (QNetworkRequest::ContentTypeHeader, "text/xml");
61
62 const auto reply = config.NAM_.post (request, GetChallengeRequestBody ());
63 const auto response = co_await *reply;
64 if (const auto err = response.IsError ())
65 {
66 qWarning () << *err;
67 co_return RequestChallengeResult::Left ({ Tr::tr ("Network error: %1").arg (err->ErrorText_) });
68 }
69
70 const auto& data = response.GetReplyData ();
71
72 QDomDocument doc;
73 if (!doc.setContent (data))
74 {
75 qWarning () << "failed to parse response from" << data;
76 co_return RequestChallengeResult::Left ({ Tr::tr ("Failed to parse response") });
77 }
78
79 const auto& challenge = GetChallenge (doc);
80 if (!challenge)
81 {
82 qWarning () << "failed to get challenge from\n" << doc.toByteArray (1).constData ();
83 co_return RequestChallengeResult::Left ({ Tr::tr ("Failed to parse response") });
84 }
85
86 co_return RequestChallengeResult::Right (*challenge);
87 }
88}
static Either Left(const LL &l)
Definition either.h:126
static Either Right(QString &&r)
Definition either.h:134
Task< RequestChallengeResult > RequestChallenge(RequestChallengeConfig config)
Definition ljutils.cpp:56
auto DomChildren(const QDomNode &parent, const QString &tag)
Creates a range iterating over direct children named tag.
QNetworkAccessManager & NAM_
Definition ljutils.h:28