Skip to content

Commit 55b8b92

Browse files
committed
initial commit
0 parents  commit 55b8b92

8 files changed

+171
-0
lines changed

.babelrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"presets": [
3+
"es2015"
4+
],
5+
"plugins": [
6+
"transform-function-bind"
7+
]
8+
}

.eslintrc

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "standard",
3+
"plugins": [
4+
"standard"
5+
],
6+
"rules": {
7+
"max-len": ["error", 80]
8+
}
9+
}

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dist/
2+
node_modules/
3+
.idea/
4+
npm-debug.log

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./dist/tryhaskell.js')

package.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "tryhaskell-bot",
3+
"private": true,
4+
"version": "1.0.0",
5+
"description": "Try Haskell in Telegram via tryhaskell.org",
6+
"main": "index.js",
7+
"scripts": {
8+
"build": "babel -d dist/ src/",
9+
"build:watch": "babel -d dist/ src/ --watch",
10+
"eslint": "eslint src/",
11+
"start": "node index.js",
12+
"test": "echo \"Error: no test specified\" && exit 1"
13+
},
14+
"author": "goodmind <andwebar@gmail.com>",
15+
"license": "MIT",
16+
"devDependencies": {
17+
"babel-cli": "^6.9.0",
18+
"babel-plugin-transform-function-bind": "^6.8.0",
19+
"eslint": "^2.11.1",
20+
"eslint-config-standard": "^5.3.1",
21+
"eslint-plugin-promise": "^1.3.1",
22+
"eslint-plugin-standard": "^1.3.2"
23+
},
24+
"dependencies": {
25+
"@cycle/core": "^6.0.3",
26+
"@cycle/http": "^8.2.2",
27+
"common-tags": "^1.2.0",
28+
"cycle-telegram": "^1.3.0",
29+
"ramda": "^0.21.0",
30+
"rx": "^4.1.0"
31+
}
32+
}

src/plugins/index.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Update } from 'cycle-telegram'
2+
3+
import TryHaskell from './tryhaskell'
4+
5+
export let plugins = [
6+
{
7+
type: Update,
8+
name: 'tryhaskell',
9+
path: /(?:[\s\S]*)/,
10+
component: TryHaskell}
11+
]

src/plugins/tryhaskell.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Observable as $ } from 'rx'
2+
import { compose, prop, curryN } from 'ramda'
3+
import { stripIndents } from 'common-tags'
4+
5+
import { reply, answerInlineQuery } from 'cycle-telegram'
6+
7+
let prettify = (query, result) => `
8+
Prelude> ${query}
9+
${result}
10+
`
11+
12+
let answer = curryN(2, (u, text) => $.just(
13+
u.inline_query ? answerInlineQuery({
14+
results: [
15+
{
16+
type: 'article',
17+
title: text,
18+
input_message_content: {
19+
message_text: prettify(u.inline_query.query, text)
20+
}
21+
}
22+
],
23+
cache_time: 0
24+
}, u) : reply({ text: prettify(u.message.text, text) }, u)))
25+
26+
function TryHaskell ({HTTP, props}, u) {
27+
let text = props[0]
28+
let res = HTTP
29+
.filter(res$ => res$.request.send.exp === text)
30+
.mergeAll()
31+
.map(compose(JSON.parse, prop('text')))
32+
.flatMapLatest(({
33+
error,
34+
success
35+
}) => error ? $.throw(error) : $.just(success))
36+
37+
return {
38+
bot: res
39+
.map(res => stripIndents`
40+
${res.stdout.join('')}
41+
${res.value} :: ${res.type}
42+
`)
43+
.flatMapLatest(answer(u))
44+
.catch(answer(u)),
45+
46+
HTTP: $.just({
47+
method: 'POST',
48+
url: 'http://tryhaskell.org/eval',
49+
category: 'tryhaskell',
50+
send: {
51+
exp: text
52+
},
53+
type: 'application/x-www-form-urlencoded',
54+
accept: 'application/json'
55+
})
56+
}
57+
}
58+
59+
export default TryHaskell

src/tryhaskell.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Observable as $ } from 'rx'
2+
import { values } from 'ramda'
3+
4+
import { run } from '@cycle/core'
5+
import { makeHTTPDriver } from '@cycle/http'
6+
import { makeTelegramDriver } from 'cycle-telegram'
7+
import { matchPlugin } from 'cycle-telegram/plugins'
8+
9+
import { plugins } from './plugins'
10+
11+
let intent = (sources) => ({
12+
messages: sources.bot
13+
.events('message')
14+
::matchPlugin(plugins, sources)
15+
.share(),
16+
17+
inlineQuery: sources.bot
18+
.events('inline_query')
19+
::matchPlugin(plugins, sources)
20+
.share()
21+
})
22+
23+
let model = ({messages, inlineQuery, commands}, sources) => $.from([
24+
messages.pluck('bot').mergeAll(),
25+
inlineQuery.pluck('bot').mergeAll()
26+
])
27+
28+
let main = (sources) => {
29+
let actions = intent(sources)
30+
31+
return {
32+
HTTP: $.merge(actions.inlineQuery, actions.messages)
33+
.pluck('HTTP')
34+
.mergeAll(),
35+
36+
bot: model(actions, sources),
37+
38+
log: $.from(values(actions))
39+
.mergeAll()
40+
}
41+
}
42+
43+
run(main, {
44+
HTTP: makeHTTPDriver(),
45+
bot: makeTelegramDriver(process.env.ACCESS_TOKEN),
46+
log: (m) => m.forEach(::console.log)
47+
})

0 commit comments

Comments
 (0)