corrade-group-linguistics – Blame information for rev 2

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 #!/usr/bin/env nodejs
2 ///////////////////////////////////////////////////////////////////////////
3 // Copyright (C) 2019 Wizardry and Steamworks - License: CC BY 2.0 //
4 ///////////////////////////////////////////////////////////////////////////
5  
6 const mqtt = require('mqtt')
7 const YAML = require('yamljs')
8 const { createLogger, format, transports } = require('winston')
9 const path = require('path')
10 const fs = require('fs')
11 const Sentiment = require('sentiment')
12 const db = require('quick.db')
13 const qs = require('qs')
14 const lambda = require('was.js').lambda
15  
16 // Create a new sentiment analyzer.
17 const sentiment = new Sentiment();
18  
19 // Load configuration file.
20 const config = YAML.load('config.yml')
21  
22 // Set up logger.
23 const logger = createLogger({
24 format: format.combine(
25 format.splat(),
26 format.simple()
27 ),
28 transports: [
29 new transports.Console({
30 timestamp: true
31 }),
32 new transports.File(
33 {
34 timestamp: true,
35 filename: path.join(path.dirname(fs.realpathSync(__filename)), "log/project.log")
36 }
37 )
38 ]
39 })
40  
41 // Subscribe to Corrade MQTT.
42 const mqttClient = mqtt.connect(config.corrade.mqtt)
43  
44 mqttClient.on('reconnect', () => {
45 logger.info('Reconnecting to Corrade MQTT server...')
46 })
47  
48 mqttClient.on('connect', () => {
49 logger.info('Connected to Corrade MQTT server.')
50 // Subscribe to group message notifications with group name and password.
51 mqttClient.subscribe(`${config.corrade.group}/${config.corrade.password}/group`, (error) => {
52 if (error) {
53 logger.info('Error subscribing to Corrade MQTT group messages.')
54 return
55 }
56  
57 logger.info('Subscribed to Corrade MQTT group messages.')
58 })
59 })
60  
61 mqttClient.on('error', (error) => {
62 logger.error(`Error found while connecting to Corrade MQTT: ${error}`)
63 })
64  
65 mqttClient.on('message', (topic, message) => {
66 let notification = qs.parse(message.toString())
67  
68 // Check the notification parameters for sanity.
69 if (notification.type !== 'group')
70 return
71  
72 // Lambda switch @ WaS!
73 lambda.switch(
74 notification.message.split(' ')[0],
75 (execute) => exeUpdate(notification),
76 (execute) => execute === config.sentiment.commands.tokens,
77 (execute) => exeTokens(notification),
78 (execute) => execute === config.sentiment.commands.sentiment,
79 (execute) => exeQuery(notification)
80 )
81 })
82  
83 /* Performs message analysis and updates the database. */
84 function exeUpdate(notification) {
85 const result = sentiment.analyze(notification.message)
86  
87 db.add(`group.${notification.group.toUpperCase()}.${notification.firstname.toUpperCase()} ${notification.lastname.toUpperCase()}.tokens.total`, result.tokens.length)
88 db.add(`group.${notification.group.toUpperCase()}.${notification.firstname.toUpperCase()} ${notification.lastname.toUpperCase()}.sentiment.score`, result.comparative)
89  
90 db.add(`group.${notification.group.toUpperCase()}.tokens.total`, result.tokens.length)
91 db.add(`group.${notification.group.toUpperCase()}.sentiment.score`, result.comparative)
92 }
93  
94 /* Returns a cumulative sentiment for either a single avatar or for an entire group. */
95 function exeQuery(notification) {
96 const command = notification.message.split(' ')
97  
98 const reply = 1 in command && 2 in command ?
99 `${command[1]} ${command[2]}'s overall sentiment: ${db.get(`group.${notification.group.toUpperCase()}.${command[1].toUpperCase()} ${command[2].toUpperCase()}.sentiment.score`)}` :
100 `Overall group sentiment: ${db.get(`group.${notification.group.toUpperCase()}.sentiment.score`)}`
101  
102 // Build the tell command.
103 const corradeCommand = qs.stringify({
104 'command': 'tell',
105 'group': config.corrade.group,
106 'password': config.corrade.password,
107 'entity': 'group',
108 'message': reply
109 })
110  
111 mqttClient.publish(`${config.corrade.group}/${config.corrade.password}/group`, corradeCommand)
112 return true
113 }
114  
115 /* Returns counted tokens for either a single avatar or for an entire group. */
116 function exeTokens(notification) {
117 const command = notification.message.split(' ')
118  
119 const reply = 1 in command && 2 in command ?
120 `${command[1]} ${command[2]}'s uttered a total number of tokens: ${db.get(`group.${notification.group.toUpperCase()}.${command[1].toUpperCase()} ${command[2].toUpperCase()}.tokens.total`)}` :
121 `Tokens uttered in this group: ${db.get(`group.${notification.group.toUpperCase()}.tokens.total`)}`
122  
123 // Build the tell command.
124 const corradeCommand = qs.stringify({
125 'command': 'tell',
126 'group': config.corrade.group,
127 'password': config.corrade.password,
128 'entity': 'group',
129 'message': reply
130 })
131  
132 mqttClient.publish(`${config.corrade.group}/${config.corrade.password}/group`, corradeCommand)
133  
134 return true
135 }