Add call function to use for deferreds

This commit is contained in:
moyamo 2016-01-02 16:00:47 +02:00
parent 03e56a4c07
commit 0b4e2f13d4
2 changed files with 44 additions and 12 deletions

View file

@ -1,3 +1,5 @@
from functools import partial
class Deferred(object): class Deferred(object):
""" """
Represents a delayed computation. This is a more elegant way to deal with Represents a delayed computation. This is a more elegant way to deal with
@ -8,7 +10,8 @@ class Deferred(object):
value by using the then method. Computations dependent on the Deferred will value by using the then method. Computations dependent on the Deferred will
only proceed when the run method is called. only proceed when the run method is called.
Attributes of a Deferred can be accessed directly as methods. Attributes of a Deferred can be accessed directly as methods. The result of
calling these functions will be Deferred.
Example: Example:
image = Deferred() image = Deferred()
@ -92,6 +95,39 @@ class Then(object):
return self.deferred.then(func) return self.deferred.then(func)
return helper return helper
def call(func, *args, **kwargs):
"""
Call a function with deferred arguments
Example:
colors = Deferred()
colors.append('blue')
colors.run(['red', 'green'])
call(print, colors) #=> ['red', 'green', 'blue']
call(print, 'hi', colors) #=> hi ['red', 'green', 'blue']
"""
for i, c in enumerate(args):
if isinstance(c, Deferred):
# Function without deferred arguments
normalfunc = partial(func, *args[:i])
# Function with deferred and possibly deferred arguments
def restfunc(*arg2, **kwarg2):
apply_deferred = partial(normalfunc, *arg2, **kwarg2)
return call(apply_deferred, *args[i + 1:], **kwargs)
return c.then(restfunc)
items = kwargs.items()
for i, (k, v) in enumerate(items):
if isinstance(v, Deferred):
# Function without deferred arguments
normalfunc = partial(func, *args, **dict(items[:i]))
# Function with deferred and possibly deferred arguments
def restfunc2(*arg2, **kwarg2):
apply_deferred = partial(normalfunc, *arg2, **kwarg2)
return call(apply_deferred, **dict(items[i + 1:]))
return c.then(restfunc2)
# No items deferred
return func(*args, **kwargs)
class DeferredHasValue(Exception): class DeferredHasValue(Exception):
def __init__(self, string): def __init__(self, string):
super(DeferredHasValue, self).__init__(string) super(DeferredHasValue, self).__init__(string)

View file

@ -40,8 +40,8 @@ from threading import Timer
from group import Group from group import Group
from bot import Bot from bot import Bot
import deferred import deferred
from deferred import call
from yowsupwrapper import YowsupApp from yowsupwrapper import YowsupApp
from functools import partial
class MsgIDs: class MsgIDs:
@ -736,22 +736,18 @@ class Session(YowsupApp):
# Send VCard # Send VCard
if ID != None: if ID != None:
response.pictureId().then(partial( call(self.logger.debug, 'Sending VCard (%s) with image id %s',
self.logger.debug, 'Sending VCard (%s) with image id %s', ID ID, response.pictureId())
))
pictureData = response.pictureData() pictureData = response.pictureData()
response.pictureData().then(partial( call(self.backend.handleVCard, self.user, ID, buddy, "", "",
self.backend.handleVCard, self.user, ID, buddy, "", "" response.pictureData())
))
# Send image hash # Send image hash
if not buddy == self.legacyName: if not buddy == self.legacyName:
obuddy = self.buddies[buddy] obuddy = self.buddies[buddy]
image_hash = pictureData.then(utils.sha1hash) image_hash = pictureData.then(utils.sha1hash)
image_hash.then(partial(self.logger.debug, 'Image hash is %s')) call(self.logger.debug, 'Image hash is %s', image_hash)
image_hash.then(partial( call(self.updateBuddy, buddy, obuddy.nick, obuddy.groups, image_hash)
self.updateBuddy, buddy, obuddy.nick, obuddy.groups
))
def onDlsuccess(self, path): def onDlsuccess(self, path):