diff --git a/Dockerfile b/Dockerfile index edbab397..cd99f47e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,9 +2,9 @@ FROM node:14-alpine WORKDIR /app -COPY package*.json . +COPY package*.json ./ -RUN npm install --only=production +RUN npm install --production COPY . . diff --git a/Socket.js b/Socket.js index 5b6d05c2..af9249ae 100644 --- a/Socket.js +++ b/Socket.js @@ -5,11 +5,11 @@ class Socket { this.webSocketServer = new WebSocket.Server({ server }) this.webSocketServer.on('listening', () => { - console.log('socket listen'); + console.log('Socket: listen'); }) this.webSocketServer.on('connection', (webSocketClient) => { - console.log('new connection'); + console.log('Socket: new connection'); }) } diff --git a/client/package-lock.json b/client/package-lock.json index 288d925c..476f8d52 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -2304,6 +2304,14 @@ "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==" }, + "@types/http-proxy": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.6.tgz", + "integrity": "sha512-+qsjqR75S/ib0ig0R9WN+CDoZeOBU6F2XLewgC4KVgdXiNHiKKHFEMRHOrs5PbYE97D5vataw5wPj4KLYfUkuQ==", + "requires": { + "@types/node": "*" + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -7449,110 +7457,21 @@ } }, "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.0.tgz", + "integrity": "sha512-S+RN5njuyvYV760aiVKnyuTXqUMcSIvYOsHA891DOVQyrdZOwaXtBHpt9FUVPEDAsOvsPArZp6VXQLs44yvkow==", "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" }, "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { + "is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" } } }, @@ -16033,6 +15952,17 @@ } } }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, "import-local": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", diff --git a/client/package.json b/client/package.json index 5a7676c1..5467e68e 100644 --- a/client/package.json +++ b/client/package.json @@ -15,6 +15,7 @@ "@types/react-redux": "^7.1.16", "@types/react-router-dom": "^5.1.7", "axios": "^0.21.1", + "http-proxy-middleware": "^2.0.0", "react": "^17.0.2", "react-dom": "^17.0.2", "react-redux": "^7.2.4", @@ -50,6 +51,5 @@ "last 1 firefox version", "last 1 safari version" ] - }, - "proxy": "http://localhost:5005" + } } diff --git a/client/src/components/Apps/AppCard/AppCard.module.css b/client/src/components/Apps/AppCard/AppCard.module.css index a66a60f2..26a8a691 100644 --- a/client/src/components/Apps/AppCard/AppCard.module.css +++ b/client/src/components/Apps/AppCard/AppCard.module.css @@ -27,4 +27,16 @@ font-weight: 400; font-size: 0.8em; opacity: 1; +} + +@media (min-width: 500px) { + .AppCard { + padding: 2px; + border-radius: 4px; + transition: all 0.10s; + } + + .AppCard:hover { + background-color: rgba(0,0,0,0.2); + } } \ No newline at end of file diff --git a/client/src/components/Apps/AppCard/AppCard.tsx b/client/src/components/Apps/AppCard/AppCard.tsx index bc6c9677..18b5dfde 100644 --- a/client/src/components/Apps/AppCard/AppCard.tsx +++ b/client/src/components/Apps/AppCard/AppCard.tsx @@ -2,6 +2,7 @@ import { Link } from 'react-router-dom'; import classes from './AppCard.module.css'; import Icon from '../../UI/Icons/Icon/Icon'; +import { iconParser } from '../../../utility/iconParser'; import { App } from '../../../interfaces'; @@ -11,22 +12,12 @@ interface ComponentProps { } const AppCard = (props: ComponentProps): JSX.Element => { - const iconParser = (mdiName: string): string => { - let parsedName = mdiName - .split('-') - .map((word: string) => `${word[0].toUpperCase()}${word.slice(1)}`) - .join(''); - parsedName = `mdi${parsedName}`; - - return parsedName; - } - const redirectHandler = (url: string): void => { window.open(url); } return ( - +
diff --git a/client/src/components/Bookmarks/BookmarkCard/BookmarkCard.module.css b/client/src/components/Bookmarks/BookmarkCard/BookmarkCard.module.css index af71a2ed..b21ed423 100644 --- a/client/src/components/Bookmarks/BookmarkCard/BookmarkCard.module.css +++ b/client/src/components/Bookmarks/BookmarkCard/BookmarkCard.module.css @@ -18,9 +18,18 @@ .Bookmarks a { line-height: 2; transition: all 0.25s; + display: flex; } .BookmarkCard a:hover { text-decoration: underline; padding-left: 10px; +} + +.BookmarkIcon { + width: 20px; + height: 20px; + display: flex; + margin-top: 3px; + margin-right: 2px; } \ No newline at end of file diff --git a/client/src/components/Bookmarks/BookmarkCard/BookmarkCard.tsx b/client/src/components/Bookmarks/BookmarkCard/BookmarkCard.tsx index 6d0b0200..5f607b2e 100644 --- a/client/src/components/Bookmarks/BookmarkCard/BookmarkCard.tsx +++ b/client/src/components/Bookmarks/BookmarkCard/BookmarkCard.tsx @@ -1,6 +1,9 @@ import { Bookmark, Category } from '../../../interfaces'; import classes from './BookmarkCard.module.css'; +import Icon from '../../UI/Icons/Icon/Icon'; +import { iconParser } from '../../../utility/iconParser'; + interface ComponentProps { category: Category; } @@ -13,8 +16,13 @@ const BookmarkCard = (props: ComponentProps): JSX.Element => { {props.category.bookmarks.map((bookmark: Bookmark) => (
+ {bookmark.icon && ( +
+ +
+ )} {bookmark.name}
))} diff --git a/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx b/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx index 984c1564..c5f5bcf8 100644 --- a/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx +++ b/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx @@ -29,9 +29,11 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => { const [formData, setFormData] = useState({ name: '', url: '', - categoryId: -1 + categoryId: -1, + icon: '' }) + // Load category data if provided for editing useEffect(() => { if (props.category) { setCategoryName({ name: props.category.name }); @@ -40,18 +42,21 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => { } }, [props.category]) + // Load bookmark data if provided for editing useEffect(() => { if (props.bookmark) { setFormData({ name: props.bookmark.name, url: props.bookmark.url, - categoryId: props.bookmark.categoryId + categoryId: props.bookmark.categoryId, + icon: props.bookmark.icon }) } else { setFormData({ name: '', url: '', - categoryId: -1 + categoryId: -1, + icon: '' }) } }, [props.bookmark]) @@ -79,7 +84,8 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => { setFormData({ name: '', url: '', - categoryId: formData.categoryId + categoryId: formData.categoryId, + icon: '' }) } } else { @@ -94,7 +100,8 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => { setFormData({ name: '', url: '', - categoryId: -1 + categoryId: -1, + icon: '' }) } @@ -201,6 +208,25 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => { })} + + + inputChangeHandler(e)} + /> + + Use icon name from MDI. + + {' '}Click here for reference + + + ) } diff --git a/client/src/components/Bookmarks/BookmarkTable/BookmarkTable.tsx b/client/src/components/Bookmarks/BookmarkTable/BookmarkTable.tsx index b674bea2..1d319fbd 100644 --- a/client/src/components/Bookmarks/BookmarkTable/BookmarkTable.tsx +++ b/client/src/components/Bookmarks/BookmarkTable/BookmarkTable.tsx @@ -96,6 +96,7 @@ const BookmarkTable = (props: ComponentProps): JSX.Element => { @@ -104,6 +105,7 @@ const BookmarkTable = (props: ComponentProps): JSX.Element => { +
{bookmark.bookmark.name} {bookmark.bookmark.url}{bookmark.bookmark.icon} {bookmark.categoryName}
{ name: '', url: '', categoryId: -1, + icon: '', id: -1, createdAt: new Date(), updatedAt: new Date() diff --git a/client/src/components/Settings/OtherSettings/OtherSettings.tsx b/client/src/components/Settings/OtherSettings/OtherSettings.tsx index 2d3a6cd9..7a6090e3 100644 --- a/client/src/components/Settings/OtherSettings/OtherSettings.tsx +++ b/client/src/components/Settings/OtherSettings/OtherSettings.tsx @@ -9,6 +9,8 @@ import { ApiResponse, Config, NewNotification } from '../../../interfaces'; interface FormState { customTitle: string; + pinAppsByDefault: number; + pinCategoriesByDefault: number; } interface ComponentProps { @@ -17,12 +19,14 @@ interface ComponentProps { const OtherSettings = (props: ComponentProps): JSX.Element => { const [formData, setFormData] = useState({ - customTitle: document.title + customTitle: document.title, + pinAppsByDefault: 0, + pinCategoriesByDefault: 0 }) // get initial config useEffect(() => { - axios.get>('/api/config?keys=customTitle') + axios.get>('/api/config?keys=customTitle,pinAppsByDefault,pinCategoriesByDefault') .then(data => { let tmpFormData = { ...formData }; @@ -60,10 +64,16 @@ const OtherSettings = (props: ComponentProps): JSX.Element => { document.title = formData.customTitle; } - const inputChangeHandler = (e: ChangeEvent) => { + const inputChangeHandler = (e: ChangeEvent, isNumber?: boolean) => { + let value: string | number = e.target.value; + + if (isNumber) { + value = parseFloat(value); + } + setFormData({ ...formData, - [e.target.name]: e.target.value + [e.target.name]: value }) } @@ -80,6 +90,30 @@ const OtherSettings = (props: ComponentProps): JSX.Element => { onChange={(e) => inputChangeHandler(e)} /> + + + + + + + + ) diff --git a/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx b/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx index 5eb7255a..3294fe41 100644 --- a/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx +++ b/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx @@ -64,6 +64,15 @@ const WeatherSettings = (props: ComponentProps): JSX.Element => { const formSubmitHandler = (e: FormEvent) => { e.preventDefault(); + // Check for api key input + if ((formData.lat || formData.long) && !formData.WEATHER_API_KEY) { + props.createNotification({ + title: 'Warning', + message: 'API Key is missing. Weather Module will NOT work' + }) + } + + // Save settings axios.put>('/api/config', formData) .then(() => { props.createNotification({ @@ -111,6 +120,7 @@ const WeatherSettings = (props: ComponentProps): JSX.Element => { target='blank'> {' '}Weather API + . Key is required for weather module to work. diff --git a/client/src/components/UI/Icons/WeatherIcon/WeatherIcon.tsx b/client/src/components/UI/Icons/WeatherIcon/WeatherIcon.tsx index 6dcfe56b..111967ed 100644 --- a/client/src/components/UI/Icons/WeatherIcon/WeatherIcon.tsx +++ b/client/src/components/UI/Icons/WeatherIcon/WeatherIcon.tsx @@ -12,8 +12,8 @@ interface ComponentProps { const WeatherIcon = (props: ComponentProps): JSX.Element => { const icon = props.isDay - ? (new IconMapping).mapIcon(props.weatherStatusCode, TimeOfDay.day) - : (new IconMapping).mapIcon(props.weatherStatusCode, TimeOfDay.night); + ? new IconMapping().mapIcon(props.weatherStatusCode, TimeOfDay.day) + : new IconMapping().mapIcon(props.weatherStatusCode, TimeOfDay.night); useEffect(() => { const delay = setTimeout(() => { @@ -25,7 +25,7 @@ const WeatherIcon = (props: ComponentProps): JSX.Element => { return () => { clearTimeout(delay); } - }, [props.weatherStatusCode]); + }, [props.weatherStatusCode, icon, props.theme.colors.accent]); return } diff --git a/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx b/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx index 7d7cbd9c..b28ef0a4 100644 --- a/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx +++ b/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx @@ -50,7 +50,11 @@ const WeatherWidget = (): JSX.Element => { // Open socket for data updates useEffect(() => { - const webSocketClient = new WebSocket('ws://localhost:5005'); + const webSocketClient = new WebSocket(`ws://${window.location.host}/socket`); + + webSocketClient.onopen = () => { + console.log('Socket: listen') + } webSocketClient.onmessage = (e) => { const data = JSON.parse(e.data); diff --git a/client/src/interfaces/Bookmark.ts b/client/src/interfaces/Bookmark.ts index 40253612..bcbf9ab9 100644 --- a/client/src/interfaces/Bookmark.ts +++ b/client/src/interfaces/Bookmark.ts @@ -4,10 +4,12 @@ export interface Bookmark extends Model { name: string; url: string; categoryId: number; + icon: string; } export interface NewBookmark { name: string; url: string; categoryId: number; + icon: string; } \ No newline at end of file diff --git a/client/src/setupProxy.js b/client/src/setupProxy.js new file mode 100644 index 00000000..5cafcb16 --- /dev/null +++ b/client/src/setupProxy.js @@ -0,0 +1,15 @@ +const { createProxyMiddleware } = require('http-proxy-middleware'); + +module.exports = function (app) { + const apiProxy = createProxyMiddleware('/api', { + target: 'http://localhost:5005' + }) + + const wsProxy = createProxyMiddleware('/socket', { + target: 'http://localhost:5005', + ws: true + }) + + app.use(apiProxy); + app.use(wsProxy); +}; \ No newline at end of file diff --git a/client/src/store/actions/app.ts b/client/src/store/actions/app.ts index f7eb3a75..1699e31c 100644 --- a/client/src/store/actions/app.ts +++ b/client/src/store/actions/app.ts @@ -23,10 +23,7 @@ export const getApps = () => async (dispatch: Dispatch) => { payload: res.data.data }) } catch (err) { - dispatch>({ - type: ActionTypes.getAppsError, - payload: err.data.data - }) + console.log(err); } } diff --git a/client/src/utility/iconParser.ts b/client/src/utility/iconParser.ts new file mode 100644 index 00000000..e846102f --- /dev/null +++ b/client/src/utility/iconParser.ts @@ -0,0 +1,9 @@ +export const iconParser = (mdiName: string): string => { + let parsedName = mdiName + .split('-') + .map((word: string) => `${word[0].toUpperCase()}${word.slice(1)}`) + .join(''); + parsedName = `mdi${parsedName}`; + + return parsedName; +} \ No newline at end of file diff --git a/controllers/apps.js b/controllers/apps.js index 496fa54c..4f213942 100644 --- a/controllers/apps.js +++ b/controllers/apps.js @@ -1,12 +1,29 @@ const asyncWrapper = require('../middleware/asyncWrapper'); const ErrorResponse = require('../utils/ErrorResponse'); const App = require('../models/App'); +const Config = require('../models/Config'); // @desc Create new app // @route POST /api/apps // @access Public exports.createApp = asyncWrapper(async (req, res, next) => { - const app = await App.create(req.body); + // Get config from database + const pinApps = await Config.findOne({ + where: { key: 'pinAppsByDefault' } + }); + + let app; + + if (pinApps) { + if (parseInt(pinApps.value)) { + app = await App.create({ + ...req.body, + isPinned: true + }) + } else { + app = await App.create(req.body); + } + } res.status(201).json({ success: true, diff --git a/controllers/category.js b/controllers/category.js index 60e7305a..a3904051 100644 --- a/controllers/category.js +++ b/controllers/category.js @@ -2,12 +2,29 @@ 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'); // @desc Create new category // @route POST /api/categories // @access Public exports.createCategory = asyncWrapper(async (req, res, next) => { - const category = await Category.create(req.body); + // Get config from database + const pinCategories = await Config.findOne({ + where: { key: 'pinCategoriesByDefault' } + }); + + let category; + + if (pinCategories) { + if (parseInt(pinCategories.value)) { + category = await Category.create({ + ...req.body, + isPinned: true + }) + } else { + category = await Category.create(req.body); + } + } res.status(201).json({ success: true, diff --git a/db.js b/db.js index b357dcac..bc4c536c 100644 --- a/db.js +++ b/db.js @@ -8,13 +8,10 @@ const sequelize = new Sequelize({ const connectDB = async () => { try { - await sequelize.authenticate({ logging: false }); + await sequelize.authenticate(); console.log('Connected to database'); - await sequelize.sync({ - // alter: true, - logging: false - }); + await sequelize.sync({ alter: true }); console.log('All models were synced'); } catch (error) { console.error('Unable to connect to the database:', error); diff --git a/models/Bookmark.js b/models/Bookmark.js index bc218089..6c7d27b3 100644 --- a/models/Bookmark.js +++ b/models/Bookmark.js @@ -13,6 +13,10 @@ const Bookmark = sequelize.define('Bookmark', { categoryId: { type: DataTypes.INTEGER, allowNull: false + }, + icon: { + type: DataTypes.STRING, + defaultValue: '' } }, { tableName: 'bookmarks' diff --git a/utils/clearWeatherData.js b/utils/clearWeatherData.js new file mode 100644 index 00000000..d43f975a --- /dev/null +++ b/utils/clearWeatherData.js @@ -0,0 +1,22 @@ +const { Op } = require('sequelize'); +const Weather = require('../models/Weather'); + +const clearWeatherData = async () => { + const weather = await Weather.findOne({ + order: [[ 'createdAt', 'DESC' ]] + }); + + if (weather) { + await Weather.destroy({ + where: { + id: { + [Op.lt]: weather.id + } + } + }) + } + + console.log('Old weather data was deleted'); +} + +module.exports = clearWeatherData; \ No newline at end of file diff --git a/utils/initConfig.js b/utils/initConfig.js index c8e43fa8..de1cc881 100644 --- a/utils/initConfig.js +++ b/utils/initConfig.js @@ -1,16 +1,13 @@ const { Op } = require('sequelize'); const Config = require('../models/Config'); +const { config } = require('./initialConfig.json'); const initConfig = async () => { - // Config keys - const keys = ['WEATHER_API_KEY', 'lat', 'long', 'isCelsius', 'customTitle']; - const values = ['', 0, 0, true, 'Flame']; - // Get config values const configPairs = await Config.findAll({ where: { key: { - [Op.or]: keys + [Op.or]: config.map(pair => pair.key) } } }) @@ -19,12 +16,12 @@ const initConfig = async () => { const configKeys = configPairs.map((pair) => pair.key); // Create missing pairs - keys.forEach(async (key, idx) => { + config.forEach(async ({ key, value}) => { if (!configKeys.includes(key)) { await Config.create({ key, - value: values[idx], - valueType: typeof values[idx] + value, + valueType: typeof value }) } }) diff --git a/utils/initialConfig.json b/utils/initialConfig.json new file mode 100644 index 00000000..eae974aa --- /dev/null +++ b/utils/initialConfig.json @@ -0,0 +1,32 @@ +{ + "config": [ + { + "key": "WEATHER_API_KEY", + "value": "" + }, + { + "key": "lat", + "value": 0 + }, + { + "key": "long", + "value": 0 + }, + { + "key": "isCelsius", + "value": true + }, + { + "key": "customTitle", + "value": "Flame" + }, + { + "key": "pinAppsByDefault", + "value": true + }, + { + "key": "pinCategoriesByDefault", + "value": true + } + ] +} \ No newline at end of file diff --git a/utils/jobs.js b/utils/jobs.js index aa8d41cd..19dc0a82 100644 --- a/utils/jobs.js +++ b/utils/jobs.js @@ -1,5 +1,6 @@ const schedule = require('node-schedule'); const getExternalWeather = require('./getExternalWeather'); +const clearWeatherData = require('./clearWeatherData'); const Sockets = require('../Sockets'); // Update weather data every 15 minutes @@ -14,6 +15,6 @@ const weatherJob = schedule.scheduleJob('updateWeather', '0 */15 * * * *', async }) // Clear old weather data every 4 hours -const weatherCleanerJob = schedule.scheduleJob('clearWeather', '0 0 */4 * * *', async () => { - console.log('clean') +const weatherCleanerJob = schedule.scheduleJob('clearWeather', '0 5 */4 * * *', async () => { + clearWeatherData(); }) \ No newline at end of file