cleaned up errors and updated build scripts

This commit is contained in:
bill bittner 2018-07-31 16:43:08 -07:00
parent dc558e9b9c
commit 60ffe5de95
28 changed files with 139 additions and 127 deletions

View file

@ -1,6 +1,5 @@
node_modules/
exports/
index.js
test/
server/render/build
client/build
node_modules/
public/bundle
server/render/build
test/

2
.gitignore vendored
View file

@ -16,4 +16,6 @@ config/siteConfig.json
public/bundle/bundle.js
public/bundle/bundle.js.map
public/bundle/Lekton-*
public/bundle/style.css

View file

@ -2,15 +2,30 @@
This repo packages the spee.ch server for use with spee.ch implementations.
### Quick start
To get started running your own version of spee.ch, visit [lbryio/www.spee.ch](https://github.com/lbryio/www.spee.ch)
### Install
Install dependencies
```
npm install spee.ch --save
npm install
```
create config file
```
npm run configure
```
build from source code
```
npm run transpile
```
create client bundle with webpack
```
npm run bundle
```
start the sever
```
npm run start
```
### Dependenceis
Make sure the following are installed
### System dependencies
Spee.ch relies on the following programs being installed on your server:
* [imagemagick](https://www.imagemagick.org/script/download.php)
* [ffmpeg](https://www.ffmpeg.org/download.html)
@ -19,6 +34,7 @@ Make sure the following are installed
* `index.js` is the entry point for the server. It creates the [express app](https://expressjs.com/), requires the routes, syncs the database, and starts the server listening on the `PORT` designated in the config file.
* the `server/routes` folder contains all of the routes for the express app
* the `server/models` folder contains all of the models which the app uses to interact with the `mysql` database. Note: this app uses the [sequelize](http://docs.sequelizejs.com/) ORM.
* the `client/` folder contains all of the client code
## Tests
* This package uses `mocha` with `chai` for testing.

View file

@ -166,7 +166,7 @@ inquirer
})
.then(() => {
console.log('\nYou\'re all done!');
console.log('Next step: run "npm run start:dev" to start your server!');
console.log('Next step: run "npm run build" to build your server, then "npm run start" to start your server!');
console.log('If you want to change any settings, you can edit the files in the "/config" folder.');
process.exit(0);
})

View file

@ -4,4 +4,4 @@ import { onHandleShowPageUri } from './show';
export default {
onHandleShowPageUri,
}
};

View file

@ -4,16 +4,16 @@ import {
updateChannelAvailability,
updateChannelCreateName,
updateChannelCreatePassword,
createChannel
createChannel,
} from '../../actions/channelCreate';
const mapStateToProps = ({channelCreate: {name, password, error, status }}) => {
const mapStateToProps = ({channelCreate: { name, password, error, status }}) => {
return {
name,
password,
error,
status,
}
};
};
const mapDispatchToProps = {

View file

@ -26,21 +26,21 @@ const reduxMiddleware = window.__REDUX_DEVTOOLS_EXTENSION__ ? compose(middleware
// create the store
let store;
if (preloadedState) {
store = createStore(Reducers, preloadedState, reduxMiddleware);
store = createStore(Reducers, preloadedState, reduxMiddleware);
} else {
store = createStore(Reducers, reduxMiddleware);
store = createStore(Reducers, reduxMiddleware);
}
sagaMiddleware.run(Sagas.rootSaga);
// render the app
hydrate(
<Provider store={store}>
<BrowserRouter>
<GAListener>
<App />
</GAListener>
</BrowserRouter>
</Provider>,
document.getElementById('react-app')
<Provider store={store}>
<BrowserRouter>
<GAListener>
<App />
</GAListener>
</BrowserRouter>
</Provider>,
document.getElementById('react-app')
);

View file

@ -4,4 +4,4 @@ import { handleShowPageUri } from './show_uri';
export default {
rootSaga,
handleShowPageUri,
}
};

View file

@ -4,24 +4,26 @@
"description": "an npm package that exports a customizeable spee.ch server",
"main": "index.js",
"scripts": {
"bundle": "webpack --config webpack.config.js",
"bundle:dev": "webpack --config webpack.config.js --watch",
"configure": "node cli/configure.js",
"fix": "eslint . --fix",
"lint": "eslint .",
"precommit": "eslint .",
"start": "npm run server",
"start:dev": "builder concurrent transpile:dev bundle:dev bundle:dev",
"server": "node server.js",
"server:dev": "nodemon server.js",
"test": "mocha --recursive",
"test:no-lbc": "npm test -- --grep @usesLbc --invert",
"lint": "eslint .",
"fix": "eslint . --fix",
"precommit": "eslint .",
"build": "builder concurrent transpile:server transpile:client transpile:client_custom webpack",
"build:dev": "builder concurrent transpile:server:dev transpile:client:dev transpile:client_custom:dev webpack:dev",
"start": "node server.js",
"start:dev": "builder concurrent build:dev server:dev",
"server:dev": "nodemon server.js",
"transpile": "builder concurrent transpile:server transpile:client transpile:client_custom",
"transpile:dev": "builder concurrent transpile:server:dev transpile:client:dev transpile:client_custom:dev",
"transpile:server": "babel server/render/src -d server/render/build",
"transpile:server:dev": "babel server/render/src -w -d server/render/build",
"transpile:client": "babel client/src -d client/build",
"transpile:client:dev": "babel client/src -w -d client/build",
"transpile:client_custom": "babel client_custom/src -d client_custom/build",
"transpile:client_custom:dev": "babel client_custom/src -w -d client_custom/build",
"webpack": "webpack --config webpack.config.js",
"webpack:dev": "webpack --config webpack.config.js --watch"
"transpile:client_custom:dev": "babel client_custom/src -w -d client_custom/build"
},
"repository": {
"type": "git",

View file

@ -21,9 +21,9 @@ try {
}
try {
const SpeechServer = require('./server');
const server = new SpeechServer();
server.start();
const Server = require('./server/index.js');
const speech = new Server();
speech.start();
} catch (error) {
console.log('server startup error:', error);
process.exit(1);

View file

@ -9,7 +9,7 @@ const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
*/
function addAtSymbolIfNecessary (name) {
if (name.substring(0,1) !== '@') {
if (name.substring(0, 1) !== '@') {
return `@${name}`;
}
return name;
@ -22,12 +22,12 @@ const channelAvailability = ({ ip, originalUrl, params: { name } }, res) => {
.then(isAvailable => {
let responseObject = {
success: true,
data: isAvailable,
data : isAvailable,
};
if (isAvailable) {
responseObject['message'] = `${name} is available`
responseObject['message'] = `${name} is available`;
} else {
responseObject['message'] = `${name} is already in use`
responseObject['message'] = `${name} is already in use`;
}
res.status(200).json(responseObject);
sendGATimingEvent('end-to-end', 'channel name availability', name, gaStartTime, Date.now());

View file

@ -1,6 +1,5 @@
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
const getChannelClaims = require('./getChannelClaims.js');
const logger = require('winston');
const NO_CHANNEL = 'NO_CHANNEL';

View file

@ -18,7 +18,7 @@ const channelData = ({ ip, originalUrl, body, params }, res) => {
.then(data => {
res.status(200).json({
success: true,
data
data,
});
})
.catch(error => {

View file

@ -14,12 +14,12 @@ const claimAvailability = ({ ip, originalUrl, params: { name } }, res) => {
.then(isAvailable => {
let responseObject = {
success: true,
data: isAvailable,
data : isAvailable,
};
if (isAvailable) {
responseObject['message'] = `That claim name is available`
responseObject['message'] = `That claim name is available`;
} else {
responseObject['message'] = `That url is already in use`
responseObject['message'] = `That url is already in use`;
}
res.status(200).json(responseObject);
sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());

View file

@ -16,12 +16,12 @@ const claimData = ({ ip, originalUrl, body, params }, res) => {
if (!claimInfo) {
return res.status(404).json({
success: false,
message: 'No claim could be found'
message: 'No claim could be found',
});
}
res.status(200).json({
success: true,
data: claimInfo
data : claimInfo,
});
})
.catch(error => {

View file

@ -28,8 +28,8 @@ const claimGet = ({ ip, originalUrl, params }, res) => {
})
.then(() => {
const fileData = createFileRecordDataAfterGet(resolveResult, getResult);
const upsertCriteria = { name, claimId};
return db.upsert(db.File, fileData, upsertCriteria, 'File')
const upsertCriteria = { name, claimId };
return db.upsert(db.File, fileData, upsertCriteria, 'File');
})
.then(() => {
const { message, completed } = getResult;

View file

@ -35,7 +35,7 @@ const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res)
if (disabled) {
return res.status(503).json({
success: false,
message: disabledMessage
message: disabledMessage,
});
}
// define variables
@ -58,14 +58,15 @@ const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res)
checkClaimAvailability(name),
createPublishParams(filePath, name, title, description, license, nsfw, thumbnail, channelName, channelClaimId),
createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw),
])
]);
})
.then(([ claimAvailable, publishParams, thumbnailPublishParams ]) => {
if (!claimAvailable) {
throw {
name: CLAIM_TAKEN,
message: 'That claim name is already taken'
const error = {
name : CLAIM_TAKEN,
message: 'That claim name is already taken',
};
throw error;
}
// publish the thumbnail, if one exists
if (thumbnailPublishParams) {
@ -81,7 +82,7 @@ const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res)
data : {
name,
claimId : result.claim_id,
url : `${host}/${result.claim_id}/${name}`, // for backwards compatability with app
url : `${host}/${result.claim_id}/${name}`, // for backwards compatability with app
showUrl : `${host}/${result.claim_id}/${name}`,
serveUrl: `${host}/${result.claim_id}/${name}${fileExtension}`,
lbryTx : result,
@ -91,7 +92,7 @@ const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res)
sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());
})
.catch(error => {
if (error.name = CLAIM_TAKEN) {
if (error.name === CLAIM_TAKEN) {
res.status(400).json({
success: false,
message: error.message,

View file

@ -5,7 +5,7 @@ const { publishing: {
thumbnailChannelId,
additionalClaimAddresses,
disabled,
disabledMessage
disabledMessage,
} } = require('@config/siteConfig');
/*
@ -22,7 +22,7 @@ const publishingConfig = (req, res) => {
thumbnailChannelId,
additionalClaimAddresses,
disabled,
disabledMessage
disabledMessage,
});
};

View file

@ -6,7 +6,6 @@ const getOEmbedDataForAsset = require('./getOEmbedDataForAsset');
const parseSpeechUrl = require('./parseSpeechUrl');
const getOEmbedData = (req, res) => {
const { query: { url, format } } = req;
logger.debug('req url', url);
logger.debug('req format', format);
@ -20,7 +19,7 @@ const getOEmbedData = (req, res) => {
({ claimName } = lbryUri.parseClaim(paramTwo));
} else {
({ isChannel, channelName, channelClaimId } = lbryUri.parseIdentifier(paramOne));
if (!isChannel ) {
if (!isChannel) {
({ claimName } = lbryUri.parseClaim(paramOne));
}
}
@ -28,11 +27,11 @@ const getOEmbedData = (req, res) => {
if (isChannel && !paramTwo) {
getOEmbedDataForChannel(channelName, channelClaimId)
.then(data => {
if (format === 'xml'){
if (format === 'xml') {
return res.status(503).json({
success: false,
message: 'xml format is not implemented yet',
})
});
} else {
return res.status(200).json(data);
}
@ -42,16 +41,15 @@ const getOEmbedData = (req, res) => {
success: false,
message: error,
});
})
});
} else {
getOEmbedDataForAsset(channelName, channelClaimId, claimName, claimId)
.then(data => {
if (format === 'xml'){
if (format === 'xml') {
return res.status(503).json({
success: false,
message: 'xml format is not implemented yet',
})
});
} else {
return res.status(200).json(data);
}
@ -61,7 +59,7 @@ const getOEmbedData = (req, res) => {
success: false,
message: error,
});
})
});
}
};

View file

@ -9,7 +9,7 @@ const db = require('../../../models');
const getTorList = (req, res) => {
db.Tor.refreshTable()
.then( result => {
.then(result => {
logger.debug('number of records', result.length);
res.status(200).json(result);
})
@ -18,7 +18,7 @@ const getTorList = (req, res) => {
res.status(500).json({
success: false,
error,
})
});
});
};

View file

@ -32,38 +32,38 @@ const updateUserPassword = ({ ip, originalUrl, body }, res) => {
userName,
},
})
.then(user => {
userRecord = user;
if (!userRecord) {
throw new Error('no user found');
}
if (oldPassword === masterPassword) {
logger.debug('master password provided');
return true;
} else {
logger.debug('old password provided');
return userRecord.comparePassword(oldPassword);
}
})
.then(isMatch => {
if (!isMatch) {
throw new Error('Incorrect old password.');
}
logger.debug('Password was a match, updating password');
return userRecord.changePassword(newPassword);
})
.then(() => {
logger.debug('Password successfully updated');
return res.status(200).json({
success: true,
message: 'Password successfully updated',
oldPassword,
newPassword,
.then(user => {
userRecord = user;
if (!userRecord) {
throw new Error('no user found');
}
if (oldPassword === masterPassword) {
logger.debug('master password provided');
return true;
} else {
logger.debug('old password provided');
return userRecord.comparePassword(oldPassword);
}
})
.then(isMatch => {
if (!isMatch) {
throw new Error('Incorrect old password.');
}
logger.debug('Password was a match, updating password');
return userRecord.changePassword(newPassword);
})
.then(() => {
logger.debug('Password successfully updated');
return res.status(200).json({
success: true,
message: 'Password successfully updated',
oldPassword,
newPassword,
});
})
.catch((error) => {
handleErrorResponse(originalUrl, ip, error, res);
});
})
.catch((error) => {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = updateUserPassword;

View file

@ -40,11 +40,9 @@ const serveByClaim = (req, res) => {
getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);
sendGAServeEvent(headers, ip, originalUrl);
} catch (error) {
return res.status(400).json({success: false, message: error.message});
}
};
module.exports = serveByClaim;

View file

@ -41,11 +41,9 @@ const serverByIdentifierAndClaim = (req, res) => {
getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);
sendGAServeEvent(headers, ip, originalUrl);
} catch (error) {
return res.status(400).json({success: false, message: error.message});
}
};
module.exports = serverByIdentifierAndClaim;

View file

@ -2,7 +2,7 @@ const logout = (req, res) => {
req.logout();
const responseObject = {
success: true,
message: 'you successfully logged out'
message: 'you successfully logged out',
};
res.status(200).json(responseObject);
};

View file

@ -1,7 +1,7 @@
const user = (req, res) => {
const responseObject = {
success: true,
data: req.user,
data : req.user,
};
res.status(200).json(responseObject);
};

View file

@ -73,8 +73,8 @@ function Server () {
// initialize passport
app.use(cookieSession({
name : 'session',
keys : [sessionKey],
name: 'session',
keys: [sessionKey],
}));
app.use(speechPassport.initialize());
app.use(speechPassport.session());
@ -82,11 +82,11 @@ function Server () {
// configure handlebars & register it with express app
const viewsPath = Path.resolve(process.cwd(), 'node_modules/spee.ch/server/views');
app.engine('handlebars', expressHandlebars({
async: false,
dataType: 'text',
async : false,
dataType : 'text',
defaultLayout: 'embed',
partialsDir: Path.join(viewsPath, '/partials'),
layoutsDir: Path.join(viewsPath, '/layouts')
partialsDir : Path.join(viewsPath, '/partials'),
layoutsDir : Path.join(viewsPath, '/layouts'),
}));
app.set('views', viewsPath);
app.set('view engine', 'handlebars');
@ -110,7 +110,7 @@ function Server () {
this.server.listen(PORT, () => {
logger.info(`Server is listening on PORT ${PORT}`);
resolve();
})
});
});
};
this.syncDatabase = () => {
@ -118,7 +118,7 @@ function Server () {
return createDatabaseIfNotExists()
.then(() => {
db.sequelize.sync();
})
});
};
this.performChecks = () => {
if (!performChecks) {
@ -130,7 +130,7 @@ function Server () {
])
.then(([walletBalance]) => {
logger.info('Starting LBC balance:', walletBalance);
})
});
};
this.performUpdates = () => {
if (!performUpdates) {
@ -144,7 +144,7 @@ function Server () {
.then(([updatedBlockedList, updatedTorList]) => {
logger.info('Blocked list updated, length:', updatedBlockedList.length);
logger.info('Tor list updated, length:', updatedTorList.length);
})
});
};
this.start = () => {
this.initialize();
@ -158,14 +158,14 @@ function Server () {
return Promise.all([
this.performChecks(),
this.performUpdates(),
])
]);
})
.then(() => {
logger.info('Spee.ch startup is complete');
})
.catch(error => {
if (error.code === 'ECONNREFUSED') {
return logger.error('Connection refused. The daemon may not be running.')
return logger.error('Connection refused. The daemon may not be running.');
} else if (error.code === 'EADDRINUSE') {
return logger.error('Server could not start listening. The port is already in use.');
} else if (error.message) {

View file

@ -19,10 +19,10 @@ const sequelize = new Sequelize(database, username, password, {
host : 'localhost',
dialect : 'mysql',
dialectOptions: {
decimalNumbers: true
decimalNumbers: true,
},
logging : false,
pool : {
logging: false,
pool : {
max : 5,
min : 0,
idle : 10000,

View file

@ -21,7 +21,6 @@ const getTorList = require('../../controllers/api/tor');
const getBlockedList = require('../../controllers/api/blocked');
const getOEmbedData = require('../../controllers/api/oEmbed');
module.exports = (app) => {
// channel routes
app.get('/api/channel/availability/:name', torCheckMiddleware, channelAvailability);
@ -48,5 +47,5 @@ module.exports = (app) => {
// blocked
app.get('/api/blocked', torCheckMiddleware, getBlockedList);
// open embed
app.get('/api/oembed', torCheckMiddleware, getOEmbedData)
app.get('/api/oembed', torCheckMiddleware, getOEmbedData);
};