From 3b1db444e6592865ca8e15dd45619a43baaaaeb3 Mon Sep 17 00:00:00 2001 From: Jemma Date: Tue, 4 Apr 2023 18:50:53 -0500 Subject: [PATCH] Added /v1/posts.search endpoint --- src/server.js | 37 ++++++++++++------- src/services/miiverse-api/index.js | 1 + src/services/miiverse-api/routes/post.js | 18 ++++++++++ src/util/CommunityPostGen.js | 45 ++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 12 deletions(-) diff --git a/src/server.js b/src/server.js index 4b15fe5..d37b08b 100644 --- a/src/server.js +++ b/src/server.js @@ -11,6 +11,7 @@ const { http: { port } } = config; const app = express(); const miiverse = require('./services/miiverse-api'); +const xml = require("object-to-xml"); app.set('etag', false); app.disable('x-powered-by'); @@ -33,24 +34,36 @@ app.use(miiverse); // 404 handler logger.info('Creating 404 status handler'); -app.use((request, response) => { +app.use((req, res) => { //logger.warn(request.protocol + '://' + request.get('host') + request.originalUrl); - response.status(404); - response.send(); + res.set("Content-Type", "application/xml"); + res.statusCode = 404; + let response = { + result: { + has_error: 1, + version: 1, + code: 404, + message: "Not Found" + } + }; + return res.send("\n" + xml(response)); }); // non-404 error handler logger.info('Creating non-404 status handler'); -app.use((error, request, response) => { +app.use((error, req, res) => { const status = error.status || 500; - - response.status(status); - - response.json({ - app: 'api', - status, - error: error.message - }); + res.set("Content-Type", "application/xml"); + res.statusCode = 404; + let response = { + result: { + has_error: 1, + version: 1, + code: status, + message: "Not Found" + } + }; + return res.send("\n" + xml(response)); }); // Starts the server diff --git a/src/services/miiverse-api/index.js b/src/services/miiverse-api/index.js index 5633a87..d888ef9 100644 --- a/src/services/miiverse-api/index.js +++ b/src/services/miiverse-api/index.js @@ -28,6 +28,7 @@ discovery.use(pnidMiddleware); // Setup routes discovery.use('/v1/endpoint', routes.DISCOVERY); api.use('/v1/posts', routes.POST); +api.use('/v1/posts.search', routes.POST); api.use('/v1/friend_messages', routes.MESSAGE); api.use('/v1/communities/', routes.COMMUNITY); api.use('/v1/people/', routes.PEOPLE); diff --git a/src/services/miiverse-api/routes/post.js b/src/services/miiverse-api/routes/post.js index b526805..e7a0256 100644 --- a/src/services/miiverse-api/routes/post.js +++ b/src/services/miiverse-api/routes/post.js @@ -61,6 +61,24 @@ router.get('/:post_id/replies', async function (req, res) { res.send(response); }); +router.get('', async function (req, res) { + const post = await database.getPostByID(req.query.post_id); + if(!post) { + res.set("Content-Type", "application/xml"); + res.statusCode = 404; + let response = { + result: { + has_error: 1, + version: 1, + code: 404, + message: "Not Found" + } + }; + return res.send("\n" + xml(response)); + } + else res.send(await communityPostGen.queryResponse(post)); +}); + module.exports = router; async function newPost(req, res) { diff --git a/src/util/CommunityPostGen.js b/src/util/CommunityPostGen.js index aa8fe2f..22aa6b8 100644 --- a/src/util/CommunityPostGen.js +++ b/src/util/CommunityPostGen.js @@ -213,6 +213,51 @@ class CommunityPostGen { return xml.end({ pretty: true, allowEmpty: true }); } + static async queryResponse(post) { + let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) + .e("has_error", "0").up() + .e("version", "1").up() + .e("request_name", "posts.search").up() + .e("posts") + .e("post"); + if (post.app_data) { + xml = xml.e("app_data", post.app_data.replace(/[^A-Za-z0-9+/=]/g, "").replace(/[\n\r]+/gm, '').trim()).up(); + } + xml = xml.e("body", post.body ? post.body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}+=,.<>/?;:'"\[\]]/g, "") : "").up() + .e("community_id", post.community_id).up() + .e("country_id", post.country_id).up() + .e("created_at", post.created_at).up() + .e("feeling_id", post.feeling_id).up() + .e("id", post.id).up() + .e("is_autopost", post.is_autopost).up() + .e("is_community_private_autopost", post.is_community_private_autopost).up() + .e("is_spoiler", post.is_spoiler).up() + .e("is_app_jumpable", post.is_app_jumpable).up() + .e("empathy_count", post.empathy_count).up() + .e("language_id", post.language_id).up(); + if(post.mii) { + xml = xml.e("mii", post.mii).up() + .e("mii_face_url", post.mii_face_url).up() + } + xml = xml.e("number", "0").up(); + if (post.painting) { + xml = xml.e("painting") + .e("format", "tga").up() + .e("content", post.painting.replace(/\r?\n|\r/g, "").trim()).up() + .e("size", post.painting.length).up() + .e("url", `https://pretendo-cdn.b-cdn.net/paintings/${post.pid}/{${post.id}.png`).up() + .up(); + } + xml = xml.e("pid", post.pid).up() + .e("platform_id", post.platform_id).up() + .e("region_id", post.region_id).up() + .e("reply_count", post.reply_count).up() + .e("screen_name", post.screen_name).up() + .e("title_id", post.title_id).up() + .up().up(); + return xml.end({ pretty: true, allowEmpty: true }); + } + static async topics(communities) { const expirationDate = moment().add(1, 'days'); let xml = xmlbuilder.create("result", { encoding: 'UTF-8' })