diff --git a/config/speechConfig.js.example b/config/speechConfig.js.example index 904db832..5af319dd 100644 --- a/config/speechConfig.js.example +++ b/config/speechConfig.js.example @@ -35,4 +35,8 @@ module.exports = { testChannel : '@testpublishchannel', // a channel to make test publishes in testChannelPassword: 'password', // password for the test channel }, + api: { + apiUri: 'localhost', + apiPort: '5279', + }, }; diff --git a/controllers/statsController.js b/controllers/statsController.js index 75ddfb9c..68215767 100644 --- a/controllers/statsController.js +++ b/controllers/statsController.js @@ -1,27 +1,94 @@ const logger = require('winston'); +const ua = require('universal-analytics'); +const config = require('../config/speechConfig.js'); const db = require('../models'); +const googleApiKey = config.analytics.googleId; module.exports = { + postToStats (action, url, ipAddress, name, claimId, result) { + logger.debug('action:', action); + // make sure the result is a string + if (result && (typeof result !== 'string')) { + result = result.toString(); + } + // make sure the ip address(es) are a string + if (ipAddress && (typeof ipAddress !== 'string')) { + ipAddress = ipAddress.toString(); + } + db.File + .findOne({where: { name, claimId }}) + .then(file => { + // create record in the db + let FileId; + if (file) { + FileId = file.dataValues.id; + } else { + FileId = null; + } + return db.Request + .create({ + action, + url, + ipAddress, + result, + FileId, + }); + }) + .catch(error => { + logger.error('Sequelize error >>', error); + }); + }, + sendGoogleAnalytics (action, headers, ip, originalUrl) { + const visitorId = ip.replace(/\./g, '-'); + const visitor = ua(googleApiKey, visitorId, { strictCidFormat: false, https: true }); + let params; + switch (action) { + case 'SERVE': + params = { + ec : 'serve', + ea : originalUrl, + uip: ip, + ua : headers['user-agent'], + ul : headers['accept-language'], + }; + break; + case 'PUBLISH': + params = { + ec : 'publish', + ea : originalUrl, + uip: ip, + ua : headers['user-agent'], + ul : headers['accept-language'], + }; + break; + default: break; + } + visitor.event(params, (err) => { + if (err) { + logger.error('Google Analytics Event Error >>', err); + } + }); + }, getTrendingClaims (startDate) { logger.debug('retrieving trending'); return new Promise((resolve, reject) => { // get the raw requests data db.getTrendingFiles(startDate) - .then(fileArray => { - let claimsPromiseArray = []; - if (fileArray) { - fileArray.forEach(file => { - claimsPromiseArray.push(db.Claim.resolveClaim(file.name, file.claimId)); - }); - return Promise.all(claimsPromiseArray); - } - }) - .then(claimsArray => { - resolve(claimsArray); - }) - .catch(error => { - reject(error); - }); + .then(fileArray => { + let claimsPromiseArray = []; + if (fileArray) { + fileArray.forEach(file => { + claimsPromiseArray.push(db.Claim.resolveClaim(file.name, file.claimId)); + }); + return Promise.all(claimsPromiseArray); + } + }) + .then(claimsArray => { + resolve(claimsArray); + }) + .catch(error => { + reject(error); + }); }); }, getRecentClaims () { @@ -29,13 +96,13 @@ module.exports = { return new Promise((resolve, reject) => { // get the raw requests data db.File.getRecentClaims() - .then(results => { - resolve(results); - }) - .catch(error => { - logger.error('sequelize error', error); - reject(error); - }); + .then(results => { + resolve(results); + }) + .catch(error => { + logger.error('sequelize error', error); + reject(error); + }); }); }, }; diff --git a/helpers/errorHandlers.js b/helpers/errorHandlers.js index e170a9aa..9a5b24d1 100644 --- a/helpers/errorHandlers.js +++ b/helpers/errorHandlers.js @@ -7,7 +7,7 @@ module.exports = { if (error.code === 'ECONNREFUSED') { status = 503; message = 'Connection refused. The daemon may not be running.'; - // check for errors from the daemon + // check for errors from the deamon } else if (error.response) { status = error.response.status || 500; if (error.response.data) { diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index 0474ca36..a8fd1b35 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -1,5 +1,8 @@ const axios = require('axios'); const logger = require('winston'); +const config = require('../config/speechConfig.js'); +const { apiUri, apiPort } = config.api; +const lbryApiUrl = 'http://' + apiUri + ':' + apiPort; function handleLbrynetResponse ({ data }, resolve, reject) { logger.debug('lbry api data:', data); @@ -22,7 +25,7 @@ module.exports = { logger.debug(`lbryApi >> Publishing claim to "${publishParams.name}"`); return new Promise((resolve, reject) => { axios - .post('http://localhost:5279/lbryapi', { + .post(lbryApiUrl, { method: 'publish', params: publishParams, }) @@ -38,7 +41,7 @@ module.exports = { logger.debug(`lbryApi >> Getting Claim for "${uri}"`); return new Promise((resolve, reject) => { axios - .post('http://localhost:5279/lbryapi', { + .post(lbryApiUrl, { method: 'get', params: { uri, timeout: 20 }, }) @@ -54,7 +57,7 @@ module.exports = { logger.debug(`lbryApi >> Getting claim_list for "${claimName}"`); return new Promise((resolve, reject) => { axios - .post('http://localhost:5279/lbryapi', { + .post(lbryApiUrl, { method: 'claim_list', params: { name: claimName }, }) @@ -71,7 +74,7 @@ module.exports = { // console.log('resolving uri', uri); return new Promise((resolve, reject) => { axios - .post('http://localhost:5279/lbryapi', { + .post(lbryApiUrl, { method: 'resolve', params: { uri }, }) @@ -91,7 +94,7 @@ module.exports = { logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...'); return new Promise((resolve, reject) => { axios - .post('http://localhost:5279/lbryapi', { + .post(lbryApiUrl, { method: 'settings_get', }) .then(({ data }) => { @@ -110,7 +113,7 @@ module.exports = { createChannel (name) { return new Promise((resolve, reject) => { axios - .post('http://localhost:5279/lbryapi', { + .post(lbryApiUrl, { method: 'channel_new', params: { channel_name: name, diff --git a/helpers/statsHelpers.js b/helpers/statsHelpers.js deleted file mode 100644 index 9dc41645..00000000 --- a/helpers/statsHelpers.js +++ /dev/null @@ -1,88 +0,0 @@ -const logger = require('winston'); -const ua = require('universal-analytics'); -const config = require('../config/speechConfig.js'); -const db = require('../models'); -const googleApiKey = config.analytics.googleId; - -module.exports = { - postToStats (action, url, ipAddress, name, claimId, result) { - logger.debug('action:', action); - // make sure the result is a string - if (result && (typeof result !== 'string')) { - result = result.toString(); - } - // make sure the ip address(es) are a string - if (ipAddress && (typeof ipAddress !== 'string')) { - ipAddress = ipAddress.toString(); - } - db.File - .findOne({where: { name, claimId }}) - .then(file => { - // create record in the db - let FileId; - if (file) { - FileId = file.dataValues.id; - } else { - FileId = null; - } - return db.Request - .create({ - action, - url, - ipAddress, - result, - FileId, - }); - }) - .catch(error => { - logger.error('Sequelize error >>', error); - }); - }, - sendGoogleAnalyticsEvent (action, headers, ip, originalUrl) { - const visitorId = ip.replace(/\./g, '-'); - const visitor = ua(googleApiKey, visitorId, { strictCidFormat: false, https: true }); - let params; - switch (action) { - case 'SERVE': - params = { - ec : 'serve', - ea : originalUrl, - uip: ip, - ua : headers['user-agent'], - ul : headers['accept-language'], - }; - break; - default: break; - } - visitor.event(params, (err) => { - if (err) { - logger.error('Google Analytics Event Error >>', err); - } - }); - }, - sendGoogleAnalyticsTiming (action, headers, ip, originalUrl, startTime, endTime) { - const visitorId = ip.replace(/\./g, '-'); - const visitor = ua(googleApiKey, visitorId, { strictCidFormat: false, https: true }); - const publishDurration = endTime - startTime; - let params; - switch (action) { - case 'PUBLISH': - params = { - userTimingCategory : 'lbrynet', - userTimingVariableName: 'publish', - userTimingTime : publishDurration, - uip : ip, - ua : headers['user-agent'], - ul : headers['accept-language'], - }; - break; - default: break; - } - visitor.timing(params, (err) => { - if (err) { - logger.error('Google Analytics Event Error >>', err); - } - logger.info(`publish completed successfully in ${publishDurration}ms`); - }); - }, -}; diff --git a/routes/api-routes.js b/routes/api-routes.js index c22f19cb..bd9ac3e1 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -7,7 +7,6 @@ const { checkClaimNameAvailability, checkChannelAvailability, publish } = requir const { getClaimList, resolveUri, getClaim } = require('../helpers/lbryApi.js'); const { createPublishParams, parsePublishApiRequestBody, parsePublishApiRequestFiles, parsePublishApiChannel } = require('../helpers/publishHelpers.js'); const errorHandlers = require('../helpers/errorHandlers.js'); -const { sendGoogleAnalyticsTiming } = require('../helpers/statsHelpers.js'); const { authenticateIfNoUserToken } = require('../auth/authentication.js'); function addGetResultsToFileData (fileInfo, getResult) { @@ -125,11 +124,9 @@ module.exports = (app) => { }); }); // route to run a publish request on the daemon - app.post('/api/claim-publish', multipartMiddleware, ({ body, files, headers, ip, originalUrl, user }, res) => { + app.post('/api/claim-publish', multipartMiddleware, ({ body, files, ip, originalUrl, user }, res) => { logger.debug('api/claim-publish body:', body); logger.debug('api/claim-publish files:', files); - const publishStartTime = Date.now(); - logger.debug('publish request started @', publishStartTime); let name, fileName, filePath, fileType, nsfw, license, title, description, thumbnail, channelName, channelPassword; // validate the body and files of the request try { @@ -171,9 +168,6 @@ module.exports = (app) => { lbryTx: result, }, }); - const publishEndTime = Date.now(); - logger.debug('publish request completed @', publishEndTime); - sendGoogleAnalyticsTiming('PUBLISH', headers, ip, originalUrl, publishStartTime, publishEndTime); }) .catch(error => { errorHandlers.handleApiError(originalUrl, ip, error, res); diff --git a/routes/serve-routes.js b/routes/serve-routes.js index 3baf1f6e..f2610f0b 100644 --- a/routes/serve-routes.js +++ b/routes/serve-routes.js @@ -2,7 +2,7 @@ const logger = require('winston'); const { getClaimId, getChannelViewData, getLocalFileRecord } = require('../controllers/serveController.js'); const serveHelpers = require('../helpers/serveHelpers.js'); const { handleRequestError } = require('../helpers/errorHandlers.js'); -const { postToStats } = require('../helpers/statsHelpers.js'); +const { postToStats } = require('../controllers/statsController.js'); const db = require('../models'); const lbryUri = require('../helpers/lbryUri.js'); diff --git a/views/partials/maintenanceBanner.handlebars b/views/partials/maintenanceBanner.handlebars deleted file mode 100644 index 2adb7536..00000000 --- a/views/partials/maintenanceBanner.handlebars +++ /dev/null @@ -1,4 +0,0 @@ -
-

Hi there! Spee.ch is currently undergoing maintenance, and as a result publishing may be disabled. Please visit our discord channel for updates.

-
diff --git a/views/partials/releaseBanner.handlebars b/views/partials/releaseBanner.handlebars new file mode 100644 index 00000000..e23a60a5 --- /dev/null +++ b/views/partials/releaseBanner.handlebars @@ -0,0 +1,3 @@ +
+ Hi there! You've stumbled upon the new version of Spee<h, launching soon! Send us your feedback in our discord +
\ No newline at end of file