Skip to content

Commit

Permalink
Merge pull request #57 from ItzNotABug/add-workflow
Browse files Browse the repository at this point in the history
Add Lint Workflow For PRs
  • Loading branch information
ItzNotABug authored Jun 3, 2024
2 parents 70fa491 + c55f6b9 commit 6251848
Show file tree
Hide file tree
Showing 32 changed files with 821 additions and 354 deletions.
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ files/
.git
.gitignore

# prettier
.prettierignore

# ci
.github

# markdown
LICENSE.md
README.md
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/source-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Source CI

on:
workflow_dispatch: # for manual runs
pull_request:
types: [ opened, synchronize ]

jobs:
build-and-test:
name: Run Lint
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 18

- name: Install Dependencies
run: npm install

- name: Run Prettier
run: npm run lint
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.json
**/*.md
**/*.css
**/*.yaml
4 changes: 2 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import express from 'express';
import Miscellaneous from './utils/misc.js';
import ProjectConfigs from './utils/data/configs.js';
import {logDebug, logTags} from './utils/log/logger.js';
import { logDebug, logTags } from './utils/log/logger.js';

// route imports
import logs from './routes/logs.js';
Expand Down Expand Up @@ -37,7 +37,7 @@ expressApp.use((req, res) => res.status(404).render('errors/404'));
logDebug(logTags.Express, 'Routes configured!');

// start the app with given port!
ProjectConfigs.ghosler().then(configs => {
ProjectConfigs.ghosler().then((configs) => {
expressApp.listen(configs.port);
logDebug(logTags.Express, 'App started successfully!');
logDebug(logTags.Express, '============================');
Expand Down
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
"main": "app.js",
"type": "module",
"author": "@itznotabug",
"prettier": {
"tabWidth": 4,
"singleQuote": true
},
"scripts": {
"lint": "prettier . --check",
"format": "prettier . --write",
"dev": "nodemon -e js,ejs --ignore custom-template.ejs app.js",
"cleanstart": "npm run buildcss && npm run dev",
"buildcss": "npx tailwindcss -i ./public/styles/tailwind.css -o ./public/styles/style.css --minify"
Expand All @@ -28,9 +34,10 @@
"winston": "^3.13.0"
},
"devDependencies": {
"@types/cheerio": "^0.22.35",
"nodemon": "^3.1.0",
"prettier": "^3.3.0",
"tailwindcss": "^3.4.1",
"@types/cheerio": "^0.22.35",
"@types/express-fileupload": "^1.5.0"
}
}
4 changes: 2 additions & 2 deletions routes/analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ router.get('/details/:postId', async (req, res) => {
const postId = req.params.postId;
const post = await Files.get(postId);
const postSentiments = await new Ghost().postSentiments(postId);
res.render('dashboard/details', {post, postSentiments});
res.render('dashboard/details', { post, postSentiments });
});

export default router;
export default router;
12 changes: 7 additions & 5 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,26 @@ const router = express.Router();
router.get('/', async (_, res) => {
const configs = await ProjectConfigs.all();

if (configs.ghosler.auth.user === 'ghosler' &&
if (
configs.ghosler.auth.user === 'ghosler' &&
configs.ghosler.auth.pass === Miscellaneous.hash('admin')
) {
res.render('index', {
level: 'error',
message: 'Update your username and password.<br><br>Default - <br>Username: ghosler, Password: admin'
message:
'Update your username and password.<br><br>Default - <br>Username: ghosler, Password: admin',
});
} else if (configs.ghost.url === '' || configs.ghost.key === '') {
res.render('index', {
level: 'error',
message: 'Set up your Ghost Site Url & add an Admin API Key.'
message: 'Set up your Ghost Site Url & add an Admin API Key.',
});
} else if (configs.mail.length === 0) {
res.render('index', {
level: 'error',
message: 'Add email credentials to send newsletters.'
message: 'Add email credentials to send newsletters.',
});
} else res.render('index');
});

export default router;
export default router;
5 changes: 2 additions & 3 deletions routes/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Miscellaneous from '../utils/misc.js';
const router = express.Router();

router.get('/login', (req, res) => {
res.render('login', {redirect: req.query.redirect ?? ''});
res.render('login', { redirect: req.query.redirect ?? '' });
});

router.post('/login', async (req, res) => {
Expand All @@ -22,5 +22,4 @@ router.get('/logout', (req, res) => {
res.redirect('/');
});


export default router;
export default router;
2 changes: 1 addition & 1 deletion routes/logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ router.get('/clear/:type', async (req, res) => {
res.redirect(`/logs/${logType}`);
});

export default router;
export default router;
41 changes: 28 additions & 13 deletions routes/newsletters.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ router.get('/:postId', async (req, res) => {
if (!postObject) {
return res.render('dashboard/newsletters', {
level: 'error',
message: 'Invalid Post Id!'
message: 'Invalid Post Id!',
});
}

if (postObject && postObject.stats && postObject.stats.newsletterStatus === 'Unsent') {
if (
postObject &&
postObject.stats &&
postObject.stats.newsletterStatus === 'Unsent'
) {
const newsletterItems = await new Ghost().newsletters();
delete newsletterItems.meta; // we don't need meta here.

Expand All @@ -28,12 +32,12 @@ router.get('/:postId', async (req, res) => {

res.render('dashboard/newsletters', {
post: postObject,
newsletters: newsletters
newsletters: newsletters,
});
} else {
res.render('dashboard/newsletters', {
level: 'error',
message: 'This post is already sent as a newsletter via email.'
message: 'This post is already sent as a newsletter via email.',
});
}
});
Expand All @@ -47,15 +51,15 @@ router.post('/send', async (req, res) => {
if (!postId || !newsletterId || !newsletterName) {
return res.render('dashboard/newsletters', {
level: 'error',
message: 'Post Id, Newsletter Id or Newsletter Name is missing!'
message: 'Post Id, Newsletter Id or Newsletter Name is missing!',
});
}

const postObject = await Files.get(postId);
if (!postObject) {
return res.render('dashboard/newsletters', {
level: 'error',
message: 'Invalid Post Id!'
message: 'Invalid Post Id!',
});
}

Expand All @@ -72,7 +76,12 @@ router.post('/send', async (req, res) => {
* 3. Post contains stats object &
* 4. Post's Stats newsletter status is 'Unsent'.
*/
if (post && post.content && post.stats && post.stats.newsletterStatus === 'Unsent') {
if (
post &&
post.content &&
post.stats &&
post.stats.newsletterStatus === 'Unsent'
) {
/**
* Mark the post's current status as 'Sending'
* This is done to prevent re-sending until Ghosler fetches members.
Expand All @@ -82,20 +91,26 @@ router.post('/send', async (req, res) => {
await post.update(true);

// send the newsletter as usual.
Newsletter.send(post, {id: newsletterId, name: newsletterName}).then();
Newsletter.send(post, {
id: newsletterId,
name: newsletterName,
}).then();

res.render('dashboard/newsletters', {
post: post,
level: 'success',
message: 'Newsletter will be sent shortly.'
message: 'Newsletter will be sent shortly.',
});

} else {
let message = 'This post is already sent as a newsletter via email.';
if (!post || !post.content || !post.stats) message = 'Post does not seem to be valid.';
if (!post || !post.content || !post.stats)
message = 'Post does not seem to be valid.';

res.render('dashboard/newsletters', {level: 'error', message: message});
res.render('dashboard/newsletters', {
level: 'error',
message: message,
});
}
});

export default router;
export default router;
3 changes: 1 addition & 2 deletions routes/password.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ router.post('/', async (req, res) => {
res.render('dashboard/password', result);
});


export default router;
export default router;
2 changes: 1 addition & 1 deletion routes/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ router.get('/', async (_, res) => {
res.set('Content-Type', 'text/html').send(template.modifiedHtml);
});

export default router;
export default router;
28 changes: 20 additions & 8 deletions routes/published.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,28 @@ import Ghost from '../utils/api/ghost.js';
import Post from '../utils/models/post.js';
import Miscellaneous from '../utils/misc.js';
import Newsletter from '../utils/newsletter.js';
import {logDebug, logTags} from '../utils/log/logger.js';
import { logDebug, logTags } from '../utils/log/logger.js';

const router = express.Router();

router.post('/', async (req, res) => {
if (!req.body || !req.body.post || !req.body.post.current) {
return res.status(400).json({message: 'Post content seems to be missing!'});
return res
.status(400)
.json({ message: 'Post content seems to be missing!' });
}

// check if the request is authenticated.
const isSecure = await Miscellaneous.isPostSecure(req);
if (!isSecure) {
return res.status(401).json({message: 'Invalid Authorization.'});
return res.status(401).json({ message: 'Invalid Authorization.' });
}

// check if contains the ignore tag.
if (Post.containsIgnoreTag(req.body)) {
return res.status(200).json({message: 'Post contains `ghosler_ignore` tag, ignoring.'});
return res
.status(200)
.json({ message: 'Post contains `ghosler_ignore` tag, ignoring.' });
}

logDebug(logTags.Newsletter, 'Post received via webhook.');
Expand All @@ -30,16 +34,24 @@ router.post('/', async (req, res) => {
const created = await post.save(newslettersCount > 1);

if (!created) {
res.status(500).json({message: 'The post data could not be saved, or emails for this post have already been sent.'});
res.status(500).json({
message:
'The post data could not be saved, or emails for this post have already been sent.',
});
} else {
if (newslettersCount === 1) {
Newsletter.send(post).then();
res.status(200).json({message: 'Newsletter will be sent shortly.'});
res.status(200).json({
message: 'Newsletter will be sent shortly.',
});
} else {
// we probably have multiple active newsletters or none at all, so just save the post.
res.status(200).json({message: 'Multiple or No active Newsletters found, current Post saved for manual action.'});
res.status(200).json({
message:
'Multiple or No active Newsletters found, current Post saved for manual action.',
});
}
}
});

export default router;
export default router;
Loading

0 comments on commit 6251848

Please sign in to comment.