Compare commits
1 Commits
renovate/g
...
23bba830f6
Author | SHA1 | Date | |
---|---|---|---|
23bba830f6 |
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.24.5
|
FROM golang:1.24.3
|
||||||
|
|
||||||
WORKDIR /api
|
WORKDIR /api
|
||||||
|
|
||||||
|
@@ -11,7 +11,4 @@ run:
|
|||||||
format:
|
format:
|
||||||
gofmt -s -w .
|
gofmt -s -w .
|
||||||
|
|
||||||
clean:
|
.PHONY: test format
|
||||||
rm -f *.elf
|
|
||||||
|
|
||||||
.PHONY: test format clean
|
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
module github.com/ngn13/website/api
|
module github.com/ngn13/website/api
|
||||||
|
|
||||||
go 1.24.5
|
go 1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gofiber/fiber/v2 v2.52.9
|
github.com/gofiber/fiber/v2 v2.52.6
|
||||||
github.com/mattn/go-sqlite3 v1.14.28
|
github.com/mattn/go-sqlite3 v1.14.28
|
||||||
github.com/ngn13/ortam v0.0.0-20250421004351-8dea81680817
|
github.com/ngn13/ortam v0.0.0-20250421004351-8dea81680817
|
||||||
)
|
)
|
||||||
|
10
api/go.sum
10
api/go.sum
@@ -1,9 +1,7 @@
|
|||||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||||
github.com/gofiber/fiber/v2 v2.52.8 h1:xl4jJQ0BV5EJTA2aWiKw/VddRpHrKeZLF0QPUxqn0x4=
|
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
|
||||||
github.com/gofiber/fiber/v2 v2.52.8/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||||
github.com/gofiber/fiber/v2 v2.52.9 h1:YjKl5DOiyP3j0mO61u3NTmK7or8GzzWzCFzkboyP5cw=
|
|
||||||
github.com/gofiber/fiber/v2 v2.52.9/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
@@ -15,8 +13,12 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
|||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
|
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
|
||||||
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
|
github.com/ngn13/ortam v0.0.0-20250412195317-e76e62a7a305 h1:1YxtSMwR14PklXNlZxIqcmfpiq2+G98YNmhSuz7GKCQ=
|
||||||
|
github.com/ngn13/ortam v0.0.0-20250412195317-e76e62a7a305/go.mod h1:MSJZ4ZstrLvVEvivbp9hhup+iL8rvtpgKcYaF3DSOKk=
|
||||||
github.com/ngn13/ortam v0.0.0-20250421004351-8dea81680817 h1:WkHM4w51N5jCsWcDVcPsXz3zhi/kCfNp/VGh2uPjwsk=
|
github.com/ngn13/ortam v0.0.0-20250421004351-8dea81680817 h1:WkHM4w51N5jCsWcDVcPsXz3zhi/kCfNp/VGh2uPjwsk=
|
||||||
github.com/ngn13/ortam v0.0.0-20250421004351-8dea81680817/go.mod h1:MSJZ4ZstrLvVEvivbp9hhup+iL8rvtpgKcYaF3DSOKk=
|
github.com/ngn13/ortam v0.0.0-20250421004351-8dea81680817/go.mod h1:MSJZ4ZstrLvVEvivbp9hhup+iL8rvtpgKcYaF3DSOKk=
|
||||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||||
|
@@ -1 +1,2 @@
|
|||||||
engine-strict=true
|
engine-strict=true
|
||||||
|
resolution-mode=highest
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"singleQuote": false,
|
"singleQuote": false,
|
||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"printWidth": 80,
|
"printWidth": 100,
|
||||||
"plugins": ["prettier-plugin-svelte"],
|
"plugins": ["prettier-plugin-svelte"],
|
||||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||||
}
|
}
|
||||||
|
59
app/package-lock.json
generated
59
app/package-lock.json
generated
@@ -9,7 +9,7 @@
|
|||||||
"version": "6.3",
|
"version": "6.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dompurify": "^3.2.3",
|
"dompurify": "^3.2.3",
|
||||||
"marked": "^16.0.0",
|
"marked": "^15.0.6",
|
||||||
"svelte-i18n": "^4.0.1"
|
"svelte-i18n": "^4.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -851,9 +851,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sveltejs/adapter-node": {
|
"node_modules/@sveltejs/adapter-node": {
|
||||||
"version": "5.2.13",
|
"version": "5.2.12",
|
||||||
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-5.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-5.2.12.tgz",
|
||||||
"integrity": "sha512-yS2TVFmIrxjGhYaV5/iIUrJ3mJl6zjaYn0lBD70vTLnYvJeqf3cjvLXeXCUCuYinhSBoyF4DpfGla49BnIy7sQ==",
|
"integrity": "sha512-0bp4Yb3jKIEcZWVcJC/L1xXp9zzJS4hDwfb4VITAkfT4OVdkspSHsx7YhqJDbb2hgLl6R9Vs7VQR+fqIVOxPUQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -867,9 +867,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sveltejs/kit": {
|
"node_modules/@sveltejs/kit": {
|
||||||
"version": "2.25.1",
|
"version": "2.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.25.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.21.1.tgz",
|
||||||
"integrity": "sha512-8H+fxDEp7Xq6tLFdrGdS5fLu6ONDQQ9DgyjboXpChubuFdfH9QoFX09ypssBpyNkJNZFt9eW3yLmXIc9CesPCA==",
|
"integrity": "sha512-vLbtVwtDcK8LhJKnFkFYwM0uCdFmzioQnif0bjEYH1I24Arz22JPr/hLUiXGVYAwhu8INKx5qrdvr4tHgPwX6w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -893,9 +893,9 @@
|
|||||||
"node": ">=18.13"
|
"node": ">=18.13"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0",
|
"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0",
|
||||||
"svelte": "^4.0.0 || ^5.0.0-next.0",
|
"svelte": "^4.0.0 || ^5.0.0-next.0",
|
||||||
"vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0"
|
"vite": "^5.0.3 || ^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sveltejs/vite-plugin-svelte": {
|
"node_modules/@sveltejs/vite-plugin-svelte": {
|
||||||
@@ -1203,9 +1203,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/esrap": {
|
"node_modules/esrap": {
|
||||||
"version": "2.1.0",
|
"version": "1.4.6",
|
||||||
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.6.tgz",
|
||||||
"integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==",
|
"integrity": "sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||||
@@ -1384,15 +1384,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/marked": {
|
"node_modules/marked": {
|
||||||
"version": "16.1.1",
|
"version": "15.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-16.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz",
|
||||||
"integrity": "sha512-ij/2lXfCRT71L6u0M29tJPhP0bM5shLL3u5BePhFwPELj2blMJ6GDtD7PfJhRLhJ/c2UwrK17ySVcDzy2YHjHQ==",
|
"integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"marked": "bin/marked.js"
|
"marked": "bin/marked.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 20"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/memoizee": {
|
"node_modules/memoizee": {
|
||||||
@@ -1515,9 +1515,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.6.2",
|
"version": "3.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
|
||||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -1649,9 +1649,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/svelte": {
|
"node_modules/svelte": {
|
||||||
"version": "5.36.8",
|
"version": "5.32.1",
|
||||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.36.8.tgz",
|
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.32.1.tgz",
|
||||||
"integrity": "sha512-8JbZWQu96hMjH/oYQPxXW6taeC6Awl6muGHeZzJTxQx7NGRQ/J9wN1hkzRKLOlSDlbS2igiFg7p5xyTp5uXG3A==",
|
"integrity": "sha512-tT02QOeF0dbSIQ+/rUZw+76DyO6ATHvZJGOM2A/Ed6fBwZwUxqIun3beErpePAtwFIK3Mi9k2QAnhFVvUBun8g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.3.0",
|
"@ampproject/remapping": "^2.3.0",
|
||||||
@@ -1663,7 +1663,7 @@
|
|||||||
"axobject-query": "^4.1.0",
|
"axobject-query": "^4.1.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"esm-env": "^1.2.1",
|
"esm-env": "^1.2.1",
|
||||||
"esrap": "^2.1.0",
|
"esrap": "^1.4.6",
|
||||||
"is-reference": "^3.0.3",
|
"is-reference": "^3.0.3",
|
||||||
"locate-character": "^3.0.0",
|
"locate-character": "^3.0.0",
|
||||||
"magic-string": "^0.30.11",
|
"magic-string": "^0.30.11",
|
||||||
@@ -2208,17 +2208,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vitefu": {
|
"node_modules/vitefu": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.3.tgz",
|
||||||
"integrity": "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==",
|
"integrity": "sha512-iKKfOMBHob2WxEJbqbJjHAkmYgvFDPhuqrO82om83S8RLk+17FtyMBfcyeH8GqD0ihShtkMW/zzJgiA51hCNCQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"workspaces": [
|
|
||||||
"tests/deps/*",
|
|
||||||
"tests/projects/*"
|
|
||||||
],
|
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
|
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0-beta.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"vite": {
|
"vite": {
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dompurify": "^3.2.3",
|
"dompurify": "^3.2.3",
|
||||||
"marked": "^16.0.0",
|
"marked": "^15.0.6",
|
||||||
"svelte-i18n": "^4.0.1"
|
"svelte-i18n": "^4.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,14 +13,11 @@ function api_urljoin(path = null, query = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function api_check_err(json) {
|
function api_check_err(json) {
|
||||||
if (!("error" in json))
|
if (!("error" in json)) throw new Error('API response is missing the "error" key');
|
||||||
throw new Error('API response is missing the "error" key');
|
|
||||||
|
|
||||||
if (json["error"] != "")
|
if (json["error"] != "") throw new Error(`API returned an error: ${json["error"]}`);
|
||||||
throw new Error(`API returned an error: ${json["error"]}`);
|
|
||||||
|
|
||||||
if (!("result" in json))
|
if (!("result" in json)) throw new Error('API response is missing the "result" key');
|
||||||
throw new Error('API response is missing the "result" key');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function api_http_get(fetch, url) {
|
async function api_http_get(fetch, url) {
|
||||||
@@ -42,10 +39,4 @@ async function api_get_projects(fetch) {
|
|||||||
return await api_http_get(fetch, api_urljoin("/projects"));
|
return await api_http_get(fetch, api_urljoin("/projects"));
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export { api_version, api_urljoin, api_get_metrics, api_get_services, api_get_projects };
|
||||||
api_version,
|
|
||||||
api_urljoin,
|
|
||||||
api_get_metrics,
|
|
||||||
api_get_services,
|
|
||||||
api_get_projects,
|
|
||||||
};
|
|
||||||
|
@@ -5,8 +5,7 @@ function doc_urljoin(path = null, query = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doc_check_err(json) {
|
function doc_check_err(json) {
|
||||||
if ("error" in json)
|
if ("error" in json) throw new Error(`Documentation server returned an error: ${json["error"]}`);
|
||||||
throw new Error(`Documentation server returned an error: ${json["error"]}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doc_http_get(fetch, url) {
|
async function doc_http_get(fetch, url) {
|
||||||
|
@@ -18,9 +18,7 @@
|
|||||||
<footer style="border-top: solid 2px var(--{color()});">
|
<footer style="border-top: solid 2px var(--{color()});">
|
||||||
<div class="links">
|
<div class="links">
|
||||||
<span>
|
<span>
|
||||||
<Link link={import.meta.env.WEBSITE_SOURCE_URL} bold={true}
|
<Link link={import.meta.env.WEBSITE_SOURCE_URL} bold={true}>{$_("footer.source")}</Link>
|
||||||
>{$_("footer.source")}</Link
|
|
||||||
>
|
|
||||||
</span>
|
</span>
|
||||||
<span>/</span>
|
<span>/</span>
|
||||||
<span>
|
<span>
|
||||||
|
@@ -28,8 +28,7 @@ function locale_from_browser() {
|
|||||||
|
|
||||||
function locale_select(l = null) {
|
function locale_select(l = null) {
|
||||||
if (l === null) {
|
if (l === null) {
|
||||||
if (browser && null !== (l = localStorage.getItem("locale")))
|
if (browser && null !== (l = localStorage.getItem("locale"))) locale_select(l);
|
||||||
locale_select(l);
|
|
||||||
else locale_select(locale_from_browser());
|
else locale_select(locale_from_browser());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -3,13 +3,14 @@
|
|||||||
import { page } from "$app/stores";
|
import { page } from "$app/stores";
|
||||||
|
|
||||||
export let link;
|
export let link;
|
||||||
|
|
||||||
|
function is_active() {
|
||||||
|
return $page.url.pathname == link;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
style="
|
style="text-decoration-color: var(--{color()}); {is_active() ? `color: var(--${color()})` : ''}"
|
||||||
text-decoration-color: var(--{color()});
|
|
||||||
{$page.url.pathname === link ? `color: var(--${color()});` : ''}
|
|
||||||
"
|
|
||||||
data-sveltekit-preload-data
|
data-sveltekit-preload-data
|
||||||
on:click={click}
|
on:click={click}
|
||||||
href={link}
|
href={link}
|
||||||
|
@@ -15,13 +15,9 @@
|
|||||||
<p>{service.desc[$locale]}</p>
|
<p>{service.desc[$locale]}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="links">
|
<div class="links">
|
||||||
<Link highlight={false} link={service.clear}
|
<Link highlight={false} link={service.clear}><Icon icon="nf-oct-link" /></Link>
|
||||||
><Icon icon="nf-oct-link" /></Link
|
|
||||||
>
|
|
||||||
{#if service.onion != ""}
|
{#if service.onion != ""}
|
||||||
<Link highlight={false} link={service.onion}
|
<Link highlight={false} link={service.onion}><Icon icon="nf-linux-tor" /></Link>
|
||||||
><Icon icon="nf-linux-tor" /></Link
|
|
||||||
>
|
|
||||||
{/if}
|
{/if}
|
||||||
{#if service.i2p != ""}
|
{#if service.i2p != ""}
|
||||||
<Link highlight={false} link={service.i2p}
|
<Link highlight={false} link={service.i2p}
|
||||||
|
@@ -59,9 +59,7 @@
|
|||||||
<Link icon="nf-md-email" link="mailto:ngn@ngn.tf">Email</Link>
|
<Link icon="nf-md-email" link="mailto:ngn@ngn.tf">Email</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link icon="nf-md-mastodon" link="https://defcon.social/@ngn"
|
<Link icon="nf-md-mastodon" link="https://defcon.social/@ngn">Mastodon</Link>
|
||||||
>Mastodon</Link
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<span>
|
<span>
|
||||||
@@ -74,8 +72,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<i style="color: var(--{color()});" class="nf nf-md-speedometer_slow"
|
<i style="color: var(--{color()});" class="nf nf-md-speedometer_slow"></i>
|
||||||
></i>
|
|
||||||
{$_("home.services.speed")}
|
{$_("home.services.speed")}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -83,8 +80,7 @@
|
|||||||
{$_("home.services.security")}
|
{$_("home.services.security")}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i style="color: var(--{color()});" class="nf nf-fa-network_wired"
|
<i style="color: var(--{color()});" class="nf nf-fa-network_wired"></i>
|
||||||
></i>
|
|
||||||
{$_("home.services.privacy")}
|
{$_("home.services.privacy")}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
@@ -30,11 +30,7 @@
|
|||||||
|
|
||||||
function get_services() {
|
function get_services() {
|
||||||
return services.filter((s) => {
|
return services.filter((s) => {
|
||||||
return (
|
return s.desc[$locale] !== "" && s.desc[$locale] !== null && s.desc[$locale] !== undefined;
|
||||||
s.desc[$locale] !== "" &&
|
|
||||||
s.desc[$locale] !== null &&
|
|
||||||
s.desc[$locale] !== undefined
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,16 +48,10 @@
|
|||||||
<main>
|
<main>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{#if show_input}
|
{#if show_input}
|
||||||
<input
|
<input oninput={change} type="text" placeholder={$_("services.search")} />
|
||||||
oninput={change}
|
|
||||||
type="text"
|
|
||||||
placeholder={$_("services.search")}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
<div>
|
<div>
|
||||||
<Link icon="nf-fa-feed" link={api_urljoin("/news/" + $locale)}
|
<Link icon="nf-fa-feed" link={api_urljoin("/news/" + $locale)}>{$_("services.feed")}</Link>
|
||||||
>{$_("services.feed")}</Link
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="services">
|
<div class="services">
|
||||||
|
@@ -34,15 +34,12 @@
|
|||||||
--size-5: 24px;
|
--size-5: 24px;
|
||||||
--size-6: 30px;
|
--size-6: 30px;
|
||||||
|
|
||||||
--box-shadow-1:
|
--box-shadow-1: rgba(20, 20, 20, 0.19) 0px 10px 20px, rgba(30, 30, 30, 0.23) 0px 6px 6px;
|
||||||
rgba(20, 20, 20, 0.19) 0px 10px 20px, rgba(30, 30, 30, 0.23) 0px 6px 6px;
|
--box-shadow-2: rgba(0, 0, 0, 0.35) 0px 30px 60px -12px inset,
|
||||||
--box-shadow-2:
|
|
||||||
rgba(0, 0, 0, 0.35) 0px 30px 60px -12px inset,
|
|
||||||
rgba(20, 20, 20, 0.3) 0px 18px 36px -18px inset;
|
rgba(20, 20, 20, 0.3) 0px 18px 36px -18px inset;
|
||||||
|
|
||||||
--text-shadow: 3px 2px 8px rgba(50, 50, 50, 0.8);
|
--text-shadow: 3px 2px 8px rgba(50, 50, 50, 0.8);
|
||||||
--background:
|
--background: linear-gradient(rgba(11, 11, 11, 0.808), rgba(1, 1, 1, 0.96)),
|
||||||
linear-gradient(rgba(11, 11, 11, 0.808), rgba(1, 1, 1, 0.96)),
|
|
||||||
url("/assets/banner.png");
|
url("/assets/banner.png");
|
||||||
--profile-size: 220px;
|
--profile-size: 220px;
|
||||||
}
|
}
|
||||||
|
@@ -5,9 +5,8 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
color: #c9d1d9;
|
color: #c9d1d9;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
font-family:
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial,
|
||||||
-apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica,
|
sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||||
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
@@ -1027,9 +1026,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.markdown-body .contains-task-list:hover .task-list-item-convert-container,
|
.markdown-body .contains-task-list:hover .task-list-item-convert-container,
|
||||||
.markdown-body
|
.markdown-body .contains-task-list:focus-within .task-list-item-convert-container {
|
||||||
.contains-task-list:focus-within
|
|
||||||
.task-list-item-convert-container {
|
|
||||||
display: block;
|
display: block;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
@@ -81,7 +81,7 @@ BreakBeforeTernaryOperators: true
|
|||||||
BreakConstructorInitializers: BeforeColon
|
BreakConstructorInitializers: BeforeColon
|
||||||
BreakInheritanceList: BeforeColon
|
BreakInheritanceList: BeforeColon
|
||||||
BreakStringLiterals: true
|
BreakStringLiterals: true
|
||||||
ColumnLimit: 80
|
ColumnLimit: 120
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
# "gnu-zero-variadic-macro-arguments" ignored because we are using GNU99
|
|
||||||
# standart
|
|
||||||
|
|
||||||
# "clang-diagnostic-language-extension-token" is ignored because we need the
|
|
||||||
# asm() extension token
|
|
||||||
|
|
||||||
# "DeprecatedOrUnsafeBufferHandling" ignored because C11 "_s" functions are not
|
|
||||||
# secure either
|
|
||||||
Checks: >-
|
|
||||||
clang-diagnostic-*,
|
|
||||||
-clang-diagnostic-gnu-zero-variadic-macro-arguments,
|
|
||||||
-clang-diagnostic-language-extension-token,
|
|
||||||
clang-analyzer-*,
|
|
||||||
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
|
||||||
portability-*,
|
|
||||||
performance-*,
|
|
||||||
WarningsAsErrors: '*'
|
|
||||||
HeaderFileExtensions:
|
|
||||||
- ''
|
|
||||||
- h
|
|
||||||
- hh
|
|
||||||
- hpp
|
|
||||||
- hxx
|
|
||||||
ImplementationFileExtensions:
|
|
||||||
- c
|
|
||||||
- cc
|
|
||||||
- cpp
|
|
||||||
- cxx
|
|
||||||
HeaderFilterRegex: '.*'
|
|
||||||
ExcludeHeaderFilterRegex: ''
|
|
||||||
FormatStyle: file
|
|
||||||
SystemHeaders: false
|
|
||||||
...
|
|
||||||
|
|
@@ -1,9 +1,9 @@
|
|||||||
FROM ghcr.io/ngn13/ctorm:1.8.1
|
FROM ghcr.io/ngn13/ctorm:1.7
|
||||||
|
|
||||||
WORKDIR /doc
|
WORKDIR /doc
|
||||||
|
|
||||||
COPY Makefile ./
|
COPY Makefile ./
|
||||||
COPY pages ./pages
|
COPY docs ./docs
|
||||||
COPY inc ./inc
|
COPY inc ./inc
|
||||||
COPY src ./src
|
COPY src ./src
|
||||||
|
|
||||||
|
@@ -26,13 +26,10 @@ $(DISTDIR)/%.o: src/%.c
|
|||||||
format:
|
format:
|
||||||
clang-format -i -style=file $(CSRCS) $(HSRCS)
|
clang-format -i -style=file $(CSRCS) $(HSRCS)
|
||||||
|
|
||||||
lint:
|
|
||||||
clang-tidy --warnings-as-errors --config= $(CSRCS) $(HSRCS)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(DISTDIR)
|
rm -rf $(DISTDIR)
|
||||||
|
|
||||||
run:
|
run:
|
||||||
./doc.elf
|
./doc.elf
|
||||||
|
|
||||||
.PHONY: format lint clean run
|
.PHONY: format clean run
|
||||||
|
4
doc/docs/privacy.en.json
Normal file
4
doc/docs/privacy.en.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"title": "privacy",
|
||||||
|
"desc": "Learn how I respect your privacy"
|
||||||
|
}
|
4
doc/docs/privacy.tr.json
Normal file
4
doc/docs/privacy.tr.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"title": "gizlilik",
|
||||||
|
"desc": "Gizliliğinize nasıl önem verdiğimi öğrenin"
|
||||||
|
}
|
@@ -3,13 +3,13 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
#include "file.h"
|
#include "util.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
file_t *file;
|
util_file_t *file;
|
||||||
char name[NAME_MAX + 1];
|
char name[NAME_MAX + 1];
|
||||||
char *lang;
|
char *lang;
|
||||||
} docs_t;
|
} docs_t;
|
||||||
|
|
||||||
bool docs_init(docs_t *docs, char *dir);
|
bool docs_init(docs_t *docs, char *dir);
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *content;
|
|
||||||
int64_t size;
|
|
||||||
} file_t;
|
|
||||||
|
|
||||||
file_t *file_load(int dirfd, char *path);
|
|
||||||
void file_free(file_t *file);
|
|
@@ -4,8 +4,16 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#define util_toupper(str) \
|
typedef struct {
|
||||||
for (char *c = str; *c != 0; c++) \
|
char *content;
|
||||||
|
uint64_t size;
|
||||||
|
} util_file_t;
|
||||||
|
|
||||||
|
#define util_toupper(str) \
|
||||||
|
for (char *c = str; *c != 0; c++) \
|
||||||
*c = toupper(*c)
|
*c = toupper(*c)
|
||||||
uint64_t util_endswith(char *str, char *suf);
|
uint64_t util_endswith(char *str, char *suf);
|
||||||
void util_send(ctorm_res_t *res, uint16_t code, cJSON *json);
|
void util_send(ctorm_res_t *res, uint16_t code, cJSON *json);
|
||||||
|
util_file_t *util_file_load(int dirfd, char *path);
|
||||||
|
void util_file_free(util_file_t *file);
|
||||||
|
bool util_parse_doc_name(char *name, char **lang, const char *ext);
|
||||||
|
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"title": "privacy",
|
|
||||||
"desc": "Privacy policy"
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"title": "gizlilik",
|
|
||||||
"desc": "Gizlilik ilkesi"
|
|
||||||
}
|
|
@@ -11,25 +11,22 @@
|
|||||||
|
|
||||||
option_t options[] = {
|
option_t options[] = {
|
||||||
// name value requied
|
// name value requied
|
||||||
{"host", "0.0.0.0:7003", true }, // host the server should listen on
|
{"host", "0.0.0.0:7003", true }, // host the server should listen on
|
||||||
{"dir", "./pages", true }, // documentation pages directory
|
{"docs_dir", "./docs", true }, // documentation directory
|
||||||
{"", NULL, false},
|
{"", NULL, false},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool config_load(config_t *conf) {
|
bool config_load(config_t *conf) {
|
||||||
memset(conf, 0, sizeof(*conf));
|
bzero(conf, sizeof(*conf));
|
||||||
|
|
||||||
char name_env[OPT_NAME_MAX + 10], name_copy[OPT_NAME_MAX], *value = NULL;
|
char name_env[OPT_NAME_MAX + 10], name_copy[OPT_NAME_MAX], *value = NULL;
|
||||||
conf->options = options;
|
conf->options = options;
|
||||||
|
|
||||||
for (option_t *opt = conf->options; opt->value != NULL;
|
for (option_t *opt = conf->options; opt->value != NULL; opt++, conf->count++) {
|
||||||
opt++, conf->count++) {
|
strcpy(name_copy, opt->name);
|
||||||
// convert option name to environment variable name
|
|
||||||
strncpy(name_copy, opt->name, OPT_NAME_MAX);
|
|
||||||
util_toupper(name_copy);
|
util_toupper(name_copy);
|
||||||
snprintf(name_env, sizeof(name_env), "WEBSITE_%s", name_copy);
|
snprintf(name_env, sizeof(name_env), "WEBSITE_%s", name_copy);
|
||||||
|
|
||||||
// attempt to load the value from the environment
|
|
||||||
if ((value = getenv(name_env)) != NULL)
|
if ((value = getenv(name_env)) != NULL)
|
||||||
opt->value = value;
|
opt->value = value;
|
||||||
|
|
||||||
@@ -39,9 +36,7 @@ bool config_load(config_t *conf) {
|
|||||||
if (!opt->required || NULL != opt->value)
|
if (!opt->required || NULL != opt->value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ctorm_fail("please specify a value for the required config option: %s (%s)",
|
ctorm_fail("please specify a value for the required config option: %s (%s)", opt->name, name_env);
|
||||||
opt->name,
|
|
||||||
name_env);
|
|
||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#define DOCS_LANG_CODE_LEN 2
|
#define DOCS_LANG_CODE_LEN 2
|
||||||
|
|
||||||
bool _docs_parse_name(docs_t *docs, char *ext) {
|
bool __docs_parse_name(docs_t *docs, char *ext) {
|
||||||
// check the extension
|
// check the extension
|
||||||
uint64_t ext_pos = util_endswith(docs->name, ext);
|
uint64_t ext_pos = util_endswith(docs->name, ext);
|
||||||
|
|
||||||
@@ -22,8 +22,7 @@ bool _docs_parse_name(docs_t *docs, char *ext) {
|
|||||||
// example.en\0json\0
|
// example.en\0json\0
|
||||||
// |
|
// |
|
||||||
// `--- find this
|
// `--- find this
|
||||||
for (docs->lang = docs->name; *docs->lang != 0 && *docs->lang != '.';
|
for (docs->lang = docs->name; *docs->lang != 0 && *docs->lang != '.'; docs->lang++)
|
||||||
docs->lang++)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*docs->lang != '.')
|
if (*docs->lang != '.')
|
||||||
@@ -40,11 +39,11 @@ bool _docs_parse_name(docs_t *docs, char *ext) {
|
|||||||
return strlen(docs->lang) == DOCS_LANG_CODE_LEN && *docs->name != 0;
|
return strlen(docs->lang) == DOCS_LANG_CODE_LEN && *docs->name != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _docs_clean(docs_t *docs) {
|
void __docs_clean(docs_t *docs) {
|
||||||
if (NULL == docs->file)
|
if (NULL == docs->file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
file_free(docs->file);
|
util_file_free(docs->file);
|
||||||
docs->file = NULL;
|
docs->file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ bool docs_init(docs_t *docs, char *dir) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(docs, 0, sizeof(*docs));
|
bzero(docs, sizeof(*docs));
|
||||||
return NULL != (docs->dir = opendir(dir));
|
return NULL != (docs->dir = opendir(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,15 +64,15 @@ char *docs_next(docs_t *docs, char *name, bool content) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct dirent *ent = NULL;
|
struct dirent *ent = NULL;
|
||||||
_docs_clean(docs);
|
__docs_clean(docs);
|
||||||
|
|
||||||
while (NULL != (ent = readdir(docs->dir))) {
|
while (NULL != (ent = readdir(docs->dir))) {
|
||||||
if (*ent->d_name == '.')
|
if (*ent->d_name == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strncpy(docs->name, ent->d_name, NAME_MAX);
|
strcpy(docs->name, ent->d_name);
|
||||||
|
|
||||||
if (!_docs_parse_name(docs, content ? ".md" : ".json"))
|
if (!__docs_parse_name(docs, content ? ".md" : ".json"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (NULL == name || strncmp(docs->name, name, NAME_MAX) == 0)
|
if (NULL == name || strncmp(docs->name, name, NAME_MAX) == 0)
|
||||||
@@ -85,7 +84,7 @@ char *docs_next(docs_t *docs, char *name, bool content) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == (docs->file = file_load(dirfd(docs->dir), ent->d_name)))
|
if (NULL == (docs->file = util_file_load(dirfd(docs->dir), ent->d_name)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return docs->file->content;
|
return docs->file->content;
|
||||||
@@ -100,8 +99,8 @@ void docs_free(docs_t *docs) {
|
|||||||
if (NULL == docs)
|
if (NULL == docs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_docs_clean(docs);
|
__docs_clean(docs);
|
||||||
closedir(docs->dir);
|
closedir(docs->dir);
|
||||||
|
|
||||||
memset(docs, 0, sizeof(*docs));
|
bzero(docs, sizeof(*docs));
|
||||||
}
|
}
|
||||||
|
@@ -1,56 +0,0 @@
|
|||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "file.h"
|
|
||||||
|
|
||||||
file_t *file_load(int dirfd, char *path) {
|
|
||||||
if (NULL == path) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_t *file = NULL;
|
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
// open the taarget file
|
|
||||||
if ((fd = openat(dirfd, path, O_RDONLY)) < 0)
|
|
||||||
goto end; // errno set by open
|
|
||||||
|
|
||||||
// allocate a new file structure
|
|
||||||
if (NULL == (file = calloc(1, sizeof(file_t))))
|
|
||||||
goto end; // errno set by malloc
|
|
||||||
|
|
||||||
// calculate the file size
|
|
||||||
if ((file->size = lseek(fd, 0, SEEK_END)) < 0)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
// memory map the file
|
|
||||||
if (NULL ==
|
|
||||||
(file->content = mmap(0, file->size, PROT_READ, MAP_PRIVATE, fd, 0)))
|
|
||||||
goto end; // errno set by mmap
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (fd != -1)
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if (NULL != file && NULL == file->content) {
|
|
||||||
free(file);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
void file_free(file_t *file) {
|
|
||||||
if (NULL == file)
|
|
||||||
return;
|
|
||||||
|
|
||||||
munmap(file->content, file->size);
|
|
||||||
free(file);
|
|
||||||
}
|
|
@@ -1,4 +1,3 @@
|
|||||||
#include <ctorm/app.h>
|
|
||||||
#include <ctorm/ctorm.h>
|
#include <ctorm/ctorm.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -20,28 +19,25 @@ int main() {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize the app config
|
|
||||||
ctorm_config_new(&app_config);
|
ctorm_config_new(&app_config);
|
||||||
app_config.disable_logging = true;
|
app_config.disable_logging = true;
|
||||||
|
app = ctorm_app_new(&app_config);
|
||||||
// create a new app
|
|
||||||
app = ctorm_app_new(&app_config);
|
|
||||||
|
|
||||||
// middlewares
|
// middlewares
|
||||||
ALL(app, "/*", route_cors);
|
MIDDLEWARE_ALL(app, "/*", route_cors);
|
||||||
ALL(app, "/*/*", route_cors);
|
MIDDLEWARE_ALL(app, "/*/*", route_cors);
|
||||||
|
|
||||||
// routes
|
// routes
|
||||||
GET(app, "/list", route_list);
|
GET(app, "/list", route_list);
|
||||||
GET(app, "/get/:name", route_get);
|
GET(app, "/get/:name", route_get);
|
||||||
|
|
||||||
ctorm_app_default(app, route_notfound);
|
ctorm_app_all(app, route_notfound);
|
||||||
ctorm_app_local(app, "config", &conf);
|
ctorm_app_local(app, "config", &conf);
|
||||||
|
|
||||||
ctorm_info("starting the web server on %s", host);
|
ctorm_info("starting the web server on %s", host);
|
||||||
|
|
||||||
if (!ctorm_app_run(app, host))
|
if (!ctorm_app_run(app, host))
|
||||||
ctorm_fail("failed to start the app: %s", ctorm_error());
|
ctorm_fail("failed to start the app: %s", ctorm_geterror());
|
||||||
|
|
||||||
ctorm_app_free(app);
|
ctorm_app_free(app);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@@ -3,8 +3,7 @@
|
|||||||
void route_cors(ctorm_req_t *req, ctorm_res_t *res) {
|
void route_cors(ctorm_req_t *req, ctorm_res_t *res) {
|
||||||
RES_SET("Access-Control-Allow-Origin", "*");
|
RES_SET("Access-Control-Allow-Origin", "*");
|
||||||
RES_SET("Access-Control-Allow-Headers",
|
RES_SET("Access-Control-Allow-Headers",
|
||||||
"Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, "
|
"Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, "
|
||||||
"Authorization, accept, origin, Cache-Control, "
|
|
||||||
"X-Requested-With");
|
"X-Requested-With");
|
||||||
RES_SET("Access-Control-Allow-Methods", "PUT, DELETE, GET");
|
RES_SET("Access-Control-Allow-Methods", "PUT, DELETE, GET");
|
||||||
}
|
}
|
||||||
|
@@ -1,30 +1,31 @@
|
|||||||
#include <linux/limits.h>
|
|
||||||
#include <cjson/cJSON.h>
|
#include <cjson/cJSON.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
#include <ctorm/ctorm.h>
|
#include <ctorm/ctorm.h>
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util.h"
|
|
||||||
#include "docs.h"
|
#include "docs.h"
|
||||||
|
|
||||||
void route_get(ctorm_req_t *req, ctorm_res_t *res) {
|
void route_get(ctorm_req_t *req, ctorm_res_t *res) {
|
||||||
config_t *conf = REQ_LOCAL("config");
|
config_t *conf = REQ_LOCAL("config");
|
||||||
char *name = REQ_PARAM("name");
|
char *doc_name = REQ_PARAM("name");
|
||||||
char *dir = config_get(conf, "dir"), *doc_data = NULL;
|
char *docs_dir = config_get(conf, "docs_dir"), *doc_data = NULL;
|
||||||
cJSON *json = NULL, *doc_json = NULL;
|
cJSON *json = NULL, *doc_json = NULL;
|
||||||
docs_t docs;
|
docs_t docs;
|
||||||
|
|
||||||
if (NULL == name) {
|
if (NULL == doc_name) {
|
||||||
ctorm_fail("documentation name not specified (how did that even happend)");
|
ctorm_fail("documentation name not specified (how did that even happend)");
|
||||||
util_send(res, 500, NULL);
|
util_send(res, 500, NULL);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!docs_init(&docs, dir)) {
|
if (!docs_init(&docs, docs_dir)) {
|
||||||
ctorm_fail("docs_init failed: %s", ctorm_error());
|
ctorm_fail("docs_init failed: %s", ctorm_geterror());
|
||||||
util_send(res, 500, NULL);
|
util_send(res, 500, NULL);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -35,7 +36,7 @@ void route_get(ctorm_req_t *req, ctorm_res_t *res) {
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (NULL != (doc_data = docs_next(&docs, name, false))) {
|
while (NULL != (doc_data = docs_next(&docs, doc_name, false))) {
|
||||||
if (NULL == (doc_json = cJSON_Parse(doc_data))) {
|
if (NULL == (doc_json = cJSON_Parse(doc_data))) {
|
||||||
ctorm_fail("failed to parse JSON: %s (%s)", docs.name, docs.lang);
|
ctorm_fail("failed to parse JSON: %s (%s)", docs.name, docs.lang);
|
||||||
continue;
|
continue;
|
||||||
@@ -52,7 +53,7 @@ void route_get(ctorm_req_t *req, ctorm_res_t *res) {
|
|||||||
|
|
||||||
docs_reset(&docs);
|
docs_reset(&docs);
|
||||||
|
|
||||||
while (NULL != (doc_data = docs_next(&docs, name, true))) {
|
while (NULL != (doc_data = docs_next(&docs, doc_name, true))) {
|
||||||
if (NULL == (doc_json = cJSON_GetObjectItem(json, docs.lang)))
|
if (NULL == (doc_json = cJSON_GetObjectItem(json, docs.lang)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@@ -3,21 +3,21 @@
|
|||||||
#include <ctorm/ctorm.h>
|
#include <ctorm/ctorm.h>
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util.h"
|
|
||||||
#include "docs.h"
|
#include "docs.h"
|
||||||
|
|
||||||
void route_list(ctorm_req_t *req, ctorm_res_t *res) {
|
void route_list(ctorm_req_t *req, ctorm_res_t *res) {
|
||||||
config_t *conf = REQ_LOCAL("config");
|
config_t *conf = REQ_LOCAL("config");
|
||||||
char *dir = config_get(conf, "dir"), *doc_data = NULL;
|
char *docs_dir = config_get(conf, "docs_dir"), *doc_data = NULL;
|
||||||
cJSON *array = NULL, *json = NULL, *doc_json = NULL;
|
cJSON *array = NULL, *json = NULL, *doc_json = NULL;
|
||||||
docs_t docs;
|
docs_t docs;
|
||||||
|
|
||||||
if (!docs_init(&docs, dir)) {
|
if (!docs_init(&docs, docs_dir)) {
|
||||||
ctorm_fail("docs_init failed: %s", ctorm_error());
|
ctorm_fail("docs_init failed: %s", ctorm_geterror());
|
||||||
util_send(res, 500, NULL);
|
util_send(res, 500, NULL);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -31,8 +31,7 @@ void route_list(ctorm_req_t *req, ctorm_res_t *res) {
|
|||||||
while (NULL != (doc_data = docs_next(&docs, NULL, false))) {
|
while (NULL != (doc_data = docs_next(&docs, NULL, false))) {
|
||||||
if (NULL == (array = cJSON_GetObjectItem(json, docs.lang)) &&
|
if (NULL == (array = cJSON_GetObjectItem(json, docs.lang)) &&
|
||||||
NULL == (array = cJSON_AddArrayToObject(json, docs.lang))) {
|
NULL == (array = cJSON_AddArrayToObject(json, docs.lang))) {
|
||||||
ctorm_fail(
|
ctorm_fail("failed to create an array object for the language %s", docs.lang);
|
||||||
"failed to create an array object for the language %s", docs.lang);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,17 @@
|
|||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <ctorm/ctorm.h>
|
#include <ctorm/ctorm.h>
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -48,3 +57,45 @@ void util_send(ctorm_res_t *res, uint16_t code, cJSON *json) {
|
|||||||
|
|
||||||
RES_JSON(json);
|
RES_JSON(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
util_file_t *util_file_load(int dirfd, char *path) {
|
||||||
|
if (NULL == path) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
util_file_t *file = NULL;
|
||||||
|
struct stat buf;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
if (NULL == (file = malloc(sizeof(util_file_t))))
|
||||||
|
goto end; // errno set by malloc
|
||||||
|
|
||||||
|
if ((fd = openat(dirfd, path, O_RDONLY)) < 0)
|
||||||
|
goto end; // errno set by open
|
||||||
|
|
||||||
|
if (fstat(fd, &buf) < 0)
|
||||||
|
goto end; // errno set by fstat
|
||||||
|
|
||||||
|
if (NULL == (file->content = mmap(0, (file->size = buf.st_size), PROT_READ, MAP_PRIVATE, fd, 0)))
|
||||||
|
goto end; // errno set by mmap
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if (NULL == file->content) {
|
||||||
|
free(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_file_free(util_file_t *file) {
|
||||||
|
if (NULL == file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
munmap(file->content, file->size);
|
||||||
|
free(file);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user