config.plugins.FritzCall.number = ConfigText(default="", fixed_size=False)
config.plugins.FritzCall.number.setUseableChars('0123456789')
+phonebook = None
+fritzbox = None
+
def initDebug():
try:
os.remove("/tmp/FritzDebug.log")
self.close()
class FritzCallFBF:
- def __init__(self, init=True):
+ def __init__(self):
debug("[FritzCallFBF] __init__")
self._callScreen = None
self._md5LoginTimestamp = None
self._md5Sid = '0000000000000000'
- self._callCallback = None
- self._loginCallback = None
- self._timestampCalls = 0
+ self._callTimestamp = 0
self._callList = []
self._callType = config.plugins.FritzCall.fbfCalls.value
self.hasMailbox = None # Holds (no of mailboxes, state0, state1, state2, state3, state4)
self.hasDect = False
- if init:
- self.getInfo(None, self._setProperties)
+ self.getInfo(None)
def _setProperties(self, status):
(boxInfo, upTime, ipAddress, wlanState, wlanEncrypt, dslState, dslSpeed, tamActive, dectActive) = status #@UnusedVariable
debug("[FritzCallFBF] _login")
if self._callScreen:
self._callScreen.updateStatus(_("login"))
- if self._md5LoginTimestamp and ((time.time() - self._md5LoginTimestamp) < float(9.5*60)): # new login after 9.5 minutes inactivity
- debug("[FritzCallFBF] _login: renew timestamp: " + str(self._md5LoginTimestamp) + " time: " + str(time.time()))
+ if self._md5LoginTimestamp and((time.time() - self._md5LoginTimestamp) < float(9.5*60)) and self._md5Sid != '0000000000000000': # new login after 9.5 minutes inactivity
+ debug("[FritzCallFBF] _login: renew timestamp: " + time.ctime(self._md5LoginTimestamp) + " time: " + time.ctime())
self._md5LoginTimestamp = time.time()
- callback()
+ callback(None)
else:
- debug("[FritzCallFBF] _login: not logged in or outdated login, renew: timestamp: " + str(self._md5LoginTimestamp) + " time: " + str(time.time()))
- self._loginCallback = callback
+ debug("[FritzCallFBF] _login: not logged in or outdated login")
# http://fritz.box/cgi-bin/webcm?getpage=../html/login_sid.xml
parms = urlencode({'getpage':'../html/login_sid.xml'})
url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
getPage(url,
method="POST",
headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
- }, postdata=parms).addCallback(self._md5Login).addErrback(self._oldLogin)
+ }, postdata=parms).addCallback(lambda x: self._md5Login(callback,x)).addErrback(lambda x:self._oldLogin(callback,x))
- def _oldLogin(self, error):
+ def _oldLogin(self, callback, error):
debug("[FritzCallFBF] _oldLogin: " + repr(error))
+ self._md5LoginTimestamp = None
if config.plugins.FritzCall.password.value != "":
parms = "login:command/password=%s" % (config.plugins.FritzCall.password.value)
url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
method="POST",
agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
- }, postdata=parms).addCallback(self._gotPageLogin).addCallback(self._loginCallback).addErrback(self._errorLogin)
- elif self._loginCallback:
- debug("[FritzCallFBF] _oldLogin: no password, calling " + repr(self._loginCallback))
- self._loginCallback()
+ }, postdata=parms).addCallback(self._gotPageLogin).addCallback(callback).addErrback(self._errorLogin)
+ elif callback:
+ debug("[FritzCallFBF] _oldLogin: no password, calling " + repr(callback))
+ callback(None)
- def _md5Login(self, sidXml):
+ def _md5Login(self, callback, sidXml):
def buildResponse(challenge, text):
debug("[FritzCallFBF] _md5Login7buildResponse: challenge: " + challenge + ' text: ' + text)
text = (challenge + '-' + text).decode('utf-8','ignore').encode('utf-16-le')
debug("[FritzCallFBF] _md5Login: SID "+ self._md5Sid)
else:
debug("[FritzCallFBF] _md5Login: no sid! That must be an old firmware.")
- self._oldLogin('No error')
+ self._oldLogin(callback, 'No error')
return
+ debug("[FritzCallFBF] _md5Login: renew timestamp: " + time.ctime(self._md5LoginTimestamp) + " time: " + time.ctime())
+ self._md5LoginTimestamp = time.time()
if sidXml.find('<iswriteaccess>0</iswriteaccess>') != -1:
debug("[FritzCallFBF] _md5Login: logging in")
found = re.match('.*<Challenge>([^<]*)</Challenge>', sidXml, re.S)
else:
challenge = None
debug("[FritzCallFBF] _md5Login: login necessary and no challenge! That is terribly wrong.")
- debug("[FritzCallFBF] _md5Login: renew timestamp: " + str(time.time()))
- self._md5LoginTimestamp = time.time()
parms = urlencode({
'getpage':'../html/de/menus/menu2.html', # 'var:pagename':'home', 'var:menu':'home',
'login:command/response': buildResponse(challenge, config.plugins.FritzCall.password.value),
method="POST",
agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
- }, postdata=parms).addCallback(self._gotPageLogin).addCallback(self._loginCallback).addErrback(self._errorLogin)
- else: # we assume value 1 here, no login necessary
- debug("[FritzCallFBF] _md5Login: no login necessary: " + str(time.time()))
- self._md5LoginTimestamp = time.time()
- self._loginCallback()
+ }, postdata=parms).addCallback(self._gotPageLogin).addCallback(callback).addErrback(self._errorLogin)
+ elif callback: # we assume value 1 here, no login necessary
+ debug("[FritzCallFBF] _md5Login: no login necessary")
+ callback(None)
def _gotPageLogin(self, html):
if self._callScreen:
debug("[FritzCallFBF] loadFritzBoxPhonebook: logging in")
self._login(self._loadFritzBoxPhonebook)
- def _loadFritzBoxPhonebook(self, html=None):
- parms = urlencode({
- 'getpage':'../html/de/menus/menu2.html',
- 'var:lang':'de',
- 'var:pagename':'fonbuch',
- 'var:menu':'fon',
- 'sid':self._md5Sid,
- 'telcfg:settings/Phonebook/Books/Select':self._phoneBookID, # this selects always the first phonbook
- })
- url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
- debug("[FritzCallFBF] _loadFritzBoxPhonebook: '" + url + "' parms: '" + parms + "'")
- getPage(url,
- method="POST",
- agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
- headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
- }, postdata=parms).addCallback(self._parseFritzBoxPhonebook).addErrback(self._errorLoad)
+ def _loadFritzBoxPhonebook(self, html):
+ if html:
+ found = re.match('.*<p class="errorMessage">FEHLER: ([^<]*)</p>', html, re.S)
+ if found:
+ self._errorLoad('Login: ' + found.group(1))
+ return
+ parms = urlencode({
+ 'getpage':'../html/de/menus/menu2.html',
+ 'var:lang':'de',
+ 'var:pagename':'fonbuch',
+ 'var:menu':'fon',
+ 'sid':self._md5Sid,
+ 'telcfg:settings/Phonebook/Books/Select':self._phoneBookID, # this selects always the first phonbook
+ })
+ url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
+ debug("[FritzCallFBF] _loadFritzBoxPhonebook: '" + url + "' parms: '" + parms + "'")
+ getPage(url,
+ method="POST",
+ agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+ headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
+ }, postdata=parms).addCallback(self._parseFritzBoxPhonebook).addErrback(self._errorLoad)
def _parseFritzBoxPhonebook(self, html):
debug("[FritzCallFBF] _parseFritzBoxPhonebook")
- self._logout()
if re.search('TrFonName', html):
#===============================================================================
# New Style: 7270 (FW 54.04.58, 54.04.63-11941, 54.04.70, 54.04.74-14371)
else:
debug("[FritzCallFBF] ignoring empty number for %s" % name)
continue
+ elif self._md5Sid=='0000000000000000': # retry, it could be a race condition
+ debug("[FritzCallFBF] _parseFritzBoxPhonebook: retry loading phonebook")
+ self.loadFritzBoxPhonebook()
else:
self._notify(_("Could not parse FRITZ!Box Phonebook entry"))
debug("[FritzCallFBF] _errorLoad: %s" % (error))
text = _("FRITZ!Box - Could not load phonebook: %s") % error
self._notify(text)
- self._logout()
def getCalls(self, callScreen, callback, type):
#
debug("[FritzCallFBF] getCalls")
self._callScreen = callScreen
self._callType = type
- self._callCallback = callback
- if (time.time() - self._timestampCalls) > 180:
- debug("[FritzCallFBF] getCalls: outdated data, login and get new ones")
- self._timestampCalls = time.time()
- self._login(self._getCalls)
+ if (time.time() - self._callTimestamp) > 180:
+ debug("[FritzCallFBF] getCalls: outdated data, login and get new ones: " + time.ctime(self._callTimestamp) + " time: " + time.ctime())
+ self._callTimestamp = time.time()
+ self._login(lambda x:self._getCalls(callback,x))
elif not self._callList:
debug("[FritzCallFBF] getCalls: time is ok, but no callList")
- self._getCalls1()
+ self._getCalls1(callback)
else:
debug("[FritzCallFBF] getCalls: time is ok, callList is ok")
- self._gotPageCalls()
+ self._gotPageCalls(callback)
- def _getCalls(self, html=None):
+ def _getCalls(self, callback, html):
+ if html:
+ found = re.match('.*<p class="errorMessage">FEHLER: ([^<]*)</p>', html, re.S)
+ if found:
+ self._errorCalls('Login: ' + found.group(1))
+ return
#
# we need this to fill Anrufliste.csv
# http://repeater1/cgi-bin/webcm?getpage=../html/de/menus/menu2.html&var:lang=de&var:menu=fon&var:pagename=foncalls
self._callScreen.updateStatus(_("preparing"))
parms = urlencode({'getpage':'../html/de/menus/menu2.html', 'var:lang':'de', 'var:pagename':'foncalls', 'var:menu':'fon', 'sid':self._md5Sid})
url = "http://%s/cgi-bin/webcm?%s" % (config.plugins.FritzCall.hostname.value, parms)
- getPage(url).addCallback(self._getCalls1).addErrback(self._errorCalls)
+ getPage(url).addCallback(lambda x:self._getCalls1(callback)).addErrback(self._errorCalls)
- def _getCalls1(self, html=""):
+ def _getCalls1(self, callback):
#
# finally we should have successfully lgged in and filled the csv
#
self._callScreen.updateStatus(_("finishing"))
parms = urlencode({'getpage':'../html/de/FRITZ!Box_Anrufliste.csv', 'sid':self._md5Sid})
url = "http://%s/cgi-bin/webcm?%s" % (config.plugins.FritzCall.hostname.value, parms)
- getPage(url).addCallback(self._gotPageCalls).addErrback(self._errorCalls)
+ getPage(url).addCallback(lambda x:self._gotPageCalls(callback,x)).addErrback(self._errorCalls)
- def _gotPageCalls(self, csv=""):
+ def _gotPageCalls(self, callback, csv=""):
def _resolveNumber(number):
if number.isdigit():
if config.plugins.FritzCall.internal.value and len(number) > 3 and number[0] == "0": number = number[1:]
# if len(number) > 20: number = number[:20]
return number
- self._logout()
if csv:
debug("[FritzCallFBF] _gotPageCalls: got csv, setting callList")
if self._callScreen:
# debug("[FritzCallFBF] _gotPageCalls result:\n" + text
- if self._callCallback is not None:
+ if callback:
# debug("[FritzCallFBF] _gotPageCalls call callback with\n" + text
- self._callCallback(_callList)
- self._callCallback = None
+ callback(_callList)
self._callScreen = None
def _errorCalls(self, error):
debug("[FritzCallFBF] _errorCalls: %s" % (error))
text = _("FRITZ!Box - Could not load calls: %s") % error
self._notify(text)
- self._logout()
def dial(self, number):
''' initiate a call to number '''
self.number = number
self._login(self._dial)
- def _dial(self, html=None):
+ def _dial(self, html):
+ if html:
+ found = re.match('.*<p class="errorMessage">FEHLER: ([^<]*)</p>', html, re.S)
+ if found:
+ self._errorDial('Login: ' + found.group(1))
+ return
url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
parms = urlencode({
'getpage':'../html/de/menus/menu2.html',
def _okDial(self, html):
debug("[FritzCallFBF] okDial")
- self._logout()
def _errorDial(self, error):
debug("[FritzCallFBF] errorDial: $s" % error)
text = _("FRITZ!Box - Dialling failed: %s") % error
self._notify(text)
- self._logout()
def changeWLAN(self, statusWLAN):
''' get status info from FBF '''
self.statusWLAN = statusWLAN
self._login(self._changeWLAN)
- def _changeWLAN(self, html=None):
+ def _changeWLAN(self, html):
+ if html:
+ found = re.match('.*<p class="errorMessage">FEHLER: ([^<]*)</p>', html, re.S)
+ if found:
+ self._errorChangeWLAN('Login: ' + found.group(1))
+ return
url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
parms = urlencode({
'getpage':'../html/de/menus/menu2.html',
def _okChangeWLAN(self, html):
debug("[FritzCallFBF] okDial")
- self._logout()
def _errorChangeWLAN(self, error):
debug("[FritzCallFBF] _errorChangeWLAN: $s" % error)
text = _("FRITZ!Box - Failed changing WLAN: %s") % error
self._notify(text)
- self._logout()
def changeMailbox(self, whichMailbox):
''' switch mailbox on/off '''
self.whichMailbox = whichMailbox
self._login(self._changeMailbox)
- def _changeMailbox(self, html=None):
+ def _changeMailbox(self, html):
+ if html:
+ found = re.match('.*<p class="errorMessage">FEHLER: ([^<]*)</p>', html, re.S)
+ if found:
+ self._errorChangeMailbox('Login: ' + found.group(1))
+ return
debug("[FritzCallFBF] _changeMailbox")
url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
if self.whichMailbox == -1:
def _okChangeMailbox(self, html):
debug("[FritzCallFBF] _okChangeMailbox")
- self._logout()
def _errorChangeMailbox(self, error):
debug("[FritzCallFBF] _errorChangeMailbox: $s" % error)
text = _("FRITZ!Box - Failed changing Mailbox: %s") % error
self._notify(text)
- self._logout()
- def getInfo(self, callscreen, callback):
+ def getInfo(self, callback):
''' get status info from FBF '''
debug("[FritzCallFBF] getInfo")
- self._callScreen = callscreen
- self.infoCallback = callback
- self._login(self._getInfo)
+ self._login(lambda x:self._getInfo(callback,x))
- def _getInfo(self, html=None):
+ def _getInfo(self, callback, html):
# http://192.168.178.1/cgi-bin/webcm?getpage=../html/de/menus/menu2.html&var:lang=de&var:pagename=home&var:menu=home
debug("[FritzCallFBF] _getInfo: verify login")
if html:
found = re.match('.*<p class="errorMessage">FEHLER: ([^<]*)</p>', html, re.S)
if found:
- debug("[FritzCallFBF] _getInfo: Login failed: " + found.group(1))
- text = _("FRITZ!Box - Error logging in: %s") + found.group(1)
- self._notify(text)
+ self._errorGetInfo('Login: ' + found.group(1))
return
url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
headers={
'Content-Type': "application/x-www-form-urlencoded",
'Content-Length': str(len(parms))},
- postdata=parms).addCallback(self._okGetInfo).addErrback(self._errorGetInfo)
+ postdata=parms).addCallback(lambda x:self._okGetInfo(callback,x)).addErrback(self._errorGetInfo)
- def _okGetInfo(self, html):
+ def _okGetInfo(self, callback, html):
def readInfo(html):
boxInfo = None
upTime = None
info = readInfo(html)
debug("[FritzCallFBF] _okGetInfo info: " + str(info))
self._setProperties(info)
- self.infoCallback(info)
- self._logout()
+ if callback:
+ callback(info)
def _errorGetInfo(self, error):
debug("[FritzCallFBF] _errorGetInfo: %s" % (error))
text = _("FRITZ!Box - Error getting status: %s") % error
self._notify(text)
- self._logout()
# linkP = open("/tmp/FritzCall_errorGetInfo.htm", "w")
# linkP.write(error)
# linkP.close()
def reset(self):
self._login(self._reset)
- def _reset(self, html=None):
+ def _reset(self, html):
# POSTDATA=getpage=../html/reboot.html&errorpage=../html/de/menus/menu2.html&var:lang=de&var:pagename=home&var:errorpagename=home&var:menu=home&var:pagemaster=&time:settings/time=1242207340%2C-120&var:tabReset=0&logic:command/reboot=../gateway/commands/saveconfig.html
- self._callScreen.close()
+ if html:
+ found = re.match('.*<p class="errorMessage">FEHLER: ([^<]*)</p>', html, re.S)
+ if found:
+ self._errorReset('Login: ' + found.group(1))
+ return
+ if self._callScreen:
+ self._callScreen.close()
url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
parms = urlencode({
'getpage':'../html/reboot.html',
def _okReset(self, html):
debug("[FritzCallFBF] _okReset")
- self._logout()
def _errorReset(self, error):
debug("[FritzCallFBF] _errorReset: %s" % (error))
text = _("FRITZ!Box - Error resetting: %s") % error
self._notify(text)
- self._logout()
#===============================================================================
# def hangup(self):
# postdata=parms)
#===============================================================================
-# fritzbox = FritzCallFBF()
+fritzbox = FritzCallFBF()
class FritzMenu(Screen,HelpableScreen):
def __init__(self, session):
self["dect_active"].hide()
self.timer = eTimer()
- self.timer.callback.append(self._getInfo1)
+ self.timer.callback.append(self._getInfo)
self.onShown.append(lambda: self.timer.start(5000))
self.onHide.append(lambda: self.timer.stop())
self._getInfo()
def _getInfo(self):
- self._getInfo1(self)
-
- def _getInfo1(self, screen=None):
- fritzbox.getInfo(screen, self._fillMenu)
-
- def updateStatus(self, text):
- self["FBFInfo"].setText(_("Getting status from FRITZ!Box Fon...") + text)
+ fritzbox.getInfo(self._fillMenu)
def _fillMenu(self, status):
(boxInfo, upTime, ipAddress, wlanState, wlanEncrypt, dslState, dslSpeed, tamActive, dectActive) = status
def toggleWlan(self):
if self.wlanActive:
debug("[FritzMenu] toggleWlan off")
- FritzCallFBF(False).changeWLAN('0') # we need a separate container so we do not collide with getInfo
+ fritzbox.changeWLAN('0') # we need a separate container so we do not collide with getInfo
else:
debug("[FritzMenu] toggleWlan off")
- FritzCallFBF(False).changeWLAN('1') # we need a separate container so we do not collide with getInfo
+ fritzbox.changeWLAN('1') # we need a separate container so we do not collide with getInfo
def toggleMailbox(self, which):
debug("[FritzMenu] toggleMailbox")
if fritzbox.hasMailbox:
debug("[FritzMenu] toggleMailbox off")
- FritzCallFBF(False).changeMailbox(which) # we need a separate container so we do not collide with getInfo
+ fritzbox.changeMailbox(which) # we need a separate container so we do not collide with getInfo
def reset(self):
fritzbox.reset()
#===============================================================================
if config.plugins.FritzCall.fritzphonebook.value:
- FritzCallFBF(False).loadFritzBoxPhonebook()
+ fritzbox.loadFritzBoxPhonebook()
if DESKTOP_WIDTH <> 1280 or DESKTOP_HEIGHT <> 720:
config.plugins.FritzCall.fullscreen.value = False
def exit(self):
self.close()
+phonebook = FritzCallPhonebook()
class FritzCallSetup(Screen, ConfigListScreen, HelpableScreen):
self["config"].l.setList(self.list)
def save(self):
- global fritzbox
# debug("[FritzCallSetup] save"
for x in self["config"].list:
x[1].save()