added unwrapped json for gallery-image/list and news/list, integerated news-list api into news api

This commit is contained in:
2024-11-05 01:01:07 +09:00
parent d4ec57aa0d
commit 1ab17242f7
7 changed files with 95 additions and 73 deletions

View File

@@ -41,16 +41,17 @@ npm run dev # JSファイル変更時に自動リロードが入る開発サー
## API(RESTful) ## API(RESTful)
* `/api/news` * `/api/news`
* GET: Unix時間で特定されたニュースの情報を取得する - `?target=<Unix時間>` * GET(`/`): Unix時間で特定されたニュースの情報を取得する - `?target=<Unix時間>`
* GET(`/list`): HTML/HTMX形式で全ニュースの情報を取得する
* GET(`/list-unwrapped`): JSON形式で全ニュースの情報を取得する
* POST: 新しいニュースを作成する * POST: 新しいニュースを作成する
* PUT: ニュースの内容を更新する * PUT: ニュースの内容を更新する
* DELETE: Unix時間で特定されたニュースを削除する - `?target=<Unix時間>` * DELETE: Unix時間で特定されたニュースを削除する - `?target=<Unix時間>`
* `/api/news-list`
* GET: 全ニュースの情報を取得する
* `/api/gallery-image` * `/api/gallery-image`
* GET(`/`): IDで指定された画像へのパスと説明文を取得する - `?target=<ID>` * GET(`/`): IDで指定された画像へのパスと説明文を取得する - `?target=<ID>`
* GET(`/list`): 全画像の情報を取得する * GET(`/list`): HTML/HTMX形式で全画像の情報を取得する
* GET(`/list-unwrapped`): JSON形式で全画像の情報を取得する
* POST: 新しい画像の情報を追加する * POST: 新しい画像の情報を追加する
* PUT: 画像の情報を更新する * PUT: 画像の情報を更新する
* DELETE: IDで指定された画像の情報を削除する - `?target=<ID>` * DELETE: IDで指定された画像の情報を削除する - `?target=<ID>`

View File

@@ -19,12 +19,9 @@ galleryImageAPI.get('/list', async (request, response) => {
for (const entry of rows) { for (const entry of rows) {
ret = ret + "<tr>\n"; ret = ret + "<tr>\n";
for (const data in entry) { for (const data in entry) {
ret = ret + `<td>${entry[data]}</td>\n`; ret = ret + `\t<td>${entry[data]}</td>\n`;
} }
ret = ret + `<td>\n ret = ret + `\t<td>\n\t\t<button class='delete-button' hx-delete='/api/gallery-image?target=${entry["id"]}'>Delete</button>\n\t\t<a href='/update-gallery-image.html?target=${entry["id"]}'><button class='edit-button' hx-confirm='unset'>Edit</button></a>\n\t</td>\n</tr>\n`;
<button class='delete-button' hx-delete='/api/gallery-image?target=${entry["id"]}'>Delete</button>\n
<a href='/update-gallery-image.html?target=${entry["id"]}'><button class='edit-button' hx-confirm='unset'>Edit</button></a>\n
</td>\n</tr>\n`;
} }
return ret; return ret;
}); });
@@ -34,6 +31,23 @@ galleryImageAPI.get('/list', async (request, response) => {
} catch (err) { } catch (err) {
console.error(err); console.error(err);
database.close(); database.close();
response.status(500).send(err);
}
});
galleryImageAPI.get('/list-unwrapped', async (request, response) => {
const database = new sqlite3.Database(databasePath);
const sqlQuery = "SELECT * FROM gallery";
try {
const result = await asyncDatabaseRead(database, sqlQuery, (rows) => { return rows; });
database.close();
response.send(result);
} catch (err) {
console.error(err);
database.close();
response.status(500).send(err);
} }
}); });
@@ -56,6 +70,7 @@ galleryImageAPI.get('/', async (request, response) => {
} catch (err) { } catch (err) {
console.error(err); console.error(err);
database.close(); database.close();
response.status(500).send(err);
} }
}); });
@@ -72,6 +87,7 @@ galleryImageAPI.post('/', async (request, response) => {
console.log("Image added successfully."); console.log("Image added successfully.");
}); });
} catch (err) { } catch (err) {
console.error(err);
response.status(500).send(err); response.status(500).send(err);
} }
@@ -99,6 +115,7 @@ galleryImageAPI.put('/', async (request, response) => {
console.log("Image updated successfully."); console.log("Image updated successfully.");
}); });
} catch (err) { } catch (err) {
console.error(err);
response.status(500).send(err); response.status(500).send(err);
} }
@@ -123,6 +140,7 @@ galleryImageAPI.delete('/', async (request, response) => {
console.log("Image deleted successfully."); console.log("Image deleted successfully.");
}); });
} catch (err) { } catch (err) {
console.error(err);
response.status(500).send(err); response.status(500).send(err);
} }
@@ -130,4 +148,4 @@ galleryImageAPI.delete('/', async (request, response) => {
response.status(200).send(); response.status(200).send();
}); });
export default galleryImageAPI; export default galleryImageAPI;

View File

@@ -1,13 +1,11 @@
import express from 'express'; import express from 'express';
import newsAPI from './news.js'; import newsAPI from './news.js';
import newsListAPI from './news-list.js';
import galleryImageAPI from './gallery-image.js'; import galleryImageAPI from './gallery-image.js';
const router = express.Router(); const router = express.Router();
router.use('/news', newsAPI); router.use('/news', newsAPI);
router.use('/news-list', newsListAPI);
router.use('/gallery-image', galleryImageAPI); router.use('/gallery-image', galleryImageAPI);
export default router; export default router;

View File

@@ -1,47 +0,0 @@
import express from 'express';
import sqlite3 from 'sqlite3';
import path from 'path';
import { fileURLToPath } from 'url';
import { asyncDatabaseRead } from '../utils/asyncDatabase.js';
const newsListAPI = express.Router();
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const databasePath = path.join(__dirname, "../../assets/databases/news.db");
newsListAPI.get('/', async (request, response) => {
const database = new sqlite3.Database(databasePath);
const sqlQuery = `SELECT * FROM news ORDER BY date DESC;`;
try {
const result = await asyncDatabaseRead(database, sqlQuery, (rows) => {
let ret = "";
for (const entry of rows) {
ret = ret + "<tr>\n";
for (const data in entry) {
if (data == "article" || data == "coverImagePath" || data == "linkPath") continue;
if (data == "entryType") {
ret = ret + `<td>${entry[data] == 0 ? "Article" : "Tweet"}</td>\n`;
continue;
}
if (data == "date") {
ret = ret + `<td>${new Date(entry[data]).toLocaleString()}</td>\n`;
continue;
}
ret = ret + `<td>${entry[data]}</td>\n`;
}
ret = ret + `<td>\n
<button class='delete-button' hx-delete='/api/news?target=${entry["date"]}'>Delete</button>\n
<a href='/update-news.html?target=${entry["date"]}'><button class='edit-button' hx-confirm='unset'>Edit</button></a>\n
</td>\n</tr>\n`;
}
return ret
});
database.close();
response.send(result);
} catch (err) {
console.error(err);
database.close();
}
});
export default newsListAPI;

View File

@@ -15,6 +15,7 @@ newsAPI.get('/', async (request, response) => {
const target = Number(request.query.target); const target = Number(request.query.target);
if (isNaN(target)) { if (isNaN(target)) {
console.error("Query is not number");
response.status(500).send("Query is not number"); response.status(500).send("Query is not number");
return; return;
} }
@@ -33,7 +34,7 @@ newsAPI.get('/', async (request, response) => {
newsAPI.post('/', async (request, response) => { newsAPI.post('/', async (request, response) => {
const database = new sqlite3.Database(databasePath); const database = new sqlite3.Database(databasePath);
const currentDate = new Date(); const currentDate = new Date();
const currentUnixTime = currentDate.valueOf(); const currentUnixTime = currentDate.valueOf();
const entryType = request.body.entryType; const entryType = request.body.entryType;
@@ -41,14 +42,15 @@ newsAPI.post('/', async (request, response) => {
const article = request.body.article; const article = request.body.article;
const linkPath = entryType == 0 ? `/news/${request.body.linkPath}` : ""; const linkPath = entryType == 0 ? `/news/${request.body.linkPath}` : "";
const coverImagePath = request.body.coverImagePath; const coverImagePath = request.body.coverImagePath;
const sqlQuery = `INSERT INTO news (date, entryType, cardContent, article, linkPath, coverImagePath) VALUES (${currentUnixTime}, ${entryType}, "${cardContent}", "${article}", "${linkPath}", "${coverImagePath}");`; const sqlQuery = `INSERT INTO news (date, entryType, cardContent, article, linkPath, coverImagePath) VALUES (${currentUnixTime}, ${entryType}, "${cardContent}", "${article}", "${linkPath}", "${coverImagePath}");`;
try { try {
await asyncDatabaseWrite(database, sqlQuery, () => { await asyncDatabaseWrite(database, sqlQuery, () => {
console.log("News added successfully."); console.log("News added successfully.");
}); });
} catch (err) { } catch (err) {
console.error(err);
response.status(500).send(err); response.status(500).send(err);
} }
database.close(); database.close();
@@ -66,6 +68,7 @@ newsAPI.put('/', async (request, response) => {
const coverImagePath = request.body.coverImagePath; const coverImagePath = request.body.coverImagePath;
if (isNaN(target)) { if (isNaN(target)) {
console.error('Target is not number');
response.status(500).send('Target is not number'); response.status(500).send('Target is not number');
return; return;
} }
@@ -77,6 +80,7 @@ newsAPI.put('/', async (request, response) => {
console.log("News updated successfully."); console.log("News updated successfully.");
}); });
} catch (err) { } catch (err) {
console.error(err);
response.status(500).send(err); response.status(500).send(err);
} }
@@ -90,6 +94,7 @@ newsAPI.delete('/', async (request, response) => {
const target = Number(request.query.target); const target = Number(request.query.target);
if (isNaN(target)) { if (isNaN(target)) {
console.error('No Entry Found!');
response.status(404).send('No Entry Found!'); response.status(404).send('No Entry Found!');
return; return;
} }
@@ -101,6 +106,7 @@ newsAPI.delete('/', async (request, response) => {
console.log("News deleted successfully."); console.log("News deleted successfully.");
}); });
} catch (err) { } catch (err) {
console.error(err);
response.status(500).send(err); response.status(500).send(err);
} }
@@ -109,4 +115,50 @@ newsAPI.delete('/', async (request, response) => {
response.status(200).send(); response.status(200).send();
}); });
export default newsAPI; newsAPI.get('/list', async (request, response) => {
const database = new sqlite3.Database(databasePath);
const sqlQuery = `SELECT id, date, entryType, cardContent FROM news ORDER BY date DESC;`;
try {
const result = await asyncDatabaseRead(database, sqlQuery, (rows) => {
let ret = "";
for (const entry of rows) {
ret = ret + "<tr>\n";
for (const data in entry) {
if (data == "entryType") {
ret = ret + `\t<td>${entry[data] == 0 ? "Article" : "Tweet"}</td>\n`;
continue;
}
if (data == "date") {
ret = ret + `\t<td>${new Date(entry[data]).toLocaleString()}</td>\n`;
continue;
}
ret = ret + `\t<td>${entry[data]}</td>\n`;
}
ret = ret + `\t<td>\n\t\t<button class='delete-button' hx-delete='/api/news?target=${entry["date"]}'>Delete</button>\n\t\t<a href='/update-news.html?target=${entry["date"]}'><button class='edit-button' hx-confirm='unset'>Edit</button></a>\n\t</td>\n</tr>\n`;
}
return ret
});
database.close();
response.send(result);
} catch (err) {
console.error(err);
database.close();
}
});
newsAPI.get('/list-unwrapped', async (request, response) => {
const database = new sqlite3.Database(databasePath);
const sqlQuery = `SELECT id, date, entryType, cardContent FROM news ORDER BY date DESC;`;
try {
const result = await asyncDatabaseRead(database, sqlQuery, (rows) => { return rows; });
database.close();
response.send(result);
} catch (err) {
console.error(err);
database.close();
}
});
export default newsAPI;

View File

@@ -38,13 +38,13 @@
} }
}, },
"node_modules/@babel/parser": { "node_modules/@babel/parser": {
"version": "7.25.9", "version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.9.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
"integrity": "sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==", "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/types": "^7.25.9" "@babel/types": "^7.26.0"
}, },
"bin": { "bin": {
"parser": "bin/babel-parser.js" "parser": "bin/babel-parser.js"
@@ -54,9 +54,9 @@
} }
}, },
"node_modules/@babel/types": { "node_modules/@babel/types": {
"version": "7.25.9", "version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.9.tgz", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
"integrity": "sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==", "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@@ -34,7 +34,7 @@
<h4>News</h4> <h4>News</h4>
<button hx-get="/api/news-list" hx-trigger="click" hx-swap="innerHTML" hx-target="#news-entries">Refresh</button> <button hx-get="/api/news/list" hx-trigger="click" hx-swap="innerHTML" hx-target="#news-entries">Refresh</button>
<table> <table>
<thead> <thead>
<tr> <tr>