diff --git a/.gitignore b/.gitignore index b7faae2..94f96cb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ node_modules package-lock.json dist/* - +*.db diff --git a/config/default.json b/config/default.json index 95da1ca..3fbab15 100755 --- a/config/default.json +++ b/config/default.json @@ -1,6 +1,25 @@ { - "http": { - "base": "ketr.ketran", - "port": 8930 + "db": { + "games": { + "dialect": "sqlite", + "storage": "../db/photos.db", + "logging" : false, + "timezone": "+00:00" + }, + "users": { + "dialect": "sqlite", + "storage": "../db/users.db", + "logging" : false, + "timezone": "+00:00" + } + }, + "server": { + "port": 8911 + }, + "frontendPath": "./", + "basePath": "/ketr.ketran", + "sessions": { + "db": "sessions.db", + "store-secret": "m@g1kc00ki3z!" } -} +} \ No newline at end of file diff --git a/config/local.json b/config/local.json old mode 100644 new mode 100755 index 353fed6..0fc7837 --- a/config/local.json +++ b/config/local.json @@ -1,5 +1,9 @@ { - "tokens": [ { - "jketreno": "1MhGsldnwNkH9d2s-yu8fxZ0JcHCpClY" - } ] + "admin": { + "mail": "james_ketran@ketrenos.com" + }, + "smtp": { + "host": "ketrenos.com", + "sender": "james_ketran@ketrenos.com" + } } diff --git a/f/.gitignore b/f/.gitignore deleted file mode 100644 index fca2ec9..0000000 --- a/f/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -!.gitignore -!package.json -node_modules -config/local.json -package-lock.json -*.log diff --git a/f/package.json b/f/package.json deleted file mode 100644 index 486bc52..0000000 --- a/f/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "ketr.ketran", - "version": "1.0.0", - "description": "Peddlers of Ketran: REST API", - "main": "index.html", - "scripts": { - "start": "NODE_CONFIG_ENV='devel' node server/app.js", - "backend": "NODE_CONFIG_ENV='production' node server/app.js" - }, - "repository": "ssh://git@gitlab.ketrenos.com:/jketreno/ketr.ketran", - "author": "James Ketrenos ", - "license": "MIT", - "private": true, - "dependencies": { - "bluebird": "^3.5.5", - "config": "^3.1.0", - "connect-sqlite3": "^0.9.11", - "cookie-parser": "^1.4.4", - "express": "^4.17.1", - "express-session": "^1.17.1", - "handlebars": "^4.7.6", - "moment": "^2.24.0", - "morgan": "^1.9.1", - "node-fetch": "^2.6.0", - "node-gzip": "^1.1.2", - "nodemailer": "^6.3.0", - "sequelize": "^5.21.6", - "sqlite3": "^4.1.1" - }, - "devDependencies": {} -} diff --git a/index.html b/index.html old mode 100644 new mode 100755 index 97e9eb1..c22200c --- a/index.html +++ b/index.html @@ -1,6 +1,10 @@ + diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 019973f..ef014d5 --- a/package.json +++ b/package.json @@ -4,8 +4,6 @@ "description": "Settlers", "main": "index.html", "scripts": { - "start": "NODE_CONFIG_ENV='devel' node server/app.js", - "backend": "NODE_CONFIG_ENV='production' node server/app.js" "start": "webpack-dev-server --mode development --host 0.0.0.0 --config webpack.dev.js", "build": "webpack --config webpack.prod.js", "watch": "webpack --config webpack.prod.js --watch", @@ -16,16 +14,22 @@ "license": "MIT", "private": true, "dependencies": { + "@material-ui/core": "^4.9.11", "animakit-expander": "^2.1.4", "bluebird": "^3.5.5", "bootstrap": "^4.4.1", "config": "^3.1.0", + "connect-sqlite3": "^0.9.11", "cookie-parser": "^1.4.4", "core-js": "^3.2.1", + "express": "^4.17.1", + "express-session": "^1.17.1", "googleapis": "^40.0.0", + "handlebars": "^4.7.6", "jira-connector": "^2.10.0", "moment": "^2.24.0", "morgan": "^1.9.1", + "node-fetch": "^2.6.0", "node-gzip": "^1.1.2", "nodemailer": "^6.3.0", "react-app-polyfill": "^1.0.2", @@ -34,21 +38,10 @@ "react-markdown": "^4.2.2", "react-router-dom": "^5.0.1", "react-scroll": "^1.7.14", - "react-syntax-highlighter": "^11.0.2" - "bluebird": "^3.5.5", - "config": "^3.1.0", - "connect-sqlite3": "^0.9.11", - "cookie-parser": "^1.4.4", - "express": "^4.17.1", - "express-session": "^1.17.1", - "handlebars": "^4.7.6", - "moment": "^2.24.0", - "morgan": "^1.9.1", - "node-fetch": "^2.6.0", - "node-gzip": "^1.1.2", - "nodemailer": "^6.3.0", + "react-syntax-highlighter": "^11.0.2", "sequelize": "^5.21.6", - "sqlite3": "^4.1.1" + "sqlite3": "^4.1.1", + "typeface-roboto": "0.0.75" }, "devDependencies": { "@babel/cli": "^7.1.0", diff --git a/server/app.js b/server/app.js index 0bc2374..ef0be8a 100755 --- a/server/app.js +++ b/server/app.js @@ -10,12 +10,11 @@ const express = require("express"), config = require("config"), session = require('express-session'), hb = require("handlebars"), - SQLiteStore = require('connect-sqlite3')(session), - scanner = require("./scanner"); + SQLiteStore = require('connect-sqlite3')(session); require("./console-line.js"); /* Monkey-patch console.log with line numbers */ -const frontEndPath = config.get("frontendPath").replace(/\/$/, "") + "/", +const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/", serverConfig = config.get("server"); let basePath = config.get("basePath"); @@ -26,6 +25,8 @@ if (basePath == "//") { console.log("Hosting server from: " + basePath); +let userDB, gameDB; + const app = express(); app.set("basePath", basePath); @@ -37,7 +38,7 @@ app.set("trust proxy", true); app.use(basePath, require("./routes/basepath.js")); /* Handle static files first so excessive logging doesn't occur */ -app.use(basePath, express.static("frontend", { index: false })); +app.use(basePath, express.static(frontendPath, { index: false })); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ @@ -236,6 +237,7 @@ const users = require("./routes/users"); app.use(basePath + "api/v1/users", users.router); app.use(function(err, req, res, next) { + console.error(err.message); res.status(err.status || 500).json({ message: err.message, error: {} @@ -271,7 +273,7 @@ app.set("port", serverConfig.port); const server = require("http").createServer(app); require("./db/games").then(function(db) { - gamesDB = db; + gameDB = db; }).then(function() { return require("./db/users").then(function(db) { userDB = db; diff --git a/server/db/games.db b/server/db/games.db deleted file mode 100644 index 4a06899..0000000 Binary files a/server/db/games.db and /dev/null differ diff --git a/server/db/games.js b/server/db/games.js new file mode 100755 index 0000000..b487f54 --- /dev/null +++ b/server/db/games.js @@ -0,0 +1,44 @@ +"use strict"; + +const fs = require('fs'), + path = require('path'), + Sequelize = require('sequelize'), + config = require('config'); + +function init() { + const db = { + sequelize: new Sequelize(config.get("db.games")), + Sequelize: Sequelize + }; + + return db.sequelize.authenticate().then(function () { + const Game = db.sequelize.define('game', { + id: { + type: Sequelize.INTEGER, + primaryKey: true, + autoIncrement: true + }, + path: Sequelize.STRING, + name: Sequelize.STRING, + }, { + timestamps: false, + classMethods: { + associate: function() { + } + } + }); + + return db.sequelize.sync({ + force: false + }).then(function () { + return db; + }); + }).catch(function (error) { + console.log("ERROR: Failed to authenticate with GAMES DB"); + console.log("ERROR: " + JSON.stringify(config.get("db"), null, 2)); + console.log(error); + throw error; + }); +} + +module.exports = init(); diff --git a/server/db/users.js b/server/db/users.js new file mode 100755 index 0000000..00e5dae --- /dev/null +++ b/server/db/users.js @@ -0,0 +1,70 @@ +"use strict"; + +const Sequelize = require('sequelize'), + config = require('config'); + +function init() { + const db = { + sequelize: new Sequelize(config.get("db.users")), + Sequelize: Sequelize + }; + + return db.sequelize.authenticate().then(function () { + const User = db.sequelize.define('users', { + id: { + type: Sequelize.INTEGER, + primaryKey: true, + autoIncrement: true + }, + displayName: Sequelize.STRING, + notes: Sequelize.STRING, + uid: Sequelize.STRING, + authToken: Sequelize.STRING, + authDate: Sequelize.DATE, + authenticated: Sequelize.BOOLEAN, + mailVerified: Sequelize.BOOLEAN, + mail: Sequelize.STRING, + memberSince: Sequelize.DATE, + password: Sequelize.STRING, /* SHA hash of user supplied password */ + passwordExpires: Sequelize.DATE + }, { + timestamps: false + }); + + const Authentication = db.sequelize.define('authentication', { + key: { + type: Sequelize.STRING, + primaryKey: true, + allowNull: false + }, + issued: Sequelize.DATE, + type: { + type: Sequelize.ENUM, + values: [ 'account-setup', 'password-reset' ] + }, + userId: { + type: Sequelize.INTEGER, + allowNull: false, + references: { + model: User, + key: 'id', + } + } + }, { + timestamps: false + }); + + return db.sequelize.sync({ + force: false + }).then(function () { + return db; + }); + }).catch(function (error) { + console.log("ERROR: Failed to authenticate with USER DB"); + console.log("ERROR: " + JSON.stringify(config.get("db"), null, 2)); + console.log(error); + throw error; + }); +} + +module.exports = init(); diff --git a/server/lib/mail.js b/server/lib/mail.js index 944c272..3cc10c2 100644 --- a/server/lib/mail.js +++ b/server/lib/mail.js @@ -68,7 +68,7 @@ const sendVerifyMail = function(userDB, req, user) { }); }).then(function(secret) { return userDB.sequelize.query( - "INSERT INTO authentications " + + "INSERT INTO authentications " + "(userId,issued,key,type) " + "VALUES (:userId,CURRENT_TIMESTAMP,:key,'account-setup')", { replacements: { @@ -104,7 +104,7 @@ const sendVerifyMail = function(userDB, req, user) { }; return new Promise(function (resolve, reject) { let attempts = 10; - + function send(envelope) { /* Rate limit to ten per second */ transporter.sendMail(envelope, function (error, info) { @@ -117,7 +117,7 @@ const sendVerifyMail = function(userDB, req, user) { console.log("Error sending email: ", error); return reject(error); } - + attempts--; console.log("Unable to send mail. Trying again in 100ms (" + attempts + " attempts remain): ", error); setTimeout(send.bind(undefined, envelope), 100); @@ -166,7 +166,7 @@ const sendPasswordChangedMail = function(userDB, req, user) { console.log("Error sending email: ", error); return reject(error); } - + attempts--; console.log("Unable to send mail. Trying again in 100ms (" + attempts + " attempts remain): ", error); setTimeout(send.bind(undefined, envelope), 100); diff --git a/server/lib/pascha-dates.js b/server/lib/pascha-dates.js deleted file mode 100644 index c2c516a..0000000 --- a/server/lib/pascha-dates.js +++ /dev/null @@ -1,512 +0,0 @@ -/* -EasterB - What date does Easter Sunday come on in a given year? -Version 1.23, last revised: 2007/07/22 -Copyright (c) 1981-2007 by author: Harry J. Smith, -19628 Via Monte Dr., Saratoga CA 95070. All rights reserved. - -Will write file: EasterB.Out for years 1875 - 2124 - -Gregorian Calendar -Easter Sunday: 1875 3/28 Western 4/25 Orthodox (April 13 Julian date) -Easter Sunday: 1876 4/16 Western Same Orthodox (April 4 Julian date) -Easter Sunday: 1877 4/ 1 Western 4/ 8 Orthodox (March 27 Julian date) -Easter Sunday: 1878 4/21 Western 4/28 Orthodox (April 16 Julian date) -Easter Sunday: 1879 4/13 Western Same Orthodox (April 1 Julian date) -Easter Sunday: 1880 3/28 Western 5/ 2 Orthodox (April 20 Julian date) -Easter Sunday: 1881 4/17 Western 4/24 Orthodox (April 12 Julian date) -Easter Sunday: 1882 4/ 9 Western Same Orthodox (March 28 Julian date) -Easter Sunday: 1883 3/25 Western 4/29 Orthodox (April 17 Julian date) -Easter Sunday: 1884 4/13 Western 4/20 Orthodox (April 8 Julian date) -Easter Sunday: 1885 4/ 5 Western Same Orthodox (March 24 Julian date) -Easter Sunday: 1886 4/25 Western Same Orthodox (April 13 Julian date) -Easter Sunday: 1887 4/10 Western 4/17 Orthodox (April 5 Julian date) -Easter Sunday: 1888 4/ 1 Western 5/ 6 Orthodox (April 24 Julian date) -Easter Sunday: 1889 4/21 Western Same Orthodox (April 9 Julian date) -Easter Sunday: 1890 4/ 6 Western 4/13 Orthodox (April 1 Julian date) -Easter Sunday: 1891 3/29 Western 5/ 3 Orthodox (April 21 Julian date) -Easter Sunday: 1892 4/17 Western Same Orthodox (April 5 Julian date) -Easter Sunday: 1893 4/ 2 Western 4/ 9 Orthodox (March 28 Julian date) -Easter Sunday: 1894 3/25 Western 4/29 Orthodox (April 17 Julian date) -Easter Sunday: 1895 4/14 Western Same Orthodox (April 2 Julian date) -Easter Sunday: 1896 4/ 5 Western Same Orthodox (March 24 Julian date) -Easter Sunday: 1897 4/18 Western 4/25 Orthodox (April 13 Julian date) -Easter Sunday: 1898 4/10 Western 4/17 Orthodox (April 5 Julian date) -Easter Sunday: 1899 4/ 2 Western 4/30 Orthodox (April 18 Julian date) -Easter Sunday: 1900 4/15 Western 4/22 Orthodox (April 9 Julian date) -Easter Sunday: 1901 4/ 7 Western 4/14 Orthodox (April 1 Julian date) -Easter Sunday: 1902 3/30 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 1903 4/12 Western 4/19 Orthodox (April 6 Julian date) -Easter Sunday: 1904 4/ 3 Western 4/10 Orthodox (March 28 Julian date) -Easter Sunday: 1905 4/23 Western 4/30 Orthodox (April 17 Julian date) -Easter Sunday: 1906 4/15 Western Same Orthodox (April 2 Julian date) -Easter Sunday: 1907 3/31 Western 5/ 5 Orthodox (April 22 Julian date) -Easter Sunday: 1908 4/19 Western 4/26 Orthodox (April 13 Julian date) -Easter Sunday: 1909 4/11 Western Same Orthodox (March 29 Julian date) -Easter Sunday: 1910 3/27 Western 5/ 1 Orthodox (April 18 Julian date) -Easter Sunday: 1911 4/16 Western 4/23 Orthodox (April 10 Julian date) -Easter Sunday: 1912 4/ 7 Western Same Orthodox (March 25 Julian date) -Easter Sunday: 1913 3/23 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 1914 4/12 Western 4/19 Orthodox (April 6 Julian date) -Easter Sunday: 1915 4/ 4 Western Same Orthodox (March 22 Julian date) -Easter Sunday: 1916 4/23 Western Same Orthodox (April 10 Julian date) -Easter Sunday: 1917 4/ 8 Western 4/15 Orthodox (April 2 Julian date) -Easter Sunday: 1918 3/31 Western 5/ 5 Orthodox (April 22 Julian date) -Easter Sunday: 1919 4/20 Western Same Orthodox (April 7 Julian date) -Easter Sunday: 1920 4/ 4 Western 4/11 Orthodox (March 29 Julian date) -Easter Sunday: 1921 3/27 Western 5/ 1 Orthodox (April 18 Julian date) -Easter Sunday: 1922 4/16 Western Same Orthodox (April 3 Julian date) -Easter Sunday: 1923 4/ 1 Western 4/ 8 Orthodox (March 26 Julian date) -Easter Sunday: 1924 4/20 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 1925 4/12 Western 4/19 Orthodox (April 6 Julian date) -Easter Sunday: 1926 4/ 4 Western 5/ 2 Orthodox (April 19 Julian date) -Easter Sunday: 1927 4/17 Western 4/24 Orthodox (April 11 Julian date) -Easter Sunday: 1928 4/ 8 Western 4/15 Orthodox (April 2 Julian date) -Easter Sunday: 1929 3/31 Western 5/ 5 Orthodox (April 22 Julian date) -Easter Sunday: 1930 4/20 Western Same Orthodox (April 7 Julian date) -Easter Sunday: 1931 4/ 5 Western 4/12 Orthodox (March 30 Julian date) -Easter Sunday: 1932 3/27 Western 5/ 1 Orthodox (April 18 Julian date) -Easter Sunday: 1933 4/16 Western Same Orthodox (April 3 Julian date) -Easter Sunday: 1934 4/ 1 Western 4/ 8 Orthodox (March 26 Julian date) -Easter Sunday: 1935 4/21 Western 4/28 Orthodox (April 15 Julian date) -Easter Sunday: 1936 4/12 Western Same Orthodox (March 30 Julian date) -Easter Sunday: 1937 3/28 Western 5/ 2 Orthodox (April 19 Julian date) -Easter Sunday: 1938 4/17 Western 4/24 Orthodox (April 11 Julian date) -Easter Sunday: 1939 4/ 9 Western Same Orthodox (March 27 Julian date) -Easter Sunday: 1940 3/24 Western 4/28 Orthodox (April 15 Julian date) -Easter Sunday: 1941 4/13 Western 4/20 Orthodox (April 7 Julian date) -Easter Sunday: 1942 4/ 5 Western Same Orthodox (March 23 Julian date) -Easter Sunday: 1943 4/25 Western Same Orthodox (April 12 Julian date) -Easter Sunday: 1944 4/ 9 Western 4/16 Orthodox (April 3 Julian date) -Easter Sunday: 1945 4/ 1 Western 5/ 6 Orthodox (April 23 Julian date) -Easter Sunday: 1946 4/21 Western Same Orthodox (April 8 Julian date) -Easter Sunday: 1947 4/ 6 Western 4/13 Orthodox (March 31 Julian date) -Easter Sunday: 1948 3/28 Western 5/ 2 Orthodox (April 19 Julian date) -Easter Sunday: 1949 4/17 Western 4/24 Orthodox (April 11 Julian date) -Easter Sunday: 1950 4/ 9 Western Same Orthodox (March 27 Julian date) -Easter Sunday: 1951 3/25 Western 4/29 Orthodox (April 16 Julian date) -Easter Sunday: 1952 4/13 Western 4/20 Orthodox (April 7 Julian date) -Easter Sunday: 1953 4/ 5 Western Same Orthodox (March 23 Julian date) -Easter Sunday: 1954 4/18 Western 4/25 Orthodox (April 12 Julian date) -Easter Sunday: 1955 4/10 Western 4/17 Orthodox (April 4 Julian date) -Easter Sunday: 1956 4/ 1 Western 5/ 6 Orthodox (April 23 Julian date) -Easter Sunday: 1957 4/21 Western Same Orthodox (April 8 Julian date) -Easter Sunday: 1958 4/ 6 Western 4/13 Orthodox (March 31 Julian date) -Easter Sunday: 1959 3/29 Western 5/ 3 Orthodox (April 20 Julian date) -Easter Sunday: 1960 4/17 Western Same Orthodox (April 4 Julian date) -Easter Sunday: 1961 4/ 2 Western 4/ 9 Orthodox (March 27 Julian date) -Easter Sunday: 1962 4/22 Western 4/29 Orthodox (April 16 Julian date) -Easter Sunday: 1963 4/14 Western Same Orthodox (April 1 Julian date) -Easter Sunday: 1964 3/29 Western 5/ 3 Orthodox (April 20 Julian date) -Easter Sunday: 1965 4/18 Western 4/25 Orthodox (April 12 Julian date) -Easter Sunday: 1966 4/10 Western Same Orthodox (March 28 Julian date) -Easter Sunday: 1967 3/26 Western 4/30 Orthodox (April 17 Julian date) -Easter Sunday: 1968 4/14 Western 4/21 Orthodox (April 8 Julian date) -Easter Sunday: 1969 4/ 6 Western 4/13 Orthodox (March 31 Julian date) -Easter Sunday: 1970 3/29 Western 4/26 Orthodox (April 13 Julian date) -Easter Sunday: 1971 4/11 Western 4/18 Orthodox (April 5 Julian date) -Easter Sunday: 1972 4/ 2 Western 4/ 9 Orthodox (March 27 Julian date) -Easter Sunday: 1973 4/22 Western 4/29 Orthodox (April 16 Julian date) -Easter Sunday: 1974 4/14 Western Same Orthodox (April 1 Julian date) -Easter Sunday: 1975 3/30 Western 5/ 4 Orthodox (April 21 Julian date) -Easter Sunday: 1976 4/18 Western 4/25 Orthodox (April 12 Julian date) -Easter Sunday: 1977 4/10 Western Same Orthodox (March 28 Julian date) -Easter Sunday: 1978 3/26 Western 4/30 Orthodox (April 17 Julian date) -Easter Sunday: 1979 4/15 Western 4/22 Orthodox (April 9 Julian date) -Easter Sunday: 1980 4/ 6 Western Same Orthodox (March 24 Julian date) -Easter Sunday: 1981 4/19 Western 4/26 Orthodox (April 13 Julian date) -Easter Sunday: 1982 4/11 Western 4/18 Orthodox (April 5 Julian date) -Easter Sunday: 1983 4/ 3 Western 5/ 8 Orthodox (April 25 Julian date) -Easter Sunday: 1984 4/22 Western Same Orthodox (April 9 Julian date) -Easter Sunday: 1985 4/ 7 Western 4/14 Orthodox (April 1 Julian date) -Easter Sunday: 1986 3/30 Western 5/ 4 Orthodox (April 21 Julian date) -Easter Sunday: 1987 4/19 Western Same Orthodox (April 6 Julian date) -Easter Sunday: 1988 4/ 3 Western 4/10 Orthodox (March 28 Julian date) -Easter Sunday: 1989 3/26 Western 4/30 Orthodox (April 17 Julian date) -Easter Sunday: 1990 4/15 Western Same Orthodox (April 2 Julian date) -Easter Sunday: 1991 3/31 Western 4/ 7 Orthodox (March 25 Julian date) -Easter Sunday: 1992 4/19 Western 4/26 Orthodox (April 13 Julian date) -Easter Sunday: 1993 4/11 Western 4/18 Orthodox (April 5 Julian date) -Easter Sunday: 1994 4/ 3 Western 5/ 1 Orthodox (April 18 Julian date) -Easter Sunday: 1995 4/16 Western 4/23 Orthodox (April 10 Julian date) -Easter Sunday: 1996 4/ 7 Western 4/14 Orthodox (April 1 Julian date) -Easter Sunday: 1997 3/30 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 1998 4/12 Western 4/19 Orthodox (April 6 Julian date) -Easter Sunday: 1999 4/ 4 Western 4/11 Orthodox (March 29 Julian date) -Easter Sunday: 2000 4/23 Western 4/30 Orthodox (April 17 Julian date) -Easter Sunday: 2001 4/15 Western Same Orthodox (April 2 Julian date) -Easter Sunday: 2002 3/31 Western 5/ 5 Orthodox (April 22 Julian date) -Easter Sunday: 2003 4/20 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 2004 4/11 Western Same Orthodox (March 29 Julian date) -Easter Sunday: 2005 3/27 Western 5/ 1 Orthodox (April 18 Julian date) -Easter Sunday: 2006 4/16 Western 4/23 Orthodox (April 10 Julian date) -Easter Sunday: 2007 4/ 8 Western Same Orthodox (March 26 Julian date) -Easter Sunday: 2008 3/23 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 2009 4/12 Western 4/19 Orthodox (April 6 Julian date) -Easter Sunday: 2010 4/ 4 Western Same Orthodox (March 22 Julian date) -Easter Sunday: 2011 4/24 Western Same Orthodox (April 11 Julian date) -Easter Sunday: 2012 4/ 8 Western 4/15 Orthodox (April 2 Julian date) -Easter Sunday: 2013 3/31 Western 5/ 5 Orthodox (April 22 Julian date) -Easter Sunday: 2014 4/20 Western Same Orthodox (April 7 Julian date) -Easter Sunday: 2015 4/ 5 Western 4/12 Orthodox (March 30 Julian date) -Easter Sunday: 2016 3/27 Western 5/ 1 Orthodox (April 18 Julian date) -Easter Sunday: 2017 4/16 Western Same Orthodox (April 3 Julian date) -Easter Sunday: 2018 4/ 1 Western 4/ 8 Orthodox (March 26 Julian date) -Easter Sunday: 2019 4/21 Western 4/28 Orthodox (April 15 Julian date) -Easter Sunday: 2020 4/12 Western 4/19 Orthodox (April 6 Julian date) -Easter Sunday: 2021 4/ 4 Western 5/ 2 Orthodox (April 19 Julian date) -Easter Sunday: 2022 4/17 Western 4/24 Orthodox (April 11 Julian date) -Easter Sunday: 2023 4/ 9 Western 4/16 Orthodox (April 3 Julian date) -Easter Sunday: 2024 3/31 Western 5/ 5 Orthodox (April 22 Julian date) -Easter Sunday: 2025 4/20 Western Same Orthodox (April 7 Julian date) -Easter Sunday: 2026 4/ 5 Western 4/12 Orthodox (March 30 Julian date) -Easter Sunday: 2027 3/28 Western 5/ 2 Orthodox (April 19 Julian date) -Easter Sunday: 2028 4/16 Western Same Orthodox (April 3 Julian date) -Easter Sunday: 2029 4/ 1 Western 4/ 8 Orthodox (March 26 Julian date) -Easter Sunday: 2030 4/21 Western 4/28 Orthodox (April 15 Julian date) -Easter Sunday: 2031 4/13 Western Same Orthodox (March 31 Julian date) -Easter Sunday: 2032 3/28 Western 5/ 2 Orthodox (April 19 Julian date) -Easter Sunday: 2033 4/17 Western 4/24 Orthodox (April 11 Julian date) -Easter Sunday: 2034 4/ 9 Western Same Orthodox (March 27 Julian date) -Easter Sunday: 2035 3/25 Western 4/29 Orthodox (April 16 Julian date) -Easter Sunday: 2036 4/13 Western 4/20 Orthodox (April 7 Julian date) -Easter Sunday: 2037 4/ 5 Western Same Orthodox (March 23 Julian date) -Easter Sunday: 2038 4/25 Western Same Orthodox (April 12 Julian date) -Easter Sunday: 2039 4/10 Western 4/17 Orthodox (April 4 Julian date) -Easter Sunday: 2040 4/ 1 Western 5/ 6 Orthodox (April 23 Julian date) -Easter Sunday: 2041 4/21 Western Same Orthodox (April 8 Julian date) -Easter Sunday: 2042 4/ 6 Western 4/13 Orthodox (March 31 Julian date) -Easter Sunday: 2043 3/29 Western 5/ 3 Orthodox (April 20 Julian date) -Easter Sunday: 2044 4/17 Western 4/24 Orthodox (April 11 Julian date) -Easter Sunday: 2045 4/ 9 Western Same Orthodox (March 27 Julian date) -Easter Sunday: 2046 3/25 Western 4/29 Orthodox (April 16 Julian date) -Easter Sunday: 2047 4/14 Western 4/21 Orthodox (April 8 Julian date) -Easter Sunday: 2048 4/ 5 Western Same Orthodox (March 23 Julian date) -Easter Sunday: 2049 4/18 Western 4/25 Orthodox (April 12 Julian date) -Easter Sunday: 2050 4/10 Western 4/17 Orthodox (April 4 Julian date) -Easter Sunday: 2051 4/ 2 Western 5/ 7 Orthodox (April 24 Julian date) -Easter Sunday: 2052 4/21 Western Same Orthodox (April 8 Julian date) -Easter Sunday: 2053 4/ 6 Western 4/13 Orthodox (March 31 Julian date) -Easter Sunday: 2054 3/29 Western 5/ 3 Orthodox (April 20 Julian date) -Easter Sunday: 2055 4/18 Western Same Orthodox (April 5 Julian date) -Easter Sunday: 2056 4/ 2 Western 4/ 9 Orthodox (March 27 Julian date) -Easter Sunday: 2057 4/22 Western 4/29 Orthodox (April 16 Julian date) -Easter Sunday: 2058 4/14 Western Same Orthodox (April 1 Julian date) -Easter Sunday: 2059 3/30 Western 5/ 4 Orthodox (April 21 Julian date) -Easter Sunday: 2060 4/18 Western 4/25 Orthodox (April 12 Julian date) -Easter Sunday: 2061 4/10 Western Same Orthodox (March 28 Julian date) -Easter Sunday: 2062 3/26 Western 4/30 Orthodox (April 17 Julian date) -Easter Sunday: 2063 4/15 Western 4/22 Orthodox (April 9 Julian date) -Easter Sunday: 2064 4/ 6 Western 4/13 Orthodox (March 31 Julian date) -Easter Sunday: 2065 3/29 Western 4/26 Orthodox (April 13 Julian date) -Easter Sunday: 2066 4/11 Western 4/18 Orthodox (April 5 Julian date) -Easter Sunday: 2067 4/ 3 Western 4/10 Orthodox (March 28 Julian date) -Easter Sunday: 2068 4/22 Western 4/29 Orthodox (April 16 Julian date) -Easter Sunday: 2069 4/14 Western Same Orthodox (April 1 Julian date) -Easter Sunday: 2070 3/30 Western 5/ 4 Orthodox (April 21 Julian date) -Easter Sunday: 2071 4/19 Western Same Orthodox (April 6 Julian date) -Easter Sunday: 2072 4/10 Western Same Orthodox (March 28 Julian date) -Easter Sunday: 2073 3/26 Western 4/30 Orthodox (April 17 Julian date) -Easter Sunday: 2074 4/15 Western 4/22 Orthodox (April 9 Julian date) -Easter Sunday: 2075 4/ 7 Western Same Orthodox (March 25 Julian date) -Easter Sunday: 2076 4/19 Western 4/26 Orthodox (April 13 Julian date) -Easter Sunday: 2077 4/11 Western 4/18 Orthodox (April 5 Julian date) -Easter Sunday: 2078 4/ 3 Western 5/ 8 Orthodox (April 25 Julian date) -Easter Sunday: 2079 4/23 Western Same Orthodox (April 10 Julian date) -Easter Sunday: 2080 4/ 7 Western 4/14 Orthodox (April 1 Julian date) -Easter Sunday: 2081 3/30 Western 5/ 4 Orthodox (April 21 Julian date) -Easter Sunday: 2082 4/19 Western Same Orthodox (April 6 Julian date) -Easter Sunday: 2083 4/ 4 Western 4/11 Orthodox (March 29 Julian date) -Easter Sunday: 2084 3/26 Western 4/30 Orthodox (April 17 Julian date) -Easter Sunday: 2085 4/15 Western Same Orthodox (April 2 Julian date) -Easter Sunday: 2086 3/31 Western 4/ 7 Orthodox (March 25 Julian date) -Easter Sunday: 2087 4/20 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 2088 4/11 Western 4/18 Orthodox (April 5 Julian date) -Easter Sunday: 2089 4/ 3 Western 5/ 1 Orthodox (April 18 Julian date) -Easter Sunday: 2090 4/16 Western 4/23 Orthodox (April 10 Julian date) -Easter Sunday: 2091 4/ 8 Western Same Orthodox (March 26 Julian date) -Easter Sunday: 2092 3/30 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 2093 4/12 Western 4/19 Orthodox (April 6 Julian date) -Easter Sunday: 2094 4/ 4 Western 4/11 Orthodox (March 29 Julian date) -Easter Sunday: 2095 4/24 Western Same Orthodox (April 11 Julian date) -Easter Sunday: 2096 4/15 Western Same Orthodox (April 2 Julian date) -Easter Sunday: 2097 3/31 Western 5/ 5 Orthodox (April 22 Julian date) -Easter Sunday: 2098 4/20 Western 4/27 Orthodox (April 14 Julian date) -Easter Sunday: 2099 4/12 Western Same Orthodox (March 30 Julian date) -Easter Sunday: 2100 3/28 Western 5/ 2 Orthodox (April 18 Julian date) -Easter Sunday: 2101 4/17 Western 4/24 Orthodox (April 10 Julian date) -Easter Sunday: 2102 4/ 9 Western Same Orthodox (March 26 Julian date) -Easter Sunday: 2103 3/25 Western 4/29 Orthodox (April 15 Julian date) -Easter Sunday: 2104 4/13 Western 4/20 Orthodox (April 6 Julian date) -Easter Sunday: 2105 4/ 5 Western Same Orthodox (March 22 Julian date) -Easter Sunday: 2106 4/18 Western 4/25 Orthodox (April 11 Julian date) -Easter Sunday: 2107 4/10 Western 4/17 Orthodox (April 3 Julian date) -Easter Sunday: 2108 4/ 1 Western 5/ 6 Orthodox (April 22 Julian date) -Easter Sunday: 2109 4/21 Western Same Orthodox (April 7 Julian date) -Easter Sunday: 2110 4/ 6 Western 4/13 Orthodox (March 30 Julian date) -Easter Sunday: 2111 3/29 Western 5/ 3 Orthodox (April 19 Julian date) -Easter Sunday: 2112 4/17 Western Same Orthodox (April 3 Julian date) -Easter Sunday: 2113 4/ 2 Western 4/ 9 Orthodox (March 26 Julian date) -Easter Sunday: 2114 4/22 Western 4/29 Orthodox (April 15 Julian date) -Easter Sunday: 2115 4/14 Western Same Orthodox (March 31 Julian date) -Easter Sunday: 2116 3/29 Western 5/ 3 Orthodox (April 19 Julian date) -Easter Sunday: 2117 4/18 Western 4/25 Orthodox (April 11 Julian date) -Easter Sunday: 2118 4/10 Western 4/17 Orthodox (April 3 Julian date) -Easter Sunday: 2119 3/26 Western 4/30 Orthodox (April 16 Julian date) -Easter Sunday: 2120 4/14 Western 4/21 Orthodox (April 7 Julian date) -Easter Sunday: 2121 4/ 6 Western 4/13 Orthodox (March 30 Julian date) -Easter Sunday: 2122 3/29 Western 5/ 3 Orthodox (April 19 Julian date) -Easter Sunday: 2123 4/11 Western 4/18 Orthodox (April 4 Julian date) -Easter Sunday: 2124 4/ 2 Western 4/ 9 Orthodox (March 26 Julian date) -*/ -module.exports = { -"1875": "1875-04-25", -"1876": "1876-04-16", -"1877": "1877-04-08", -"1878": "1878-04-28", -"1879": "1879-04-13", -"1880": "1880-05-02", -"1881": "1881-04-24", -"1882": "1882-04-09", -"1883": "1883-04-29", -"1884": "1884-04-20", -"1885": "1885-04-05", -"1886": "1886-04-25", -"1887": "1887-04-17", -"1888": "1888-05-06", -"1889": "1889-04-21", -"1890": "1890-04-13", -"1891": "1891-05-03", -"1892": "1892-04-17", -"1893": "1893-04-09", -"1894": "1894-04-29", -"1895": "1895-04-14", -"1896": "1896-04-05", -"1897": "1897-04-25", -"1898": "1898-04-17", -"1899": "1899-04-30", -"1900": "1900-04-22", -"1901": "1901-04-14", -"1902": "1902-04-27", -"1903": "1903-04-19", -"1904": "1904-04-10", -"1905": "1905-04-30", -"1906": "1906-04-15", -"1907": "1907-05-05", -"1908": "1908-04-26", -"1909": "1909-04-11", -"1910": "1910-05-01", -"1911": "1911-04-23", -"1912": "1912-04-07", -"1913": "1913-04-27", -"1914": "1914-04-19", -"1915": "1915-04-04", -"1916": "1916-04-23", -"1917": "1917-04-15", -"1918": "1918-05-05", -"1919": "1919-04-20", -"1920": "1920-04-11", -"1921": "1921-05-01", -"1922": "1922-04-16", -"1923": "1923-04-08", -"1924": "1924-04-27", -"1925": "1925-04-19", -"1926": "1926-05-02", -"1927": "1927-04-24", -"1928": "1928-04-15", -"1929": "1929-05-05", -"1930": "1930-04-20", -"1931": "1931-04-12", -"1932": "1932-05-01", -"1933": "1933-04-16", -"1934": "1934-04-08", -"1935": "1935-04-28", -"1936": "1936-04-12", -"1937": "1937-05-02", -"1938": "1938-04-24", -"1939": "1939-04-09", -"1940": "1940-04-28", -"1941": "1941-04-20", -"1942": "1942-04-05", -"1943": "1943-04-25", -"1944": "1944-04-16", -"1945": "1945-05-06", -"1946": "1946-04-21", -"1947": "1947-04-13", -"1948": "1948-05-02", -"1949": "1949-04-24", -"1950": "1950-04-09", -"1951": "1951-04-29", -"1952": "1952-04-20", -"1953": "1953-04-05", -"1954": "1954-04-25", -"1955": "1955-04-17", -"1956": "1956-05-06", -"1957": "1957-04-21", -"1958": "1958-04-13", -"1959": "1959-05-03", -"1960": "1960-04-17", -"1961": "1961-04-09", -"1962": "1962-04-29", -"1963": "1963-04-14", -"1964": "1964-05-03", -"1965": "1965-04-25", -"1966": "1966-04-10", -"1967": "1967-04-30", -"1968": "1968-04-21", -"1969": "1969-04-13", -"1970": "1970-04-26", -"1971": "1971-04-18", -"1972": "1972-04-09", -"1973": "1973-04-29", -"1974": "1974-04-14", -"1975": "1975-05-04", -"1976": "1976-04-25", -"1977": "1977-04-10", -"1978": "1978-04-30", -"1979": "1979-04-22", -"1980": "1980-04-06", -"1981": "1981-04-26", -"1982": "1982-04-18", -"1983": "1983-05-08", -"1984": "1984-04-22", -"1985": "1985-04-14", -"1986": "1986-05-04", -"1987": "1987-04-19", -"1988": "1988-04-10", -"1989": "1989-04-30", -"1990": "1990-04-15", -"1991": "1991-04-07", -"1992": "1992-04-26", -"1993": "1993-04-18", -"1994": "1994-05-01", -"1995": "1995-04-23", -"1996": "1996-04-14", -"1997": "1997-04-27", -"1998": "1998-04-19", -"1999": "1999-04-11", -"2000": "2000-04-30", -"2001": "2001-04-15", -"2002": "2002-05-05", -"2003": "2003-04-27", -"2004": "2004-04-11", -"2005": "2005-05-01", -"2006": "2006-04-23", -"2007": "2007-04-08", -"2008": "2008-04-27", -"2009": "2009-04-19", -"2010": "2010-04-04", -"2011": "2011-04-24", -"2012": "2012-04-15", -"2013": "2013-05-05", -"2014": "2014-04-20", -"2015": "2015-04-12", -"2016": "2016-05-01", -"2017": "2017-04-16", -"2018": "2018-04-08", -"2019": "2019-04-28", -"2020": "2020-04-19", -"2021": "2021-05-02", -"2022": "2022-04-24", -"2023": "2023-04-16", -"2024": "2024-05-05", -"2025": "2025-04-20", -"2026": "2026-04-12", -"2027": "2027-05-02", -"2028": "2028-04-16", -"2029": "2029-04-08", -"2030": "2030-04-28", -"2031": "2031-04-13", -"2032": "2032-05-02", -"2033": "2033-04-24", -"2034": "2034-04-09", -"2035": "2035-04-29", -"2036": "2036-04-20", -"2037": "2037-04-05", -"2038": "2038-04-25", -"2039": "2039-04-17", -"2040": "2040-05-06", -"2041": "2041-04-21", -"2042": "2042-04-13", -"2043": "2043-05-03", -"2044": "2044-04-24", -"2045": "2045-04-09", -"2046": "2046-04-29", -"2047": "2047-04-21", -"2048": "2048-04-05", -"2049": "2049-04-25", -"2050": "2050-04-17", -"2051": "2051-05-07", -"2052": "2052-04-21", -"2053": "2053-04-13", -"2054": "2054-05-03", -"2055": "2055-04-18", -"2056": "2056-04-09", -"2057": "2057-04-29", -"2058": "2058-04-14", -"2059": "2059-05-04", -"2060": "2060-04-25", -"2061": "2061-04-10", -"2062": "2062-04-30", -"2063": "2063-04-22", -"2064": "2064-04-13", -"2065": "2065-04-26", -"2066": "2066-04-18", -"2067": "2067-04-10", -"2068": "2068-04-29", -"2069": "2069-04-14", -"2070": "2070-05-04", -"2071": "2071-04-19", -"2072": "2072-04-10", -"2073": "2073-04-30", -"2074": "2074-04-22", -"2075": "2075-04-07", -"2076": "2076-04-26", -"2077": "2077-04-18", -"2078": "2078-05-08", -"2079": "2079-04-23", -"2080": "2080-04-14", -"2081": "2081-05-04", -"2082": "2082-04-19", -"2083": "2083-04-11", -"2084": "2084-04-30", -"2085": "2085-04-15", -"2086": "2086-04-07", -"2087": "2087-04-27", -"2088": "2088-04-18", -"2089": "2089-05-01", -"2090": "2090-04-23", -"2091": "2091-04-08", -"2092": "2092-04-27", -"2093": "2093-04-19", -"2094": "2094-04-11", -"2095": "2095-04-24", -"2096": "2096-04-15", -"2097": "2097-05-05", -"2098": "2098-04-27", -"2099": "2099-04-12", -"2100": "2100-05-02", -"2101": "2101-04-24", -"2102": "2102-04-09", -"2103": "2103-04-29", -"2104": "2104-04-20", -"2105": "2105-04-05", -"2106": "2106-04-25", -"2107": "2107-04-17", -"2108": "2108-05-06", -"2109": "2109-04-21", -"2110": "2110-04-13", -"2111": "2111-05-03", -"2112": "2112-04-17", -"2113": "2113-04-09", -"2114": "2114-04-29", -"2115": "2115-04-14", -"2116": "2116-05-03", -"2117": "2117-04-25", -"2118": "2118-04-17", -"2119": "2119-04-30", -"2120": "2120-04-21", -"2121": "2121-04-13", -"2122": "2122-05-03", -"2123": "2123-04-18", -"2124": "2124-04-09", -}; diff --git a/server/lib/pascha.js b/server/lib/pascha.js deleted file mode 100644 index 9f9526d..0000000 --- a/server/lib/pascha.js +++ /dev/null @@ -1,116 +0,0 @@ -//! moment-holiday.js locale configuration -//! locale : pascha Related Holidays -//! author : Kodie Grantham : https://github.com/kodie - -//(function() { -// var moment = (typeof require !== 'undefined' && require !== null) && !require.amd ? require('moment') : this.moment; -function init(moment) { -// moment.holidays.pascha = { - moment.modifyHolidays.add({ - "Lent": { - date: 'pascha-46|pascha-3' - }, - /* - "Holy Monday": { - date: 'pascha-6', - keywords_y: ['great', 'monday'] - }, - "Holy Tuesday": { - date: 'pascha-5', - keywords_y: ['great', 'tuesday'] - }, - "Holy Wednesday": { - date: 'pascha-4', - keywords_y: ['great', 'wednesday'] - }, - "Holy Thursday": { - date: 'pascha-3', - keywords_y: ['great', 'thursday'] - }, - "Holy Friday": { - date: 'pascha-2', - keywords_y: ['great', 'friday'] - }, - "Holy Saturday": { - date: 'pascha-1', - keywords_y: ['holy', 'saturday'] - }, - */ - "Pascha Sunday": { - date: 'pascha', - keywords_y: ['pascha'], - keywords: ['sunday'] - }, - "Bright Week": { - date: 'pascha+1|pascha+6' - }, - "Pentecost Sunday": { - date: 'pascha+49', - keywords_y: ['pentecost'], - keywords: ['sunday'] - }, - //}; - }); - -/* - const orthodoxDates = require("./pascha-dates.js"); - - var pascha = function(year) { - var date = orthodoxDates[year].split("-"); - date[1] -= 1; // month needs to be zero index - return moment(date); - } -*/ - - /** - * Calculates Easter in the Gregorian/Western (Catholic and Protestant) calendar - * based on the algorithm by Oudin (1940) from http://www.tondering.dk/claus/cal/easter.php - * @returns {array} [int month, int day] - */ - var pascha = function(year) { - var f = Math.floor, - // Golden Number - 1 - G = year % 19, - C = f(year / 100), - // related to Epact - H = (C - f(C / 4) - f((8 * C + 13)/25) + 19 * G + 15) % 30, - // number of days from 21 March to the Paschal full moon - I = H - f(H/28) * (1 - f(29/(H + 1)) * f((21-G)/11)), - // weekday for the Paschal full moon - J = (year + f(year / 4) + I + 2 - C + f(C / 4)) % 7, - // number of days from 21 March to the Sunday on or before the Paschal full moon - L = I - J, - month = 3 + f((L + 40)/44), - day = L + 28 - 31 * f(month / 4); - - return moment([year, (month - 1),day]); - } - - moment.modifyHolidays.extendParser(function(m, date){ - if (~date.indexOf('pascha')) { - var dates = date.split('|'); - var ds = []; - - for (var i = 0; i < dates.length; i++) { - if (dates[i].substring(0, 6) === 'pascha') { - var e = pascha(m.year()); - - if (dates[i].charAt(6) === '-') { e.subtract(dates[i].substring(7), 'days'); } - if (dates[i].charAt(6) === '+') { e.add(dates[i].substring(7), 'days'); } - - if (dates.length === 1) { return e; } - ds.push(e.format('M/D')); - } else { - ds.push(dates[i]); - } - } - - if (ds.length) { return ds.join('|'); } - } - }); -} - -module.exports = init; - -// if ((typeof module !== 'undefined' && module !== null ? module.exports : void 0) != null) { module.exports = moment; } -//}).call(this); \ No newline at end of file diff --git a/server/routes/games.js b/server/routes/games.js old mode 100644 new mode 100755 index c60998b..548ec6c --- a/server/routes/games.js +++ b/server/routes/games.js @@ -1,291 +1,27 @@ "use strict"; const express = require("express"), - fs = require("fs"), config = require("config"), - moment = require("moment-holiday"), + moment = require("moment"), crypto = require("crypto"), util = require("util"), Promise = require("bluebird"); -require("../lib/pascha.js")(moment); +let gameDB; -const execFile = util.promisify(require("child_process").execFile); - -let photoDB; - -require("../db/photos").then(function(db) { - photoDB = db; +require("../db/games").then(function(db) { + gameDB = db; }); const router = express.Router(); -const picturesPath = config.get("picturesPath").replace(/\/$/, "") + "/"; - -const unlink = function (_path) { - if (_path.indexOf(picturesPath.replace(/\/$/, "")) == 0) { - _path = _path.substring(picturesPath.length); - } - - let path = picturesPath + _path; - - return new Promise(function (resolve, reject) { - fs.unlink(path, function (error, stats) { - if (error) { - return reject(error); - } - return resolve(stats); - }); - }); -} - -const rename = function (_src, _dst) { - if (_src.indexOf(picturesPath.replace(/\/$/, "")) == 0) { - _src = _src.substring(picturesPath.length); - } - if (_dst.indexOf(picturesPath.replace(/\/$/, "")) == 0) { - _dst = _dst.substring(picturesPath.length); - } - - let src = picturesPath + _src, - dst = picturesPath + _dst; - - return new Promise(function (resolve, reject) { - fs.rename(src, dst, function (error, stats) { - if (error) { - return reject(error); - } - return resolve(stats); - }); - }); -} - - -const computeHash = function(_filepath) { - if (_filepath.indexOf(picturesPath.replace(/\/$/, "")) == 0) { - _filepath = _filepath.substring(picturesPath.length); - } - - let filepath = picturesPath + _filepath; - return new Promise(function(resolve, reject) { - let input = fs.createReadStream(filepath), - hash = crypto.createHash("sha256"); - if (!input) { - return reject(); - } - - input.on("readable", function() { - const data = input.read(); - if (data) { - hash.update(data); - } else { - input.close(); - resolve(hash.digest("hex")); - hash = null; - input = null; - } - }); - }); -}; - -const stat = function (_path) { - if (_path.indexOf(picturesPath.replace(/\/$/, "")) == 0) { - _path = _path.substring(picturesPath.length); - } - - let path = picturesPath + _path; - - return new Promise(function (resolve, reject) { - fs.stat(path, function (error, stats) { - if (error) { - return reject(error); - } - return resolve(stats); - }); - }); -} - -const sharp = require("sharp"); - -const inProcess = []; - - -router.put("/:id", function(req, res/*, next*/) { - if (!req.user.maintainer) { - return res.status(401).send("Unauthorized to modify photos."); - } - - const replacements = { - id: req.params.id - }; - - if (inProcess.indexOf(req.params.id) != -1) { - console.log("Request to modify asset currently in modification: " + req.params.id); - return res.status(409).send("Asset " + req.params.id + " is already being processed. Please try again."); - } - - inProcess.push(req.params.id); +router.post("/", (req, res/*, next*/) => { console.log("PUT /" + replacements.id, req.query); - switch (req.query.a) { - case "undelete": - console.log("Undeleting " + req.params.id); - return photoDB.sequelize.query("UPDATE photos SET deleted=0,updated=CURRENT_TIMESTAMP WHERE id=:id", { - replacements: replacements - }).then(function() { - return res.status(200).send(req.params.id + " updated."); - }).catch(function(error) { - console.log(error); - return res.status(500).send(error); - }).then(function() { - inProcess.splice(inProcess.indexOf(req.params.id), 1); - }); - - case "rename": - return getPhoto(req.params.id).then(function(asset) { - if (!asset) { - return res.status(404).send(req.params.id + " not found."); - } - - let src = asset.filename; - - asset.filename = asset.filename.replace(/(\.[^.]*)$/, "-" + asset.hash.substring(0, 8) + "$1"); - return rename(picturesPath + asset.path + src, picturesPath + asset.path + asset.filename).then(function() { - return rename(picturesPath + asset.path + "thumbs/" + src, picturesPath + asset.path + "thumbs/" + asset.filename); - }).then(function() { - return rename(picturesPath + asset.path + "thumbs/scaled/" + src, picturesPath + asset.path + "thumbs/scaled/" + asset.filename); - }).then(function() { - return photoDB.sequelize.query("UPDATE photos SET filename=:filename WHERE id=:id", { - replacements: asset - }).then(function() { - return res.status(200).send(asset); - }); - }); - }).catch(function(error) { - console.log(error); - return res.status(500).send(error); - }).then(function() { - inProcess.splice(inProcess.indexOf(req.params.id), 1); - }); - - case "rotate": - let direction = req.query.direction || "right"; - if (direction == "right") { - direction = 90; - } else { - direction = -90; - } - return getPhoto(req.params.id).then(function(asset) { - if (!asset) { - return res.status(404).send(req.params.id + " not found."); - } - - let original = picturesPath + asset.path + asset.filename, - target = picturesPath + asset.path + ".tmp." + asset.filename, - thumb = picturesPath + asset.path + "thumbs/" + asset.filename, - scaled = picturesPath + asset.path + "thumbs/scaled/" + asset.filename; - - let tmp = asset.width; - asset.width = asset.height; - asset.height = tmp; - - asset.image = sharp(original); - return asset.image.rotate(direction).withMetadata().toFile(target).then(function() { - let stamp = moment(new Date(asset.modified)).format("YYYYMMDDhhmm.ss"); - console.log("Restamping " + target + " to " + stamp); - /* Re-stamp the file's ctime with the original ctime */ - return execFile("touch", [ - "-t", - stamp, - target - ]); - }).then(function() { - return asset.image.rotate(direction).resize(256, 256).withMetadata().toFile(thumb); - }).then(function() { - return asset.image.resize(Math.min(1024, asset.width)).withMetadata().toFile(scaled); - }).then(function() { - return stat(target).then(function(stats) { - if (!stats) { - throw "Unable to find original file after attempting to rotate!"; - } - asset.size = stats.size; - asset.modified = stats.mtime; - return unlink(original).then(function() { - return rename(target, original); - }).then(function() { - return photoDB.sequelize.query("UPDATE photos SET " + - "modified=:modified,width=:width,height=:height,size=:size,updated=CURRENT_TIMESTAMP,scanned=CURRENT_TIMESTAMP " + - "WHERE id=:id", { - replacements: asset - }); - }); - }); - }).then(function() { - sharp.cache(false); - sharp.cache(true); - res.status(200).send(asset); - - return computeHash(asset.filepath).then(function(hash) { - asset.hash = hash; - return asset; - }).then(function(asset) { - return photoDB.sequelize.query("SELECT photos.id,photohashes.*,photos.filename,albums.path FROM photohashes " + - "LEFT JOIN photos ON (photos.id=photohashes.photoId) " + - "LEFT JOIN albums ON (albums.id=photos.albumId) " + - "WHERE hash=:hash OR photoId=:id", { - replacements: asset, - type: photoDB.sequelize.QueryTypes.SELECT - }).then(function(results) { - let query; - - if (results.length == 0) { - query = "INSERT INTO photohashes (hash,photoId) VALUES(:hash,:id)"; - console.warn("HASH being updated and photoId " + asset.id + " *should* already exist, but it doesn't."); - } else if (results.length > 1) { - /* This image is now a duplicate! */ - for (var i = 0; i < results.length; i++) { - if (results[i].id != asset.id) { - console.log("Duplicate asset: " + - "'" + asset.filepath + "' is a copy of " + - "'" + results[i].path + results[i].filename + "'"); - asset.duplicate = results[i].id; - break; - } - } - - query = "UPDATE photos SET duplicate=:duplicate WHERE id=:id; " + - "DELETE FROM photohashes WHERE photoId=:id"; - - console.log("Updating photo " + asset.id + " as duplicate of " + asset.duplicate); - } else if (results[0].hash != asset.hash) { - query = "UPDATE photohashes SET hash=:hash WHERE photoId=:id; UPDATE photos SET duplicate=0 WHERE id=:id"; - - console.log("Updating photohash for " + asset.id + " to " + asset.hash + ", and clearing duplicate field."); - } else { - console.log("Unexpected!", asset, results[0]); - return; - } - - return photoDB.sequelize.query(query, { - replacements: asset, - }).then(function() { - return asset; - }); - }); - }); - }); - }).catch(function(error) { - console.log(error); - return res.status(500).send(error); - }).then(function() { - inProcess.splice(inProcess.indexOf(req.params.id), 1); - }); - } - return res.status(400).send("Invalid request"); }); -const getPhoto = function(id) { - return photoDB.sequelize.query("SELECT " + +/* + return gameDB.sequelize.query("SELECT " + "photos.*,albums.path AS path,photohashes.hash,modified,(albums.path || photos.filename) AS filepath FROM photos " + "LEFT JOIN albums ON albums.id=photos.albumId " + "LEFT JOIN photohashes ON photohashes.photoId=photos.id " + @@ -293,745 +29,19 @@ const getPhoto = function(id) { replacements: { id: id }, - type: photoDB.Sequelize.QueryTypes.SELECT, + type: gameDB.Sequelize.QueryTypes.SELECT, raw: true }).then(function(photos) { if (photos.length == 0) { return null; } - - if (!photos[0].duplicate) { - return photos[0]; - } - - return photoDB.sequelize.query("SELECT hash FROM photohashes WHERE photoId=:duplicate", { - replacements: photos[0], - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then(function(results) { - if (results.length != 0) { - photos[0].hash = results[0].hash; - } - return photos[0]; - }); - }); -} - -const tasks = []; -const Task = function() { - return new Promise(function(resolve, reject) { - crypto.randomBytes(16, function(error, buffer) { - if (error) { - return reject(error); - } - - let now = Date.now(), task; - - task = { - started: now, - lastUpdate: now, - eta: now, - processed: 0, - remaining: 0, - token: buffer.toString('hex'), - }; - - tasks.push(task); - return resolve(task); - }); - }); -}; - -const removeTask = function(task) { - let i = tasks.indexOf(task); - if (i != -1) { - tasks.splice(i, 1); - } -} - -router.get("/status/:token", function(req, res) { - if (!req.params.token) { - return res.status(400).send("Usage /status/:token"); - } - - for (var i = 0; i < tasks.length; i++) { - if (tasks[i].token == req.params.token) { - return res.status(200).send(tasks[i]); - } - } - - return res.status(404).send("Task " + req.params.token + " not found."); -}); - -/** - * 1. Look if there are duplicates. - * 2. Update all other duplicates to be duplicates of the first image that remains - * 3. If no duplicates, DELETE the entry from photohashes - * 4. If there are duplicates, update the HASH entry to point to the first image that remains - * 5. Delete the entry from photos - * 6. Delete the scaled, thumb, and original from disk - */ -const deletePhoto = function(photo) { - return photoDB.sequelize.transaction(function(transaction) { - return photoDB.sequelize.query("SELECT id FROM photos WHERE duplicate=:id", { - replacements: photo, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then(function(duplicates) { - if (!duplicates.length) { - return null; - } - - let first = duplicates.shift(); - let needsUpdate = []; - duplicates.forEach(function(duplicate) { - needsUpdate.push(duplicate.id); - }); - - if (!needsUpdate.length) { - return first; - } - - // 2. Update all other duplicates to be duplicates of the first image that remains - console.log("Updating " + needsUpdate + " to point to " + first.id); - return photoDB.sequelize.query( - "UPDATE photos SET duplicate=:first WHERE id IN (:needsUpdate)", { - replacements: { - first: first.id, - needsUpdate: needsUpdate - }, - transaction: transaction - }).then(function() { - return first; - }); - }).then(function(first) { - if (!first) { - console.log("Deleting "+ photo.id + " from photohash."); - // 3. If no duplicates, DELETE the entry from photohashes - return photoDB.sequelize.query( - "DELETE FROM photohashes WHERE photoId=:id", { - replacements: photo, - transaction: transaction - }); - } - console.log("Updating photohash for " + photo.id + " to point to " + first.id); - // 4. If there are duplicates, update the HASH entry to point to the first image that remains - return photoDB.sequelize.query( - "UPDATE photohashes SET photoId=:first WHERE photoId=:photo", { - replacements: { - first: first.id, - photo: photo.id - }, - transaction: transaction - }); - }).then(function() { - console.log("Deleting " + photo.path + photo.filename + " from DB."); - // 5. Delete the entry from photos - return photoDB.sequelize.query("DELETE FROM photos WHERE id=:id", { - replacements: photo, - transaction: transaction - }); - }).then(function() { - // 6. Delete the scaled, thumb, and original from disk - console.log("Deleting " + photo.path + photo.filename + " from disk."); - return unlink(photo.path + "thumbs/scaled/" + photo.filename).catch(function() {}).then(function() { - return unlink(photo.path + "thumbs/" + photo.filename).catch(function() {}).then(function() { - return unlink(photo.path + photo.filename).catch(function(error) { - console.log("Error removing file: " + error); - }); - }); - }); - }); - }); -} - -router.delete("/:id?", function(req, res/*, next*/) { - if (!req.user.maintainer) { - return res.status(401).send("Unauthorized to delete photos."); - } - - const replacements = { - id: req.params.id || "*" - }; - - if (!req.params.id && !req.query.permanent) { - return res.status(400).send("Trash can only be emptied if permanent."); - } - - let where = ""; - if (req.params.id) { - where = "photos.id=:id"; - if (req.query.permanent) { - where += " AND photos.deleted=1"; - } - } else { - where = "photos.deleted=1"; - } - - console.log("DELETE /" + replacements.id, req.query); - - let sent = false; - - return photoDB.sequelize.query("SELECT " + - "photos.*,albums.path AS path,photohashes.hash,(albums.path || photos.filename) AS filepath FROM photos " + - "LEFT JOIN albums ON albums.id=photos.albumId " + - "LEFT JOIN photohashes ON photohashes.photoId=photos.id " + - "WHERE " + where, { - replacements: replacements, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then(function(photos) { - if (photos.length == 0) { - sent = true; - return res.status(404).send("Unable to find photo " + replacements.id); - } - - if (!req.query.permanent) { - return photoDB.sequelize.query("UPDATE photos SET deleted=1,updated=CURRENT_TIMESTAMP WHERE id=:id", { - replacements: replacements - }).then(function() { - sent = true; - return res.status(200).send({ - id: req.params.id, - deleted: true, - permanent: (req.query && req.query.permanent) || false - }); - }); - } - - /** - * Delete the asset from disk and the DB - */ - return Task().then(function(task) { - task.remaining = photos.length; - task.eta = -1; - - sent = true; - res.status(200).send({ - id: req.params.id, - task: task, - permanent: (req.query && req.query.permanent) || false - }); - - return Promise.mapSeries(photos, function(photo) { - let lastStamp = Date.now(); - return deletePhoto(photo).then(function() { - let now = Date.now(), elapsed = now - lastStamp; - lastStamp= now; - task.processed++; - task.remaining--; - task.lastUpdate = Date.now(); - task.eta = elapsed * task.remaining; - }) - }).then(function() { - console.log("Processing task " + task.token + " finished: " + (task.lastUpdate - task.started)); - removeTask(task); - }).catch(function(error) { - console.log("Processing task " + task.token + " failed: " + error); - removeTask(task); - }); - }); - }).catch(function(error) { - console.log(error); - if (!sent) { - sent = true; - res.status(500).send("Unable to delete photo " + req.params.id + ": " + error); - } - }); -}); - -router.get("/holiday/:holiday", function(req, res/*, next*/) { - let startYear = 1990, - endYear = moment().year(), - dayIsHoliday = "", - holidayName, - date = undefined; - - /* Find the holiday in the list of holidays */ - let lookup = moment().holidays([req.params.holiday]); - if (!lookup) { - date = req.params.holiday.match(/^((\d{4})-)?(\d{2})-(\d{2})$/); - if (!date) { - return res.status(404).send(req.params.holiday + " holiday not found."); - } - date = { - year: date[1], - month: date[3], - day: date[4] - }; - if (date.year) { - startYear = date.year; - endYear = date.year; - } - } - - holidayName = date ? req.params.holiday : Object.getOwnPropertyNames(lookup)[0]; - console.log("Searching for holiday: " + holidayName); - /* Lookup the date for the holiday on every year from 'startYear' (1990) to today */ - for (let year = startYear; year <= endYear; year++) { - console.log("Getting year: " + year); - let holiday; - - if (!date) { - holiday = moment(year + "-01-01", "YYYY-MM-DD").holiday(req.params.holiday); - if (!holiday) { - /* 'Leap Year' doesn't exist every year... */ - continue; - } - - /* - * NOTE: Memorial Day and Labor Day are two special cases -- the holiday is a Monday, - * however the entire weekend typically is holidy-esque. Account for that below. - * - * For those that have 'eve' celebrations, include those too. - * - * We (should) could expand this to account for Fri or Mon on the 4th of July or the - * entire weekend if it occurs on a Thu or Tues */ - - let extraDays = 0; - switch (req.params.holiday.toLowerCase()) { - case 'labor day': - case 'memorial day': - extraDays = -2; /* Include two days prior */ - break; - case 'christmas day': - case 'new year\'s day': - extraDays = -1; /* Include 'Eve' */ - break; - } - let direction = extraDays < 0 ? -1 : 1; - - for (let i = 0; i <= Math.abs(extraDays); i++) { - let comparison = "strftime('%Y-%m-%d',taken)='" + holiday.format("YYYY-MM-DD") + "'"; - /* If no holiday has been set yet, start the comparison function passed to WHERE - * otherwise append it with OR. */ - if (!dayIsHoliday) { - dayIsHoliday = comparison; - } else { - dayIsHoliday += " OR " + comparison; - } - - holiday.date(holiday.date() + direction); - } - } else { - let comparison = "strftime('%Y-%m-%d',taken)='" - + moment(year + "-" + date.month + "-" + date.day, "YYYY-MM-DD").format("YYYY-MM-DD") - + "'"; - if (!dayIsHoliday) { - dayIsHoliday = comparison; - } else { - dayIsHoliday += " OR " + comparison; - } - } - } - - let query = "SELECT photos.*,albums.path AS path FROM photos " + - "INNER JOIN albums ON (albums.id=photos.albumId) " + - "WHERE (photos.duplicate=0 AND photos.deleted=0 AND photos.scanned NOT NULL AND (" + dayIsHoliday + ")) " + - "ORDER BY strftime('%Y-%m-%d', taken) DESC,id DESC"; - - return photoDB.sequelize.query(query, { - type: photoDB.Sequelize.QueryTypes.SELECT - }).then(function(photos) { - photos.forEach(function(photo) { - for (var key in photo) { - if (photo[key] instanceof Date) { - photo[key] = moment(photo[key]); - } - } - }); - - return res.status(200).json({ - holiday: holidayName, - items: photos - }); - - }).catch(function(error) { - console.error("Query failed: " + query); - return Promise.reject(error); - }); -}); - - -/* Each photos has: - -* locations -* people -* date -* tags -* photo info - */ -router.get("/memories/:date?", function(req, res/*, next*/) { - let limit = parseInt(req.query.limit) || 50, - id, cursor, index; - if (req.query.next) { - let parts = req.query.next.split("_"); - cursor = new Date(parts[0]); - id = parseInt(parts[1]); - } else { - cursor = ""; - id = -1; - } - - if (id == -1) { - index = "strftime('%m-%d',taken)=strftime('%m-%d',:date)"; - } else { - index = "((strftime('%Y-%m-%d',taken)=strftime('%Y-%m-%d',:cursor) AND photos.id<"+id+ ") OR " + - "(strftime('%m-%d',taken)=strftime('%m-%d',:cursor) AND strftime('%Y',taken) limit; /* We queried one extra item to see if there are more than LIMIT available */ - - let last; - if (more) { - photos.splice(limit); - last = photos[photos.length - 1]; - } - - let results = { - items: photos.sort(function(a, b) { - return new Date(b.taken) - new Date(a.taken); - }) - }; - - if (more) { - results.cursor = new Date(last.taken).toISOString().replace(/T.*/, "") + "_" + last.id; - results.more = true; - } - return res.status(200).json(results); - }).catch(function(error) { - console.error("Query failed: " + query); - return Promise.reject(error); - }); -}); - -router.get("/duplicates", function(req, res/*, next*/) { - let replacements = {}; - - return photoDB.sequelize.query( - "SELECT filename,COUNT(*) AS count FROM photos WHERE photos.duplicate=0 AND photos.deleted!=1 " + - "GROUP BY filename HAVING count > 1", { +router.get("/*", (req, res/*, next*/) => { + return gameDB.sequelize.query(query, { replacements: replacements, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then(function(duplicates) { - let filenames = []; - duplicates.forEach(function(duplicate) { - filenames.push(duplicate.filename); - }); - replacements.filenames = filenames; - - return photoDB.sequelize.query( - "SELECT photos.*,albums.path AS path,photohashes.hash,(albums.path || photos.filename) AS filepath FROM photos " + - "LEFT JOIN albums ON albums.id=photos.albumId " + - "LEFT JOIN photohashes ON photohashes.photoId=photos.id " + - "WHERE filename IN (:filenames) ORDER BY photos.filename,photos.width,photos.height,photos.size DESC", { - replacements: replacements, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then(function(photos) { - return res.status(200).json({ - items: photos - }); - }); - }).catch(function(error) { - return Promise.reject(error); - }); -}); - -router.get("/trash", function(req, res/*, next*/) { - return photoDB.sequelize.query( - "SELECT photos.*,albums.path AS path,(albums.path || photos.filename) AS filepath FROM photos " + - "LEFT JOIN albums ON albums.id=photos.albumId " + - "WHERE deleted=1 ORDER BY photos.updated DESC", { - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then(function(photos) { - return res.status(200).json({ - items: photos - }); - }); -}); - -function getFacesForPhoto(id) { - /* Get the set of faces in this photo */ - return photoDB.sequelize.query( - "SELECT * FROM faces WHERE photoId=:id AND faceConfidence>0.9", { - replacements: { - id: id, - }, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then((faces) => { - /* For each face in the photo, get the related faces */ - return photoDB.sequelize.query( - "SELECT relatedFaces.photoId AS photoId,fd.face1Id,fd.face2Id,fd.distance,relatedFaces.faceConfidence " + - "FROM (SELECT id,photoId,faceConfidence FROM faces WHERE faces.faceConfidence>=0.9 AND faces.id IN (:ids)) AS faces " + - "INNER JOIN faces AS relatedFaces ON relatedFaces.faceConfidence>=0.9 AND relatedFaces.id IN (fd.face1Id,fd.face2Id) " + - "INNER JOIN facedistances AS fd ON fd.distance<=0.5 " + - " AND (fd.face1Id=faces.id OR fd.face2Id=faces.id) " + - "WHERE (faces.id=fd.face1Id OR faces.id=fd.face2Id) " + - "ORDER BY fd.distance ASC", { - replacements: { - ids: faces.map(face => face.id), - }, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then((relatedFaces) => { - faces.forEach((face) => { - face.relatedFaces = relatedFaces.filter((related) => { - return (related.photoId != id && (related.face1Id == face.id || related.face2Id == face.id)); - }).map((related) => { - return { - distance: related.distance, - faceConfidence: related.faceConfidence, - photoId: related.photoId, - faceId: related.face1Id != face.id ? related.face1Id : related.face2Id - } - }); - }); - return faces; - }); - }); -} - -router.get("/faces/:id", (req, res) => { - const id = parseInt(req.params.id); - if (id != req.params.id) { - return res.status(400).send({ message: "Usage faces/:id"}); - } - return getFacesForPhoto(id).then((faces) => { - return res.status(200).json(faces); - }); -}); - -router.get("/random/:id?", (req, res) => { - let id = parseInt(req.params.id), - filter = ""; - - if (id == req.params.id) { - console.log("GET /random/" + id); - filter = "AND id=:id"; - } else { - filter = "AND faces>0"; - id = undefined; - } - - return photoDB.sequelize.query("SELECT id,duplicate FROM photos WHERE deleted=0 " + filter, { - replacements: { - id: id - }, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then((results) => { - if (!results.length) { - return []; - } - if (id) { - if (results[0].duplicate) { - id = results[0].duplicate; - } - } else { - id = results[Math.floor(Math.random() * results.length)].id; - } - - return photoDB.sequelize.query( - "SELECT photos.*,albums.path AS path FROM photos " + - "INNER JOIN albums ON albums.id=photos.albumId " + - "WHERE photos.duplicate=0 AND photos.deleted=0 AND photos.scanned NOT NULL AND photos.id=:id", { - replacements: { - id: id, - }, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }); - }).then(function(photos) { - if (!photos.length) { - return res.status(404).send(id + " not found."); - } - const photo = photos[0]; - for (var key in photo) { - if (photo[key] instanceof Date) { - photo[key] = moment(photo[key]); - } - } - return getFacesForPhoto(photo.id).then((faces) => { - photo.faces = faces; - return res.status(200).json(photo); - }) - }); -}) - -router.get("/mvimg/*", function(req, res/*, next*/) { - let limit = parseInt(req.query.limit) || 50, - id, cursor, index; - - if (req.query.next) { - let parts = req.query.next.split("_"); - cursor = parts[0]; - id = parseInt(parts[1]); - } else { - cursor = ""; - id = -1; - } - - if (id == -1) { - index = ""; - } else { - index = "AND ((strftime('%Y-%m-%d',taken)=strftime('%Y-%m-%d',:cursor) AND photos.id<:id) OR " + - "strftime('%Y-%m-%d',taken) limit; /* We queried one extra item to see if there are more than LIMIT available */ - -// console.log("Requested " + limit + " and matched " + photos.length); - - let last; - if (more) { - photos.splice(limit); - last = photos[photos.length - 1]; - } - - let results = { - items: photos.sort(function(a, b) { - return new Date(b.taken) - new Date(a.taken); - }) - }; - - if (more) { - results.cursor = new Date(last.taken).toISOString().replace(/T.*/, "") + "_" + last.id; - results.more = true; - } - return res.status(200).json(results); - }).catch(function(error) { - console.error("Query failed: " + query); - return Promise.reject(error); - }); -}); - -router.get("/*", function(req, res/*, next*/) { - let limit = parseInt(req.query.limit) || 50, - id, cursor, index; - - if (req.query.next) { - let parts = req.query.next.split("_"); - cursor = parts[0]; - id = parseInt(parts[1]); - } else { - cursor = ""; - id = -1; - } - - if (id == -1) { - index = ""; - } else { - index = "AND ((strftime('%Y-%m-%d',taken)=strftime('%Y-%m-%d',:cursor) AND photos.id<:id) OR " + - "strftime('%Y-%m-%d',taken) limit; /* We queried one extra item to see if there are more than LIMIT available */ - -// console.log("Requested " + limit + " and matched " + photos.length); - - let last; - if (more) { - photos.splice(limit); - last = photos[photos.length - 1]; - } - - let results = { - items: photos.sort(function(a, b) { - return new Date(b.taken) - new Date(a.taken); - }) - }; - - if (more) { - results.cursor = new Date(last.taken).toISOString().replace(/T.*/, "") + "_" + last.id; - results.more = true; - } - return res.status(200).json(results); - }).catch(function(error) { - console.error("Query failed: " + query); - return Promise.reject(error); + type: gameDB.Sequelize.QueryTypes.SELECT + }).then((photos) => { }); }); diff --git a/server/routes/index.js b/server/routes/index.js old mode 100644 new mode 100755 index 1abdadf..b55885d --- a/server/routes/index.js +++ b/server/routes/index.js @@ -2,7 +2,8 @@ const express = require("express"), fs = require("fs"), - url = require("url"); + url = require("url"), + config = require("config"); const router = express.Router(); @@ -45,7 +46,8 @@ router.get("/*", function(req, res, next) { /* Replace in index.html with * the basePath */ - const index = fs.readFileSync("frontend/index.html", "utf8"); + const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/", + index = fs.readFileSync(frontendPath + "/index.html", "utf8"); res.send(index.replace( /