Commit cdc6e175 authored by dmorley's avatar dmorley
Browse files

API v2 using graphql

parent 5f1c1eee
......@@ -9,13 +9,17 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
### Fixed
### Security
## [Unreleased]
## [2.8.2]
### Added
- API v2 using graphql and Siler framework
- graphiql web-ide
### Changed
- Tell robots not to follow links to pods
- Limit stats to 2019 further as old data is inconsistant
- Limit stats to 2019 further as old data is inconsistent
- yarn 2.0
### Deprecated
- yarn 1.0 support
- API v1 api.php
### Removed
### Fixed
- Show stats in proper order yymm
......
#Graphql API Endpoint
Install your favorite Graphql extension on your browser and build away
<html>
<head>
<title>GraphiQL</title>
<link href="/node_modules/graphiql/graphiql.min.css" rel="stylesheet" />
</head>
<body style="margin: 0;">
<div class="graphiql-container" style="height: 2vh;">Use your favorite graphql browser extension, IDE, or graphiql below to get started.</div>
<div id="graphiql" style="height: 98vh;"></div>
<script
src="/node_modules/react/umd/react.production.min.js"
></script>
<script
src="/node_modules/react-dom/umd/react-dom.production.min.js"
></script>
<script
src="/node_modules/graphiql/graphiql.min.js"
></script>
<script>
const graphQLFetcher = graphQLParams =>
fetch('', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(graphQLParams),
})
.then(response => response.json())
.catch(() => response.text());
ReactDOM.render(
React.createElement(GraphiQL, { fetcher: graphQLFetcher }),
document.getElementById('graphiql'),
);
</script>
</body>
</html>
<?php
use Siler\GraphQL;
use Siler\Http\Request;
use Siler\Http\Response;
require_once __DIR__ . '/../boot.php';
Response\cors();
if (Request\method_is('post')) {
$schema = include __DIR__.'/schema.php';
GraphQL\init($schema);
} else {
require 'graphiql.php';
}
<?php
use RedBeanPHP\R;
use function Siler\{array_get_str};
require_once __DIR__ . '/../boot.php';
$queryType = array(
'nodes' => function () {
return R::getAll('
SELECT
id,
domain,
name,
softwarename,
masterversion,
fullversion,
shortversion,
stats_apikey,
score,
ip,
detectedlanguage,
country,
countryname,
city,
state,
lat,
long,
email,
ipv6,
sslvalid,
monthsmonitored,
daysmonitored,
signup,
total_users,
active_users_halfyear,
active_users_monthly,
local_posts,
uptime_alltime,
status,
latency,
service_xmpp,
services,
protocols,
token,
publickey,
tokenexpire,
podmin_statement,
podmin_notify,
podmin_notify_level,
sslexpire,
dnssec,
comment_counts,
weight,
date_updated,
date_laststats,
date_created
FROM pods
');
},
'node' => function ($_, array $args) {
$domain = array_get_str($args, 'domain');
return R::getAll('
SELECT
id,
domain,
name,
softwarename,
masterversion,
fullversion,
shortversion,
stats_apikey,
score,
ip,
detectedlanguage,
country,
countryname,
city,
state,
lat,
long,
email,
ipv6,
sslvalid,
monthsmonitored,
daysmonitored,
signup,
total_users,
active_users_halfyear,
active_users_monthly,
local_posts,
uptime_alltime,
status,
latency,
service_xmpp,
services,
protocols,
token,
publickey,
tokenexpire,
podmin_statement,
podmin_notify,
podmin_notify_level,
sslexpire,
dnssec,
comment_counts,
weight,
date_updated,
date_laststats,
date_created
FROM pods
WHERE domain = ?
', [$domain]);
},
'checks' => function ($_, array $args) {
if ($args) {
$limit = array_get_str($args, 'limit');
} else {
$limit = 5000;
}
return R::getAll('
SELECT id, domain, online, error, latency, total_users, local_posts, comment_counts, shortversion, version, date_checked
FROM checks
ORDER BY date_checked DESC
LIMIT ?
', [$limit]);
},
'clicks' => function ($_, array $args) {
if ($args) {
$limit = array_get_str($args, 'limit');
} else {
$limit = 5000;
}
return R::getAll('
SELECT id, domain, manualclick, autoclick, date_clicked
FROM clicks
ORDER BY date_clicked DESC
LIMIT ?
', [$limit]);
},
'monthlystats' => function () {
return R::getAll('
SELECT id, softwarename, total_users, total_posts, total_comments, total_pods, total_uptime, date_checked
FROM monthlystats
');
},
'masterversions' => function () {
return R::getAll('
SELECT id, software, version, devlastcommit, releasedate, date_checked
FROM masterversions
');
},
);
return [
'Query' => $queryType,
];
type Node {
id: Int!
name: String
domain: String
podmin_statement: String
masterversion: String
shortversion: String
softwarename: String
daysmonitored: Int
monthsmonitored: Int
fullversion: String
score: Int
ip: String
detectedlanguage: String
country: String
countryname: String
city: String
state: String
lat: String
long: String
ipv6: Boolean
sslvalid: String
signup: Boolean
total_users: Int
active_users_halfyear: Int
active_users_monthly: Int
local_posts: Int
uptime_alltime: String
status: Int
latency: Int
service_xmpp: Boolean
services: String
protocols: String
sslexpire: String
dnssec: Boolean
comment_counts: Int
weight: Int
date_updated: String
date_laststats: String
date_created: String
}
type Click {
id: Int!
domain: String
manualclick: Int
autoclick: Int
date_clicked: String
}
type Check {
id: Int!
domain: String
online: Boolean
error: String
latency: Int
total_users: Int
local_posts: Int
comment_counts: Int
shortversion: String
version: String
date_checked: String
}
type MonthlyStat {
id: Int!
softwarename: String
total_users: Int
total_posts: Int
total_comments: Int
total_pods: Int
total_uptime: Int
date_checked: String
}
type MasterVersion {
id: Int!
software: String
version: String
devlastcommit: String
releasedate: String
date_checked: String
}
type Query {
nodes: [Node]
node (domain: String): [Node]
clicks (limit: Int): [Click]
checks (limit: Int): [Check]
monthlystats: [MonthlyStat]
masterversions: [MasterVersion]
}
<?php
use Siler\GraphQL;
$typeDefs = file_get_contents(__DIR__.'/schema.graphql');
$resolvers = include __DIR__.'/resolvers.php';
return GraphQL\schema($typeDefs, $resolvers);
This diff is collapsed.
......@@ -88,7 +88,8 @@ $navs = [
['text' => 'Edit a pod', 'href' => '/podminedit', 'active' => $podminedit],
['text' => 'Open Source Code', 'href' => 'https://git.feneas.org/diasporg/Poduptime', 'active' => false],
['text' => 'Support', 'href' => 'https://dia.so/support', 'active' => false],
['text' => 'Wiki/API', 'href' => 'https://git.feneas.org/diasporg/Poduptime/wikis/home', 'active' => false],
['text' => 'Wiki', 'href' => 'https://git.feneas.org/diasporg/Poduptime/wikis/home', 'active' => false],
['text' => 'API', 'href' => '//api.' . c('domain'), 'active' => false],
['text' => 'More about the Fediverse', 'href' => 'https://fediverse.party', 'active' => false],
['text' => 'Federated Networks Association', 'href' => 'https://feneas.org', 'active' => false],
],
......
......@@ -12,6 +12,15 @@ __metadata:
languageName: node
linkType: hard
"argparse@npm:^1.0.7":
version: 1.0.10
resolution: "argparse@npm:1.0.10"
dependencies:
sprintf-js: ~1.0.2
checksum: 435adaef5f6671c3ef1478a22be6fd54bdb99fdbbce8f5561b9cbbb05068ccce87b7df3b9f3322ff52a6ebb9cab2b427cbedac47a07611690a9beaa5184093e2
languageName: node
linkType: hard
"bootstrap@npm:^4.5.3":
version: 4.5.3
resolution: "bootstrap@npm:4.5.3"
......@@ -51,6 +60,26 @@ __metadata:
languageName: node
linkType: hard
"codemirror-graphql@npm:^0.13.0":
version: 0.13.0
resolution: "codemirror-graphql@npm:0.13.0"
dependencies:
graphql-language-service-interface: ^2.5.0
graphql-language-service-parser: ^1.6.5
peerDependencies:
codemirror: ^5.54.0
graphql: ^14.0.0 || ^15.0.0
checksum: a0e001443775b08c945f9796b17c9db0f2389e5b2ccfae6f7b467243bd502f6a89463027b8371a2e52daf06e8ac928edf1887770a52c15d5c99b25a2654e46a0
languageName: node
linkType: hard
"codemirror@npm:^5.54.0":
version: 5.59.0
resolution: "codemirror@npm:5.59.0"
checksum: fc417586d4f9f012d9ee22e26508cee4d8307760ebefefe8ee935d99504eeb120261cc1c2d90128ae3a5bfb7ef322c65e36eb5fb2a440ad122fe0b67dff5730f
languageName: node
linkType: hard
"color-convert@npm:^1.9.3":
version: 1.9.3
resolution: "color-convert@npm:1.9.3"
......@@ -74,6 +103,29 @@ __metadata:
languageName: node
linkType: hard
"copy-to-clipboard@npm:^3.2.0":
version: 3.3.1
resolution: "copy-to-clipboard@npm:3.3.1"
dependencies:
toggle-selection: ^1.0.6
checksum: 9707f2e405ca4019de1f4194565568acdf3d1dd8a59f7b8f63d0e7257648132b579461e7aeb6140169cb943cf4b6a243b377cf0437d8c10c6f5e5bb3935dea78
languageName: node
linkType: hard
"entities@npm:^2.0.0":
version: 2.1.0
resolution: "entities@npm:2.1.0"
checksum: 91d5330633b97df881bcd02e233d32067876d45abdc7c75cf058ded524d8b22f8dc7a3965813d6982ceeba918abdbd9029a0459759ee5f6f98ec953a4786612f
languageName: node
linkType: hard
"entities@npm:~2.0.0":
version: 2.0.3
resolution: "entities@npm:2.0.3"
checksum: 02dfe1fbf531dd667420ff4e963ddc049203471ba8ad2873655303aff4cf65f27823effb397521af4d58b5609d33fc0492b0cc073c8374f3bbe6d3b5bcec1a42
languageName: node
linkType: hard
"featherlight@npm:^1.7.14":
version: 1.7.14
resolution: "featherlight@npm:1.7.14"
......@@ -88,6 +140,69 @@ fork-awesome@ForkAwesome/Fork-Awesome:
languageName: node
linkType: hard
"graphiql@npm:^1.2.0":
version: 1.2.0
resolution: "graphiql@npm:1.2.0"
dependencies:
codemirror: ^5.54.0
codemirror-graphql: ^0.13.0
copy-to-clipboard: ^3.2.0
entities: ^2.0.0
markdown-it: ^10.0.0
peerDependencies:
graphql: ^14.0.0 || ^15.0.0
prop-types: ">=15.5.0"
react: ^16.8.0
react-dom: ^16.8.0
checksum: f675923d3cd83180c8deef96d6e6fd1eac2fd4fa7f2c34ae7ae6affacf82f228c3b830a83b39f089dcd0f19ba451ab5546c64af826e1d6a877c9e7adb5c3e64b
languageName: node
linkType: hard
"graphql-language-service-interface@npm:^2.5.0":
version: 2.5.0
resolution: "graphql-language-service-interface@npm:2.5.0"
dependencies:
graphql-language-service-parser: ^1.6.5
graphql-language-service-types: ^1.6.3
graphql-language-service-utils: ^2.4.3
vscode-languageserver-types: ^3.15.1
peerDependencies:
graphql: ^14.0.0 || ^15.0.0
checksum: e3bc228518dcfa567a4941105539b8773032e0f55454a9e22b50827425f88238426d3869a15b95681636a2a21e81d057ee10833724bbc8cf4f2cc1eea6b34398
languageName: node
linkType: hard
"graphql-language-service-parser@npm:^1.6.5":
version: 1.6.5
resolution: "graphql-language-service-parser@npm:1.6.5"
dependencies:
graphql-language-service-types: ^1.6.3
peerDependencies:
graphql: ^14.0.0 || ^15.0.0
checksum: 17fd5ea886a0a0e8f6d2fd85cf09909260b280716e5e5a57e7985edb563faaa869b69ef34eb5e7f6407927ffd7c12f08785772045bcff0ec6ed7495107c35742
languageName: node
linkType: hard
"graphql-language-service-types@npm:^1.6.3":
version: 1.6.3
resolution: "graphql-language-service-types@npm:1.6.3"
peerDependencies:
graphql: ^14.0.0 || ^15.0.0
checksum: 8d699357bbca67b18772c18b8567daea245f04b812fb0f0f4f792ef430a29e8b271eb61036210c43e8f360535f069de99bf6eb6a8e9621f0e2da4da5dbda005c
languageName: node
linkType: hard
"graphql-language-service-utils@npm:^2.4.3":
version: 2.4.3
resolution: "graphql-language-service-utils@npm:2.4.3"
dependencies:
graphql-language-service-types: ^1.6.3
peerDependencies:
graphql: ^14.0.0 || ^15.0.0
checksum: 86a45ebe88bc94df5d0af3f947339b58f95f79ac8b199ac906c6e0e464e06117738be2dc1489a94e790995cdcae7e04616a29d90585d1f3262ca1648beeb2625
languageName: node
linkType: hard
"ion-rangeslider@npm:^2.2.0":
version: 2.3.1
resolution: "ion-rangeslider@npm:2.3.1"
......@@ -104,6 +219,13 @@ fork-awesome@ForkAwesome/Fork-Awesome:
languageName: node
linkType: hard
"js-tokens@npm:^3.0.0 || ^4.0.0":
version: 4.0.0
resolution: "js-tokens@npm:4.0.0"
checksum: 1fc4e4667ac2d972aba65148b9cbf9c17566b2394d3504238d8492bbd3e68f496c657eab06b26b40b17db5cac0a34d153a12130e2d2d2bb6dc2cdc8a4764eb1b
languageName: node
linkType: hard
"leaflet.markercluster@npm:^1.4.1":
version: 1.4.1
resolution: "leaflet.markercluster@npm:1.4.1"
......@@ -120,6 +242,48 @@ fork-awesome@ForkAwesome/Fork-Awesome:
languageName: node
linkType: hard
"linkify-it@npm:^2.0.0":
version: 2.2.0
resolution: "linkify-it@npm:2.2.0"
dependencies:
uc.micro: ^1.0.1
checksum: 7905b34078d1fd85d4310c5c5381164cbdf781835e0cb5ac73d13ff14d0c87347e02655bdff5cec63631949a3b586c5f8e1e81ee0ce62ae799df58178748eb3e
languageName: node
linkType: hard
"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
dependencies:
js-tokens: ^3.0.0 || ^4.0.0
bin:
loose-envify: cli.js
checksum: 5c3b47bbe5f597a3889fb001a3a98aaea2a3fafa48089c19034de1e0121bf57dbee609d184478514d74d5c5a7e9cfa3d846343455e5123b060040d46c39e91dc
languageName: node
linkType: hard
"markdown-it@npm:^10.0.0":
version: 10.0.0
resolution: "markdown-it@npm:10.0.0"
dependencies:
argparse: ^1.0.7
entities: ~2.0.0
linkify-it: ^2.0.0
mdurl: ^1.0.1
uc.micro: ^1.0.5
bin:
markdown-it: bin/markdown-it.js
checksum: f0529067445a432fa5b32b6544e1aaa21d0ee54d43f28a3fb4d6afab271e17c749481da936529bb72a5544146cdd541757893c27f6b0ff8d45339b5cf3f98be5
languageName: node
linkType: hard
"mdurl@npm:^1.0.1":
version: 1.0.1
resolution: "mdurl@npm:1.0.1"
checksum: ed5e81efed218ca1cb61bbb5c41857c98ce456382d630a2f45a1b050087a10119a24107ca1acd4ccef2f1a17b02b8d61fb3c630d3d7c0f22df906dbdd2e5f7b5
languageName: node
linkType: hard
"moment@npm:^2.10.2":
version: 2.29.1
resolution: "moment@npm:2.29.1"
......@@ -127,6 +291,13 @@ fork-awesome@ForkAwesome/Fork-Awesome:
languageName: node
linkType: hard
"object-assign@npm:^4.1.1":
version: 4.1.1
resolution: "object-assign@npm:4.1.1"
checksum: 66cf021898fc1b13ea573ea8635fbd5a76533f50cecbc2fcd5eee1e8029af41bcebe7023788b6d0e06cbe4401ecea075d972f78ec74467cdc571a0f1a4d1a081
languageName: node
linkType: hard
"poduptime@workspace:.":
version: 0.0.0-use.local
resolution: "poduptime@workspace:."
......@@ -136,11 +307,15 @@ fork-awesome@ForkAwesome/Fork-Awesome:
chart.js: ^2.9.4
featherlight: ^1.7.14
fork-awesome: ForkAwesome/Fork-Awesome
graphiql: ^1.2.0
ion-rangeslider: ^2.2.0
jquery: ^3.5.0
leaflet: ^1.4.1
leaflet.markercluster: ^1.4.1
popper.js: ^1.15.0
prop-types: ^15.7.2
react: ^17.0.1
react-dom: ^17.0.1
tablesorter: ^2.31.3
languageName: unknown
linkType: soft
......@@ -152,6 +327,64 @@ fork-awesome@ForkAwesome/Fork-Awesome:
languageName: node
linkType: hard
"prop-types@npm:^15.7.2":
version: 15.7.2
resolution: "prop-types@npm:15.7.2"
dependencies:
loose-envify: ^1.4.0
object-assign: ^4.1.1
react-is: ^16.8.1
checksum: a440dd406c5cf53bf39f3e898d2c65178511d34ca3c8c789b30c177992408b9e4273969726b274719aa69ccce5ab34b2fd8caa60b90f23cd2e910cdcf682de52
languageName: node
linkType: hard
"react-dom@npm:^17.0.1":
version: 17.0.1
resolution: "react-dom@npm:17.0.1"
dependencies:
loose-envify: ^1.1.0
object-assign: ^4.1.1
scheduler: ^0.20.1
peerDependencies:
react: 17.0.1
checksum: 6a70028fbe3c95e0056c5e8ce065b4a9b8d4ff3bffde9b016454072bde5e4b012af7668ca45b7235ace428267d5be5237b68ea87ce8c296e54e81a8d678a4355
languageName: node
linkType: hard