Skip to content

Commit

Permalink
helper function: waitData to retry a promise until get right
Browse files Browse the repository at this point in the history
  • Loading branch information
huan committed May 24, 2016
1 parent c300e01 commit 34e0397
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 86 deletions.
15 changes: 10 additions & 5 deletions example/ding-dong-bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,17 @@ Please wait... I'm trying to login in...
console.log(welcome)
const bot = new Wechaty({head: true})

bot.on('scan', ({url, code}) => {
console.log(`Scan qrcode in url to login: \n${url}`)
console.log(code)
})

bot
.on('login' , () => log.info('Bot', 'logined'))
.on('logout' , () => log.info('Bot', 'logouted'))
.on('scan', ({url, code}) => {
console.log(`Scan qrcode in url to login: ${code}\n${url}`)
})
.on('message', m => {
m.ready()
.then(msg => {
log.info('Bot', 'recv: %s', msg)
logToFile(JSON.stringify(msg.rawObj))
})
.catch(e => log.error('Bot', 'ready: %s' , e))

Expand All @@ -60,3 +59,9 @@ bot.init()
bot.quit()
process.exit(-1)
})

function logToFile(data) {
require('fs').appendFile('message.log', data + '\n\n#############################\n\n', err => {
if (err) { log.error('LogToFile: %s', err) }
})
}
32 changes: 19 additions & 13 deletions example/tuling123-bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,13 @@ bot
.on('message', m => {
co(function* () {
const msg = yield m.ready()
log.info('Bot', 'recv: %s' , msg)

if (m.group()) {
return
if (m.group() && /Wechaty/i.test(m.group().name())) {
log.info('Bot', 'talk: %s' , msg)
talk(m)
} else {
log.info('Bot', 'recv: %s' , msg)
}

const reply = new Wechaty.Message()
.set('to', m.get('from'))

const content = m.get('content')
const {code, text} = yield brain.ask(content, {userid: msg.get('from')})
reply.set('content', text)

yield bot.send(reply)
log.info('Bot', `REPLY: {code:${code}, text:${text}}`)
})
.catch(e => log.error('Bot', 'on message rejected: %s' , e))
})
Expand All @@ -65,3 +57,17 @@ bot.init()
process.exit(-1)
})

function talk(m) {
co(function* () {
const fromId = m.from().id
const content = m.content()
const {code, text} = yield brain.ask(content, {userid: fromId})

const minDelayTime = 5000
const maxDelayTime = 15000
const delayTime = Math.floor(Math.random() * (maxDelayTime - minDelayTime)) + minDelayTime

log.info('Bot', `REPLY(after ${Math.floor(delayTime/1000)}s): {code:${code}, text:${text}}`)
setTimeout(r => { bot.reply(m, text) }, delayTime)
})
}
47 changes: 23 additions & 24 deletions src/contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,9 @@ class Contact {
this.obj = {}
}

ready(contactGetter) {
log.silly('Contact', 'ready(' + typeof contactGetter + ')')
if (this.obj.id) {
return Promise.resolve(this)
}

if (!contactGetter) {
log.silly('Contact', 'get contact via ' + Contact.puppet.constructor.name)
contactGetter = Contact.puppet.getContact.bind(Contact.puppet)
}
return contactGetter(this.id)
.then(data => {
log.silly('Contact', `contactGetter(${this.id}) resolved`)
this.rawObj = data
this.obj = this.parse(data)
return this
}).catch(e => {
log.error('Contact', `contactGetter(${this.id}) rejected: `, e)
throw new Error('contactGetter: ' + e)
})
toString() {
var name = this.obj.name ? `${this.obj.name}@${this.id}` : this.id
return `Contact(${name})`
}

parse(rawObj) {
Expand All @@ -56,6 +39,26 @@ class Contact {
}
name() { return this.obj.name }

ready(contactGetter) {
log.silly('Contact', 'ready(' + typeof contactGetter + ')')
if (this.obj.id) { return Promise.resolve(this) }

if (!contactGetter) {
log.silly('Contact', 'get contact via ' + Contact.puppet.constructor.name)
contactGetter = Contact.puppet.getContact.bind(Contact.puppet)
}
return contactGetter(this.id)
.then(data => {
log.silly('Contact', `contactGetter(${this.id}) resolved`)
this.rawObj = data
this.obj = this.parse(data)
return this
}).catch(e => {
log.error('Contact', `contactGetter(${this.id}) rejected: %s`, e)
throw e
})
}

dumpRaw() {
console.error('======= dump raw contact =======')
Object.keys(this.rawObj).forEach(k => console.error(`${k}: ${this.rawObj[k]}`))
Expand All @@ -65,10 +68,6 @@ class Contact {
Object.keys(this.obj).forEach(k => console.error(`${k}: ${this.obj[k]}`))
}

toString() {
return `Contact(${this.id})`
}

get(prop) { return this.obj[prop] }

send(message) {
Expand Down
12 changes: 8 additions & 4 deletions src/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ class Group {
}
}

toString() { return this.obj.name ? this.obj.name : this.id }
toString() {
var name = this.obj.name ? `[${this.obj.name}]${this.id}` : this.id
return `Group(${name})`
}

ready(contactGetter) {
log.silly('Group', `ready(${contactGetter})`)
if (this.obj.id) {
return Promise.resolve(this)
}
if (this.obj.id) { return Promise.resolve(this) }

contactGetter = contactGetter || Group.puppet.getContact.bind(Group.puppet)
return contactGetter(this.id)
.then(data => {
Expand All @@ -39,6 +41,8 @@ class Group {
})
}

name() { return this.obj.name }

parse(rawObj) {
return !rawObj ? {} : {
id: rawObj.UserName
Expand Down
22 changes: 7 additions & 15 deletions src/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,11 @@ class Message {
constructor(rawObj) {
Message.counter++

this.logToFile(JSON.stringify(rawObj))

this.rawObj = rawObj = rawObj || {}
this.obj = this.parse(rawObj)
this.id = this.obj.id
}

logToFile(data) {
require('fs').appendFile('message.log', data + '\n\n#############################\n\n', err => {
if (err) { log.error('Message', 'logToFile: ' + err) }
})
}
// Transform rawObj to local m
parse(rawObj) {
return {
Expand All @@ -52,9 +45,9 @@ class Message {
return s
}
getSenderString() {
const name = this.obj.from.get('name')
const name = this.obj.from.get('remark') || this.obj.from.get('name')
const group = this.obj.group
return '<' + name + (group ? `@[${group}]` : '') + '>'
return '<' + name + (group ? `@${group}` : '') + '>'
}
getContentString() {
let content = this.unescapeHtml(this.stripHtml(this.obj.content))
Expand All @@ -74,20 +67,19 @@ class Message {
from() { return this.obj.from }
to() { return this.obj.to }
content() { return this.obj.content }
group() { return this.obj.group }

ready() {
return this.obj.from.ready() // Contact from
return this.obj.from.ready() // Contact from
.then(r => this.obj.to.ready()) // Contact to
.then(r => this.obj.group && this.obj.group.ready()) // Group member list
.then(r => this)
.catch(e => { // REJECT
log.error('Message', 'ready() rejected:' + e)
.then(r => this) // ready return this for chain
.catch(e => { // REJECTED
log.error('Message', 'ready() rejected: %s', e)
throw new Error(e)
})
}

group() { return !!(this.obj.group) }

get(prop) {
if (!prop || !(prop in this.obj)) {
const s = '[' + Object.keys(this.obj).join(',') + ']'
Expand Down
48 changes: 46 additions & 2 deletions src/puppet-web-bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,50 @@ class Bridge {
getLoginQrImgUrl() { return this.proxyWechaty('getLoginQrImgUrl') }
getUserName() { return this.proxyWechaty('getUserName') }

getContact(id) { return this.proxyWechaty('getContact', id) }
getContact(id) {
return this.waitData(r => {
return this.proxyWechaty('getContact', id)
}, 3000)
}

/**
* Call a function repeatly untill it return a value
*
* @param <function> pfunc
* @param <number> timeout
*
*/
waitData(pfunc, timeout) {
log.silly('Bridge', 'waitData()')
const waitTime = 50
let totalTime = 0
return new Promise((resolve, reject) => {
function retry() {
log.silly('Bridge', 'retry()@waitData()')
try {
pfunc().then(data => {
if (data) {
log.silly('Bridge', `waitData(${totalTime}/${timeout}) succ`)
return resolve(data)
} else if (totalTime > timeout) {
log.silly('Bridge', `waitData(${totalTime}/${timeout}) timeout`)
return resolve()
} else {
log.silly('Bridge', `waitData(${totalTime}/${timeout}) retry`)
totalTime += waitTime
return setTimeout(retry, waitTime)
}
throw new Error('should not run to here')
})
} catch (e) {
log.silly('Bridge', `waitData(${totalTime}/${timeout}) exception: %s`, e)
return reject(e)
}
}
return retry()
})
}

send(toUserName, content) { return this.proxyWechaty('send', toUserName, content) }

getInjectio() {
Expand All @@ -54,10 +97,11 @@ class Bridge {
})
.then(r => {
if (true===r) { log.verbose('Bridge', 'Wechaty.init() return: ' + r) }
else { throw new Error('Wechaty.init() return not true') }
else { throw new Error('Wechaty.init() return not true: ' + r) }
return r
})
} catch (e) {
log.error('Bridge', 'inject() exception: %s', e)
return Promise.reject('inject exception: ' + e)
}
throw new Error('should not run to here')
Expand Down
18 changes: 15 additions & 3 deletions src/puppet-web-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ class Browser {
initDriver() {
log.verbose('Browser', 'initDriver()')
if (this.head) {
this.driver = new WebDriver.Builder().forBrowser('chrome').build()
this.driver = new WebDriver.Builder()
.setAlertBehavior('ignore')
.forBrowser('chrome')
.build()
} else {
this.driver = this.getPhantomJsDriver()
}
Expand All @@ -59,6 +62,7 @@ class Browser {
const phantomjsExe = require('phantomjs-prebuilt').path
// const phantomjsExe = require('phantomjs2').path
const customPhantom = WebDriver.Capabilities.phantomjs()
.setAlertBehavior('ignore')
.set('phantomjs.binary.path', phantomjsExe)
.set('phantomjs.cli.args', [
'--ignore-ssl-errors=true' // this help socket.io connect with localhost
Expand Down Expand Up @@ -95,10 +99,18 @@ class Browser {
execute(script, ...args) {
//log.verbose('Browser', `Browser.execute(${script})`)
if (!this.driver) {
throw new Error('driver not found')
// throw new Error('driver not found')
const errMsg = 'execute() called without driver'
log.verbose('Browser', errMsg)
return Promise.reject(errMsg)
}
// return promise
return this.driver.executeScript.apply(this.driver, arguments)
try {
return this.driver.executeScript.apply(this.driver, arguments)
} catch (e) {
log.error('Browser', e)
return Promise.reject(e)
}
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/puppet-web-injectio.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,11 @@ return (function(port) {
return chat.sendMessage(m)
}
function getContact(id) {
return Wechaty.glue.contactFactory
? Wechaty.glue.contactFactory.getContact(id)
: null
if (Wechaty.glue.contactFactory) {
return Wechaty.glue.contactFactory.getContact(id)
}
log('contactFactory not inited')
return null
}
function getUserName() {
return Wechaty.glue.accountFactory
Expand Down
8 changes: 3 additions & 5 deletions src/puppet-web-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,10 @@ class Server extends EventEmitter {
this.emit('connection', client)

client.on('disconnect', e => {
log.verbose('Server', 'socket.io disconnected: ' + e)
/**
* 1. Browser reload / 2. Lost connection(Bad network)
*/
log.verbose('Server', 'socket.io disconnect: %s', e)
// 1. Browser reload / 2. Lost connection(Bad network)
this.socketClient = null
this.emit('disconnect', 'server re-emit from socketio')
this.emit('disconnect', e)
})

client.on('error', e => log.error('Server', 'socketio client error: %s', e))
Expand Down
Loading

0 comments on commit 34e0397

Please sign in to comment.