mirror of
https://github.com/ModOrganizer2/githubpp.git
synced 2026-07-27 14:04:49 -07:00
Apply formatting.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
---
|
||||
# We'll use defaults from the LLVM style, but with 4 columns indentation.
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 2
|
||||
---
|
||||
Language: Cpp
|
||||
DeriveLineEnding: false
|
||||
UseCRLF: true
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
AlignConsecutiveAssignments: true
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: Empty
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
AccessModifierOffset: -2
|
||||
AlignTrailingComments: true
|
||||
SpacesBeforeTrailingComments: 2
|
||||
NamespaceIndentation: Inner
|
||||
MaxEmptyLinesToKeep: 1
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: true
|
||||
ColumnLimit: 88
|
||||
ForEachMacros: ['Q_FOREACH', 'foreach']
|
||||
@@ -0,0 +1,7 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.cpp text eol=crlf
|
||||
*.h text eol=crlf
|
||||
@@ -0,0 +1,16 @@
|
||||
name: Lint Github++
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Check format
|
||||
uses: ModOrganizer2/check-formatting-action@master
|
||||
with:
|
||||
check-path: "."
|
||||
+31
-32
@@ -1,32 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkCookieJar>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QTimer>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkCookieJar>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
#include <functional>
|
||||
|
||||
class GitHubException : public std::exception
|
||||
{
|
||||
public:
|
||||
GitHubException(const QJsonObject &errorObj)
|
||||
: std::exception()
|
||||
GitHubException(const QJsonObject& errorObj) : std::exception()
|
||||
{
|
||||
initMessage(errorObj);
|
||||
}
|
||||
|
||||
virtual ~GitHubException() throw() override {}
|
||||
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return m_Message.constData();
|
||||
}
|
||||
virtual const char* what() const throw() { return m_Message.constData(); }
|
||||
|
||||
private:
|
||||
void initMessage(const QJsonObject &obj)
|
||||
void initMessage(const QJsonObject& obj)
|
||||
{
|
||||
if (obj.contains("http_status")) {
|
||||
m_Message = QString("HTTP Status %1: %2")
|
||||
@@ -55,48 +51,51 @@ class GitHub : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class Method { GET, POST };
|
||||
enum class Method
|
||||
{
|
||||
GET,
|
||||
POST
|
||||
};
|
||||
|
||||
struct Repository {
|
||||
Repository(const QString &owner, const QString &project)
|
||||
: owner(owner)
|
||||
, project(project)
|
||||
{
|
||||
}
|
||||
struct Repository
|
||||
{
|
||||
Repository(const QString& owner, const QString& project)
|
||||
: owner(owner), project(project)
|
||||
{}
|
||||
QString owner;
|
||||
QString project;
|
||||
};
|
||||
|
||||
public:
|
||||
GitHub(const char *clientId = nullptr);
|
||||
GitHub(const char* clientId = nullptr);
|
||||
~GitHub();
|
||||
|
||||
QJsonArray releases(const Repository &repo);
|
||||
void releases(const Repository &repo,
|
||||
const std::function<void (const QJsonArray &)> &callback);
|
||||
QJsonArray releases(const Repository& repo);
|
||||
void releases(const Repository& repo,
|
||||
const std::function<void(const QJsonArray&)>& callback);
|
||||
|
||||
private:
|
||||
QJsonDocument request(Method method, const QString &path,
|
||||
const QByteArray &data, bool relative);
|
||||
void request(Method method, const QString &path, const QByteArray &data,
|
||||
const std::function<void (const QJsonDocument &)> &callback,
|
||||
QJsonDocument request(Method method, const QString& path, const QByteArray& data,
|
||||
bool relative);
|
||||
void request(Method method, const QString& path, const QByteArray& data,
|
||||
const std::function<void(const QJsonDocument&)>& callback,
|
||||
bool relative);
|
||||
|
||||
QJsonDocument handleReply(QNetworkReply *reply);
|
||||
QNetworkReply *genReply(Method method, const QString &path,
|
||||
const QByteArray &data, bool relative);
|
||||
QJsonDocument handleReply(QNetworkReply* reply);
|
||||
QNetworkReply* genReply(Method method, const QString& path, const QByteArray& data,
|
||||
bool relative);
|
||||
|
||||
private:
|
||||
struct Request
|
||||
{
|
||||
Method method = Method::GET;
|
||||
QByteArray data;
|
||||
std::function<void (const QJsonDocument &)> callback;
|
||||
QTimer* timer = nullptr;
|
||||
std::function<void(const QJsonDocument&)> callback;
|
||||
QTimer* timer = nullptr;
|
||||
QNetworkReply* reply = nullptr;
|
||||
};
|
||||
|
||||
QNetworkAccessManager *m_AccessManager;
|
||||
QNetworkAccessManager* m_AccessManager;
|
||||
|
||||
// remember the replies that are in flight and delete them in the destructor
|
||||
std::vector<QNetworkReply*> m_replies;
|
||||
|
||||
+58
-59
@@ -1,17 +1,16 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkRequest>
|
||||
#include "github.h"
|
||||
#include <QEventLoop>
|
||||
#include <QJsonDocument>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#include <QThread>
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
|
||||
static const QString GITHUB_URL("https://api.github.com");
|
||||
static const QString USER_AGENT("GitHubPP");
|
||||
|
||||
|
||||
GitHub::GitHub(const char* clientId)
|
||||
: m_AccessManager(new QNetworkAccessManager(this)) {}
|
||||
GitHub::GitHub(const char* clientId) : m_AccessManager(new QNetworkAccessManager(this))
|
||||
{}
|
||||
|
||||
GitHub::~GitHub()
|
||||
{
|
||||
@@ -23,43 +22,40 @@ GitHub::~GitHub()
|
||||
}
|
||||
}
|
||||
|
||||
QJsonArray GitHub::releases(const Repository &repo)
|
||||
QJsonArray GitHub::releases(const Repository& repo)
|
||||
{
|
||||
QJsonDocument result
|
||||
= request(Method::GET,
|
||||
QString("repos/%1/%2/releases").arg(repo.owner, repo.project),
|
||||
QByteArray(),
|
||||
true);
|
||||
QJsonDocument result = request(
|
||||
Method::GET, QString("repos/%1/%2/releases").arg(repo.owner, repo.project),
|
||||
QByteArray(), true);
|
||||
return result.array();
|
||||
}
|
||||
|
||||
void GitHub::releases(const Repository &repo,
|
||||
const std::function<void(const QJsonArray &)> &callback)
|
||||
void GitHub::releases(const Repository& repo,
|
||||
const std::function<void(const QJsonArray&)>& callback)
|
||||
{
|
||||
request(Method::GET,
|
||||
QString("repos/%1/%2/releases").arg(repo.owner, repo.project),
|
||||
QByteArray(), [callback](const QJsonDocument &result) {
|
||||
callback(result.array());
|
||||
}, true);
|
||||
request(
|
||||
Method::GET, QString("repos/%1/%2/releases").arg(repo.owner, repo.project),
|
||||
QByteArray(),
|
||||
[callback](const QJsonDocument& result) {
|
||||
callback(result.array());
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
QJsonDocument GitHub::handleReply(QNetworkReply *reply)
|
||||
QJsonDocument GitHub::handleReply(QNetworkReply* reply)
|
||||
{
|
||||
int statusCode
|
||||
= reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if (statusCode != 200) {
|
||||
return QJsonDocument(QJsonObject(
|
||||
{{"http_status", statusCode},
|
||||
{"redirection",
|
||||
reply->attribute(QNetworkRequest::RedirectionTargetAttribute)
|
||||
.toString()},
|
||||
{"reason", reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute)
|
||||
.toString()}}));
|
||||
reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString()},
|
||||
{"reason",
|
||||
reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()}}));
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
if (data.isNull() || data.isEmpty()
|
||||
|| (strcmp(data.constData(), "null") == 0)) {
|
||||
if (data.isNull() || data.isEmpty() || (strcmp(data.constData(), "null") == 0)) {
|
||||
return QJsonDocument();
|
||||
}
|
||||
|
||||
@@ -67,15 +63,14 @@ QJsonDocument GitHub::handleReply(QNetworkReply *reply)
|
||||
QJsonDocument result = QJsonDocument::fromJson(data, &parseError);
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
return QJsonDocument(
|
||||
QJsonObject({{"parse_error", parseError.errorString()}}));
|
||||
return QJsonDocument(QJsonObject({{"parse_error", parseError.errorString()}}));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QNetworkReply *GitHub::genReply(Method method, const QString &path,
|
||||
const QByteArray &data, bool relative)
|
||||
QNetworkReply* GitHub::genReply(Method method, const QString& path,
|
||||
const QByteArray& data, bool relative)
|
||||
{
|
||||
QNetworkRequest request(relative ? GITHUB_URL + "/" + path : path);
|
||||
|
||||
@@ -83,21 +78,21 @@ QNetworkReply *GitHub::genReply(Method method, const QString &path,
|
||||
request.setRawHeader("Accept", "application/vnd.github.v3+json");
|
||||
|
||||
switch (method) {
|
||||
case Method::GET:
|
||||
return m_AccessManager->get(request);
|
||||
case Method::POST:
|
||||
return m_AccessManager->post(request, data);
|
||||
default:
|
||||
// this shouldn't be possible as all enum options are handled
|
||||
throw std::runtime_error("invalid method");
|
||||
case Method::GET:
|
||||
return m_AccessManager->get(request);
|
||||
case Method::POST:
|
||||
return m_AccessManager->post(request, data);
|
||||
default:
|
||||
// this shouldn't be possible as all enum options are handled
|
||||
throw std::runtime_error("invalid method");
|
||||
}
|
||||
}
|
||||
|
||||
QJsonDocument GitHub::request(Method method, const QString &path,
|
||||
const QByteArray &data, bool relative)
|
||||
QJsonDocument GitHub::request(Method method, const QString& path,
|
||||
const QByteArray& data, bool relative)
|
||||
{
|
||||
QEventLoop wait;
|
||||
QNetworkReply *reply = genReply(method, path, data, relative);
|
||||
QNetworkReply* reply = genReply(method, path, data, relative);
|
||||
|
||||
connect(reply, SIGNAL(finished), &wait, SLOT(quit()));
|
||||
wait.exec();
|
||||
@@ -112,18 +107,18 @@ QJsonDocument GitHub::request(Method method, const QString &path,
|
||||
}
|
||||
}
|
||||
|
||||
void GitHub::request(Method method, const QString &path, const QByteArray &data,
|
||||
const std::function<void(const QJsonDocument &)> &callback,
|
||||
void GitHub::request(Method method, const QString& path, const QByteArray& data,
|
||||
const std::function<void(const QJsonDocument&)>& callback,
|
||||
bool relative)
|
||||
{
|
||||
// make sure the timer is owned by this so it's deleted correctly and
|
||||
// doesn't fire after the GitHub object is destroyed; this happens when
|
||||
// restarting MO by switching instances, for example
|
||||
QTimer *timer = new QTimer(this);
|
||||
QTimer* timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
timer->setInterval(10000);
|
||||
|
||||
QNetworkReply *reply = genReply(method, path, data, relative);
|
||||
QNetworkReply* reply = genReply(method, path, data, relative);
|
||||
|
||||
// remember this reply so it can be deleted in the destructor if necessary
|
||||
m_replies.push_back(reply);
|
||||
@@ -131,15 +126,20 @@ void GitHub::request(Method method, const QString &path, const QByteArray &data,
|
||||
Request req = {method, data, callback, timer, reply};
|
||||
|
||||
// finished
|
||||
connect(reply, &QNetworkReply::finished, [this, req]{ onFinished(req); });
|
||||
connect(reply, &QNetworkReply::finished, [this, req] {
|
||||
onFinished(req);
|
||||
});
|
||||
|
||||
// error
|
||||
connect(
|
||||
reply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::errorOccurred),
|
||||
[this, req](auto&& error){ onError(req, error); });
|
||||
connect(reply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::errorOccurred),
|
||||
[this, req](auto&& error) {
|
||||
onError(req, error);
|
||||
});
|
||||
|
||||
// timeout
|
||||
connect(timer, &QTimer::timeout, [this, req]{ onTimeout(req); });
|
||||
connect(timer, &QTimer::timeout, [this, req] {
|
||||
onTimeout(req);
|
||||
});
|
||||
|
||||
timer->start();
|
||||
}
|
||||
@@ -147,14 +147,13 @@ void GitHub::request(Method method, const QString &path, const QByteArray &data,
|
||||
void GitHub::onFinished(const Request& req)
|
||||
{
|
||||
QJsonDocument result = handleReply(req.reply);
|
||||
QJsonObject object = result.object();
|
||||
QJsonObject object = result.object();
|
||||
|
||||
req.timer->stop();
|
||||
|
||||
if (object.value("http_status").toInt() == 301) {
|
||||
request(
|
||||
req.method, object.value("redirection").toString(),
|
||||
req.data, req.callback, false);
|
||||
request(req.method, object.value("redirection").toString(), req.data, req.callback,
|
||||
false);
|
||||
} else {
|
||||
req.callback(result);
|
||||
}
|
||||
@@ -168,8 +167,8 @@ void GitHub::onError(const Request& req, QNetworkReply::NetworkError error)
|
||||
// already logs a message
|
||||
if (error != QNetworkReply::OperationCanceledError) {
|
||||
qCritical().noquote().nospace()
|
||||
<< "Github: request for " << req.reply->url().toString() << " failed, "
|
||||
<< req.reply->errorString() << " (" << error << ")";
|
||||
<< "Github: request for " << req.reply->url().toString() << " failed, "
|
||||
<< req.reply->errorString() << " (" << error << ")";
|
||||
}
|
||||
|
||||
req.timer->stop();
|
||||
@@ -186,7 +185,7 @@ void GitHub::onError(const Request& req, QNetworkReply::NetworkError error)
|
||||
void GitHub::onTimeout(const Request& req)
|
||||
{
|
||||
qCritical().noquote().nospace()
|
||||
<< "Github: request for " << req.reply->url().toString() << " timed out";
|
||||
<< "Github: request for " << req.reply->url().toString() << " timed out";
|
||||
|
||||
// don't delete the reply, abort will fire the error() handler above
|
||||
req.reply->abort();
|
||||
|
||||
Reference in New Issue
Block a user