#!/usr/bin/env python
# -*- coding: utf-8 -*-
#http://www.ip-phone-forum.de/showthread.php?t=246673
import sys
import os
import socket
######################################################
# Konfiguration und Optionen
######################################################
# IP des Routers
routerIP = 'fritz.box'
port = 49000
#### Asgabe-Methode 1, 2 oder 3 waehlen
style = 3
## Methode 1: komplette Ausgabe der Werte mit Balken in Textform - schnell, simpel und retro :)
"""Die folgende Zeile gehoert in die Conky-Konfigurationsdatei
${exec ~/.conky/upnp_traffic.py}
"""
## Methode 2: direkte Auswertung des Python-Skripts in Conky - relativ langsam, Skript muss jeweils fuer jede Variable durchlaufen
"""Die folgenden vier Zeilen gehoeren in die Conky-Konfigurationsdatei
Down: ${exec ~/.conky/upnp_traffic.py | sed -n 1p}
${execbar ~/.conky/upnp_traffic.py | sed -n 3p}
Up: ${exec ~/.conky/upnp_traffic.py | sed -n 2p}
${execbar ~/.conky/upnp_traffic.py | sed -n 4p}
"""
## Methode 3: schnelle, stabile Auswertung - Umweg ueber eine "Vermittlungs-Datei", Python-Skript schreibt die Werte in eine Textdatei, Conky liest die Werte aus
"""Die folgenden fuenf Zeilen gehoeren in die Conky-Konfigurationsdatei
${exec ~/.conky/upnp_traffic.py}
Down: ${exec cat ~/.conky/upnp_traffic_tmp | sed -n 1p}
${execbar cat ~/.conky/upnp_traffic_tmp | sed -n 3p}
Up: ${exec cat ~/.conky/upnp_traffic_tmp | sed -n 2p}
${execbar cat ~/.conky/upnp_traffic_tmp | sed -n 4p}
"""
#### IP-Adresse ausgeben (True oder False)
showIP = True
"""Die Zeile gehoert in die Conky-Konfigurationsdatei
## bei Methode 1:
WAN IP: ${exec ~/.conky/upnp_traffic.py | sed -n 5p}
## bei Methode 2:
WAN IP: ${exec cat ~/.conky/upnp_traffic_tmp | sed -n 5p}
"""
#### Uptime ausgeben (True oder False) Zeigt die abgelaufene Zeit, seit der der Router online ist
show_uptime = True
"""Die Zeile gehoert in die Conky-Konfigurationsdatei
## bei Methode 1:
Uptime: ${exec ~/.conky/upnp_traffic.py | sed -n 6p}
## bei Methode 2:
Uptime: ${exec cat ~/.conky/upnp_traffic_tmp | sed -n 6p}
"""
#### *optional: Progress-Balken-Optionen - Dies sind die Balken aus Methode Nr. 1
# mehr Infos unter http://code.activestate.com/recipes/577871/
custom_options = {
'end': 100, # Max. Prozentwert
'width': 37, # Breite
'fill': '-', # Fuellungs-Zeichen
'blank': '.', # Leer-Stellen-Zeichen
'format': '[%(fill)s|%(blank)s]' # Augabemuster
}
#### *optional: Pfad zum home-Verzeichnis des Benutzers. Nur fuer die Asgabe-Methode Nr. 3
homefolder = os.path.expanduser('~') # Standart ist os.path.expanduser('~')
conky_path = '.conky' # Conky Verzeichnis im Benutzerordner
temp_file_name = 'upnp_traffic_tmp' # Name der "Vermittlungs-Textdatei"
#### Textbausteine fuer moegliche Uebersetzung
text_download = "Down:\t"
text_upload = "Up:\t"
text_WAN_IP = "WAN IP:"
text_uptime = "Uptime:"
text_kibs = "KiBs"
text_mibs = "MiBs"
text_day = "Tag"
text_days = "Tage"
text_max_dl = "Max"
text_max_ul = "Max"
text_debug1 = "OK"
text_debug2 = "Error: Your Computer is connected with the router.\nBut can't connect to the web.\nMaybe some problems with your bad ISP or with hardware/cable?"
text_debug3 = "Error: Oh noo! No connection to the router... Check the IP settings!"
######################################################
# Ende der Konfiguration und Optionen
######################################################
# Werte automatisch in Kibibyte/Sek oder Mebibyte/Sek mit Suffix
def kbmb(x):
x = int(x)
if x < 900*1024: # ab 900 Kibibyte wird in Mebibyte angezeigt
value = x/1024 # Umrechnung Bytes in Kibibyte
value_suffix = text_kibs
else:
value = (float(x))/1048576 # Umrechnung Bytes in Mebibyte
value_suffix = text_mibs
value=round(value, 2) # Runden auf zwei Nachkomma-Stellen
return value, value_suffix
#kbmb()[0] entspricht dem Augabewert
#kbmb()[1] ist der Suffix KiBs / MiBs
# Sekunden in Tage, Stunden, Minuten, Sekunden umrechnen und formatiert zurueck geben
def dhms(seconds):
if seconds is None: return (0,0,0,0)
minutes = seconds / 60
seconds %= 60
hours = minutes / 60
minutes %= 60
days = hours / 24
hours %= 24
if days == 1:
return str(days) +' '+ text_day +' '+ "%02d:%02d:%02d" % (hours, minutes, seconds)
elif days > 1:
return str(days) +' '+ text_days +' '+ "%02d:%02d:%02d" % (hours, minutes, seconds)
elif days == 0:
return "%02d:%02d:%02d" % (hours, minutes, seconds)
elif days == 0 and hours == 0:
return "%02d:%02d" % (minutes, seconds)
elif days == 0 and hours == 0 and minutes == 0:
return "%02d" % (seconds)
# ###########################################################
# Informationen des Routers auslesen.
class upnp():
def __init__(self, host=routerIP, port=port):
self.host=host
self.port=port
# Sendet eine Anfrage an den Router und liefert den Antwortstring zurueck
def send_req_resp(self,controlURL,serviceType, action):
body='<?xml version="1.0"?>\n' \
'<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"\n' \
' s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">\n' \
' <s:Body>\n' \
' <u:'+action+' xmlns:u="urn:schemas-upnp-org:service:'+serviceType+'"/>\n' \
' </s:Body>\n' \
'</s:Envelope>\n'
pream='POST /upnp/control/'+controlURL+' HTTP/1.0\r\n' \
'HOST: '+self.host+':'+str(self.port)+'\r\n' \
'CONTENT-LENGTH: '+str(len(body))+'\r\n' \
'CONTENT-TYPE: text/xml; charset="utf-8"\r\n' \
'SOAPACTION: "urn:schemas-upnp-org:service:'+serviceType+'#'+action+'"\r\n\r\n'
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((self.host, self.port))
sock.send(pream + body)
resp = ""
while True:
data=sock.recv(1024)
if len(data)==0:
break
resp+=data
sock.close()
return(resp)
# liefert aus "xml_str" den Teilstring, der zwischen <"arg"> und </"arg"> steht.
def get_argument(self, xml_str, arg):
v="<"+arg+">"
p1=xml_str.find(v)
if p1>=0:
p2=xml_str.find("</"+arg+">", p1)
if p2>=0:
return(xml_str[p1+len(v):p2])
return(None)
# Liefert die Maximal-Werte der Verbindung.
def MaxBandwidth(self, div=1):
s=self.send_req_resp("WANCommonIFC1","WANCommonInterfaceConfig:1","GetCommonLinkProperties")
# /9 fuer "Bit/Sek" zu "Byte/Sek"
maxSnd=int(self.get_argument(s, "NewLayer1UpstreamMaxBitRate"))/9
maxRec=int(self.get_argument(s, "NewLayer1DownstreamMaxBitRate"))/9
return((maxRec/div, maxSnd/div))
# Liefert die aktuellen Uebertragungsraten.
def Traffic(self, div=1):
s=self.send_req_resp("WANCommonIFC1","WANCommonInterfaceConfig:1","GetAddonInfos")
snd=int(self.get_argument(s, "NewByteSendRate"))
rec=int(self.get_argument(s, "NewByteReceiveRate"))
return((rec/div, snd/div))
# Liefert die externe IP.
def ExternalIP(self, div=1):
s=self.send_req_resp("WANCommonIFC1","WANIPConnection:1","GetExternalIPAddress")
ip=str(self.get_argument(s, "NewExternalIPAddress"))
return ip
# Liefert die "Uptime".
def Uptime(self, div=1):
s=self.send_req_resp("WANCommonIFC1","WANIPConnection:1","GetStatusInfo")
uptime=int(self.get_argument(s, "NewUptime"))
try:
uptime = int(uptime)
except (ValueError,TypeError):
uptime = None
if uptime is None: uptime = 0
return dhms(uptime)
# Liefert den Verbindungs-Status.
def Status(self):
s=self.send_req_resp("WANDSLLinkC1","WANDSLLinkConfig:1","GetDSLLinkInfo")
status=str(self.get_argument(s, "NewLinkStatus"))
return status
# Verbindungs-Status pruefen
def checkConnection():
get=upnp()
try:
if get.Status() == 'Up' or 'Down' or 'Initializing':
status = 1
debug = text_debug1 # 'OK'
elif get.Status() == 'Unavailable':
status = 2
debug = text_debug2 # 'maybe some router/hardware problems?'
elif get.Status() != 'Up' or 'Down' or 'Initializing' or 'Unavailable':
status = 3
debug = text_debug3 # 'check IP settings!'
return status, debug
except socket.error, msg:
status = 4
debug = 'Socket error:' + str(msg)
return status, debug
## {{{ http://code.activestate.com/recipes/577871/ (r1)
class ProgressBar(object):
"""ProgressBar class holds the options of the progress bar.
The options are:
start State from which start the progress. For example, if start is
5 and the end is 10, the progress of this state is 50%
end State in which the progress has terminated.
width --
fill String to use for "filled" used to represent the progress
blank String to use for "filled" used to represent remaining space.
format Format
incremental
"""
def __init__(self, start=0, end=10, width=12, fill='=', blank='.', format='[%(fill)s>%(blank)s] %(progress)s%%', incremental=True):
super(ProgressBar, self).__init__()
self.start = start
self.end = end
self.width = width
self.fill = fill
self.blank = blank
self.format = format
self.incremental = incremental
self.step = 100 / float(width) #fix
self.reset()
def __add__(self, increment):
increment = self._get_progress(increment)
if 100 > self.progress + increment:
self.progress += increment
else:
self.progress = 100
return self
def __str__(self):
progressed = int(self.progress / self.step) #fix
fill = progressed * self.fill
blank = (self.width - progressed) * self.blank
return self.format % {'fill': fill, 'blank': blank, 'progress': int(self.progress)}
__repr__ = __str__
def _get_progress(self, increment):
return float(increment * 100) / self.end
def reset(self):
"""Resets the current progress to the start point"""
self.progress = self._get_progress(self.start)
return self
# Asgabe-Methode 1
def retroOutput():
get=upnp()
traffic = get.Traffic() # traffic[0] ist Download, traffic[1] ist Upload
# Prozentwert des Traffics
dwn_percent=int((float(traffic[0])/get.MaxBandwidth()[0])*100)
up_percent=int((float(traffic[1])/get.MaxBandwidth()[1])*100)
if (dwn_percent or up_percent) > 100: # pruefen ob Wert ueber 100%
return retroOutput()
else:
dwn_bar = ProgressBar(**custom_options) + dwn_percent # Download-Progress-Balken
up_bar = ProgressBar(**custom_options) + up_percent # Upload-Progress-Balken
print text_download, kbmb(traffic[0])[0], kbmb(traffic[0])[1] # Augabewert KiBs/MiBs mit Suffix
print dwn_bar, int(dwn_percent),"\b%" # Download-Progress-Balken und Prozentwert
print text_upload, kbmb(traffic[1])[0], kbmb(traffic[1])[1] # Augabewert KiBs/MiBs mit Suffix
print up_bar, int(up_percent),"\b%" # Upload-Progress-Balken und Prozentwert
if showIP == True: print text_WAN_IP, get.ExternalIP()
if show_uptime == True: print text_uptime, get.Uptime()
# Asgabe-Methode 2
def compactOutput():
get=upnp()
traffic = get.Traffic() # traffic[0] ist Download, traffic[1] ist Upload
# Prozentwert des Traffics
dwn_percent=int((float(traffic[0])/get.MaxBandwidth()[0])*100)
up_percent=int((float(traffic[1])/get.MaxBandwidth()[1])*100)
if (dwn_percent or up_percent) > 100: # pruefen ob Wert ueber 100%
return compactOutput()
else:
print kbmb(traffic[0])[0], kbmb(traffic[0])[1] # Download-Traffic
print kbmb(traffic[1])[0], kbmb(traffic[1])[1] # Upload-Traffic
print dwn_percent # Download-Prozent
print up_percent # Upload-Prozent
if showIP == True: print get.ExternalIP()
if show_uptime == True: print text_uptime, get.Uptime()
# Asgabe-Methode 3
def fileOutput():
tr_temp_file_path = homefolder + '/' + conky_path + '/' + temp_file_name # Pfad zur der Textdatei wird gebildet
get=upnp()
traffic = get.Traffic() # traffic[0] ist Download, traffic[1] ist Upload
# Prozentwert des Traffics
dwn_percent=int((float(traffic[0])/get.MaxBandwidth()[0])*100)
up_percent=int((float(traffic[1])/get.MaxBandwidth()[1])*100)
if (dwn_percent or up_percent) > 100: # pruefen ob Wert ueber 100%
return fileOutput()
else:
fobj = open(tr_temp_file_path, "w")
print >> fobj, kbmb(traffic[0])[0], kbmb(traffic[0])[1]
print >> fobj, kbmb(traffic[1])[0], kbmb(traffic[1])[1]
print >> fobj, dwn_percent
print >> fobj, up_percent
if showIP == True: print >> fobj, get.ExternalIP()
if show_uptime == True: print >> fobj, get.Uptime()
fobj.close()
# Ausgabewahl
def Output(method):
if method == 1: retroOutput()
elif method == 2: compactOutput()
elif method == 3: fileOutput()
# Ausgabe-Start
if checkConnection()[0] == 1: Output(style)
else: print checkConnection()[1]