use sqids
This commit is contained in:
13
package-lock.json
generated
13
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "archery",
|
"name": "archery",
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "archery",
|
"name": "archery",
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^1.20.3",
|
"body-parser": "^1.20.3",
|
||||||
@@ -15,7 +15,8 @@
|
|||||||
"express-ws": "^5.0.2",
|
"express-ws": "^5.0.2",
|
||||||
"pg": "^8.15.6",
|
"pg": "^8.15.6",
|
||||||
"pg-hstore": "^2.3.4",
|
"pg-hstore": "^2.3.4",
|
||||||
"sequelize": "^6.37.7"
|
"sequelize": "^6.37.7",
|
||||||
|
"sqids": "0.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/csso": "5.0.4",
|
"@types/csso": "5.0.4",
|
||||||
@@ -1998,6 +1999,12 @@
|
|||||||
"node": ">= 10.x"
|
"node": ">= 10.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sqids": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sqids/-/sqids-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "archery",
|
"name": "archery",
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"description": "Build Arch packages through a web interface",
|
"description": "Build Arch packages through a web interface",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"docker",
|
"docker",
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
"express-ws": "^5.0.2",
|
"express-ws": "^5.0.2",
|
||||||
"pg": "^8.15.6",
|
"pg": "^8.15.6",
|
||||||
"pg-hstore": "^2.3.4",
|
"pg-hstore": "^2.3.4",
|
||||||
"sequelize": "^6.37.7"
|
"sequelize": "^6.37.7",
|
||||||
|
"sqids": "0.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/csso": "5.0.4",
|
"@types/csso": "5.0.4",
|
||||||
|
@@ -24,6 +24,7 @@ interface Build {
|
|||||||
endTime?: Date;
|
endTime?: Date;
|
||||||
status: Status;
|
status: Status;
|
||||||
pid?: number;
|
pid?: number;
|
||||||
|
sqid?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LogChunk {
|
interface LogChunk {
|
||||||
@@ -51,7 +52,8 @@ class DB {
|
|||||||
this.sequelize = new Sequelize(config.db || 'archery', config.user || 'archery', process.env.PASSWORD || config.password || '', {
|
this.sequelize = new Sequelize(config.db || 'archery', config.user || 'archery', process.env.PASSWORD || config.password || '', {
|
||||||
host: config.host || 'localhost',
|
host: config.host || 'localhost',
|
||||||
port: config.port || 5432,
|
port: config.port || 5432,
|
||||||
dialect: 'postgres'
|
dialect: 'postgres',
|
||||||
|
logging: false
|
||||||
});
|
});
|
||||||
this.build = this.sequelize.define('builds', {
|
this.build = this.sequelize.define('builds', {
|
||||||
id: {
|
id: {
|
||||||
|
35
src/Web.ts
35
src/Web.ts
@@ -4,6 +4,7 @@ import type { Express } from "express";
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import expressWs from "express-ws";
|
import expressWs from "express-ws";
|
||||||
import bodyParser from "body-parser";
|
import bodyParser from "body-parser";
|
||||||
|
import Sqids from 'sqids';
|
||||||
import type { DB, LogChunk } from "./DB.ts";
|
import type { DB, LogChunk } from "./DB.ts";
|
||||||
import type { BuildController, BuildEvent } from "./BuildController.ts";
|
import type { BuildController, BuildEvent } from "./BuildController.ts";
|
||||||
|
|
||||||
@@ -41,6 +42,10 @@ class Web {
|
|||||||
private port: number;
|
private port: number;
|
||||||
|
|
||||||
constructor(options: WebConfig = {}) {
|
constructor(options: WebConfig = {}) {
|
||||||
|
const sqids = new Sqids({
|
||||||
|
minLength: 6,
|
||||||
|
alphabet: 'abcdefghijkmnprstuvwxyz'
|
||||||
|
});
|
||||||
const app: Express = express();
|
const app: Express = express();
|
||||||
const wsApp = this.app = expressWs(app).app;
|
const wsApp = this.app = expressWs(app).app;
|
||||||
this.port = notStupidParseInt(process.env.PORT) || options['port'] as number || 8080;
|
this.port = notStupidParseInt(process.env.PORT) || options['port'] as number || 8080;
|
||||||
@@ -66,6 +71,9 @@ class Web {
|
|||||||
app.get('/', async (req, res) => {
|
app.get('/', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const builds = 'q' in req.query ? await this.db.searchBuilds(req.query.q as string) : await this.db.getBuildsBy(req.query);
|
const builds = 'q' in req.query ? await this.db.searchBuilds(req.query.q as string) : await this.db.getBuildsBy(req.query);
|
||||||
|
builds.forEach(b => {
|
||||||
|
b.sqid = sqids.encode([b.id]);
|
||||||
|
});
|
||||||
res.render('index', {
|
res.render('index', {
|
||||||
page: {
|
page: {
|
||||||
title: 'Archery',
|
title: 'Archery',
|
||||||
@@ -100,22 +108,23 @@ class Web {
|
|||||||
req.body.distro || 'arch',
|
req.body.distro || 'arch',
|
||||||
req.body.dependencies || 'stable'
|
req.body.dependencies || 'stable'
|
||||||
);
|
);
|
||||||
res.redirect(`/build/${buildId}`);
|
res.redirect(`/build/${sqids.encode([buildId])}`);
|
||||||
this.buildController.triggerBuild();
|
this.buildController.triggerBuild();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/build/:num/?', async (req, res) => {
|
app.get('/build/:id/?', async (req, res) => {
|
||||||
const build = await this.db.getBuild(parseInt(req.params.num));
|
const build = await this.db.getBuild(sqids.decode(req.params.id)?.[0]);
|
||||||
if (!build) {
|
if (!build) {
|
||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
build.sqid = sqids.encode([build.id]);
|
||||||
const log = splitLines(await this.db.getLog(build.id));
|
const log = splitLines(await this.db.getLog(build.id));
|
||||||
|
|
||||||
res.render('build', {
|
res.render('build', {
|
||||||
page: {
|
page: {
|
||||||
title: 'Archery',
|
title: 'Archery',
|
||||||
titlesuffix: `Build #${req.params.num}`,
|
titlesuffix: `Build #${build.id}`,
|
||||||
description: `Building ${build.repo} on ${build.distro}`
|
description: `Building ${build.repo} on ${build.distro}`
|
||||||
},
|
},
|
||||||
build,
|
build,
|
||||||
@@ -124,8 +133,8 @@ class Web {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/build/:num/cancel', async (req, res) => {
|
app.get('/build/:id/cancel', async (req, res) => {
|
||||||
const build = await this.db.getBuild(parseInt(req.params.num));
|
const build = await this.db.getBuild(sqids.decode(req.params.id)?.[0]);
|
||||||
if (!build) {
|
if (!build) {
|
||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
return;
|
return;
|
||||||
@@ -136,11 +145,11 @@ class Web {
|
|||||||
catch (ex) {
|
catch (ex) {
|
||||||
console.error(ex);
|
console.error(ex);
|
||||||
}
|
}
|
||||||
res.redirect(`/build/${build.id}`);
|
res.redirect(`/build/${req.params.id}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/build/:num/logs/?', async (req, res) => {
|
app.get('/build/:id/logs/?', async (req, res) => {
|
||||||
const build = await this.db.getBuild(parseInt(req.params.num));
|
const build = await this.db.getBuild(sqids.decode(req.params.id)?.[0]);
|
||||||
if (!build) {
|
if (!build) {
|
||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
return;
|
return;
|
||||||
@@ -149,8 +158,8 @@ class Web {
|
|||||||
res.set('Content-Type', 'text/plain').send(log);
|
res.set('Content-Type', 'text/plain').send(log);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/build/:num/patch/?', async (req, res) => {
|
app.get('/build/:id/patch/?', async (req, res) => {
|
||||||
const build = await this.db.getBuild(parseInt(req.params.num));
|
const build = await this.db.getBuild(sqids.decode(req.params.id)?.[0]);
|
||||||
if (!build || !build.patch) {
|
if (!build || !build.patch) {
|
||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
return;
|
return;
|
||||||
@@ -162,10 +171,10 @@ class Web {
|
|||||||
res.send('Healthy');
|
res.send('Healthy');
|
||||||
});
|
});
|
||||||
|
|
||||||
wsApp.ws('/build/:num/ws', (ws, req) => {
|
wsApp.ws('/build/:id/ws', (ws, req) => {
|
||||||
console.log('WS Opened');
|
console.log('WS Opened');
|
||||||
const eventListener = (be: BuildEvent) => {
|
const eventListener = (be: BuildEvent) => {
|
||||||
if (be.id === notStupidParseInt(req.params.num)) {
|
if (be.id === sqids.decode(req.params.id)?.[0]) {
|
||||||
ws.send(JSON.stringify(be));
|
ws.send(JSON.stringify(be));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
<div class="grid-2col">
|
<div class="grid-2col">
|
||||||
<label>Repo</label> <span><%= build.repo %></span>
|
<label>Repo</label> <span><%= build.repo %></span>
|
||||||
<label>Commit</label> <span><% if (build.commit) { %><%= build.commit %><% } else { %>latest<% } %></span>
|
<label>Commit</label> <span><% if (build.commit) { %><%= build.commit %><% } else { %>latest<% } %></span>
|
||||||
<label>Patch</label> <span><% if (build.patch) { %><a href="/build/<%= build.id %>/patch">patch file</a><% } else { %>none<% } %></span>
|
<label>Patch</label> <span><% if (build.patch) { %><a href="/build/<%= build.sqid %>/patch">patch file</a><% } else { %>none<% } %></span>
|
||||||
<label>Distro</label> <span><%= build.distro %></span>
|
<label>Distro</label> <span><%= build.distro %></span>
|
||||||
<label>Dependencies</label> <span><%= build.dependencies %></span>
|
<label>Dependencies</label> <span><%= build.dependencies %></span>
|
||||||
<label>Start time</label> <span class="to-local-time"><%= build.startTime %></span>
|
<label>Start time</label> <span class="to-local-time"><%= build.startTime %></span>
|
||||||
@@ -22,10 +22,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<% if (!ended) { %>
|
<% if (!ended) { %>
|
||||||
<div>
|
<div>
|
||||||
<a href="/build/<%= build.id %>/cancel" class="button">Cancel build</a>
|
<a href="/build/<%= build.sqid %>/cancel" class="button">Cancel build</a>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
<p><a href="/build/<%= build.id %>/logs">Full logs</a></p>
|
<p><a href="/build/<%= build.sqid %>/logs">Full logs</a></p>
|
||||||
<pre class="overflow-x"><div class="logs" id="logs"><% (log || []).forEach(line => { %><p><%= line %></p><% }) %></div></pre>
|
<pre class="overflow-x"><div class="logs" id="logs"><% (log || []).forEach(line => { %><p><%= line %></p><% }) %></div></pre>
|
||||||
|
|
||||||
<% if (!ended) { %>
|
<% if (!ended) { %>
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<% builds.forEach(build => { %>
|
<% builds.forEach(build => { %>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="/build/<%= build.id %>"><%= build.repo %></a></td>
|
<td><a href="/build/<%= build.sqid %>"><%= build.repo %></a></td>
|
||||||
<td><%= build.distro %></td>
|
<td><%= build.distro %></td>
|
||||||
<td class="to-local-time"><%= build.startTime %></td>
|
<td class="to-local-time"><%= build.startTime %></td>
|
||||||
<td><%= timeElapsed(build.startTime, build.endTime) %></td>
|
<td><%= timeElapsed(build.startTime, build.endTime) %></td>
|
||||||
|
Reference in New Issue
Block a user