-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
166 lines (148 loc) · 6.12 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
* Plugin dependencies.
*
* @type {exports}
*/
var metaInspector = require('node-metainspector');
var moment = require('moment');
var _ = require('lodash');
/**
* URL log plugin for UniBot
*
* @param {Object} options Plugin options object, description below.
* db: {mongoose} the mongodb connection
* bot: {irc} the irc bot
* web: {connect} a connect + connect-rest webserver
* config: {object} UniBot configuration
*
* @return {Function} Init function to access shared resources
*/
module.exports = function init(options) {
var mongoose = options.db;
var webserver = options.web;
var config = options.config;
// Specify database schema for plugin
var Urls = new mongoose.Schema({
channel: {
type: String, // channel._id
index: {
unique: true,
dropDups: false
}
},
urls: {
type: mongoose.Schema.Types.Mixed,
default: []
}
});
var model = mongoose.model('Urls', Urls);
/**
* Default plugin configuration. These can be override on your UniBot config.js file, just add 'urllog' section to
* your plugin section.
*
* @type {{
* dateFormat: string,
* oldMessage: string
* }}
*/
var pluginConfig = {
"dateFormat": "D.M.YYYY HH:mm:ss",
"oldMessage": "${nick}: Old link!!1! ${existUrl.from} told this already ${formattedDate}"
};
// Merge configuration for plugin
if (_.isObject(config.plugins) && _.isObject(config.plugins.urllog)) {
pluginConfig = _.merge(pluginConfig, config.plugins.urllog);
}
/**
* Getter method for plugin template for UniBot frontend.
*
* @param {Request} req Request object
* @param {Response} res Response object
* @param {Function} next Callback function
*/
webserver.get('/urllog', function getTemplate(req, res, next) {
res.sendFile(__dirname + '/index.html');
});
/**
* Getter method for URL log data for UniBot frontend.
*
* @param {Request} req Request object
* @param {Response} res Response object
* @param {Function} next Callback function
*/
webserver.get('/urllog/:channel', function getData(req, res, next) {
model.findOne({ channel: req.params.channel }, function callback(error, logs) {
res.send(error || logs);
});
});
/**
* Actual UniBot URL log plugin. This will match all URLs from IRC channel and stores those to database for later
* usage. Plugin specified regex will match "any real url" on channel messages.
*
* If URL has been already stored to database plugin will inform that user about that.
*/
return function plugin(channel){
var urls = [];
// Initial of URL log store
model.findOne({ channel: channel.id }, function callback(error, _urls_) {
if (error || !_urls_) {
urls = new model({
channel: channel.id
});
urls.save();
} else {
urls = _urls_;
}
});
// Plugin regexp
return {
"[.*]?((?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:/\\S*)?)[\\s+]?(.*)?": function onMatch(from, matches) {
var url = matches[1];
var description = matches[2];
var client = new metaInspector(url, { limit: 500000 });
// Find "same" URL from database
model.findOne({channel: channel.id, 'urls.url': url}, function callback(error, _url) {
if (error) {
channel.say(from, 'Oh noes, error: ' + error);
} else if (_url) { // URL founded => notify user if he/she is not same as first person who sent URL
// Specify used template variables
var templateVars = {
url: url,
nick: from,
title: client.title,
formattedDate: moment(_url.urls[0].timestamp).format(pluginConfig.dateFormat),
existUrl: _url.urls[0]
};
if (_url.urls[0].from !== from) {
channel.say(_.template(pluginConfig.oldMessage, templateVars));
}
} else {
client.on('fetch', function onFetch() {
var title = client.title.replace(/^\s+|\s+$/gm,'').replace(/\n|\r/g, '');
var data = {
url: url,
description: description,
title: title,
from: from,
timestamp: Date.now()
};
urls.urls.push(data);
urls.markModified('urls');
urls.save();
// If URL has "real" title say that on channel
if (title) {
channel.say(title);
}
});
// Error occurred while fetching URL contents
client.on('error', function onError(error) {
channel.say(from, 'Oh noes, error: ' + error);
});
// Fetch URL data
client.fetch();
}
});
}
};
};
};