Skip to content

Instantly share code, notes, and snippets.

@kyuucr
Last active December 15, 2015 03:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyuucr/5195607 to your computer and use it in GitHub Desktop.
Save kyuucr/5195607 to your computer and use it in GitHub Desktop.
This is an Ubuntu Unity Indicator to track your Dorm internet usage in NTUST. Added manual update quota, changed html parser. Written on Python 2.7
#!/usr/bin/env python
# -*- coding: utf8 -*-
import appindicator
import bs4
import datetime
import glib
import gtk
import logging
import pynotify
import re
import requests
import socket
import sys
logging.basicConfig(level=logging.DEBUG)
capabilities = {'actions': False,
'body': False,
'body-hyperlinks': False,
'body-images': False,
'body-markup': False,
'icon-multi': False,
'icon-static': False,
'sound': False,
'image/svg+xml': False,
'private-synchronous': False,
'append': False,
'private-icon-only': False}
def initCaps():
caps = pynotify.get_server_caps()
if caps is None:
print "Failed to receive server caps."
sys.exit(1)
for cap in caps:
capabilities[cap] = True
def printCaps():
info = pynotify.get_server_info()
print "Name: " + info["name"]
print "Vendor: " + info["vendor"]
print "Version: " + info["version"]
print "Spec. Version: " + info["spec-version"]
caps = pynotify.get_server_caps()
if caps is None:
print "Failed to receive server caps."
sys.exit(1)
print "Supported capabilities/hints:"
if capabilities['actions']:
print "\tactions"
if capabilities['body']:
print "\tbody"
if capabilities['body-hyperlinks']:
print "\tbody-hyperlinks"
if capabilities['body-images']:
print "\tbody-images"
if capabilities['body-markup']:
print "\tbody-markup"
if capabilities['icon-multi']:
print "\ticon-multi"
if capabilities['icon-static']:
print "\ticon-static"
if capabilities['sound']:
print "\tsound"
if capabilities['image/svg+xml']:
print "\timage/svg+xml"
if capabilities['private-synchronous']:
print "\tprivate-synchronous"
if capabilities['append']:
print "\tappend"
if capabilities['private-icon-only']:
print "\tprivate-icon-only"
print "Notes:"
if info["name"] == "notify-osd":
print "\tx- and y-coordinates hints are ignored"
print "\texpire-timeout is ignored"
print "\tbody-markup is accepted but filtered"
else:
print "\tnone"
class ThreadClass():
def __init__(self, menu_items):
self.__menu_items = menu_items
self.__set_menu_message_default()
self.__menu_items[4].set_label("Update now")
self.__menu_items[4].connect("activate", self.updateQuota)
self.__usage_alert = pynotify.Notification("NTUST Dormweb Indicator", "Your quota has reached 2.5 GB", "dialog-warning")
def run(self):
try:
self.updateQuota("")
except Exception:
# if anything happen, just set the default message
logging.exception("Something happened! Set default message..")
self.__set_menu_message_default()
ind.set_status(appindicator.STATUS_ATTENTION)
finally:
# set interval
logging.debug("UPDATED " + datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
glib.timeout_add(300000, self.run)
def updateQuota(self, w):
date = datetime.datetime.now()
# query IP address
logging.debug("Querying IP address..")
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("netweb.ntust.edu.tw", 80))
ip = s.getsockname()[0]
s.close()
logging.debug("IP " + ip)
# query usage
logging.debug("Querying Usage..")
usage = self.requestUsage(ip, date.strftime("%Y/%m/%d"))
logging.debug(usage)
if usage[0] > 2500000000:
self.__usage_alert.show()
ind.set_status(appindicator.STATUS_ATTENTION)
else:
ind.set_status(appindicator.STATUS_ACTIVE)
self.__set_menu_message([
ip,
"{0:.2f}".format(usage[0] / 1000000) + " MB",
"{0:.2f}".format(usage[1] / 1000000) + " MB",
"{0:.2f}".format(usage[2] / 1000000) + " MB"
])
def requestUsage(self, ip, datestring):
# define post variables then request to netweb page
payload = {"__EVENTTARGET": "ipdata",
"__EVENTARGUMENT": "",
"__VIEWSTATE": "dDwtNDY0NjA5NTM4O3Q8O2w8aTwyPjs+O2w8dDw7bDxpPDE+O2k8Mz47aTw1PjtpPDc+O2k8MTM+Oz47bDx0PDtsPGk8MT47aTw3PjtpPDk+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPOWci+eri+WPsOeBo+enkeaKgOWkp+WtuCDlsI3lpJbntrLot6/mtYHph4/mn6XoqaI7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPOeZu+WFpeaXpeacn++8mjIwMTMvMDMvMTk7Pj47Pjs7Pjt0PDtsPGk8MD47PjtsPHQ8O2w8aTwxPjtpPDI+Oz47bDx0PDtsPGk8MD47PjtsPHQ8dDw7O2w8aTwwPjs+Pjs7Pjs+Pjt0PDtsPGk8MT47PjtsPHQ8dDxwPHA8bDxEYXRhVGV4dEZpZWxkOz47bDxTdHJpbmdUZXh0Oz4+Oz47dDxpPDQ+O0A8Qnl0ZXM7S0I7TUI7R0I7PjtAPEJ5dGVzO0tCO01CO0dCOz4+Oz47Oz47Pj47Pj47Pj47Pj47dDw7bDxpPDc+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPFxlOz4+Oz47Oz47Pj47dDxwPHA8bDxUZXh0Oz47bDxcPGJyXD7ms6jmhI/vvJrlm6DntbHoqIjln7rmupbkuI3lkIzvvIzoq4vli7/oiIflgIvkurrpm7vohabmr5TovIPvvIzlpoLmnInllY/poYzoq4ttYWls5YiwIGNjcG9zdG1hbkBtYWlsLm50dXN0LmVkdS50dyDoqI7oq5bjgII7Pj47Pjs7Pjt0PHA8cDxsPFZpc2libGU7PjtsPG88Zj47Pj47PjtsPGk8MT47aTwzPjs+O2w8dDxwPHA8bDxUZXh0Oz47bDzoqbPntLDmtYHph4/mn6XoqaI7Pj47Pjs7Pjt0PEAwPHA8cDxsPFBhZ2VTaXplOz47bDxpPDMyNzYwPjs+Pjs+Ozs7Ozs7Ozs7Oz47Oz47Pj47dDxwPHA8bDxWaXNpYmxlOz47bDxvPGY+Oz4+Oz47bDxpPDE+O2k8NT47aTw3PjtpPDk+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPCo7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFxlOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDwwOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxcZTs+Pjs+Ozs+Oz4+Oz4+Oz4+Oz52G6uOlzw4wrbT3T3UWSV19EjV9Q==",
"RB_1": "詳細流量查詢",
"un": "Bytes",
"do_date": datestring,
"ipdata": ip,
"hip": re.sub('[0-9]+\.[0-9]+$', '', ip),
"msg_sysadm": ",請撥分機6212洽管理者!",
"p_ip": ip,
"dorm": "",
"pdate": datestring,
"page_size": "32760",
"sel_str": "dodate='*****'",
"tablename": "ipflowtable",
"tot_columns": "4",
"tot_rows": "0",
"tinsert": "",
"hmaxlen": "10,14,14,14,13,10,13,6,6,13,20,15,15,15,15",
"od_str": "",
"un_v": "1"}
r = requests.post('http://netweb.ntust.edu.tw/dormweb/flowquery.aspx', data=payload)
# response text to DOM using BeautifulSoup
soup = bs4.BeautifulSoup(r.text, "html.parser")
total = float(soup.find(id="tablelist__ctl3_tid1")["value"].replace(",", ""))
upload = float(soup.find(id="tablelist__ctl3_tid2")["value"].replace(",", ""))
download = float(soup.find(id="tablelist__ctl3_tid3")["value"].replace(",", ""))
return [total, upload, download]
def __set_menu_message_default(self):
self.__set_menu_message(["N/A", "N/A", "N/A", "N/A"])
def __set_menu_message(self, msg):
self.__menu_items[0].set_label("Local address: " + msg[0])
self.__menu_items[1].set_label("Total: " + msg[1])
self.__menu_items[2].set_label("Upload: " + msg[2])
self.__menu_items[3].set_label("Download: " + msg[3])
if __name__ == "__main__":
if not pynotify.init("summary-body"):
sys.exit(1)
# call this so we can savely use capabilities dictionary later
initCaps()
# show what's supported
printCaps()
ind = appindicator.Indicator("ntust-dormweb-indicator",
"nm-adhoc",
appindicator.CATEGORY_APPLICATION_STATUS)
ind.set_status(appindicator.STATUS_ACTIVE)
ind.set_attention_icon("new-messages-red")
# create a menu
menu = gtk.Menu()
# create some menu items
menu_items = []
for x in xrange(1, 6):
menu_item = gtk.MenuItem()
menu_items.append(menu_item)
menu.append(menu_item)
menu_item.show()
# set the menu
ind.set_menu(menu)
# fire up the thread!
t = ThreadClass(menu_items)
t.run()
gtk.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment