Example #1
0
class CollectDigitsRunner(Runner):
    """User's single interaction to enter a set of digits

    Note: Asterisk is hard-coded to use # to exit the entry-mode...
    """
    def __call__(self, *args, **named):
        """Begin the AGI processing for the menu"""
        self.readDigits()
        return self.finalDF

    def readDigits(self, result=None):
        """Begin process of reading digits from the user"""
        soundFile = getattr(self.model, 'soundFile', None)
        if soundFile:
            # easiest possibility, just read out the file...
            return self.agi.getData(
                soundFile, timeout=self.model.timeout,
                maxDigits = getattr(self.model, 'maxDigits', None),
            ).addCallback(self.onReadDigits).addErrback(self.returnError)
        else:
            raise NotImplemented("""Haven't got non-soundfile menus working yet""")

        self.agi.getData(self.menu. filename, timeout=2.000, maxDigits=None)

    def validEntry(self, digits):
        """Determine whether given digits are considered a "valid" entry"""
        minDigits = getattr(self.model, 'minDigits', None)
        if minDigits is not None:
            if len(digits) < minDigits:
                return False, 'Too few digits'
        return True, None

    def onReadDigits(self, (digits,timeout)):
        """Deal with succesful result from reading digits"""
        log.info("""onReadDigits: %r, %s""", digits, timeout)
        valid, reason = self.validEntry(digits)
        if (not digits) and (not timeout):
            # user pressed #
            raise error.MenuExit(
                self.model,
                """User cancelled entry of digits""",
            )
        if not valid:
            if self.model.tellInvalid:
                # this should be a menu, letting the user decide to re-enter,
                # or cancel entry
                pass
            self.alreadyRepeated += 1
            if self.alreadyRepeated >= self.model.maxRepetitions:
                log.warn("""User did not complete digit-entry for %s, timing out""", self.model)
                raise error.MenuTimeout(
                    self.model,
                    """User did not finish digit-entry in %s passes of collection""" % (
                        self.alreadyRepeated,
                    )
                )
            return self.readDigits()
        else:
            # Yay, we got a valid response!
            return self.returnResult([(self, digits)])
Example #2
0
 def onReadDigits(self, values):
     """Deal with succesful result from reading digits"""
     (digits, timeout) = values
     log.info("""onReadDigits: %r, %s""", digits, timeout)
     valid, reason = self.validEntry(digits)
     if (not digits) and (not timeout):
         # user pressed #
         raise error.MenuExit(
             self.model,
             """User cancelled entry of digits""",
         )
     if not valid:
         if self.model.tellInvalid:
             # this should be a menu, letting the user decide to re-enter,
             # or cancel entry
             pass
         self.alreadyRepeated += 1
         if self.alreadyRepeated >= self.model.maxRepetitions:
             log.warn(
                 """User did not complete digit-entry for %s, timing out""",
                 self.model)
             raise error.MenuTimeout(
                 self.model,
                 """User did not finish digit-entry in %s passes of collection"""
                 % (self.alreadyRepeated, ))
         return self.readDigits()
     else:
         # Yay, we got a valid response!
         return self.returnResult([(self, digits)])
Example #3
0
File: menu.py Project: daasara/riba
 def onReadMenu(self, pressed):
     """Deal with succesful result from reading menu"""
     log.info("""onReadMenu: %r""", pressed)
     if not pressed:
         self.alreadyRepeated += 1
         if self.alreadyRepeated >= self.model.maxRepetitions:
             log.warn(
                 """User did not complete menu selection for %s, timing out""",
                 self.model)
             if not self.finalDF.called:
                 raise error.MenuTimeout(
                     self.model,
                     """User did not finish selection in %s passes of menu"""
                     % (self.alreadyRepeated, ))
             return None
         return self.readMenu()
     else:
         # Yay, we got an escape-key pressed
         for option in self.model.options:
             if pressed in option.option:
                 if callable(option):
                     # allow for chaining down into sub-menus and the like...
                     # we return the result of calling the option via self.finalDF
                     return defer.maybeDeferred(option, pressed,
                                                self).addCallbacks(
                                                    self.returnResult,
                                                    self.returnError)
                 elif hasattr(option, 'onSuccess'):
                     return defer.maybeDeferred(option.onSuccess, pressed,
                                                self).addCallbacks(
                                                    self.returnResult,
                                                    self.returnError)
                 else:
                     return self.returnResult([
                         (option, pressed),
                     ])
         # but it wasn't anything we expected...
         if not self.model.tellInvalid:
             raise error.MenuUnexpectedOption(
                 self.model,
                 """User somehow selected %r, which isn't a recognised option?"""
                 % (pressed, ),
             )
         else:
             return self.agi.getOption(
                 self.model.INVALID_OPTION_FILE,
                 self.escapeDigits,
                 timeout=0,
             ).addCallback(self.readMenu).addErrback(self.returnError)