224 lines
8.8 KiB
JavaScript
224 lines
8.8 KiB
JavaScript
exports.newSocialTradingModulesWebAppInterface = function newSocialTradingModulesWebAppInterface() {
|
|
/*
|
|
This module handles the incomming messages from the Web App.
|
|
At it's current version, it will jusr forward those messages
|
|
to the Network Node it is connected to.
|
|
|
|
Later, it will try to use the personal social graph as a cache,
|
|
so as to minimize the requests to Network Nodes.
|
|
*/
|
|
let thisObject = {
|
|
messageReceived: messageReceived,
|
|
initialize: initialize,
|
|
finalize: finalize
|
|
}
|
|
|
|
return thisObject
|
|
|
|
function finalize() {
|
|
|
|
}
|
|
|
|
function initialize() {
|
|
|
|
}
|
|
|
|
async function messageReceived(message) {
|
|
let messageHeader
|
|
try {
|
|
messageHeader = JSON.parse(message)
|
|
} catch (err) {
|
|
let response = {
|
|
result: 'Error',
|
|
message: 'messageHeader Not Coorrect JSON Format.'
|
|
}
|
|
return JSON.stringify(response)
|
|
}
|
|
|
|
switch (messageHeader.requestType) {
|
|
case 'Query': {
|
|
let queryMessage
|
|
try {
|
|
queryMessage = JSON.parse(messageHeader.queryMessage)
|
|
} catch (err) {
|
|
let response = {
|
|
result: 'Error',
|
|
message: 'queryMessage Not Coorrect JSON Format.'
|
|
}
|
|
return JSON.stringify(response)
|
|
}
|
|
queryMessage.emitterUserProfileId = SA.secrets.map.get('Social Trading Desktop').userProfileId
|
|
messageHeader.queryMessage = JSON.stringify(queryMessage)
|
|
|
|
let response
|
|
|
|
// console.log((new Date()).toISOString(), '- Web App Interface', '- Query Message Received', JSON.stringify(queryMessage))
|
|
|
|
if (queryMessage.queryType !== SA.projects.socialTrading.globals.queryTypes.EVENTS) {
|
|
response = {
|
|
result: 'Ok',
|
|
message: 'Web App Interface Query Processed.',
|
|
data: await DK.running.webSocketsClient.sendMessage(JSON.stringify(messageHeader))
|
|
}
|
|
} else {
|
|
|
|
let events = await DK.running.webSocketsClient.sendMessage(JSON.stringify(messageHeader))
|
|
for (let i = 0; i < events.length; i++) {
|
|
let event = events[i]
|
|
if (event.eventType === SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST) {
|
|
event.postText = await getPostText(event.emitterUserProfile.userProfileHandle, event.emitterPost.emitterPostHash, event.timestamp)
|
|
}
|
|
}
|
|
|
|
response = {
|
|
result: 'Ok',
|
|
message: 'Web App Interface Query Processed.',
|
|
data: events
|
|
}
|
|
}
|
|
|
|
// console.log((new Date()).toISOString(), '- Web App Interface', '- Query Respose Sent', JSON.stringify(response))
|
|
|
|
return response
|
|
}
|
|
case 'Event': {
|
|
let eventMessage
|
|
try {
|
|
eventMessage = JSON.parse(messageHeader.eventMessage)
|
|
} catch (err) {
|
|
let response = {
|
|
result: 'Error',
|
|
message: 'eventMessage Not Coorrect JSON Format.'
|
|
}
|
|
return JSON.stringify(response)
|
|
}
|
|
|
|
if (
|
|
eventMessage.eventType === SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST ||
|
|
eventMessage.eventType === SA.projects.socialTrading.globals.eventTypes.REPLY_TO_USER_POST ||
|
|
eventMessage.eventType === SA.projects.socialTrading.globals.eventTypes.REPOST_USER_POST
|
|
) {
|
|
/*
|
|
We need to save the post at the User's storage and remove the text from the message
|
|
going to the Network Node.
|
|
*/
|
|
let commitMessage
|
|
switch (eventMessage.eventType) {
|
|
case SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST: {
|
|
commitMessage = "New Post"
|
|
break
|
|
}
|
|
case SA.projects.socialTrading.globals.eventTypes.REPLY_TO_USER_POST: {
|
|
commitMessage = "Reply to User Post"
|
|
break
|
|
}
|
|
case SA.projects.socialTrading.globals.eventTypes.REPOST_USER_POST: {
|
|
commitMessage = "Repost User Post"
|
|
break
|
|
}
|
|
}
|
|
/*
|
|
The post text is eliminated, since it is now at the user's storage,
|
|
and a hash of the content was generated, and that is what is going to
|
|
the Network Node.
|
|
*/
|
|
eventMessage.emitterPostHash = await savePostAtStorage(eventMessage.postText, commitMessage, eventMessage.timestamp)
|
|
eventMessage.postText = undefined
|
|
}
|
|
|
|
eventMessage.emitterUserProfileId = SA.secrets.map.get('Social Trading Desktop').userProfileId
|
|
messageHeader.eventMessage = JSON.stringify(eventMessage)
|
|
|
|
let response = {
|
|
result: 'Ok',
|
|
message: 'Web App Interface Event Processed.',
|
|
data: await DK.running.webSocketsClient.sendMessage(JSON.stringify(messageHeader))
|
|
}
|
|
return response
|
|
}
|
|
default: {
|
|
let response = {
|
|
result: 'Error',
|
|
message: 'requestType Not Supported.'
|
|
}
|
|
return JSON.stringify(response)
|
|
}
|
|
}
|
|
}
|
|
|
|
async function savePostAtStorage(postText, commitMessage, timestamp) {
|
|
/*
|
|
Each user, has a git repository that acts as his publicly accesible
|
|
storage for posts.
|
|
|
|
They way we store post there is first saving the data at the local disk
|
|
which has a clone of the remote git repository, and once done, we push
|
|
the changes to the public git repo.
|
|
*/
|
|
const { createHash } = await import('crypto')
|
|
const hash = createHash('sha256')
|
|
let post = {
|
|
timestamp: timestamp,
|
|
postText: postText
|
|
}
|
|
|
|
const fileContent = JSON.stringify(post, undefined, 4)
|
|
const fileHash = hash.update(fileContent).digest('hex')
|
|
const fileName = fileHash + ".json"
|
|
const filePath = './My-Social-Trading-Data/User-Posts/' + SA.projects.foundations.utilities.filesAndDirectories.pathFromDate(timestamp)
|
|
|
|
SA.projects.foundations.utilities.filesAndDirectories.mkDirByPathSync(filePath + '/')
|
|
SA.nodeModules.fs.writeFileSync(filePath + '/' + fileName, fileContent)
|
|
|
|
const options = {
|
|
baseDir: process.cwd() + '/My-Social-Trading-Data',
|
|
binary: 'git',
|
|
maxConcurrentProcesses: 6,
|
|
}
|
|
const git = SA.nodeModules.simpleGit(options)
|
|
|
|
await git.add('./*')
|
|
await git.commit(commitMessage)
|
|
await git.push('origin')
|
|
|
|
return fileHash
|
|
}
|
|
|
|
async function getPostText(userProfileHandle, postHash, timestamp) {
|
|
/*
|
|
When the Web App makes a query that includes Post text as responses,
|
|
we need to fetch the text from the public git repositories, since
|
|
the Network Nodes do not store that info themselves, they just
|
|
store the structure of the social graph.
|
|
*/
|
|
let promise = new Promise((resolve, reject) => {
|
|
|
|
const fileName = postHash + ".json"
|
|
const filePath = 'My-Social-Trading-Data/main/User-Posts/' + SA.projects.foundations.utilities.filesAndDirectories.pathFromDate(timestamp)
|
|
|
|
const fetch = SA.nodeModules.nodeFetch
|
|
let url = 'https://raw.githubusercontent.com/' + userProfileHandle + '/' + filePath + '/' + fileName
|
|
|
|
fetch(url)
|
|
.then((response) => {
|
|
|
|
if (response.status != 200) {
|
|
reject('Github.com responded with status ' + response.status)
|
|
return
|
|
}
|
|
|
|
response.text().then(body => {
|
|
post = JSON.parse(body)
|
|
resolve(post.postText)
|
|
})
|
|
})
|
|
.catch(err => {
|
|
resolve('Post Text could not be fetched. ' + err.message)
|
|
})
|
|
|
|
}
|
|
)
|
|
|
|
return promise
|
|
}
|
|
} |