diff --git a/.gitignore b/.gitignore
index a45e5a85..356b3db2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
node_modules
.idea
-config/config.json
config/sequelizeCliConfig.js
config/speechConfig.js
\ No newline at end of file
diff --git a/.sequelizerc b/.sequelizerc
new file mode 100644
index 00000000..f2daa0b6
--- /dev/null
+++ b/.sequelizerc
@@ -0,0 +1,5 @@
+const path = require('path');
+
+module.exports = {
+ 'config': path.resolve('config', 'sequelizeCliConfig.js'),
+}
\ No newline at end of file
diff --git a/config/sequelizeCliConfig.js.example b/config/sequelizeCliConfig.js.example
new file mode 100644
index 00000000..8b91eccb
--- /dev/null
+++ b/config/sequelizeCliConfig.js.example
@@ -0,0 +1,23 @@
+module.exports = {
+ development: {
+ username: '',
+ password: '',
+ database: '',
+ host : '127.0.0.1',
+ dialect : 'mysql',
+ },
+ test: {
+ username: '',
+ password: '',
+ database: '',
+ host : '127.0.0.1',
+ dialect : 'mysql',
+ },
+ production: {
+ username: '',
+ password: '',
+ database: '',
+ host : '127.0.0.1',
+ dialect : 'mysql',
+ },
+};
diff --git a/config/speechConfig.js.example b/config/speechConfig.js.example
index d10745a3..f485fb34 100644
--- a/config/speechConfig.js.example
+++ b/config/speechConfig.js.example
@@ -19,4 +19,7 @@ module.exports = {
session: {
sessionKey: null, // enter a secret key to be used for session encryption
},
+ files: {
+ uploadDirectory: null, // enter file path to where uploads/publishes should be stored
+ },
};
diff --git a/migrations/AddChannelNameToClaim.js b/migrations/AddChannelNameToClaim.js
deleted file mode 100644
index b9ac1da8..00000000
--- a/migrations/AddChannelNameToClaim.js
+++ /dev/null
@@ -1,22 +0,0 @@
-module.exports = {
- up: (queryInterface, Sequelize) => {
- // logic for transforming into the new state
- const p1 = queryInterface.addColumn(
- 'Claim',
- 'channelName',
- {
- type : Sequelize.STRING,
- allowNull: true,
- }
- );
- return Promise.all([p1]);
- },
- down: (queryInterface, Sequelize) => {
- // logic for reverting the changes
- const p1 = queryInterface.removeColumn(
- 'Claim',
- 'channelName'
- );
- return Promise.all([p1]);
- },
-};
diff --git a/migrations/ChangeCertificateColumnTypes2.js b/migrations/ChangeCertificateColumnTypes2.js
new file mode 100644
index 00000000..8fbcee79
--- /dev/null
+++ b/migrations/ChangeCertificateColumnTypes2.js
@@ -0,0 +1,42 @@
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ // logic for transforming into the new state
+ const p1 = queryInterface.changeColumn(
+ 'Certificate',
+ 'amount',
+ {
+ type : Sequelize.DECIMAL(19, 8),
+ allowNull: true,
+ }
+ );
+ const p2 = queryInterface.changeColumn(
+ 'Certificate',
+ 'effectiveAmount',
+ {
+ type : Sequelize.DECIMAL(19, 8),
+ allowNull: true,
+ }
+ );
+ return Promise.all([p1, p2]);
+ },
+ down: (queryInterface, Sequelize) => {
+ // logic for reverting the changes
+ const p1 = queryInterface.changeColumn(
+ 'Certificate',
+ 'amount',
+ {
+ type : Sequelize.DOUBLE,
+ allowNull: true,
+ }
+ );
+ const p2 = queryInterface.changeColumn(
+ 'Certificate',
+ 'effectiveAmount',
+ {
+ type : Sequelize.DOUBLE,
+ allowNull: true,
+ }
+ );
+ return Promise.all([p1, p2]);
+ },
+};
diff --git a/migrations/ChangeClaimColumnTypes.js b/migrations/ChangeClaimColumnTypes.js
new file mode 100644
index 00000000..11c2bb52
--- /dev/null
+++ b/migrations/ChangeClaimColumnTypes.js
@@ -0,0 +1,42 @@
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ // logic for transforming into the new state
+ const p1 = queryInterface.changeColumn(
+ 'Claim',
+ 'amount',
+ {
+ type : Sequelize.DECIMAL(19, 8),
+ allowNull: true,
+ }
+ );
+ const p2 = queryInterface.changeColumn(
+ 'Claim',
+ 'effectiveAmount',
+ {
+ type : Sequelize.DECIMAL(19, 8),
+ allowNull: true,
+ }
+ );
+ return Promise.all([p1, p2]);
+ },
+ down: (queryInterface, Sequelize) => {
+ // logic for reverting the changes
+ const p1 = queryInterface.changeColumn(
+ 'Claim',
+ 'amount',
+ {
+ type : Sequelize.DOUBLE,
+ allowNull: true,
+ }
+ );
+ const p2 = queryInterface.changeColumn(
+ 'Claim',
+ 'effectiveAmount',
+ {
+ type : Sequelize.DOUBLE,
+ allowNull: true,
+ }
+ );
+ return Promise.all([p1, p2]);
+ },
+};
diff --git a/migrations/UpdateUserPasswords5.js b/migrations/UpdateUserPasswords5.js
deleted file mode 100644
index f911c86e..00000000
--- a/migrations/UpdateUserPasswords5.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const db = require('../models');
-const bcrypt = require('bcrypt');
-const logger = require('winston');
-
-module.exports = {
- up: (queryInterface, Sequelize) => {
- // get all the users
- return db.User
- .findAll()
- .then((users) => {
- // create an array of promises, with each promise bcrypting a password and updating the record
- const promises = users.map((record) => {
- // bcrypt
- // generate a salt string to use for hashing
- return new Promise((resolve, reject) => {
- bcrypt.genSalt((saltError, salt) => {
- if (saltError) {
- logger.error('salt error', saltError);
- reject(saltError);
- return;
- }
- // generate a hashed version of the user's password
- bcrypt.hash(record.password, salt, (hashError, hash) => {
- // if there is an error with the hash generation return the error
- if (hashError) {
- logger.error('hash error', hashError);
- reject(hashError);
- return;
- }
- // replace the password string with the hash password value
- resolve(queryInterface.sequelize.query(`UPDATE User SET User.password = "${hash}" WHERE User.id = ${record.id}`));
- });
- });
- });
- });
- // return the array of promises
- return Promise.all(promises);
- })
- .catch(error => {
- logger.error('error prepping promises array', error);
- });
- },
- down: (queryInterface, Sequelize) => {
- // logic for reverting the changes
- },
-};
diff --git a/models/certificate.js b/models/certificate.js
index 19ad8b39..eb081826 100644
--- a/models/certificate.js
+++ b/models/certificate.js
@@ -2,7 +2,7 @@ const logger = require('winston');
const { returnShortId } = require('../helpers/sequelizeHelpers.js');
const NO_CHANNEL = 'NO_CHANNEL';
-module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
+module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
const Certificate = sequelize.define(
'Certificate',
{
@@ -11,7 +11,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
default: null,
},
amount: {
- type : STRING,
+ type : DECIMAL(19, 8),
default: null,
},
claimId: {
@@ -31,7 +31,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
default: null,
},
effectiveAmount: {
- type : STRING,
+ type : DECIMAL(19, 8),
default: null,
},
hasSignature: {
@@ -39,7 +39,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
default: null,
},
height: {
- type : STRING,
+ type : INTEGER,
default: null,
},
hex: {
@@ -59,7 +59,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
default: null,
},
validAtHeight: {
- type : STRING,
+ type : INTEGER,
default: null,
},
outpoint: {
diff --git a/models/claim.js b/models/claim.js
index cb6a6d7a..64d565a5 100644
--- a/models/claim.js
+++ b/models/claim.js
@@ -2,7 +2,7 @@ const logger = require('winston');
const { returnShortId } = require('../helpers/sequelizeHelpers.js');
const NO_CLAIM = 'NO_CLAIM';
-module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, DOUBLE, Op }) => {
+module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
const Claim = sequelize.define(
'Claim',
{
@@ -11,7 +11,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
default: null,
},
amount: {
- type : STRING,
+ type : DECIMAL(19, 8),
default: null,
},
claimId: {
@@ -31,7 +31,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
default: null,
},
effectiveAmount: {
- type : STRING,
+ type : DECIMAL(19, 8),
default: null,
},
hasSignature: {
@@ -39,7 +39,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
default: null,
},
height: {
- type : STRING,
+ type : INTEGER,
default: null,
},
hex: {
@@ -59,7 +59,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
default: null,
},
validAtHeight: {
- type : STRING,
+ type : INTEGER,
default: null,
},
outpoint: {
diff --git a/models/index.js b/models/index.js
index 83f277e9..4bc622fd 100644
--- a/models/index.js
+++ b/models/index.js
@@ -2,19 +2,20 @@ const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(module.filename);
-const config = require('../config/speechConfig.js');
-const db = {};
const logger = require('winston');
-
+const config = require('../config/speechConfig.js');
const database = config.sql.database;
const username = config.sql.username;
const password = config.sql.password;
+const db = {};
+// set sequelize options
const sequelize = new Sequelize(database, username, password, {
- host : 'localhost',
- dialect: 'mysql',
- logging: false,
- pool : {
+ host : 'localhost',
+ dialect : 'mysql',
+ dialectOptions: {decimalNumbers: true}, // fix to ensure DECIMAL will not be stored as a string
+ logging : false,
+ pool : {
max : 5,
min : 0,
idle : 10000,
@@ -53,6 +54,7 @@ Object.keys(db).forEach(modelName => {
db.sequelize = sequelize;
db.Sequelize = Sequelize;
+// add an 'upsert' method to the db object
db.upsert = (Model, values, condition, tableName) => {
return Model
.findOne({ where: condition })
@@ -70,6 +72,7 @@ db.upsert = (Model, values, condition, tableName) => {
});
};
+// add a 'getTrendingClaims' method to the db object
db.getTrendingClaims = (startDate) => {
return db.sequelize.query(`SELECT COUNT(*), File.* FROM Request LEFT JOIN File ON Request.FileId = File.id WHERE FileId IS NOT NULL AND nsfw != 1 AND trendingEligible = 1 AND Request.createdAt > "${startDate}" GROUP BY FileId ORDER BY COUNT(*) DESC LIMIT 25;`, { type: db.sequelize.QueryTypes.SELECT });
};
diff --git a/public/assets/css/general.css b/public/assets/css/general.css
index 9b8c8e77..1fcfefe9 100644
--- a/public/assets/css/general.css
+++ b/public/assets/css/general.css
@@ -74,7 +74,7 @@ body, .flex-container--column {
/* TEXT */
-body, button, input, textarea, label, select, option {
+body, button, input, textarea, label, select, option, #channel-publish-in-progress > p, #channel-publish-done > p {
font-family: 'Lekton', monospace;
font-size: large;
}
diff --git a/public/assets/js/createChannelFunctions.js b/public/assets/js/createChannelFunctions.js
index 379c9430..dbcf4e49 100644
--- a/public/assets/js/createChannelFunctions.js
+++ b/public/assets/js/createChannelFunctions.js
@@ -1,11 +1,14 @@
+// display the content that shows channel creation has started
function showChannelCreateInProgressDisplay () {
const publishChannelForm = document.getElementById('publish-channel-form');
- publishChannelForm.hidden = true;
const inProgress = document.getElementById('channel-publish-in-progress');
+ const channelProgressBar = document.getElementById('create-channel-progress-bar');
+ publishChannelForm.hidden = true;
inProgress.hidden = false;
- createProgressBar(document.getElementById('create-channel-progress-bar'), 12);
+ createProgressBar(channelProgressBar, 12);
}
+// display the content that shows channle creation is done
function showChannelCreateDoneDisplay() {
const inProgress = document.getElementById('channel-publish-in-progress');
inProgress.hidden=true;
@@ -38,7 +41,6 @@ function publishNewChannel (event) {
if (window.location.pathname === '/') {
// remove old channel and replace with new one & select it
replaceChannelOptionInPublishChannelSelect();
- // remove old channel and replace with new one & select it
replaceChannelOptionInNavBarChannelSelect();
} else {
window.location = '/';
@@ -47,7 +49,7 @@ function publishNewChannel (event) {
.catch(error => {
if (error.name === 'ChannelNameError' || error.name === 'ChannelPasswordError'){
const channelNameErrorDisplayElement = document.getElementById('input-error-channel-name');
- showError(channelNameErrorDisplayElement, error.message);
+ validationFunctions.showError(channelNameErrorDisplayElement, error.message);
} else {
console.log('signup failure:', error);
showChannelCreationError('Unfortunately, Spee.ch encountered an error while creating your channel. Please let us know in slack!');
diff --git a/public/assets/js/generalFunctions.js b/public/assets/js/generalFunctions.js
index d591a0ee..ec56009f 100644
--- a/public/assets/js/generalFunctions.js
+++ b/public/assets/js/generalFunctions.js
@@ -151,7 +151,7 @@ function copyToClipboard(event){
try {
document.execCommand('copy');
} catch (err) {
- showError(errorElement, 'Oops, unable to copy');
+ validationFunctions.showError(errorElement, 'Oops, unable to copy');
}
}
diff --git a/public/assets/js/validationFunctions.js b/public/assets/js/validationFunctions.js
index 3cb2fcaf..f79cc4fa 100644
--- a/public/assets/js/validationFunctions.js
+++ b/public/assets/js/validationFunctions.js
@@ -38,7 +38,6 @@ const validationFunctions = {
},
// validation function that checks to make sure the claim name is valid
validateClaimName: function (name) {
- console.log('validating the claim name');
// ensure a name was entered
if (name.length < 1) {
throw new NameError("You must enter a name for your url");
diff --git a/routes/api-routes.js b/routes/api-routes.js
index 821caf07..38b5b1e8 100644
--- a/routes/api-routes.js
+++ b/routes/api-routes.js
@@ -1,6 +1,7 @@
const logger = require('winston');
const multipart = require('connect-multiparty');
-const multipartMiddleware = multipart({uploadDir: '/home/lbry/test/'});
+const config = require('../config/speechConfig.js');
+const multipartMiddleware = multipart({uploadDir: config.files.uploadDirectory});
const db = require('../models');
const { publish } = require('../controllers/publishController.js');
const { getClaimList, resolveUri } = require('../helpers/lbryApi.js');
diff --git a/speech.js b/speech.js
index 19253e10..7e7a4e5f 100644
--- a/speech.js
+++ b/speech.js
@@ -1,7 +1,6 @@
// load dependencies
const express = require('express');
const bodyParser = require('body-parser');
-const siofu = require('socketio-file-upload');
const expressHandlebars = require('express-handlebars');
const Handlebars = require('handlebars');
const handlebarsHelpers = require('./helpers/handlebarsHelpers.js');
@@ -32,7 +31,6 @@ app.use(helmet()); // set HTTP headers to protect against well-known web vulnera
app.use(express.static(`${__dirname}/public`)); // 'express.static' to serve static files from public directory
app.use(bodyParser.json()); // 'body parser' for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded
-app.use(siofu.router); // 'socketio-file-upload' router for uploading with socket.io
app.use((req, res, next) => { // custom logging middleware to log all incoming http requests
logger.verbose(`Request on ${req.originalUrl} from ${req.ip}`);
logger.debug('req.body:', req.body);
@@ -76,7 +74,7 @@ db.sequelize
.then(hostedContentPath => {
// add the hosted content folder at a static path
app.use('/media', express.static(hostedContentPath));
- // require routes & wrap in socket.io
+ // require routes
require('./routes/auth-routes.js')(app);
require('./routes/api-routes.js')(app);
require('./routes/page-routes.js')(app);
diff --git a/views/index.handlebars b/views/index.handlebars
index 09c01c0e..0b09d8a6 100644
--- a/views/index.handlebars
+++ b/views/index.handlebars
@@ -1,8 +1,8 @@
-
+
Drag & drop image or video here to publish
@@ -22,7 +22,7 @@
-
+
Drag & drop image or video here
OR
diff --git a/views/partials/publishForm-Channel.handlebars b/views/partials/publishForm-Channel.handlebars
index a11da68c..cf8a32fe 100644
--- a/views/partials/publishForm-Channel.handlebars
+++ b/views/partials/publishForm-Channel.handlebars
@@ -75,7 +75,7 @@
// hide the login and new channel forms
loginToChannelTool.hidden = true;
createChannelTool.hidden = true;
- hideError(document.getElementById('input-error-channel-select'));
+ validationFunctions.hideError(document.getElementById('input-error-channel-select'));
}
// update url
updateUrl(selectedChannel);