Compare commits

...

27 Commits

Author SHA1 Message Date
f319252ae8
fix weather tests 2018-09-15 13:29:13 +02:00
1f2e32aa79
update yarn lock 2018-09-15 13:21:07 +02:00
b4c8c0160b
update gitignore 2018-09-15 13:20:54 +02:00
4934996654
improve weather regex 2018-09-15 13:19:43 +02:00
77027c1478
add yarn lock file 2018-06-21 03:30:45 +02:00
f000022189
add html report for integrity tests 2018-06-21 03:30:24 +02:00
68f56ede58
switch to nyc and rewrite coverage module 2018-06-21 01:10:22 +02:00
3f307b5257
update all dependencies 2018-06-20 20:13:28 +02:00
c93c217a94
switch to yarn 2018-06-20 20:12:48 +02:00
dfe44218c0
only match whole words on "assa?" 2018-06-12 13:42:51 +00:00
880319e035
separate api and git url 2018-06-11 23:50:40 +00:00
5fdb274023
add nix expression 2018-06-11 23:28:38 +00:00
ec09b5f00b github -> gogs 2018-06-12 01:27:02 +02:00
2210914740 tweak graphicsmagick parameters 2018-02-07 13:40:23 +01:00
875a1b6eeb add deepfry script 2018-02-07 00:15:51 +01:00
rnhmjoj
5f714392ea remove interjection 2017-04-28 19:21:34 +02:00
rnhmjoj
3afb1d991d Revert "Removed stale meme"
This reverts commit 076d50baa4.
2017-04-28 19:15:00 +02:00
Michele Guerini Rocco
fc338804f9 Merge pull request #29 from adolfintel/master
Removed stale meme
2017-04-27 21:17:50 +02:00
d73e85c04d Removed stale meme 2017-04-27 20:52:46 +02:00
rnhmjoj
a8649de6b3 update github test 2017-02-27 15:45:25 +01:00
rnhmjoj
142e9bded4 update github repo information 2017-02-27 15:35:53 +01:00
rnhmjoj
00cd51fbf5 update readme for matrix 2017-02-27 01:14:54 +01:00
rnhmjoj
c3069755c2 remove quotes 2017-02-27 00:28:36 +01:00
rnhmjoj
13890a8aac move asjon-testing 2017-02-27 00:27:39 +01:00
rnhmjoj
b3c706e116 use my fork of hubot-matrix 2017-02-27 00:26:51 +01:00
rnhmjoj
d987119035 update doge script for matrix 2017-02-26 17:28:29 +01:00
Michele Guerini Rocco
89594cbb03 Merge pull request #28 from rnhmjoj/matrix
Matrix
2017-02-25 19:05:24 +01:00
30 changed files with 3186 additions and 3372 deletions

4
.gitignore vendored
View File

@ -1,5 +1,5 @@
node_modules node_modules
.hubot_history .hubot_history
.nyc_output
matrix-data matrix-data
config/ report
coverage/

View File

@ -11,7 +11,7 @@ Asjon può:
- creare memes - creare memes
- fare calcoli e risolvere problemi con wolfram|alpha - fare calcoli e risolvere problemi con wolfram|alpha
- inviare immagini di [RMS](https://en.wikipedia.org/wiki/Richard_Stallman) - inviare immagini di [RMS](https://en.wikipedia.org/wiki/Richard_Stallman)
- invitare persone in un gruppo di telegram - invitare persone in una stanza
- dare informazioni sui propri contatti - dare informazioni sui propri contatti
- aprire [reverse shell](http://unix.stackexchange.com/q/46235) - aprire [reverse shell](http://unix.stackexchange.com/q/46235)
- aggiornarsi ed eseguire test autonomamente - aggiornarsi ed eseguire test autonomamente
@ -24,7 +24,7 @@ dell'IIS Galileo Galilei di Crema.
## Usare Asjon ## Usare Asjon
Asjon è sempre online su Telegram con l'username `Asjon ROBOT` Asjon è sempre online su [matrix](https://matrix.org/) con l'username `@asjon:maxwell.ydns.eu`
## Sviluppare Asjon ## Sviluppare Asjon
@ -36,9 +36,9 @@ correttamente (ad esempio i dati di accesso al registro elettronico per l'agenda
Asjon necessita di: Asjon necessita di:
- `node` e `npm` - `node` e `yarn`
- `redis` se si vuole salvare la sua memoria in maniera persistente - `redis` se si vuole salvare la sua memoria in maniera persistente
- `telegram-cli` con supporto python per l'adapter di telegram - `graphicsmagick` per la compressione delle immagini
### Installazione ### Installazione
@ -50,18 +50,18 @@ eseguendo
nella directory. Nella nuova shell installare asjon con nella directory. Nella nuova shell installare asjon con
$ npm install $ yarn install
### Utilizzo ### Utilizzo
Puoi avviare asjon tramite `nix-shell` con Puoi avviare asjon tramite `nix-shell` con
$ nix-shell --arg mode \"run\" $ nix-shell --argstr mode run
Altre `mode` possibili sono: Altre `mode` possibili sono:
* `runTg`: avvia asjon sull'adapter di telegram (è necessario fare il login al primo utilizzo) * `run`: avvia asjon sull'adapter di maxwell (è necessario impostare user/pass con le rispettie variabili)
* `test`: esegui i test d'integrità * `test`: esegui i test d'integrità
* `shell` (default): apre una nix-shell * `shell` (default): apre una nix-shell
@ -82,9 +82,9 @@ Asjon dispone di alcuni test d'integrità nella cartella `test/`.
Per eseguirli, occorre: Per eseguirli, occorre:
1. installare [mocha](http://mochajs.org) tramite `npm install -g mocha` (potrebbe essere necessario sudo) 1. installare [mocha](http://mochajs.org) tramite `yarn global add mocha`
1. lanciare i test tramite `npm test` dalla cartella della repo 1. lanciare i test tramite `yarn test` dalla cartella della repo
1. opzionalmente è possibile generare i report di copertura dei test usando `npm run coverage-html` o `npm run coverage-json` in base al formato desiderato. 1. opzionalmente è possibile generare i report di copertura dei test usando `yarn coverage`.
__Nota Bene:__ è opportuno __eseguire sempre i test d'integrità prima di contribuire una modifica__. Ancora meglio sarebbe __Nota Bene:__ è opportuno __eseguire sempre i test d'integrità prima di contribuire una modifica__. Ancora meglio sarebbe
allegare dei test di integrità insieme alle nuove funzioni aggiunte allegare dei test di integrità insieme alle nuove funzioni aggiunte
@ -100,8 +100,8 @@ La [Scripting Guide](scripting-docs) di hubot è molto utile per imparare come f
Asjon può essere hostato come un qualsiasi Hubot. Asjon può essere hostato come un qualsiasi Hubot.
Il ramo `master` di Asjon è sempre hostato online ed è accessibile tramite telegram all'username Il ramo `master` di Asjon è sempre hostato online ed è accessibile tramite matrix all'username
Asjon ROBOT. `@asjon:maxwell.ydns.eu`.
## Licenza ## Licenza

View File

@ -3,4 +3,4 @@ set -e
export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH" export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"
export DEBUG=nightmare export DEBUG=nightmare
node_modules/.bin/hubot --name "asjon" --alias "assa" "$@" node_modules/.bin/hubot --name asjon --alias assa "$@"

View File

@ -3,41 +3,57 @@
"version": "1.8.0", "version": "1.8.0",
"private": true, "private": true,
"author": "Enrico Fasoli <fazius2009@gmail.com>", "author": "Enrico Fasoli <fazius2009@gmail.com>",
"description": "Il miglior amico della 5IA", "description": "our local chat bot",
"dependencies": { "dependencies": {
"async": "^1.4.2", "async": "^2.6.1",
"chai": "^2.3.0", "chai": "^4.1.2",
"cheerio": "^0.19.0", "cheerio": "^1.0.0-rc.2",
"coffee-coverage": "^0.4.6", "coffeescript": "^1.9.2",
"coffee-script": "^1.9.2", "fast-levenshtein": "^2.0.6",
"fast-levenshtein": "^1.0.6", "mocha": "^5.2.0",
"github": "^0.2.4", "mochawesome": "^3.0.1",
"hubot": "^2.12.0", "mock-fs": "^4.5.0",
"nyc": "^13.0.0",
"moment": "^2.22.2",
"needle": "^2.2.1",
"nock": "^9.3.3",
"valid-url": "^1.0.9",
"hubot": "^2.19.0",
"hubot-bitcoin": "^1.0.3", "hubot-bitcoin": "^1.0.3",
"hubot-diagnostics": "0.0.1", "hubot-diagnostics": "0.0.2",
"hubot-google-images": "^0.1.4", "hubot-google-images": "^0.2.7",
"hubot-google-translate": "^0.1.0", "hubot-google-translate": "^0.2.1",
"hubot-help": "^0.1.1", "hubot-help": "^0.2.2",
"hubot-heroku-keepalive": "0.0.4", "hubot-heroku-keepalive": "1.0.3",
"hubot-maps": "0.0.2", "hubot-maps": "0.0.3",
"hubot-mock-adapter": "^1.0.0", "hubot-mock-adapter": "^1.0.0",
"hubot-pugme": "^0.1.0", "hubot-pugme": "^0.1.1",
"hubot-redis-brain": "0.0.2", "hubot-redis-brain": "0.0.4",
"hubot-rules": "^0.1.0", "hubot-rules": "^0.1.2",
"hubot-scripts": "^2.5.16", "hubot-scripts": "^2.17.2",
"hubot-shipit": "^0.2.0", "hubot-shipit": "^0.2.1",
"hubot-tg": "davidar/hubot-matrix", "hubot-matrix": "git+https://maxwell.ydns.eu/git/rnhmjoj/hubot-matrix.git",
"hubot-youtube": "^0.1.2", "hubot-youtube": "^1.1.0"
"mocha": "^3.2.0",
"moment": "^2.10.2",
"needle": "^0.10.0",
"nock": "^1.7.1",
"valid-url": "^1.0.9"
}, },
"scripts": { "scripts": {
"coverage-html": "mkdir -p coverage && mocha test/ --require coffee-coverage/register --compilers coffee:coffee-script/register -R html-cov scripts/ > coverage/coverage.html", "test": "nyc mocha; true"
"coverage-json": "mkdir -p coverage && mocha test/ --require coffee-coverage/register --compilers coffee:coffee-script/register -R json-cov scripts/ > coverage/coverage.json", },
"test": "mocha test/ --compilers coffee:coffee-script/register" "nyc": {
"include": [
"scripts/*.coffee"
],
"extension": [ ".coffee" ],
"require": [
"coffeescript/register"
],
"reporter": [
"json-summary",
"html"
],
"report-dir": "report/coverage",
"sourceMap": true,
"instrument": true,
"cache": true
}, },
"engines": { "engines": {
"node": "0.10.x" "node": "0.10.x"

45
scripts/coverage.coffee Normal file
View File

@ -0,0 +1,45 @@
# Description:
# shows integrity tests coverage
#
# Dependencies:
# None
#
# Configuration:
# None
#
# Commands:
# hubot (mostrami la) copertura (dei test)
#
# Author:
# Enrico Fasoli (fazo96)
moment = require 'moment'
path = require 'path'
fs = require 'fs'
module.exports = (robot) ->
robot.respond /(?:mostrami la )?(?:copertura|coverage)(?: dei test)?/i, (res) ->
url = 'https://maxwell.ydns.eu/asjon/report/coverage'
file = 'report/coverage/coverage-summary.json'
try
report = JSON.parse (fs.readFileSync file, 'utf8')
catch err
if err.code is 'ENOENT'
return res.send 'report non disponibile. forse \
non è ancora stato generato?'
else
return res.send "errore nel leggere il report:\n#{err}"
files = []
for name, file of report
if name isnt "total"
files.push "- #{path.basename name} is covered at #{file.lines.pct}%"
res.send """
=== Coverage: #{report.total.lines.pct}%
#{files.join '\n'}
HTML report: #{url}
JSON report: #{url}/coverage-summary.json
"""

94
scripts/deepfry.coffee Normal file
View File

@ -0,0 +1,94 @@
# Description:
# deep fry an image
#
# Commands:
# hubot deepfry/friggi[mi] <url>
#
# Dependencies:
# "async": "^1.4.2",
# "hubot-matrix": "rnhmjoj/hubot-matrix",
# "needle": "^0.10.0",
#
# Configuration:
# None
#
# Author:
# Michele Guerini Rocco (rnhmjoj)
ne = require 'needle'
async = require 'async'
gm = require 'gm'
url = require 'url'
module.exports = (robot) ->
# utilities
concat = (x) -> [].concat.apply([], x)
init = (x) -> (f) -> f(null, x)
times = (n, x) -> x for i in [1..n]
rand = (min, max) -> Math.random() * (max - min) + min
# effects
compress = (image, callback) ->
gm(image)
.noProfile()
.noise('uniform')
.quality(rand(30,80))
.noise('uniform')
.toBuffer callback
resize = (image, callback) ->
gm(image)
.scale('95%')
.scale('105%')
.toBuffer callback
colorize = (image, callback) ->
gm(image)
.modulate(rand(100,110), rand(100,150))
.toBuffer callback
deepFry = (res, image) ->
script = concat [
init(image),
resize,
colorize
times(50, compress),
]
async.waterfall script, (err, image) ->
if err?
robot.logger.warning "frying failed:\n#{err}"
return res.send 'scusa, si è rotta la friggitrice.'
# send image
robot.logger.info 'image fried successfully'
robot.adapter.sendImage
room: res.message.room
, image, 'fried.jpeg', ->
res.reply res.random [ 'meme fritto per te.', 'eccoti servito.']
robot.respond /(?:deepfry|friggi(?:mi)?) (questo|.+)/i, (res) ->
if not url.parse(res.match[1]).hostname
return res.send res.random [ 'non si usa così.', 'è un url questo?', 'cosa?' ]
imageURL = res.match[1]
# supported image mime types
accepted = ['image/jpeg', 'image/png', 'image/tiff']
# fetch headers
ne.head imageURL, follow_max: 5, (err, re) ->
if err?
robot.logger.warning "headers download failed:\n#{err}"
return res.send 'non riesco ad aprire il link.'
mimetype = re.headers['content-type'].split(';')[0]
if not (mimetype in accepted)
robot.logger.info 'url is not an image'
return res.send "non è un'immagine questo!"
# download and process
robot.logger.info 'downloading image...'
ne.get imageURL, follow_max: 5, (err, re, body) ->
robot.logger.info 'image downloaded'
deepFry res, body

View File

@ -1,6 +1,6 @@
# Description: # Description:
# Doge meme generator # Doge meme generator
# Requires hubot-tg adapter to access message history # Requires hubot-matrix adapter to access history
# #
# Configuration: # Configuration:
# Uses hubot-tg enviroment variables # Uses hubot-tg enviroment variables
@ -13,55 +13,55 @@
# #
net = require 'net'
module.exports = (robot) -> module.exports = (robot) ->
match_all = (regex, str) -> matrix = robot.adapter.client
matches = [] return unless robot.adapterName is 'matrix' and matrix?
str.replace regex, ->
arr = [].slice.call arguments, 0
extras = arr.splice -2
arr.index = extras[0]
arr.input = extras[1]
matches.push arr
matches
# get the messages history for a chat room
get_history = (room, size, callback) ->
room = matrix.getRoom room.id
matrix.scrollback room, size, (err, res) ->
return callback err, null if err?
return unless res.chunk?
callback null, res.chunk.map (event) ->
type: event.content.msgtype
sender: robot.brain.userForId event.sender
content: event.content.body
# concat list of lists
concat = (list) -> list.reduce (x, y) -> x.concat y concat = (list) -> list.reduce (x, y) -> x.concat y
# remove duplicates in a list
nub = (list) -> Array.from new Set list
# URL escape strings
escape = (str) -> escape = (str) ->
str.replace(/\d|\?|#/g, '') # not supported str.replace(/\d|\?|#/g, '') # not supported
.replace( /\ /g, '%20') # spaces .replace( /\ /g, '%20') # spaces
# format doge API URL
doge_url = (text) -> doge_url = (text) ->
"http://dogr.io/#{escape text}.png?split=false" "http://dogr.io/#{escape text}.png?split=false"
shiba = (res, words) -> # dogeify text
doge = (res, words) ->
prefix = [ 'much', 'such', 'many', 'very'] prefix = [ 'much', 'such', 'many', 'very']
word = words.filter (x) -> word = words.filter (x) ->
/^[a-zA-ZàèéìòùÀÈÉÌÒÙ\-_!&@#?]{4,}$/.test x /^[a-zA-ZàèéìòùÀÈÉÌÒÙ\-_!&@#?]{4,}$/.test x
(res.random prefix) + ' ' + (res.random words) (res.random prefix) + ' ' + (res.random words)
run_command = (command, callback) ->
client = net.connect robot.adapter.port, robot.adapter.host, ->
client.write command+'\n'
client.setEncoding 'utf8'
client.on 'data', (reply) ->
if callback?
callback (reply.split '\n')[1..-3]
client.end()
get_history = (chat, size, callback) ->
regex = /\[(.+)\] (.+) [>«»]+ ((?:(?!\n(\[|\d))[\s\S])+)/g
parse_line = (x) ->
date: x[1]
peer: x[2].replace(chat, '').trim()
text: x[3].trim().replace '\n', ' '
run_command "history #{chat} #{size}", (lines) ->
callback ((match_all regex, lines.join '\n').map parse_line)
robot.respond /doge(?: (\d+))?/, (res) -> robot.respond /doge(?: (\d+))?/, (res) ->
n = res.match[1] || 20 n = res.match[1] || 10
get_history res.message.room, n, (history) -> get_history res.message.room, n, (err, history) ->
words = concat (message.text.split ' ' for message in history) return res.send "c'è stato un errore: #{err}" if err?
sample = (res.random ['wow', shiba res, words] for _ in [0..8])
res.send (doge_url sample.join '/') words = ((nub concat (history.filter (msg) ->
msg.type is 'm.text').map (msg) ->
msg.content.split /\W/).sort (a, b) ->
b.length - a.length).slice 0, 50
sample = [0..15].map ->
if Math.random() <= 0.2 then 'wow'
else doge res, words
res.send doge_url sample.join '/'

View File

@ -1,37 +0,0 @@
# Description:
# integrazione con drone.io e funzioni annesse
#
# Dependencies:
# None
#
# Configuration:
# None
#
# Commands:
# hubot (mostrami la) copertura (dei test)
#
# Author:
# Enrico Fasoli (fazo96)
moment = require 'moment'
module.exports = (robot) ->
robot.respond /(?:mostrami la )?(?:copertura|coverage)(?: dei test)?/i, (res) ->
url = 'https://drone.io/github.com/fazo96/asjon/files/coverage/coverage.'
robot.http(url+'json')
.get() (err, resp, body) ->
try
report = JSON.parse body
catch e
if /^404/g.test body
return res.send 'Coverage report non disponibile (404) forse \
non è ancora stato generato?'
return res.send 'Errore: '+e+'\n\nRisposta del server: '+body
unless report?.files?.push? and report?.coverage?.toFixed?
return res.send 'Errore: informazioni insufficienti'
t = '=== Coverage: ' + report.coverage.toFixed(0) + '%'
t += report.files.map (f) ->
'\n - ' + f.filename + ' is covered at ' + f.coverage.toFixed(0) + '%'
t += '\nHTML report: '+url+'html'
t += '\nJSON report: '+url+'json'
res.send t

69
scripts/git.coffee Normal file
View File

@ -0,0 +1,69 @@
# Description:
# interazioni tra asjon e git
#
# Dependencies:
# None
#
# Configuration:
# HUBOT_GIT_URL - git server url
# HUBOT_GIT_API - git server API url
# HUBOT_GIT_TOKEN - Gogs v1 or GitHub v3 API token
# HUBOT_GIT_REPO - repository name (owner/repo)
#
# Commands:
# asjon mostra le issue - mostra le issue aperte su rnhmjoj/asjon
#
# Author:
# Enrico Fasoli (fazo96)
# Michele Guerini Rocco (rnhmjoj)
module.exports = (robot) ->
githook = (req, res) ->
res.send 200
dest = name: req.params.name, room: id: req.params.room
robot.emit 'githook', req.body, req.params
s = "branch #{req.body.ref} aggiornato!\n"
cm = req.body.commits.map (c) ->
[c.committer.username, c.message].join ' -> '
robot.send dest, s + cm.join '\n'
unless process.env.TESTING_ASJON
# Disabilito http route durante i test
robot.router.post '/hubot/githook/:room/:name?', githook
robot.respond /(?:(?:mostra(?:mi)?|fammi vedere) )?(?:le )?issue(?:s)?/i, (res) ->
msg = state: 'open', user: 'rnhmjoj', repo: 'asjon', sort: 'updated'
res.send 'controllo issues...'
url = process.env.HUBOT_GIT_API
repo = process.env.HUBOT_GIT_REPO
token = process.env.HUBOT_GIT_TOKEN
if not token
return res.send 'non ho il token per la repo'
robot.http("#{url}/repos/#{repo}/issues?state=open&sort=updated")
.header('Authorization', 'token '+token)
.get() (err, r, body) ->
if err then return res.send err
data = JSON.parse body
if data.length is 0 then return res.send '0 issues'
r = data.map (i) ->
labels = i.labels.map((x) -> x.name).join ', '
if labels is '' then labels = 'nessuno'
["#"+i.number,i.title,"By: "+i.user.login,'Tags: '+labels].join(' | ')
res.send r.join '\n'
robot.respond /linkami (?:la )?issue (?:(?:n(?:°)?(?: )?)|numero )?(\d+)/i, (res) ->
url = process.env.HUBOT_GIT_URL
repo = process.env.HUBOT_GIT_REPO
base = "#{url}/#{repo}/issues/"
res.send base+res.match[1]
robot.respond /linkami (?:la )?repo (\w+\/\w+)/i, (res) ->
url = process.env.HUBOT_GIT_URL
res.send "#{url}/#{res.match[1]}/"
# rendo l'handler dell'hook di git accessibile
# in caso serve (nei test)
return githook

View File

@ -1,52 +0,0 @@
# Description:
# interazioni tra asjon e github
#
# Requires:
# "github": "0.2.4"
#
# Commands:
# asjon mostra le issue - mostra le issue aperte su fazo96/asjon
#
# Author:
# Enrico Fasoli (fazo96)
GitHubAPI = require 'github'
github = new GitHubAPI version: '3.0.0'
module.exports = (robot) ->
githubhook = (req, res) ->
res.send 200
dest = name: req.params.name, room: req.params.room.replace(':','#')
robot.emit 'githubhook', req.body, req.params
s = 'Branch '+req.body.ref+' aggiornato!\n'
cm = req.body.commits.map (c) ->
[c.committer.username,c.message].join ' -> '
robot.send dest, s+cm.join('\n')
unless process.env.TESTING_ASJON
# Disabilito http route durante i test
robot.router.post '/hubot/githubhook/:room/:name?', githubhook
robot.respond /(?:(?:mostra(?:mi)?|fammi vedere) )?(?:le )?issue(?:s)?/i, (res) ->
msg = state: 'open', user: 'fazo96', repo: 'asjon', sort: 'updated'
res.send 'controllo issues...'
github.issues.repoIssues msg, (err,data) ->
if err then return res.send err
if data.length is 0 then return res.send '0 issues'
r = data.map (i) ->
labels = i.labels.map((x) -> x.name).join ', '
if labels is '' then labels = 'nessuno'
["#"+i.number,i.title,"By: "+i.user.login,'Tags: '+labels].join(' | ')
res.send r.join '\n'
robot.respond /linkami (?:la )?issue (?:(?:n(?:°)?(?: )?)|numero )?(\d+)/i, (res) ->
base = 'http://github.com/fazo96/asjon/issues/'
res.send base+res.match[1]
robot.respond /linkami (?:la )?repo (\w+\/\w+)/i, (res) ->
res.send 'https://github.com/'+res.match[1]
# rendo l'handler dell'hook di github accessibile
# in caso serve (nei test)
return githubhook

View File

@ -1,68 +0,0 @@
# Description:
# What you are referring to is actually GNU + Linux....
#
# Configuration:
# None
#
# Author:
# Enrico Fasoli (fazo96)
image1 = 'https://lut.im/trSfl2cdfX/TDIkX3SjLhKJ2qm5.jpg'
image2 = 'https://lut.im/PLRw8AxYlI/UYH3pv7MWkROQ2BW.jpg'
song = 'https://www.youtube.com/watch?v=9sJUDx7iEJw'
interjection = "
Id just like to interject for a moment. What youre referring to as Linux, is
in fact, GNU/Linux, or as Ive recently taken to calling it, GNU plus Linux.
Linux is not an operating system unto itself, but rather another free component
of a fully functioning GNU system made useful by the GNU corelibs, shell
utilities and vital system components comprising a full OS as defined by POSIX.
Many computer users run a modified version of the GNU system every day, without
realizing it. Through a peculiar turn of events, the version of GNU which is
widely used today is often called Linux, and many of its users are not aware
that it is basically the GNU system, developed by the GNU Project.
There really is a Linux, and these people are using it, but it is just a part of
the system they use. Linux is the kernel: the program in the system that
allocates the machines resources to the other programs that you run. The kernel
is an essential part of an operating system, but useless by itself; it can only
function in the context of a complete operating system. Linux is normally used
in combination with the GNU operating system: the whole system is basically GNU
with Linux added, or GNU/Linux. All the so-called Linux distributions are
really distributions of GNU/Linux.
"
interjection_es = "
Me gustaría interponer por un sólo momento. Lo que usted se refiere como Linux,
es, de hecho, GNU/Linux, o como recientemente yo he empezado a llamar, GNU plus
Linux. Linux no es un sistema operativo en mismo, sino más bien otro
componente libre de un sistema GNU enteramente functional, hacho útil por los
GNU corelibs, utilidades de shell y los componentes vitales del sistema que
comprende un sistema operativo completo según lo definido por POSIX.
Muchos usuarios de computadoras ejecutan una versión modificada del sistema GNU
todos los días, sin darse cuenta. A través de un giro peculiar de eventos, la
versión de GNU, que es ampliamente utilizado hoy en día es a menudo llamado
Linux, y muchos de sus usuarios no son conscientes de que es básicamente el
sistema GNU, desarrollado por el proyecto GNU.
Realmente hay un Linux, y estas personas lo están utilizando, pero es sólo una
parte del sistema que utilizan. Linux es el núcleo: el programa en el sistema
que asigna los recursos de la máquina a los otros programas que se ejecutan.
El núcleo es una parte esencial de un sistema operativo, pero inútil por
mismo; sólo puede funcionar en el contexto de un sistema operativo completo.
Linux se utiliza normalmente en combinación con el sistema operativo GNU:
todo el sistema es básicamente GNU con Linux agregado, o GNU/Linux. Todas las
llamadas distribuciones de Linux son realmente distribuciones de GNU/Linux.
"
module.exports = (robot) ->
robot.hear /linux/i, (res) ->
s = res.message.text
if not s.match /(GNU ?[+\/])|(kernel )Linux/i
if Math.random() < 0.1
res.send image2, interjection_es, song
else
res.send image1, interjection

View File

@ -16,7 +16,7 @@
moment = require 'moment' moment = require 'moment'
regex = /(?:(?:d(?:a|i)mmi il )?meteo(?: per (.+))?|che tempo (?:fa|c'è)(?: (?:a|in) (.+))?)\??$/i regex = /(?:(?:(?:(?:mi (?:dici|dai)|dammi) (?:il (?:tempo|meteo)|(?:le previsioni)))(?: ?(?:(?:per ?(?:(?:l')|il |lo |la |i |gli |le )?)|di |a ))?|(?:che tempo (?:fa|(?:c'?(?:è|e|e')))(?: ?(?:in|a) )?))|meteo)([^?!]+)?.*$/i
url1 = 'http://ip-api.com/json/' url1 = 'http://ip-api.com/json/'
url2 = 'http://api.openweathermap.org/data/2.5/weather?lang=it&units=metric' url2 = 'http://api.openweathermap.org/data/2.5/weather?lang=it&units=metric'
@ -64,7 +64,7 @@ module.exports = (robot) ->
tramonto alle #{dusk}" tramonto alle #{dusk}"
robot.respond regex, (res) -> robot.respond regex, (res) ->
city = res.match[1] || res.match[2] city = res.match[1]
if city? if city?
get_weather city, send_weather res get_weather city, send_weather res
else else

View File

@ -124,5 +124,5 @@ module.exports = (robot) ->
robot.respond /ci sei\?/i, (res) -> robot.respond /ci sei\?/i, (res) ->
res.send res.random confirm res.send res.random confirm
robot.hear /assa\?/, (res) -> robot.hear /\bassa\?/, (res) ->
res.send res.random confirm res.send res.random confirm

View File

@ -5,7 +5,7 @@
# None # None
# #
# Commands: # Commands:
# asjon run/esegui/shell git/npm args... # asjon run/esegui/shell git/yarn args...
# #
# Author: # Author:
# Enrico Fasoli (fazo96) # Enrico Fasoli (fazo96)
@ -41,7 +41,7 @@ module.exports = (robot) ->
if process.env.AUTO_RUN_TESTS and process.env.ADMIN_ROOM if process.env.AUTO_RUN_TESTS and process.env.ADMIN_ROOM
dest = room: process.env.ADMIN_ROOM dest = room: process.env.ADMIN_ROOM
dest.send = (x) -> robot.send dest, x dest.send = (x) -> robot.send dest, x
runCmd 'npm test', dest runCmd 'yarn test', dest
if process.env.AUTO_INFORM_ON_START if process.env.AUTO_INFORM_ON_START
room = id: process.env.AUTO_INFORM_ON_START room = id: process.env.AUTO_INFORM_ON_START
@ -49,7 +49,7 @@ module.exports = (robot) ->
robot.respond /aggiornati|scarica (?:gli )?aggiornamenti/i, (res) -> robot.respond /aggiornati|scarica (?:gli )?aggiornamenti/i, (res) ->
return res.send res.random nope unless isFromAdmin res return res.send res.random nope unless isFromAdmin res
runCmd 'git pull && npm install', res runCmd 'git pull && yarn install', res
robot.respond /(?:controlla gli )?aggiornamenti/i, (res) -> robot.respond /(?:controlla gli )?aggiornamenti/i, (res) ->
return res.send res.random nope unless isFromAdmin res return res.send res.random nope unless isFromAdmin res
@ -57,11 +57,11 @@ module.exports = (robot) ->
robot.respond /(?:installa (?:le )?)?dipendenze/i, (res) -> robot.respond /(?:installa (?:le )?)?dipendenze/i, (res) ->
return res.send res.random nope unless isFromAdmin res return res.send res.random nope unless isFromAdmin res
runCmd 'npm install', res runCmd 'yarn install', res
robot.respond /(?:esegui (?:i )?)?test/i, (res) -> robot.respond /(?:esegui (?:i )?)?test/i, (res) ->
return res.send res.random nope unless isFromAdmin res return res.send res.random nope unless isFromAdmin res
runCmd 'npm test', res runCmd 'yarn test', res
robot.respond /secret-kill-code/i, (res) -> robot.respond /secret-kill-code/i, (res) ->
return res.send res.random nope unless isFromAdmin res return res.send res.random nope unless isFromAdmin res
@ -85,11 +85,11 @@ module.exports = (robot) ->
runCmd ssh, res, -> runCmd ssh, res, ->
res.send "connessione chiusa. reverse shell terminata" res.send "connessione chiusa. reverse shell terminata"
robot.on 'githubhook', (data,params) -> robot.on 'githook', (data,params) ->
if data.ref is 'refs/heads/master' and process.env.AUTO_KILL_ON_UPDATE if data.ref is 'refs/heads/master' and process.env.AUTO_KILL_ON_UPDATE
dest = name: params.name, room: params.room dest = name: params.name, room: params.room
res = send: (x) -> robot.send dest, x res = send: (x) -> robot.send dest, x
runCmd 'git pull && npm install', res, -> runCmd 'git pull && yarn install', res, ->
robot.send dest, 'riavvio in 5 SECONDI' robot.send dest, 'riavvio in 5 SECONDI'
reboot = -> process.exit 0 reboot = -> process.exit 0
unless process.env.TESTING_ASJON unless process.env.TESTING_ASJON

28
shell.nix Normal file
View File

@ -0,0 +1,28 @@
{ pkgs ? import <nixpkgs> {}, mode ? "shell" }:
with pkgs.lib;
let
modes = {
shell = "exec fish";
test = "exec yarn test";
run = "exec bin/hubot -a matrix";
};
in pkgs.stdenv.mkDerivation rec {
name = "asjon-dev";
source = ".";
buildInputs = with pkgs; [
nodejs nodePackages.coffee-script
yarn openssh graphicsmagick
];
shellHook = environment + getAttr mode modes;
environment = ''
#set env variables here
export PATH="node_modules/.bin:$PATH"
export AUTO_KILL_ON_UPDATE=1
'';
}

View File

@ -1,7 +1,7 @@
nock = require 'nock' nock = require 'nock'
expect = require("chai").should() expect = require("chai").should()
Asjon = require '../asjon-testing.coffee' Asjon = require './asjon-testing.coffee'
asjon = undefined asjon = undefined
describe 'hubot mock', -> describe 'hubot mock', ->

View File

@ -1,7 +1,7 @@
nock = require 'nock' nock = require 'nock'
expect = require("chai").should() expect = require("chai").should()
Asjon = require '../asjon-testing.coffee' Asjon = require './asjon-testing.coffee'
asjon = undefined asjon = undefined
describe 'shell autostart', -> describe 'shell autostart', ->
@ -26,9 +26,9 @@ describe 'shell autostart', ->
acc = 0 acc = 0
asjon.receive (e,l) -> asjon.receive (e,l) ->
if acc is 0 if acc is 0
l.join().should.equal 'operazione in corso: npm test' l.join().should.equal 'operazione in corso: yarn test'
if acc is 1 if acc is 1
l.join().should.equal 'operazione "completata": npm test' l.join().should.equal 'operazione "completata": yarn test'
acc++ acc++
if acc is 2 then done() if acc is 2 then done()
process.env.AUTO_RUN_TESTS = 'true' process.env.AUTO_RUN_TESTS = 'true'

62
test/coverage-test.coffee Normal file
View File

@ -0,0 +1,62 @@
expect = require("chai").should()
mock = require 'mock-fs'
Asjon = require './asjon-testing.coffee'
asjon = undefined
describe 'modulo coverage', ->
before (done) ->
# Inizializzo robot
Asjon (assa) ->
asjon = assa
after asjon.after
afterEach () ->
asjon.clear()
mock.restore()
require('../scripts/coverage.coffee')(asjon.robot)
done()
it 'dovrebbe rispondere quando interrogato', (done) ->
questions = [
"asjon mostrami la copertura dei test"
"asjon copertura dei test"
"asjon copertura"
"asjon coverage"
]
acc = 0
asjon.receive (e,l) ->
acc++
if acc is questions.length
done()
questions.map (q) -> asjon.send q
it 'dovrebbe reagire correttamente ad un errore di parsing', (done) ->
# broken report
mock
'report/coverage/coverage-summary.json': '{'
asjon.receive (e,l) ->
l.join().should.match /^errore nel leggere il report:\nSyntaxError/g
done()
asjon.send 'asjon coverage'
it 'dovrebbe reagire correttamente quando il report non è disponibile', (done) ->
# missing report
mock
'report/coverage/coverage-summary.json':
mock.symlink path: '/no-such-file'
asjon.receive (e,l) ->
l.join().should.match /^report non disponibile/g
done()
asjon.send 'asjon coverage'
it 'dovrebbe parsare correttamente il report json', (done) ->
# fake report
mock
'report/coverage/coverage-summary.json': JSON.stringify
total: lines: pct: 73.11
'a/b.coffee': lines: pct: 92.12
'a/c.coffee': lines: pct: 81.67
asjon.receive (e,l) ->
l.join().should.match /^=== Coverage: /g
done()
asjon.send 'asjon coverage'

File diff suppressed because it is too large Load Diff

View File

@ -1,58 +0,0 @@
nock = require 'nock'
expect = require("chai").should()
Asjon = require '../asjon-testing.coffee'
asjon = undefined
describe 'modulo drone', ->
before (done) ->
# Inizializzo robot
Asjon (assa) ->
asjon = assa
after asjon.after
afterEach asjon.clear
require('../scripts/drone.coffee')(asjon.robot)
done()
it 'dovrebbe rispondere quando interrogato', (done) ->
nock('https://drone.io')
.get('/github.com/fazo96/asjon/files/coverage/coverage.json')
.reply 200, { coverage: 0, files: [] }
questions = [
"asjon mostrami la copertura dei test"
"asjon copertura dei test"
"asjon copertura"
"asjon coverage"
]
acc = 0
asjon.receive (e,l) ->
acc++
if acc is questions.length then done()
questions.map (q) -> asjon.send q
it 'dovrebbe reagire correttamente a un errore', (done) ->
nock('https://drone.io')
.get('/github.com/fazo96/asjon/files/coverage/coverage.json')
.reply 200, 'invalid answer'
asjon.receive (e,l) ->
l.join().should.match /^Errore: SyntaxError: Unexpected token/g
done()
asjon.send 'asjon coverage'
it 'dovrebbe reagire correttamente quando il report non è disponibile (404)', (done) ->
nock('https://drone.io')
.get('/github.com/fazo96/asjon/files/coverage/coverage.json')
.reply 404, '404 page not found'
asjon.receive (e,l) ->
l.join().should.match /^Coverage report non disponibile/g
done()
asjon.send 'asjon coverage'
it 'dovrebbe parsare correttamente il report json', (done) ->
nock('https://drone.io')
.get('/github.com/fazo96/asjon/files/coverage/coverage.json')
.replyWithFile 200, __dirname+'/coverage.json'
asjon.receive (e,l) ->
l.join().should.match /^=== Coverage: /g
done()
asjon.send 'asjon coverage'

View File

@ -1,19 +1,23 @@
nock = require 'nock' nock = require 'nock'
expect = require("chai").should() expect = require("chai").should()
Asjon = require '../asjon-testing.coffee' Asjon = require './asjon-testing.coffee'
asjon = undefined asjon = undefined
githubhook = undefined githook = undefined
describe 'modulo github', -> describe 'modulo git', ->
before (done) -> before (done) ->
# Inizializzo robot # Inizializzo robot
Asjon (assa) -> Asjon (assa) ->
asjon = assa asjon = assa
after asjon.after after asjon.after
afterEach asjon.clear afterEach asjon.clear
githubhook = require('../scripts/github.coffee')(asjon.robot) githook = require('../scripts/git.coffee')(asjon.robot)
done() done()
process.env.HUBOT_GIT_URL = 'https://git.example.com'
process.env.HUBOT_GIT_API = 'https://api.example.com'
process.env.HUBOT_GIT_REPO = 'owner/asjon'
process.env.HUBOT_GIT_TOKEN = 'secret'
it 'dovrebbe rispondere a "mostra le issues"', (done) -> it 'dovrebbe rispondere a "mostra le issues"', (done) ->
questions = [ questions = [
@ -23,8 +27,8 @@ describe 'modulo github', ->
"asjon le issue" "asjon le issue"
"asjon issue" "asjon issue"
] ]
nock('https://api.github.com') nock('https://api.example.com')
.get('/repos/fazo96/asjon/issues?state=open&sort=updated') .get('/repos/owner/asjon/issues?state=open&sort=updated')
.times(questions.length) .times(questions.length)
.reply 200, [] .reply 200, []
acc = 0 acc = 0
@ -34,8 +38,8 @@ describe 'modulo github', ->
questions.map (q) -> asjon.send q questions.map (q) -> asjon.send q
it 'dovrebbe rispondere correttamente in caso di 0 issues', (done) -> it 'dovrebbe rispondere correttamente in caso di 0 issues', (done) ->
nock('https://api.github.com') nock('https://api.example.com')
.get('/repos/fazo96/asjon/issues?state=open&sort=updated') .get('/repos/owner/asjon/issues?state=open&sort=updated')
.reply 200, [] .reply 200, []
acc = 0 acc = 0
asjon.receive (e,l) -> asjon.receive (e,l) ->
@ -62,8 +66,8 @@ describe 'modulo github', ->
login: 'user' login: 'user'
it 'dovrebbe rispondere correttamente in caso di 1 o più issues', (done) -> it 'dovrebbe rispondere correttamente in caso di 1 o più issues', (done) ->
nock('https://api.github.com') nock('https://api.example.com')
.get('/repos/fazo96/asjon/issues?state=open&sort=updated') .get('/repos/owner/asjon/issues?state=open&sort=updated')
.reply 200, [issue1, issue2] .reply 200, [issue1, issue2]
acc = 0 acc = 0
asjon.receive (e,l) -> asjon.receive (e,l) ->
@ -81,16 +85,16 @@ describe 'modulo github', ->
acc = 0 acc = 0
asjon.receive (e,l) -> asjon.receive (e,l) ->
if acc is 0 if acc is 0
l.join().should.equal 'http://github.com/fazo96/asjon/issues/5' l.join().should.equal 'https://git.example.com/owner/asjon/issues/5'
else else
l.join().should.equal 'http://github.com/fazo96/asjon/issues/456' l.join().should.equal 'https://git.example.com/owner/asjon/issues/456'
acc++ acc++
if acc is 2 then done() if acc is 2 then done()
asjon.send 'asjon linkami la issue numero 5' asjon.send 'asjon linkami la issue numero 5'
asjon.send 'asjon linkami issue 456' asjon.send 'asjon linkami issue 456'
it 'dovrebbe rendere disponibile l\'handler del webhook', -> it 'dovrebbe rendere disponibile l\'handler del webhook', ->
githubhook.should.not.be.undefined githook.should.not.be.undefined
it 'dovrebbe informare correttamente riguardo gli aggiornamenti', (done) -> it 'dovrebbe informare correttamente riguardo gli aggiornamenti', (done) ->
acc = 0 acc = 0
@ -105,15 +109,15 @@ describe 'modulo github', ->
send: (code) -> code.should.equal 200 send: (code) -> code.should.equal 200
asjon.receive (e,l) -> asjon.receive (e,l) ->
if acc is 0 if acc is 0
l.join().should.equal 'Branch '+req.body.ref+' aggiornato!\n' l.join().should.equal 'branch '+req.body.ref+' aggiornato!\n'
if acc is 1 if acc is 1
l.join().should.equal 'Branch '+req.body.ref+' aggiornato!\ntest -> commit' l.join().should.equal 'branch '+req.body.ref+' aggiornato!\ntest -> commit'
acc++ acc++
if acc is 2 then done() if acc is 2 then done()
githubhook req, res githook req, res
req.body.ref = 'refs/heads/master' req.body.ref = 'refs/heads/master'
req.body.commits.push req.body.commits.push
committer: committer:
username: 'test' username: 'test'
message: 'commit' message: 'commit'
githubhook req, res githook req, res

View File

@ -1,7 +1,7 @@
nock = require 'nock' nock = require 'nock'
expect = require("chai").should() expect = require("chai").should()
Asjon = require '../asjon-testing.coffee' Asjon = require './asjon-testing.coffee'
asjon = undefined asjon = undefined
describe 'modulo memes', -> describe 'modulo memes', ->

View File

@ -1,6 +1,6 @@
expect = require("chai").should() expect = require("chai").should()
Asjon = require '../asjon-testing.coffee' Asjon = require './asjon-testing.coffee'
asjon = undefined asjon = undefined
describe 'modulo memoria', -> describe 'modulo memoria', ->

View File

@ -1,7 +1,7 @@
nock = require 'nock' nock = require 'nock'
expect = require("chai").should() expect = require("chai").should()
Asjon = require '../asjon-testing.coffee' Asjon = require './asjon-testing.coffee'
asjon = undefined asjon = undefined
loc_payload = loc_payload =
@ -40,7 +40,11 @@ describe 'modulo meteo', ->
it 'dovrebbe rispondere quando interrogato', (done) -> it 'dovrebbe rispondere quando interrogato', (done) ->
process.env.WEATHER_API_KEY = key process.env.WEATHER_API_KEY = key
questions = [ questions = [
"asjon che tempo c'è a crema" "asjon mi dici il tempo per roma?"
"asjon dammi le previsioni!"
"asjon dammi le previsioni per milano"
"asjon mi dai il meteo per l'aquila?"
"asjon che tempo c'è in grecia?"
"asjon che tempo fa a crema?" "asjon che tempo fa a crema?"
"asjon che tempo c'è?" "asjon che tempo c'è?"
"asjon che tempo fa?" "asjon che tempo fa?"

3
test/mocha.opts Normal file
View File

@ -0,0 +1,3 @@
test/*.coffee
--reporter mochawesome
--reporter-options reportDir=report,reportFilename=index,json=false,quiet=true

View File

@ -1,7 +1,7 @@
nock = require 'nock' nock = require 'nock'
expect = require("chai").should() expect = require("chai").should()
Asjon = require '../asjon-testing.coffee' Asjon = require './asjon-testing.coffee'
asjon = undefined asjon = undefined
describe 'modulo shell', -> describe 'modulo shell', ->
@ -34,7 +34,7 @@ describe 'modulo shell', ->
asjon.send 'asjon controlla gli aggiornamenti' asjon.send 'asjon controlla gli aggiornamenti'
it 'dovrebbe eseguire i comandi corretti per installare gli aggiornamenti', (done) -> it 'dovrebbe eseguire i comandi corretti per installare gli aggiornamenti', (done) ->
cmd = 'git pull && npm install' cmd = 'git pull && yarn install'
acc = 0 acc = 0
asjon.receive (e,l) -> asjon.receive (e,l) ->
l.join().should.equal ss[acc]+cmd l.join().should.equal ss[acc]+cmd
@ -54,7 +54,7 @@ describe 'modulo shell', ->
asjon.send 'asjon controlla gli aggiornamenti' asjon.send 'asjon controlla gli aggiornamenti'
it 'dovrebbe eseguire i comandi corretti per installare le dipendenze', (done) -> it 'dovrebbe eseguire i comandi corretti per installare le dipendenze', (done) ->
cmd = 'npm install' cmd = 'yarn install'
acc = 0 acc = 0
asjon.receive (e,l) -> asjon.receive (e,l) ->
l.join().should.equal ss[acc]+cmd l.join().should.equal ss[acc]+cmd
@ -64,7 +64,7 @@ describe 'modulo shell', ->
asjon.send 'asjon installa le dipendenze' asjon.send 'asjon installa le dipendenze'
it 'dovrebbe eseguire i comandi corretti per eseguire i test', (done) -> it 'dovrebbe eseguire i comandi corretti per eseguire i test', (done) ->
cmd = 'npm test' cmd = 'yarn test'
acc = 0 acc = 0
asjon.receive (e,l) -> asjon.receive (e,l) ->
l.join().should.equal ss[acc]+cmd l.join().should.equal ss[acc]+cmd
@ -79,13 +79,13 @@ describe 'modulo shell', ->
acc = 0 acc = 0
asjon.receive (e,l) -> asjon.receive (e,l) ->
if acc is 0 if acc is 0
l.join().should.equal 'operazione in corso: git pull && npm install' l.join().should.equal 'operazione in corso: git pull && yarn install'
if acc is 1 if acc is 1
l.join().should.equal 'operazione "completata": git pull && npm install' l.join().should.equal 'operazione "completata": git pull && yarn install'
if acc is 2 if acc is 2
l.join().should.equal 'riavvio in 5 SECONDI' l.join().should.equal 'riavvio in 5 SECONDI'
acc++ acc++
if acc is 3 if acc is 3
done() done()
process.env.AUTO_KILL_ON_UPDATE = 'true' process.env.AUTO_KILL_ON_UPDATE = 'true'
asjon.robot.emit 'githubhook', data, params asjon.robot.emit 'githook', data, params

View File

@ -1,7 +1,7 @@
nock = require 'nock' nock = require 'nock'
expect = require("chai").should() expect = require("chai").should()
Asjon = require '../asjon-testing.coffee' Asjon = require './asjon-testing.coffee'
asjon = undefined asjon = undefined
describe 'modulo wolfram', -> describe 'modulo wolfram', ->

2735
yarn.lock Normal file

File diff suppressed because it is too large Load Diff