diff --git a/src/models/post.js b/src/models/post.js index 3e23155..510d430 100644 --- a/src/models/post.js +++ b/src/models/post.js @@ -8,6 +8,7 @@ const PostSchema = new Schema({ app_data: String, painting: String, screenshot: String, + screenshot_length: Number, search_key: { type: [String], default: undefined diff --git a/src/services/miiverse-api/routes/communities.js b/src/services/miiverse-api/routes/communities.js index 1f84a1e..9764bf5 100644 --- a/src/services/miiverse-api/routes/communities.js +++ b/src/services/miiverse-api/routes/communities.js @@ -1,7 +1,7 @@ const express = require('express'); const router = express.Router(); const database = require('../../../database'); -const comPostGen = require('../../../util/CommunityPostGen'); +const comPostGen = require('../../../util/xmlResponseGenerator'); const processHeaders = require('../../../util/util'); const {COMMUNITY} = require("../../../models/communities"); const {POST} = require("../../../models/post"); @@ -25,10 +25,7 @@ router.get('/popular', async function (req, res) { if (community != null) { res.contentType("application/json"); res.send(community); - } else { - res.status(404); - res.send(); - } + } else res.sendStatus(404); }); router.get('/new', async function (req, res) { @@ -36,10 +33,7 @@ router.get('/new', async function (req, res) { if (community != null) { res.contentType("application/json"); res.send(community); - } else { - res.status(404); - res.send(); - } + } else res.sendStatus(404); }); router.get('/0/posts', async function (req, res) { @@ -53,19 +47,14 @@ router.get('/0/posts', async function (req, res) { else posts = await database.getPostsByCommunity(community, parseInt(req.query.limit)); /* Build formatted response and send it off. */ - let response; - if(req.query.with_mii === '1') - response = await comPostGen.PostsResponseWithMii(posts, community); - else - response = await comPostGen.PostsResponse(posts, community); + let options = { + name: 'posts', + with_mii: req.query.with_mii === 1 + } res.contentType("application/xml"); - res.send(response); - } - else - { - res.status(404); - res.send(); + res.send(await comPostGen.PostsResponse(posts, community, options)); } + else res.sendStatus(404); }); router.get('/:appID/posts', async function (req, res) { @@ -89,13 +78,12 @@ router.get('/:appID/posts', async function (req, res) { let posts = await POST.find(query).sort({ created_at: -1}).limit(parseInt(req.query.limit)); /* Build formatted response and send it off. */ - let response; - if(req.query.with_mii === '1') - response = await comPostGen.PostsResponseWithMii(posts, community); - else - response = await comPostGen.PostsResponse(posts, community); + let options = { + name: 'posts', + with_mii: req.query.with_mii === 1 + } res.contentType("application/xml"); - res.send(response); + res.send(await comPostGen.PostsResponse(posts, community, options)); }); module.exports = router; diff --git a/src/services/miiverse-api/routes/people.js b/src/services/miiverse-api/routes/people.js index 7c0b5d7..94fbd8d 100644 --- a/src/services/miiverse-api/routes/people.js +++ b/src/services/miiverse-api/routes/people.js @@ -1,7 +1,7 @@ const express = require('express'); const router = express.Router(); const database = require('../../../database'); -const pplPostGen = require('../../../util/peoplePostGen'); +const xmlGenerator = require('../../../util/xmlResponseGenerator'); /* GET post titles. */ router.get('/', async function (req, res) { @@ -15,13 +15,12 @@ router.get('/', async function (req, res) { posts = await database.getPostsByCommunity(community, parseInt(req.query.limit)); /* Build formatted response and send it off. */ - let response; - if(req.query.with_mii === 1) - response = await pplPostGen.PostsResponseWithMii(posts, community); - else - response = await pplPostGen.PostsResponse(posts, community); + let options = { + name: 'people', + with_mii: req.query.with_mii === 1 + } res.contentType("application/xml"); - res.send(response); + res.send(await xmlGenerator.PostsResponse(posts, community, options)); } else { @@ -35,7 +34,7 @@ router.get('/:pid/following', async function (req, res) { if(!user) res.sendStatus(404); let people = await database.getFollowedUsers(user); if(!people) res.sendStatus(404); - res.send(await pplPostGen.People(people)); + res.send(await xmlGenerator.People(people)); }); module.exports = router; diff --git a/src/services/miiverse-api/routes/post.js b/src/services/miiverse-api/routes/post.js index e7a0256..281ea4c 100644 --- a/src/services/miiverse-api/routes/post.js +++ b/src/services/miiverse-api/routes/post.js @@ -6,10 +6,10 @@ const util = require('../../../util/util'); const database = require('../../../database'); const multer = require('multer'); const snowflake = require('node-snowflake').Snowflake; -const communityPostGen = require('../../../util/CommunityPostGen'); +const communityPostGen = require('../../../util/xmlResponseGenerator'); const {COMMUNITY} = require("../../../models/communities"); const processHeaders = require("../../../util/util"); -const comPostGen = require("../../../util/CommunityPostGen"); +const comPostGen = require("../../../util/xmlResponseGenerator"); const upload = multer(); /* GET post titles. */ @@ -54,9 +54,12 @@ router.get('/:post_id/replies', async function (req, res) { const posts = await database.getPostReplies(post.id, req.query.limit) if(!posts.length === 0) return res.sendStatus(404); - + let options = { + name: 'replies', + with_mii: req.query.with_mii === 1 + } /* Build formatted response and send it off. */ - let response = await communityPostGen.RepliesResponse(posts) + let response = await communityPostGen.RepliesResponse(posts, options) res.contentType("application/xml"); res.send(response); }); @@ -76,7 +79,7 @@ router.get('', async function (req, res) { }; return res.send("\n" + xml(response)); } - else res.send(await communityPostGen.queryResponse(post)); + else res.send(await communityPostGen.QueryResponse(post)); }); module.exports = router; @@ -148,6 +151,7 @@ async function newPost(req, res) { app_data: appData, painting: painting, screenshot: screenshot ? `/screenshots/${req.pid}/${postID}.jpg`: "", + screenshot_length: screenshot ? screenshot.length : null, country_id: paramPackData.country_id, created_at: new Date(), feeling_id: req.body.feeling_id, @@ -158,7 +162,7 @@ async function newPost(req, res) { is_app_jumpable: req.body.is_app_jumpable, language_id: req.body.language_id, mii: PNID.mii.data, - mii_face_url: `http://mii.olv.pretendo.cc/mii/${PNID.pid}/${miiFace}`, + mii_face_url: `https://mii.olv.pretendo.cc/mii/${PNID.pid}/${miiFace}`, pid: req.pid, platform_id: paramPackData.platform_id, region_id: paramPackData.region_id, diff --git a/src/services/miiverse-api/routes/topics.js b/src/services/miiverse-api/routes/topics.js index d0fcdc3..6e418a3 100644 --- a/src/services/miiverse-api/routes/topics.js +++ b/src/services/miiverse-api/routes/topics.js @@ -1,7 +1,7 @@ const express = require('express'); const router = express.Router(); const database = require('../../../database'); -const comPostGen = require('../../../util/CommunityPostGen'); +const comPostGen = require('../../../util/xmlResponseGenerator'); let memoize = require("memoizee"); memoized = memoize(comPostGen.topics, { async: true, maxAge: 1000 * 60 * 60 }); diff --git a/src/util/CommunityPostGen.js b/src/util/CommunityPostGen.js deleted file mode 100644 index 22aa6b8..0000000 --- a/src/util/CommunityPostGen.js +++ /dev/null @@ -1,329 +0,0 @@ -const xmlbuilder = require("xmlbuilder"); -const moment = require("moment"); -const database = require('../database'); - -class CommunityPostGen { - /* TODO lots of stubs and constants in here */ - static async PostsResponse(posts, community) { - let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) - .e("has_error", "0").up() - .e("version", "1").up() - .e("request_name", "posts").up() - .e("topic") - .e("community_id", community.app_id ? community.app_id : community.community_id).up() - .up() - .e("posts"); - for (let i = 0; i < posts.length; i++) { - xml = xml.e("post") - .e("app_data", posts[i].app_data.replace(/[^A-Za-z0-9+/=\s\r?\n|\r]/g, "").replace(/[\n\r]+/gm, '').trim()).up() - .e("body", posts[i].body ? posts[i].body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}+=,.<>/?;:'"\[\]]/g, "") : "").up() - .e("community_id", 0).up() - .e("country_id", "254").up() - .e("created_at", moment(posts[i].created_at).format("YYYY-MM-DD hh:mm:ss")).up() - .e("feeling_id", "1").up() - .e("id", posts[i].id).up() - .e("is_autopost", "0").up() - .e("is_community_private_autopost", "0").up() - .e("is_spoiler", "0").up() - .e("is_app_jumpable", "0").up() - .e("empathy_count", posts[i].empathy_count).up() - .e("language_id", "1").up() - .e("number", "0").up(); - if (posts[i].painting) { - xml = xml.e("painting") - .e("format", "tga").up() - .e("content", posts[i].painting).up() - .e("size", posts[i].painting.length).up() - .e("url", "https://s3.amazonaws.com/olv-public/pap/WVW69koebmETvBVqm1").up() - .up(); - } - xml = xml.e("pid", posts[i].pid).up() - .e("platform_id", "1").up() - .e("region_id", "4").up() - .e("reply_count", "0").up() - .e("screen_name", posts[i].screen_name.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}+=,.<>/?;:'"\[\]]/g, "")).up() - .e("title_id", community.title_id[0]).up() - .up(); - } - - return xml.end({ pretty: true, allowEmpty: true }); - } - - static async RepliesResponse(posts) { - let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) - .e("has_error", "0").up() - .e("version", "1").up() - .e("request_name", "replies").up() - .e("posts"); - for (let i = 0; i < posts.length; i++) { - xml = xml.e("post") - .e("app_data", posts[i].app_data.replace(/[^A-Za-z0-9+/=\s\r?\n|\r]/g, "").replace(/[\n\r]+/gm, '').trim()).up() - .e("body", posts[i].body ? posts[i].body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}+=,.<>/?;:'"\[\]]/g, "") : "").up() - .e("community_id", 0).up() - .e("country_id", "254").up() - .e("created_at", moment(posts[i].created_at).format("YYYY-MM-DD hh:mm:ss")).up() - .e("feeling_id", "1").up() - .e("id", posts[i].id).up() - .e("is_autopost", posts[i].is_autopost).up() - .e("is_community_private_autopost", posts[i].is_community_private_autopost).up() - .e("is_spoiler", posts[i].is_spoiler).up() - .e("is_app_jumpable", "0").up() - .e("empathy_count", posts[i].empathy_count).up() - .e("language_id", posts[i].language_id).up() - .e("mii", posts[i].mii.replace(/\r?\n|\r/g, "").trim()).up() - .e("mii_face_url", posts[i].mii_face_url).up() - .e("number", "0").up(); - if (posts[i].painting) { - xml = xml.e("painting") - .e("format", "tga").up() - .e("content", posts[i].painting).up() - .e("size", posts[i].painting.length).up() - .e("url", "https://s3.amazonaws.com/olv-public/pap/WVW69koebmETvBVqm1").up() - .up(); - } - xml = xml.e("pid", posts[i].pid).up() - .e("platform_id", "1").up() - .e("region_id", "4").up() - .e("reply_count", "0").up() - .e("screen_name", posts[i].screen_name.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}+=,.<>/?;:'"\[\]]/g, "")).up() - .e("title_id", posts[i].title_id[0]).up() - .up(); - } - - return xml.end({ pretty: true, allowEmpty: true }); - } - - static async PostsResponseWithMii(posts, community) { - let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) - .e("has_error", "0").up() - .e("version", "1").up() - .e("request_name", "posts").up() - .e("topic") - .e("community_id", community.app_id ? community.app_id : community.community_id).up() - .up() - .e("posts"); - for (let i = 0; i < posts.length; i++) { - xml = xml.e("post") - .e("app_data", posts[i].app_data.replace(/[^A-Za-z0-9+/=\s\r?\n|\r]/g, "").replace(/[\n\r]+/gm, '').trim()).up() - .e("body", posts[i].body ? posts[i].body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}+=,.<>/?;:'"\[\]]/g, "") : "").up() - .e("community_id", community.community_id).up() - .e("country_id", "254").up() - .e("created_at", moment(posts[i].created_at).format('YYYY-MM-DD HH:MM:SS')).up() - .e("feeling_id", "1").up() - .e("id", posts[i].id).up() - .e("is_autopost", "0").up() - .e("is_community_private_autopost", "0").up() - .e("is_spoiler", "0").up() - .e("is_app_jumpable", "0").up() - .e("empathy_count", posts[i].empathy_count).up() - .e("language_id", "1").up() - .e("mii", posts[i].mii.replace(/\r?\n|\r/g, "").trim()).up() - .e("mii_face_url", posts[i].mii_face_url).up() - .e("number", "0").up(); - if (posts[i].painting) { - xml = xml.e("painting") - .e("format", "tga").up() - .e("content", posts[i].painting.replace(/\r?\n|\r/g, "").trim()).up() - .e("size", posts[i].painting.length).up() - .e("url", "https://s3.amazonaws.com/olv-public/pap/WVW69koebmETvBVqm1").up() - .up(); - } - xml = xml.e("pid", posts[i].pid).up() - .e("platform_id", posts[i].platform_id).up() - .e("region_id", posts[i].region_id).up() - .e("reply_count", posts[i].reply_count).up() - .e("screen_name", posts[i].screen_name).up() - .e("title_id", posts[i].title_id).up() - .up(); - } - - return xml.end({ pretty: true, allowEmpty: true }); - } - - static async EmptyResponse() { - const xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) - .e("has_error", "0").up() - .e("version", "1").up(); - return xml.end({ pretty: true, allowEmpty: true }); - } - - static async Communities(communities) { - let parent = communities[0].community_id; - let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) - .e("has_error", "0").up() - .e("version", "1").up() - .e("request_name", "communities").up() - .e("communities"); - for(let community of communities) { - xml = xml.e("community") - .e('olive_community_id', parent).up() - .e('community_id', community.app_id ? community.app_id.padStart(6, '0') : community.community_id).up() - .e("name", community.name).up() - .e("description", community.description).up() - .e("icon").up() - .e("icon_3ds").up() - .e("pid").up() - .e("app_data", community.app_data).up() - .e("is_user_community", 0).up() - .up() - } - return xml.up().end({ pretty: true, allowEmpty: true}); - } - /* TODO Again, some constants */ - static async SinglePostResponse(post) { - let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) - .e("has_error", "0").up() - .e("version", "1").up() - .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", "254").up() - .e("created_at", post.created_at).up() - .e("feeling_id", "1").up() - .e("id", post.id).up() - .e("is_autopost", "0").up() - .e("is_community_private_autopost", "0").up() - .e("is_spoiler", "0").up() - .e("is_app_jumpable", "0").up() - .e("empathy_count", post.empathy_count).up() - .e("language_id", "1").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://s3.amazonaws.com/olv-public/pap/WVW69koebmETvBVqm1").up() - .up(); - } - xml = xml.e("pid", post.pid).up() - .e("platform_id", "1").up() - .e("region_id", "4").up() - .e("reply_count", "0").up() - .e("screen_name", post.screen_name).up() - .e("title_id", post.title_id).up() - .up(); - 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' }) - .e("has_error", "0").up() - .e("version", "1").up() - .e("request_name", "topics").up() - .e("expire", expirationDate.format('YYYY-MM-DD HH:MM:SS')).up() - .e("topics"); - for (const community of communities) { - let posts = await database.getNumberNewCommunityPostsByID(community, 30); - xml = xml.e('topic') - .e('empathy_count', community.empathy_count).up() - .e('has_shop_page', community.has_shop_page).up() - .e('icon', community.icon).up() - .e('title_ids'); - community.title_id.forEach(function (title_id) { - if(title_id !== '') - xml = xml.e('title_id', title_id).up(); - }) - xml = xml.up() - .e('title_id', community.title_id[0]).up() - .e('community_id', community.community_id).up() - .e('is_recommended', community.is_recommended).up() - .e('name', community.name).up() - .e("people"); - for (const post of posts) { - xml = xml.e("person") - .e("posts") - .e("post") - .e("body", post.body ? post.body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}+=,.<>/?;:'"\[\]]/g, "") : "").up() - .e("community_id", community.community_id).up() - .e("country_id", post.country_id || 0).up() - .e("created_at", moment(post.created_at).format('YYYY-MM-DD HH:MM:SS')).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() - .e("mii", post.mii.toString().replace(/[\n\r]+/gm, '')).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]+/gm, "" )).up() - .e("size", post.painting.length).up() - .e("url", `https://cdn.pretendo.cc/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", 'placeholder').up() - .e("title_id", post.title_id).up() - .up().up().up(); - } - xml = xml.up().up() - } - return xml.end({ pretty: false, allowEmpty: true }); - } -} - -if (typeof module !== "undefined") { - module.exports = CommunityPostGen; -} diff --git a/src/util/peoplePostGen.js b/src/util/peoplePostGen.js deleted file mode 100644 index ecb6777..0000000 --- a/src/util/peoplePostGen.js +++ /dev/null @@ -1,165 +0,0 @@ -const xmlbuilder = require("xmlbuilder"); -const moment = require("moment"); - -class CommunityPostGen { - /* TODO lots of stubs and constants in here */ - static async PostsResponse(posts, community) { - const expirationDate = moment().add(11, 'days'); - - let xml = xmlbuilder.create("result") - .e("has_error", "0").up() - .e("version", "1").up() - .e("expire", expirationDate.format('YYYY-MM-DD HH:MM:SS')).up() - .e("request_name", "people").up() - .e("people"); - for (let i = 0; i < posts.length; i++) { - xml = xml.e("person") - .e("posts") - .e("post") - .e("body", posts[i].body).up() - .e("community_id", community.community_id).up() - .e("country_id", "254").up() - .e("created_at", posts[i].created_at).up() - .e("feeling_id", "1").up() - .e("id", posts[i].id).up() - .e("is_autopost", "0").up() - .e("is_community_private_autopost", "0").up() - .e("is_spoiler", "0").up() - .e("is_app_jumpable", "0").up() - .e("empathy_count", posts[i].empathy_count).up() - .e("language_id", "1").up(); - xml = xml.e("number", "0").up(); - if (posts[i].painting) { - xml = xml.e("painting") - .e("format", "tga").up() - .e("content", posts[i].painting).up() - .e("size", posts[i].painting.length).up() - .e("url", "https://s3.amazonaws.com/olv-public/pap/WVW69koebmETvBVqm1").up() - .up(); - } - xml = xml.e("pid", posts[i].pid).up() - .e("platform_id", "1").up() - .e("region_id", "4").up() - .e("reply_count", "0").up() - .e("screen_name", posts[i].screen_name).up() - .e("title_id", posts[i].title_id).up() - .up().up().up(); - } - - return xml.end({ pretty: true, allowEmpty: true }); - } - - static async PostsResponseWithMii(posts, community) { - let xml = xmlbuilder.create("result") - .e("has_error", "0").up() - .e("version", "1").up() - .e("request_name", "posts").up() - .e("topic") - .e("community_id", community.community_id).up() - .up() - .e("posts"); - for (let i = 0; i < posts.length; i++) { - xml = xml.e("person") - .e("posts") - .e("post") - .e("body", posts[i].body).up() - .e("community_id", community.community_id).up() - .e("country_id", "254").up() - .e("created_at", posts[i].created_at).up() - .e("feeling_id", "1").up() - .e("id", posts[i].id).up() - .e("is_autopost", "0").up() - .e("is_community_private_autopost", "0").up() - .e("is_spoiler", "0").up() - .e("is_app_jumpable", "0").up() - .e("empathy_count", posts[i].empathy_count).up() - .e("language_id", "1").up() - .e("mii", posts[i].mii).up() - .e("mii_face_url", posts[i].mii_face_url).up() - .e("number", "0").up(); - if (posts[i].painting) { - xml = xml.e("painting") - .e("format", "tga").up() - .e("content", posts[i].painting).up() - .e("size", posts[i].painting.length).up() - .e("url", "https://s3.amazonaws.com/olv-public/pap/WVW69koebmETvBVqm1").up() - .up(); - } - xml = xml.e("pid", posts[i].pid).up() - .e("platform_id", "1").up() - .e("region_id", "4").up() - .e("reply_count", "0").up() - .e("screen_name", posts[i].screen_name).up() - .e("title_id", posts[i].title_id).up() - .up(); - } - - return xml.end({ pretty: true, allowEmpty: true }); - } - - static async EmptyResponse() { - const xml = xmlbuilder.create("result") - .e("has_error", "0").up() - .e("version", "1").up(); - return xml.end({ pretty: true, allowEmpty: true }); - } - - /* TODO Again, some constants */ - static async SinglePostResponse(post) { - let xml = xmlbuilder.create("result") - .e("has_error", "0").up() - .e("version", "1").up() - .e("post"); - if (post.app_data) { - xml = xml.e("app_data", post.app_data).up(); - } - xml = xml.e("body", post.body).up() - .e("community_id", post.community_id).up() - .e("country_id", "254").up() - .e("created_at", post.created_at).up() - .e("feeling_id", "1").up() - .e("id", post.id).up() - .e("is_autopost", "0").up() - .e("is_community_private_autopost", "0").up() - .e("is_spoiler", "0").up() - .e("is_app_jumpable", "0").up() - .e("empathy_count", post.empathy_count).up() - .e("language_id", "1").up() - .e("number", "0").up(); - if (post.painting) { - xml = xml.e("painting") - .e("format", "tga").up() - .e("content", post.painting).up() - .e("size", post.painting.length).up() - .e("url", "https://s3.amazonaws.com/olv-public/pap/WVW69koebmETvBVqm1").up() - .up(); - } - xml = xml.e("pid", post.pid).up() - .e("platform_id", "1").up() - .e("region_id", "4").up() - .e("reply_count", "0").up() - .e("screen_name", post.screen_name).up() - .e("title_id", post.title_id).up() - .up(); - return xml.end({ pretty: true, allowEmpty: true }); - } - - static async People(people) { - let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) - .e("has_error", "0").up() - .e("version", "1").up() - .e("request_name", "user_infos").up() - .e("people"); - for(let person of people) { - xml = xml.e("person") - .e('pid', person.pid).up() - .e('screen_name', person.screen_name).up() - .up() - } - return xml.up().end({ pretty: true, allowEmpty: true}); - } -} - -if (typeof module !== "undefined") { - module.exports = CommunityPostGen; -} diff --git a/src/util/xmlResponseGenerator.js b/src/util/xmlResponseGenerator.js new file mode 100644 index 0000000..80e25ed --- /dev/null +++ b/src/util/xmlResponseGenerator.js @@ -0,0 +1,239 @@ +const xmlbuilder = require("xmlbuilder"); +const moment = require("moment"); +const database = require('../database'); + +class XmlResponseGenerator { + /** + * Generate response to reply request + * @param posts + * @param options + * @returns xml + * @constructor + */ + static async RepliesResponse(posts, options) { + let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) + .e("has_error", "0").up() + .e("version", "1").up() + .e("request_name", "replies").up() + .e("posts"); + for (const post of posts) { + postObj(xml, post, options); + } + xml = xml.up(); + return xml.end({ pretty: true, allowEmpty: true }); + } + + /** + * Generate response to community posts response + * @param posts + * @param community + * @param options + * @returns xml + * @constructor + */ + static async PostsResponse(posts, community, options) { + let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) + .e("has_error", "0").up() + .e("version", "1").up() + .e("request_name", options.name).up() + .e("topic") + .e("community_id", community.app_id ? community.app_id : community.community_id).up() + .up() + .e("posts"); + for (const post of posts) { + postObj(xml, post, options); + } + xml = xml.up(); + return xml.end({ pretty: true, allowEmpty: true }); + } + + /** + * Generate empty xml response + * @returns xml + * @constructor + */ + static async EmptyResponse() { + const xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) + .e("has_error", "0").up() + .e("version", "1").up(); + return xml.end({ pretty: true, allowEmpty: true }); + } + + /** + * Generates response to list of communities request + * @param communities + * @returns xml + * @constructor + */ + static async Communities(communities) { + let parent = communities[0].community_id; + let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) + .e("has_error", "0").up() + .e("version", "1").up() + .e("request_name", "communities").up() + .e("communities"); + for(let community of communities) { + xml = xml.e("community") + .e('olive_community_id', parent).up() + .e('community_id', community.app_id ? community.app_id.padStart(6, '0') : community.community_id).up() + .e("name", community.name).up() + .e("description", community.description).up() + .e("icon").up() + .e("icon_3ds").up() + .e("pid").up() + .e("app_data", community.app_data).up() + .e("is_user_community", 0).up() + .up() + } + return xml.up().end({ pretty: true, allowEmpty: true}); + } + + /** + * Generate response to request for single post + * @param post + * @returns xml + * @constructor + */ + static async SinglePostResponse(post) { + let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) + .e("has_error", "0").up() + .e("version", "1").up() + .e("post"); + postObj(xml, post, { with_mii: true }); + xml = xml.up(); + return xml.end({ pretty: true, allowEmpty: true }); + } + + /** + * Generate response to search for post + * @param post + * @returns xml + * @constructor + */ + 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"); + postObj(xml, post, { with_mii: true }); + xml = xml.up(); + return xml.end({ pretty: true, allowEmpty: true }); + } + + /** + * Generate response to /v1/topics + * @param communities + * @returns xml + */ + static async topics(communities) { + const expirationDate = moment().add(1, 'days'); + let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) + .e("has_error", "0").up() + .e("version", "1").up() + .e("request_name", "topics").up() + .e("expire", expirationDate.format('YYYY-MM-DD HH:MM:SS')).up() + .e("topics"); + for (const community of communities) { + let posts = await database.getNumberNewCommunityPostsByID(community, 30); + xml = xml.e('topic') + .e('empathy_count', community.empathy_count).up() + .e('has_shop_page', community.has_shop_page).up() + .e('icon', community.icon).up() + .e('title_ids'); + community.title_id.forEach(function (title_id) { + if(title_id !== '') + xml = xml.e('title_id', title_id).up(); + }) + xml = xml.up() + .e('title_id', community.title_id[0]).up() + .e('community_id', community.community_id).up() + .e('is_recommended', community.is_recommended).up() + .e('name', community.name).up() + .e("people"); + for (const post of posts) { + xml = xml.e("person") + .e("posts") + postObj(xml, post, { with_mii: true }); + xml = xml.up().up(); + } + xml = xml.up().up() + } + return xml.end({ pretty: false, allowEmpty: true }); + } + + /** + * Generate response to /v1/people + * @param people + * @returns xml + * @constructor + */ + static async People(people) { + let xml = xmlbuilder.create("result", { encoding: 'UTF-8' }) + .e("has_error", "0").up() + .e("version", "1").up() + .e("request_name", "user_infos").up() + .e("people"); + for(let person of people) { + xml = xml.e("person") + .e('pid', person.pid).up() + .e('screen_name', person.screen_name).up() + .up() + } + return xml.up().end({ pretty: true, allowEmpty: true}); + } +} + +/** + * Generate xml for individual post + * @param xml + * @param post + * @param options + */ +function postObj(xml, post, options) { + xml = xml.e("post"); + if (post.app_data) { + xml.e("app_data", post.app_data.replace(/[^A-Za-z0-9+/=]/g, "").replace(/[\n\r]+/gm, '').trim()).up(); + } + 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 && options.with_mii) { + xml.e("mii", post.mii.replace(/[^A-Za-z0-9+/=]/g, "").replace(/[\n\r]+/gm, '').trim()).up() + .e("mii_face_url", post.mii_face_url).up() + } + xml.e("number", "0").up(); + if (post.painting) { + 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.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(); + if (post.screenshot && post.screenshot_length) { + xml.e("screenshot") + .e("size", post.screenshot_length).up() + .e("url", `https://pretendo-cdn.b-cdn.net/screenshots/${post.pid}/${post.id}.jpg`).up() + .up(); + } + xml.e("title_id", post.title_id).up().up() +} + +if (typeof module !== "undefined") { + module.exports = XmlResponseGenerator; +}