Преглед изворни кода

Split remaining controllers into separate files. Added iOS homescreen icon. Removed additional logging from weather module.

Paweł Malak пре 3 година
родитељ
комит
4ed29fe276
32 измењених фајлова са 418 додато и 312 уклоњено
  1. 1 0
      .gitignore
  2. 3 0
      CHANGELOG.md
  3. BIN
      client/public/icons/apple-touch-icon-114x114.png
  4. BIN
      client/public/icons/apple-touch-icon-120x120.png
  5. BIN
      client/public/icons/apple-touch-icon-144x144.png
  6. BIN
      client/public/icons/apple-touch-icon-152x152.png
  7. BIN
      client/public/icons/apple-touch-icon-180x180.png
  8. BIN
      client/public/icons/apple-touch-icon-57x57.png
  9. BIN
      client/public/icons/apple-touch-icon-72x72.png
  10. BIN
      client/public/icons/apple-touch-icon-76x76.png
  11. BIN
      client/public/icons/apple-touch-icon.png
  12. 0 0
      client/public/icons/favicon.ico
  13. 45 1
      client/public/index.html
  14. 28 0
      controllers/categories/createCategory.js
  15. 45 0
      controllers/categories/deleteCategory.js
  16. 43 0
      controllers/categories/getAllCategories.js
  17. 35 0
      controllers/categories/getSingleCategory.js
  18. 8 0
      controllers/categories/index.js
  19. 22 0
      controllers/categories/reorderCategories.js
  20. 30 0
      controllers/categories/updateCategory.js
  21. 0 178
      controllers/category.js
  22. 21 0
      controllers/queries/addQuery.js
  23. 22 0
      controllers/queries/deleteQuery.js
  24. 17 0
      controllers/queries/getQueries.js
  25. 6 81
      controllers/queries/index.js
  26. 32 0
      controllers/queries/updateQuery.js
  27. 0 31
      controllers/weather.js
  28. 19 0
      controllers/weather/getWather.js
  29. 4 0
      controllers/weather/index.js
  30. 16 0
      controllers/weather/updateWeather.js
  31. 8 13
      routes/category.js
  32. 13 8
      utils/clearWeatherData.js

+ 1 - 0
.gitignore

@@ -1,4 +1,5 @@
 node_modules
 data
 public
+!client/public
 build.sh

+ 3 - 0
CHANGELOG.md

@@ -1,3 +1,6 @@
+### v1.7.4 (TBA)
+- Added iOS "Add to homescreen" icon ([#131](https://github.com/pawelmalak/flame/issues/131))
+
 ### v1.7.3 (2021-10-28)
 - Fixed bug with custom CSS not updating
 

BIN
client/public/icons/apple-touch-icon-114x114.png


BIN
client/public/icons/apple-touch-icon-120x120.png


BIN
client/public/icons/apple-touch-icon-144x144.png


BIN
client/public/icons/apple-touch-icon-152x152.png


BIN
client/public/icons/apple-touch-icon-180x180.png


BIN
client/public/icons/apple-touch-icon-57x57.png


BIN
client/public/icons/apple-touch-icon-72x72.png


BIN
client/public/icons/apple-touch-icon-76x76.png


BIN
client/public/icons/apple-touch-icon.png


+ 0 - 0
client/public/favicon.ico → client/public/icons/favicon.ico


+ 45 - 1
client/public/index.html

@@ -2,7 +2,51 @@
 <html lang="en">
   <head>
     <meta charset="utf-8" />
-    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
+    <link rel="icon" href="%PUBLIC_URL%/icons/favicon.ico" />
+    <link
+      rel="apple-touch-icon"
+      href="%PUBLIC_URL%/icons/apple-touch-icon.png"
+    />
+    <link
+      rel="apple-touch-icon"
+      sizes="57x57"
+      href="%PUBLIC_URL%/icons/apple-touch-icon-57x57.png"
+    />
+    <link
+      rel="apple-touch-icon"
+      sizes="72x72"
+      href="%PUBLIC_URL%/icons/apple-touch-icon-72x72.png"
+    />
+    <link
+      rel="apple-touch-icon"
+      sizes="76x76"
+      href="%PUBLIC_URL%/icons/apple-touch-icon-76x76.png"
+    />
+    <link
+      rel="apple-touch-icon"
+      sizes="114x114"
+      href="%PUBLIC_URL%/icons/apple-touch-icon-114x114.png"
+    />
+    <link
+      rel="apple-touch-icon"
+      sizes="120x120"
+      href="%PUBLIC_URL%/icons/apple-touch-icon-120x120.png"
+    />
+    <link
+      rel="apple-touch-icon"
+      sizes="144x144"
+      href="%PUBLIC_URL%/icons/apple-touch-icon-144x144.png"
+    />
+    <link
+      rel="apple-touch-icon"
+      sizes="152x152"
+      href="%PUBLIC_URL%/icons/apple-touch-icon-152x152.png"
+    />
+    <link
+      rel="apple-touch-icon"
+      sizes="180x180"
+      href="%PUBLIC_URL%/icons/apple-touch-icon-180x180.png"
+    />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
     <meta
       name="description"

+ 28 - 0
controllers/categories/createCategory.js

@@ -0,0 +1,28 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const Category = require('../../models/Category');
+const loadConfig = require('../../utils/loadConfig');
+
+// @desc      Create new category
+// @route     POST /api/categories
+// @access    Public
+const createCategory = asyncWrapper(async (req, res, next) => {
+  const { pinCategoriesByDefault: pinCategories } = await loadConfig();
+
+  let category;
+
+  if (pinCategories) {
+    category = await Category.create({
+      ...req.body,
+      isPinned: true,
+    });
+  } else {
+    category = await Category.create(req.body);
+  }
+
+  res.status(201).json({
+    success: true,
+    data: category,
+  });
+});
+
+module.exports = createCategory;

+ 45 - 0
controllers/categories/deleteCategory.js

@@ -0,0 +1,45 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const ErrorResponse = require('../../utils/ErrorResponse');
+const Category = require('../../models/Category');
+const Bookmark = require('../../models/Bookmark');
+
+// @desc      Delete category
+// @route     DELETE /api/categories/:id
+// @access    Public
+const deleteCategory = asyncWrapper(async (req, res, next) => {
+  const category = await Category.findOne({
+    where: { id: req.params.id },
+    include: [
+      {
+        model: Bookmark,
+        as: 'bookmarks',
+      },
+    ],
+  });
+
+  if (!category) {
+    return next(
+      new ErrorResponse(
+        `Category with id of ${req.params.id} was not found`,
+        404
+      )
+    );
+  }
+
+  category.bookmarks.forEach(async (bookmark) => {
+    await Bookmark.destroy({
+      where: { id: bookmark.id },
+    });
+  });
+
+  await Category.destroy({
+    where: { id: req.params.id },
+  });
+
+  res.status(200).json({
+    success: true,
+    data: {},
+  });
+});
+
+module.exports = deleteCategory;

+ 43 - 0
controllers/categories/getAllCategories.js

@@ -0,0 +1,43 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const Category = require('../../models/Category');
+const Bookmark = require('../../models/Bookmark');
+const { Sequelize } = require('sequelize');
+const loadConfig = require('../../utils/loadConfig');
+
+// @desc      Get all categories
+// @route     GET /api/categories
+// @access    Public
+const getAllCategories = asyncWrapper(async (req, res, next) => {
+  const { useOrdering: orderType } = await loadConfig();
+
+  let categories;
+
+  if (orderType == 'name') {
+    categories = await Category.findAll({
+      include: [
+        {
+          model: Bookmark,
+          as: 'bookmarks',
+        },
+      ],
+      order: [[Sequelize.fn('lower', Sequelize.col('Category.name')), 'ASC']],
+    });
+  } else {
+    categories = await Category.findAll({
+      include: [
+        {
+          model: Bookmark,
+          as: 'bookmarks',
+        },
+      ],
+      order: [[orderType, 'ASC']],
+    });
+  }
+
+  res.status(200).json({
+    success: true,
+    data: categories,
+  });
+});
+
+module.exports = getAllCategories;

+ 35 - 0
controllers/categories/getSingleCategory.js

@@ -0,0 +1,35 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const ErrorResponse = require('../../utils/ErrorResponse');
+const Category = require('../../models/Category');
+const Bookmark = require('../../models/Bookmark');
+
+// @desc      Get single category
+// @route     GET /api/categories/:id
+// @access    Public
+const getSingleCategory = asyncWrapper(async (req, res, next) => {
+  const category = await Category.findOne({
+    where: { id: req.params.id },
+    include: [
+      {
+        model: Bookmark,
+        as: 'bookmarks',
+      },
+    ],
+  });
+
+  if (!category) {
+    return next(
+      new ErrorResponse(
+        `Category with id of ${req.params.id} was not found`,
+        404
+      )
+    );
+  }
+
+  res.status(200).json({
+    success: true,
+    data: category,
+  });
+});
+
+module.exports = getSingleCategory;

+ 8 - 0
controllers/categories/index.js

@@ -0,0 +1,8 @@
+module.exports = {
+  createCategory: require('./createCategory'),
+  getAllCategories: require('./getAllCategories'),
+  getSingleCategory: require('./getSingleCategory'),
+  updateCategory: require('./updateCategory'),
+  deleteCategory: require('./deleteCategory'),
+  reorderCategories: require('./reorderCategories'),
+};

+ 22 - 0
controllers/categories/reorderCategories.js

@@ -0,0 +1,22 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const Category = require('../../models/Category');
+// @desc      Reorder categories
+// @route     PUT /api/categories/0/reorder
+// @access    Public
+const reorderCategories = asyncWrapper(async (req, res, next) => {
+  req.body.categories.forEach(async ({ id, orderId }) => {
+    await Category.update(
+      { orderId },
+      {
+        where: { id },
+      }
+    );
+  });
+
+  res.status(200).json({
+    success: true,
+    data: {},
+  });
+});
+
+module.exports = reorderCategories;

+ 30 - 0
controllers/categories/updateCategory.js

@@ -0,0 +1,30 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const ErrorResponse = require('../../utils/ErrorResponse');
+const Category = require('../../models/Category');
+
+// @desc      Update category
+// @route     PUT /api/categories/:id
+// @access    Public
+const updateCategory = asyncWrapper(async (req, res, next) => {
+  let category = await Category.findOne({
+    where: { id: req.params.id },
+  });
+
+  if (!category) {
+    return next(
+      new ErrorResponse(
+        `Category with id of ${req.params.id} was not found`,
+        404
+      )
+    );
+  }
+
+  category = await category.update({ ...req.body });
+
+  res.status(200).json({
+    success: true,
+    data: category,
+  });
+});
+
+module.exports = updateCategory;

+ 0 - 178
controllers/category.js

@@ -1,178 +0,0 @@
-const asyncWrapper = require('../middleware/asyncWrapper');
-const ErrorResponse = require('../utils/ErrorResponse');
-const Category = require('../models/Category');
-const Bookmark = require('../models/Bookmark');
-const Config = require('../models/Config');
-const { Sequelize } = require('sequelize');
-const loadConfig = require('../utils/loadConfig');
-
-// @desc      Create new category
-// @route     POST /api/categories
-// @access    Public
-exports.createCategory = asyncWrapper(async (req, res, next) => {
-  const { pinCategoriesByDefault: pinCategories } = await loadConfig();
-
-  let category;
-
-  if (pinCategories) {
-    category = await Category.create({
-      ...req.body,
-      isPinned: true,
-    });
-  } else {
-    category = await Category.create(req.body);
-  }
-
-  res.status(201).json({
-    success: true,
-    data: category,
-  });
-});
-
-// @desc      Get all categories
-// @route     GET /api/categories
-// @access    Public
-exports.getCategories = asyncWrapper(async (req, res, next) => {
-  const { useOrdering: orderType } = await loadConfig();
-
-  let categories;
-
-  if (orderType == 'name') {
-    categories = await Category.findAll({
-      include: [
-        {
-          model: Bookmark,
-          as: 'bookmarks',
-        },
-      ],
-      order: [[Sequelize.fn('lower', Sequelize.col('Category.name')), 'ASC']],
-    });
-  } else {
-    categories = await Category.findAll({
-      include: [
-        {
-          model: Bookmark,
-          as: 'bookmarks',
-        },
-      ],
-      order: [[orderType, 'ASC']],
-    });
-  }
-
-  res.status(200).json({
-    success: true,
-    data: categories,
-  });
-});
-
-// @desc      Get single category
-// @route     GET /api/categories/:id
-// @access    Public
-exports.getCategory = asyncWrapper(async (req, res, next) => {
-  const category = await Category.findOne({
-    where: { id: req.params.id },
-    include: [
-      {
-        model: Bookmark,
-        as: 'bookmarks',
-      },
-    ],
-  });
-
-  if (!category) {
-    return next(
-      new ErrorResponse(
-        `Category with id of ${req.params.id} was not found`,
-        404
-      )
-    );
-  }
-
-  res.status(200).json({
-    success: true,
-    data: category,
-  });
-});
-
-// @desc      Update category
-// @route     PUT /api/categories/:id
-// @access    Public
-exports.updateCategory = asyncWrapper(async (req, res, next) => {
-  let category = await Category.findOne({
-    where: { id: req.params.id },
-  });
-
-  if (!category) {
-    return next(
-      new ErrorResponse(
-        `Category with id of ${req.params.id} was not found`,
-        404
-      )
-    );
-  }
-
-  category = await category.update({ ...req.body });
-
-  res.status(200).json({
-    success: true,
-    data: category,
-  });
-});
-
-// @desc      Delete category
-// @route     DELETE /api/categories/:id
-// @access    Public
-exports.deleteCategory = asyncWrapper(async (req, res, next) => {
-  const category = await Category.findOne({
-    where: { id: req.params.id },
-    include: [
-      {
-        model: Bookmark,
-        as: 'bookmarks',
-      },
-    ],
-  });
-
-  if (!category) {
-    return next(
-      new ErrorResponse(
-        `Category with id of ${req.params.id} was not found`,
-        404
-      )
-    );
-  }
-
-  category.bookmarks.forEach(async (bookmark) => {
-    await Bookmark.destroy({
-      where: { id: bookmark.id },
-    });
-  });
-
-  await Category.destroy({
-    where: { id: req.params.id },
-  });
-
-  res.status(200).json({
-    success: true,
-    data: {},
-  });
-});
-
-// @desc      Reorder categories
-// @route     PUT /api/categories/0/reorder
-// @access    Public
-exports.reorderCategories = asyncWrapper(async (req, res, next) => {
-  req.body.categories.forEach(async ({ id, orderId }) => {
-    await Category.update(
-      { orderId },
-      {
-        where: { id },
-      }
-    );
-  });
-
-  res.status(200).json({
-    success: true,
-    data: {},
-  });
-});

+ 21 - 0
controllers/queries/addQuery.js

@@ -0,0 +1,21 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const File = require('../../utils/File');
+
+// @desc      Add custom search query
+// @route     POST /api/queries
+// @access    Public
+const addQuery = asyncWrapper(async (req, res, next) => {
+  const file = new File('data/customQueries.json');
+  let content = JSON.parse(file.read());
+
+  // Add new query
+  content.queries.push(req.body);
+  file.write(content, true);
+
+  res.status(201).json({
+    success: true,
+    data: req.body,
+  });
+});
+
+module.exports = addQuery;

+ 22 - 0
controllers/queries/deleteQuery.js

@@ -0,0 +1,22 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const File = require('../../utils/File');
+
+// @desc      Delete query
+// @route     DELETE /api/queries/:prefix
+// @access    Public
+const deleteQuery = asyncWrapper(async (req, res, next) => {
+  const file = new File('data/customQueries.json');
+  let content = JSON.parse(file.read());
+
+  content.queries = content.queries.filter(
+    (q) => q.prefix != req.params.prefix
+  );
+  file.write(content, true);
+
+  res.status(200).json({
+    success: true,
+    data: content.queries,
+  });
+});
+
+module.exports = deleteQuery;

+ 17 - 0
controllers/queries/getQueries.js

@@ -0,0 +1,17 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const File = require('../../utils/File');
+
+// @desc      Get custom queries file
+// @route     GET /api/queries
+// @access    Public
+const getQueries = asyncWrapper(async (req, res, next) => {
+  const file = new File('data/customQueries.json');
+  const content = JSON.parse(file.read());
+
+  res.status(200).json({
+    success: true,
+    data: content.queries,
+  });
+});
+
+module.exports = getQueries;

+ 6 - 81
controllers/queries/index.js

@@ -1,81 +1,6 @@
-const asyncWrapper = require('../../middleware/asyncWrapper');
-const File = require('../../utils/File');
-const { join } = require('path');
-
-const QUERIES_PATH = join(__dirname, '../../data/customQueries.json');
-
-// @desc      Add custom search query
-// @route     POST /api/queries
-// @access    Public
-exports.addQuery = asyncWrapper(async (req, res, next) => {
-  const file = new File(QUERIES_PATH);
-  let content = JSON.parse(file.read());
-
-  // Add new query
-  content.queries.push(req.body);
-  file.write(content, true);
-
-  res.status(201).json({
-    success: true,
-    data: req.body,
-  });
-});
-
-// @desc      Get custom queries file
-// @route     GET /api/queries
-// @access    Public
-exports.getQueries = asyncWrapper(async (req, res, next) => {
-  const file = new File(QUERIES_PATH);
-  const content = JSON.parse(file.read());
-
-  res.status(200).json({
-    success: true,
-    data: content.queries,
-  });
-});
-
-// @desc      Update query
-// @route     PUT /api/queries/:prefix
-// @access    Public
-exports.updateQuery = asyncWrapper(async (req, res, next) => {
-  const file = new File(QUERIES_PATH);
-  let content = JSON.parse(file.read());
-
-  let queryIdx = content.queries.findIndex(
-    (q) => q.prefix == req.params.prefix
-  );
-
-  // query found
-  if (queryIdx > -1) {
-    content.queries = [
-      ...content.queries.slice(0, queryIdx),
-      req.body,
-      ...content.queries.slice(queryIdx + 1),
-    ];
-  }
-
-  file.write(content, true);
-
-  res.status(200).json({
-    success: true,
-    data: content.queries,
-  });
-});
-
-// @desc      Delete query
-// @route     DELETE /api/queries/:prefix
-// @access    Public
-exports.deleteQuery = asyncWrapper(async (req, res, next) => {
-  const file = new File(QUERIES_PATH);
-  let content = JSON.parse(file.read());
-
-  content.queries = content.queries.filter(
-    (q) => q.prefix != req.params.prefix
-  );
-  file.write(content, true);
-
-  res.status(200).json({
-    success: true,
-    data: content.queries,
-  });
-});
+module.exports = {
+  addQuery: require('./addQuery'),
+  getQueries: require('./getQueries'),
+  updateQuery: require('./updateQuery'),
+  deleteQuery: require('./deleteQuery'),
+};

+ 32 - 0
controllers/queries/updateQuery.js

@@ -0,0 +1,32 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const File = require('../../utils/File');
+
+// @desc      Update query
+// @route     PUT /api/queries/:prefix
+// @access    Public
+const updateQuery = asyncWrapper(async (req, res, next) => {
+  const file = new File('data/customQueries.json');
+  let content = JSON.parse(file.read());
+
+  let queryIdx = content.queries.findIndex(
+    (q) => q.prefix == req.params.prefix
+  );
+
+  // query found
+  if (queryIdx > -1) {
+    content.queries = [
+      ...content.queries.slice(0, queryIdx),
+      req.body,
+      ...content.queries.slice(queryIdx + 1),
+    ];
+  }
+
+  file.write(content, true);
+
+  res.status(200).json({
+    success: true,
+    data: content.queries,
+  });
+});
+
+module.exports = updateQuery;

+ 0 - 31
controllers/weather.js

@@ -1,31 +0,0 @@
-const asyncWrapper = require('../middleware/asyncWrapper');
-const ErrorResponse = require('../utils/ErrorResponse');
-const Weather = require('../models/Weather');
-const getExternalWeather = require('../utils/getExternalWeather');
-
-// @desc      Get latest weather status
-// @route     GET /api/weather
-// @access    Public
-exports.getWeather = asyncWrapper(async (req, res, next) => {
-  const weather = await Weather.findAll({
-    order: [['createdAt', 'DESC']],
-    limit: 1,
-  });
-
-  res.status(200).json({
-    success: true,
-    data: weather,
-  });
-});
-
-// @desc      Update weather
-// @route     GET /api/weather/update
-// @access    Public
-exports.updateWeather = asyncWrapper(async (req, res, next) => {
-  const weather = await getExternalWeather();
-
-  res.status(200).json({
-    success: true,
-    data: weather,
-  });
-});

+ 19 - 0
controllers/weather/getWather.js

@@ -0,0 +1,19 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const Weather = require('../../models/Weather');
+
+// @desc      Get latest weather status
+// @route     GET /api/weather
+// @access    Public
+const getWeather = asyncWrapper(async (req, res, next) => {
+  const weather = await Weather.findAll({
+    order: [['createdAt', 'DESC']],
+    limit: 1,
+  });
+
+  res.status(200).json({
+    success: true,
+    data: weather,
+  });
+});
+
+module.exports = getWeather;

+ 4 - 0
controllers/weather/index.js

@@ -0,0 +1,4 @@
+module.exports = {
+  getWeather: require('./getWather'),
+  updateWeather: require('./updateWeather'),
+};

+ 16 - 0
controllers/weather/updateWeather.js

@@ -0,0 +1,16 @@
+const asyncWrapper = require('../../middleware/asyncWrapper');
+const getExternalWeather = require('../../utils/getExternalWeather');
+
+// @desc      Update weather
+// @route     GET /api/weather/update
+// @access    Public
+const updateWeather = asyncWrapper(async (req, res, next) => {
+  const weather = await getExternalWeather();
+
+  res.status(200).json({
+    success: true,
+    data: weather,
+  });
+});
+
+module.exports = updateWeather;

+ 8 - 13
routes/category.js

@@ -3,26 +3,21 @@ const router = express.Router();
 
 const {
   createCategory,
-  getCategories,
-  getCategory,
+  getAllCategories,
+  getSingleCategory,
   updateCategory,
   deleteCategory,
-  reorderCategories
-} = require('../controllers/category');
+  reorderCategories,
+} = require('../controllers/categories');
 
-router
-  .route('/')
-  .post(createCategory)
-  .get(getCategories);
+router.route('/').post(createCategory).get(getAllCategories);
 
 router
   .route('/:id')
-  .get(getCategory)
+  .get(getSingleCategory)
   .put(updateCategory)
   .delete(deleteCategory);
 
-router
-  .route('/0/reorder')
-  .put(reorderCategories);
+router.route('/0/reorder').put(reorderCategories);
 
-module.exports = router;
+module.exports = router;

+ 13 - 8
utils/clearWeatherData.js

@@ -2,23 +2,28 @@ const { Op } = require('sequelize');
 const Weather = require('../models/Weather');
 const Logger = require('./Logger');
 const logger = new Logger();
+const loadConfig = require('./loadConfig');
 
 const clearWeatherData = async () => {
+  const { WEATHER_API_KEY: secret } = await loadConfig();
+
   const weather = await Weather.findOne({
-    order: [[ 'createdAt', 'DESC' ]]
+    order: [['createdAt', 'DESC']],
   });
 
   if (weather) {
     await Weather.destroy({
       where: {
         id: {
-          [Op.lt]: weather.id
-        }
-      }
-    })
+          [Op.lt]: weather.id,
+        },
+      },
+    });
   }
 
-  logger.log('Old weather data was deleted');
-}
+  if (secret) {
+    logger.log('Old weather data was deleted');
+  }
+};
 
-module.exports = clearWeatherData;
+module.exports = clearWeatherData;