From 9f96a4d382b8b6874b4caf69db0869c4c2776b0b Mon Sep 17 00:00:00 2001 From: Dhruv Jain Date: Fri, 30 Jul 2021 00:32:01 +0530 Subject: [PATCH 1/4] [NEW] Cron to populate discourse collection in strapi --- app/cron.sh | 3 +++ app/pages/index.js | 5 ++--- cms/api/discourse/controllers/discourse.js | 8 +++++++ cms/api/discourse/models/discourse.js | 8 +++++++ .../discourse/models/discourse.settings.json | 21 +++++++++++++++++++ cms/api/discourse/services/discourse.js | 8 +++++++ 6 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 app/cron.sh create mode 100644 cms/api/discourse/controllers/discourse.js create mode 100644 cms/api/discourse/models/discourse.js create mode 100644 cms/api/discourse/models/discourse.settings.json create mode 100644 cms/api/discourse/services/discourse.js diff --git a/app/cron.sh b/app/cron.sh new file mode 100644 index 00000000..63909514 --- /dev/null +++ b/app/cron.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +curl -H "Content-Type: application/json" -X PUT -d "{\"TopPost\": $(curl -H "Api-Key: $1" -H "Api-Username: $2" $3/top.json?period=all)}" "$4/discourses/$5" \ No newline at end of file diff --git a/app/pages/index.js b/app/pages/index.js index 9900968f..27a425ae 100644 --- a/app/pages/index.js +++ b/app/pages/index.js @@ -1,7 +1,6 @@ import React, { useState } from "react"; import { fetchAPI } from "../lib/api"; import { - Button, TextField, Select, MenuItem, @@ -260,7 +259,7 @@ export default function Home({ prevArrow={} nextArrow={} > - {carousels.map((item, i) => ( + {carousels?.body?.map((item, i) => ( ))} @@ -268,7 +267,7 @@ export default function Home({ {t("unsigned-home-demo.select-role-heading")}
- {personas.map((persona) => ( + {personas?.body?.map((persona) => (
Date: Fri, 30 Jul 2021 01:13:34 +0530 Subject: [PATCH 2/4] [FIX] Discourse route not working --- cms/api/discourse/config/routes.json | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 cms/api/discourse/config/routes.json diff --git a/cms/api/discourse/config/routes.json b/cms/api/discourse/config/routes.json new file mode 100644 index 00000000..c1828d63 --- /dev/null +++ b/cms/api/discourse/config/routes.json @@ -0,0 +1,52 @@ +{ + "routes": [ + { + "method": "GET", + "path": "/discourses", + "handler": "discourse.find", + "config": { + "policies": [] + } + }, + { + "method": "GET", + "path": "/discourses/count", + "handler": "discourse.count", + "config": { + "policies": [] + } + }, + { + "method": "GET", + "path": "/discourses/:id", + "handler": "discourse.findOne", + "config": { + "policies": [] + } + }, + { + "method": "POST", + "path": "/discourses", + "handler": "discourse.create", + "config": { + "policies": [] + } + }, + { + "method": "PUT", + "path": "/discourses/:id", + "handler": "discourse.update", + "config": { + "policies": [] + } + }, + { + "method": "DELETE", + "path": "/discourses/:id", + "handler": "discourse.delete", + "config": { + "policies": [] + } + } + ] +} From e2547822156c9bdb153fe1086b81f7d9cecd75ef Mon Sep 17 00:00:00 2001 From: Dhruv Jain Date: Fri, 30 Jul 2021 20:01:30 +0530 Subject: [PATCH 3/4] [NEW] Dynamically populate index page community activity with the top topics --- app/pages/index.js | 93 ++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/app/pages/index.js b/app/pages/index.js index 27a425ae..3e550ffc 100644 --- a/app/pages/index.js +++ b/app/pages/index.js @@ -30,50 +30,50 @@ export default function Home({ guides, releaseNotes, topNavItems, + topPosts }) { const [searchCategory, setSearchCategory] = useState(""); const { t } = useTranslation(); let loginWindow = null; - const activityItems = [ - { - title: - "I am setting up live chat and want to send an attachment ...how do I do that?", - author: "LigayaFernandez", - role: "LiveChat User", - community: "Question Forum", - time: "17 min ago", - upvotes: 0, - comments: 1, - }, - { - title: "Stranger Introduction", - author: "Izzie ", - role: "GSoC Student", - community: "GSoC 2021", - time: "1 hour ago", - upvotes: 5, - comments: 10, - }, - { - title: "Setting Up Rocket Chat", - author: "arary", - role: "Developer", - community: "Developer Discussions", - time: "2 hours ago", - upvotes: 0, - comments: 1, - }, - { - title: "RC4Community Improvements", - author: "aumurad", - role: "Admin", - community: "Announcements", - time: "4 hours ago", - upvotes: 50, - comments: 3, - }, - ]; + + function timeSince(date) { + let seconds = Math.floor((new Date() - date) / 1000); + let interval = seconds / 31536000; + if (interval > 1) { + return Math.floor(interval) + " years"; + } + interval = seconds / 2592000; + if (interval > 1) { + return Math.floor(interval) + " months ago"; + } + interval = seconds / 86400; + if (interval > 1) { + return Math.floor(interval) + " days ago"; + } + interval = seconds / 3600; + if (interval > 1) { + return Math.floor(interval) + " hours ago"; + } + interval = seconds / 60; + if (interval > 1) { + return Math.floor(interval) + " minutes ago"; + } + return Math.floor(seconds) + " seconds ago"; + } + let activityItems = []; + topPosts[0]?.TopPost?.topic_list?.topics.map((topic) => { + let newTopic = { + title: topic.fancy_title, + time: timeSince(new Date(topic.created_at)), + upvotes: topic.like_count, + comments: topic.posts_count, + link: `https://forums.rocket.chat/t/${topic.slug}/${topic.id}`, + image_url: topic.image_url + } + activityItems.push(newTopic); + }) + const Item = (props) => { return ( @@ -282,20 +282,16 @@ export default function Home({ -
+ ))}
@@ -333,9 +329,10 @@ export async function getStaticProps({ params }) { const guides = await fetchAPI("/guides"); const releaseNotes = await fetchAPI("/release-notes"); const topNavItems = await fetchAPI("/top-nav-item"); + const topPosts = await fetchAPI("/discourses"); return { - props: { carousels, personas, guides, releaseNotes, topNavItems }, + props: { carousels, personas, guides, releaseNotes, topNavItems, topPosts }, // Next.js will attempt to re-generate the page: // - When a request comes in // - At most once every 1 second From ea1fb39ec23a16928800e2f23a28f0a080653a61 Mon Sep 17 00:00:00 2001 From: Dhruv Jain Date: Fri, 13 Aug 2021 21:34:17 +0530 Subject: [PATCH 4/4] [FIX] Move cron to strapi, remove personas and carousels body field in index --- README.md | 7 +++++-- app/cron.sh | 3 --- app/pages/index.js | 4 ++-- cms/config/functions/bootstrap.js | 3 +++ cms/config/functions/cron.js | 5 ++++- cms/config/functions/fetchTopPosts.js | 25 +++++++++++++++++++++++++ cms/config/server.js | 3 +++ 7 files changed, 42 insertions(+), 8 deletions(-) delete mode 100644 app/cron.sh create mode 100644 cms/config/functions/fetchTopPosts.js diff --git a/README.md b/README.md index 622f93b2..e5707e5e 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,13 @@ Start strapi: git clone https://github.com/rocketchat/RC4Community cd cms npm i -INITIALIZE_DATA=true npm run develop +INITIALIZE_DATA=true DISCOURSE_DOMAIN=domain DISCOURSE_API_USERNAME=username DISCOURSE_API_KEY=api_key npm run develop ``` -Note the `INITIALIZE_DATA` environment variable is only needed the first time you startup the cms for development. It will seed the cms with a default set of components for you to start your own customization. (see [fetch data](https://github.com/RonLek/RC4Community/blob/master/cms/config/functions/fetchData.js) for the actual default initialization code) +Note: +1. `INITIALIZE_DATA` environment variable is only needed the first time you startup the cms for development. It will seed the cms with a default set of components for you to start your own customization. (see [fetch data](https://github.com/RonLek/RC4Community/blob/master/cms/config/functions/fetchData.js) for the actual default initialization code) +2. `DISCOURSE_DOMAIN`, `DISCOURSE_API_USERNAME`, `DISCOURSE_API_KEY` environment variables are required for the cron job to fetch the latest top activity on discourse with the time interval of 5 mins. + The application is written on nextjs and deployable on all nextjs compatible CDN + microservices and scaled deployment platforms. For build and design, start it in a shell: diff --git a/app/cron.sh b/app/cron.sh deleted file mode 100644 index 63909514..00000000 --- a/app/cron.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -curl -H "Content-Type: application/json" -X PUT -d "{\"TopPost\": $(curl -H "Api-Key: $1" -H "Api-Username: $2" $3/top.json?period=all)}" "$4/discourses/$5" \ No newline at end of file diff --git a/app/pages/index.js b/app/pages/index.js index 3e550ffc..8bc66a6a 100644 --- a/app/pages/index.js +++ b/app/pages/index.js @@ -259,7 +259,7 @@ export default function Home({ prevArrow={} nextArrow={} > - {carousels?.body?.map((item, i) => ( + {carousels.map((item, i) => ( ))} @@ -267,7 +267,7 @@ export default function Home({ {t("unsigned-home-demo.select-role-heading")}
- {personas?.body?.map((persona) => ( + {personas.map((persona) => (
{ // Fetches data and populates CMS from remote on server restart if (process.env.INITIALIZE_DATA) { await strapi.config.functions.fetchData(); + await getLatestCommunityActivity(); } }; diff --git a/cms/config/functions/cron.js b/cms/config/functions/cron.js index fe26854c..0f90c276 100644 --- a/cms/config/functions/cron.js +++ b/cms/config/functions/cron.js @@ -1,5 +1,5 @@ 'use strict'; - +const { getLatestCommunityActivity } = require("./fetchTopPosts"); /** * Cron config that gives you an opportunity * to run scheduled jobs. @@ -18,4 +18,7 @@ module.exports = { // '0 1 * * 1': () => { // // } + '*/5 * * * *': () => { + getLatestCommunityActivity(); + } }; diff --git a/cms/config/functions/fetchTopPosts.js b/cms/config/functions/fetchTopPosts.js new file mode 100644 index 00000000..f46f08dd --- /dev/null +++ b/cms/config/functions/fetchTopPosts.js @@ -0,0 +1,25 @@ +const axios = require("axios"); + +module.exports.getLatestCommunityActivity = async () => { + const TopPost = await axios({ + url: `${process.env.DISCOURSE_DOMAIN}/top.json?period=all`, + method: "GET", + headers: { + "Api-Username": process.env.DISCOURSE_API_USERNAME, + "Api-Key": process.env.DISCOURSE_API_KEY, + }, + }); + let currentTopPost = await strapi.query("discourse").find(); + if (currentTopPost.length !== 0) { + await strapi.query("discourse").update( + { id: currentTopPost[0].id }, + { + TopPost: TopPost.data, + } + ); + } else { + await strapi.query("discourse").create({ + TopPost: TopPost.data, + }); + } +}; diff --git a/cms/config/server.js b/cms/config/server.js index ce7f7bdb..59707ac2 100644 --- a/cms/config/server.js +++ b/cms/config/server.js @@ -6,4 +6,7 @@ module.exports = ({ env }) => ({ secret: env('ADMIN_JWT_SECRET', '9e07dfd3396d88a43609466615259199'), }, }, + cron: { + enabled: true, + }, });