From 858ed9350a3115195509d0fbc1cf11a5b9a80750 Mon Sep 17 00:00:00 2001 From: Vikraman Choudhury Date: Sun, 21 Aug 2011 20:11:37 +0530 Subject: commented server code --- server/__init__.py | 1 + server/about.py | 3 +++ server/arch.py | 1 + server/config.py | 6 ++++++ server/dbconfig.py | 6 ++++++ server/feature.py | 3 ++- server/helpers.py | 49 ++++++++++++++++++++++++++++++++++++---------- server/host.py | 25 +++++++++++++++++------ server/index.py | 1 + server/kwd.py | 7 ++++++- server/lang.py | 3 ++- server/mirror.py | 3 ++- server/package.py | 12 ++++++++++++ server/repo.py | 4 +++- server/search.py | 9 +++++++++ server/tests/test_host.py | 18 +++++++++++++++++ server/tests/test_index.py | 12 ++++++++++++ 17 files changed, 142 insertions(+), 21 deletions(-) diff --git a/server/__init__.py b/server/__init__.py index e69de29..3c6cfa2 100644 --- a/server/__init__.py +++ b/server/__init__.py @@ -0,0 +1 @@ +# Make this a python package diff --git a/server/about.py b/server/about.py index c808341..62eb30c 100644 --- a/server/about.py +++ b/server/about.py @@ -4,4 +4,7 @@ import web class About(object): def GET(self): + """ + Redirect to static about page + """ raise web.seeother('/static/about.html') diff --git a/server/arch.py b/server/arch.py index 814c7c4..b6ddc9f 100644 --- a/server/arch.py +++ b/server/arch.py @@ -11,6 +11,7 @@ class Arch(object): if helpers.is_json_request(): return helpers.serialize(arch_data) else: + # generate plot x_ticklabels = arch_data.keys() y_values = [ arch_data[a]['HOSTS'] for a in x_ticklabels ] arch_plot = helpers.barchart(title = 'Hosts per arch', x_label = 'Arch', diff --git a/server/config.py b/server/config.py index 98326ae..cca5c0e 100644 --- a/server/config.py +++ b/server/config.py @@ -17,7 +17,13 @@ db = web.database( render = web.template.render(rootdir + 'templates/', base='layout') def notfound(): + """ + Rendered for HTTP 404 errors + """ return web.notfound(render.error_404()) def internalerror(): + """ + Rendered for HTTP 500 errors + """ return web.internalerror(render.error_500()) diff --git a/server/dbconfig.py b/server/dbconfig.py index e5eb42c..f0a8418 100644 --- a/server/dbconfig.py +++ b/server/dbconfig.py @@ -5,12 +5,18 @@ import ConfigParser class DBConfig(object): def __init__(self, configfile): + """ + Initialie db config from configfile + """ self.config = ConfigParser.ConfigParser() if len(self.config.read(configfile)) == 0: sys.stderr.write('Cannot read ' + configfile) sys.exit(1) def get_config(self): + """ + Return db config as dict + """ ret = dict() try: ret['DB'] = self.config.get('MYSQL', 'DB') diff --git a/server/feature.py b/server/feature.py index 1ea1c36..68e8657 100644 --- a/server/feature.py +++ b/server/feature.py @@ -4,7 +4,8 @@ from config import render, db class Feature(object): def GET(self): - feature_count = db.query('SELECT FEATURE,COUNT(UUID) AS HOSTS FROM HOST_FEATURES NATURAL JOIN FEATURES GROUP BY FEATURE') + feature_count = db.query('SELECT FEATURE,COUNT(UUID) AS HOSTS\ + FROM HOST_FEATURES NATURAL JOIN FEATURES GROUP BY FEATURE') feature_data = dict() for t in feature_count: feature_data[t['FEATURE']] = {'HOSTS':t['HOSTS']} diff --git a/server/helpers.py b/server/helpers.py index 5b81cb3..6e12ae1 100644 --- a/server/helpers.py +++ b/server/helpers.py @@ -13,22 +13,24 @@ os.environ['HOME'] = '/tmp' from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.figure import Figure -# check valid uuid - def is_uuid(uuid): + """ + Check uuid validity + """ regex = re.compile(r'^(\w{8})-(\w{4})-(\w{4})-(\w{4})-(\w{12})$') return regex.search(uuid) -# convert uuid string to raw bytes - def uuidbin(string): - #TODO: string is not a valid uuid + """ + Convert uuid string to raw bytes + """ u = uuid.UUID(string) return u.bytes -# custom pkgsplit - def pkgsplit(pkgname): + """ + Custom pkgsplit + """ cpv={'cat':'','pkg':'','ver':''} cpvr = catpkgsplit(pkgname) if cpvr is None: @@ -43,10 +45,10 @@ def pkgsplit(pkgname): cpv['ver'] = cpv['ver'] + '-' + cpvr[3] return cpv -# get functions for index keys -# lookup key and insert if not found - def get_kwkey(db, keyword): + """ + Lookup keyword and return index key. Insert keyword if not found. + """ if keyword is None: return None db_keyword = db.select('KEYWORDS', vars={'keyword':keyword}, where='KEYWORD=$keyword') @@ -57,6 +59,9 @@ def get_kwkey(db, keyword): return kwkey def get_lkey(db, lang): + """ + Lookup lang and return index key. Insert lang if not found. + """ if lang is None: return None db_lang = db.select('LANG', vars={'lang':lang}, where='LANG=$lang') @@ -67,6 +72,9 @@ def get_lkey(db, lang): return lkey def get_fkey(db, feature): + """ + Lookup feature and return index key. Insert feature if not found. + """ if feature is None: return None db_feature = db.select('FEATURES', vars={'feature':feature}, where='FEATURE=$feature') @@ -77,6 +85,9 @@ def get_fkey(db, feature): return fkey def get_mkey(db, mirror): + """ + Lookup mirror and return index key. Insert mirror if not found. + """ if mirror is None: return None db_mirror = db.select('GENTOO_MIRRORS', vars={'mirror':mirror}, where='MIRROR=$mirror') @@ -87,6 +98,9 @@ def get_mkey(db, mirror): return mkey def get_ukey(db, useflag): + """ + Lookup useflag and return index key. Insert useflag if not found. + """ if useflag is None: return None db_useflag = db.select('USEFLAGS', vars={'useflag':useflag}, where='USEFLAG=$useflag') @@ -97,6 +111,9 @@ def get_ukey(db, useflag): return ukey def get_pkey(db, package): + """ + Lookup package and return index key. Insert package if not found. + """ if package is None: return None cpv = pkgsplit(package) @@ -108,6 +125,9 @@ def get_pkey(db, package): return pkey def get_rkey(db, repo): + """ + Lookup repo and return index key. Insert repo if not found. + """ if repo is None: return None db_repo = db.select('REPOSITORIES', vars={'repo':repo}, where='REPO=$repo') @@ -118,9 +138,15 @@ def get_rkey(db, repo): return rkey def is_json_request(): + """ + Check for json headers + """ return web.ctx.environ['HTTP_ACCEPT'].find('json') != -1 def serialize(object, human=True): + """ + Encode object in json + """ if human: indent = 2 else: @@ -128,6 +154,9 @@ def serialize(object, human=True): return json.JSONEncoder(indent=indent).encode(object) def barchart(title, x_label, x_ticklabels, y_label, y_values): + """ + Generate a barchart and return base64 encoded image data + """ fig = Figure() canvas = FigureCanvas(fig) ind = range(len(y_values)) diff --git a/server/host.py b/server/host.py index 7fd8132..c354939 100644 --- a/server/host.py +++ b/server/host.py @@ -6,6 +6,7 @@ import config from web import form from config import render, db +# host search form host_form = form.Form( form.Textbox('uuid', description = 'UUID'), form.Button('submit', description = 'Submit') @@ -36,32 +37,44 @@ class Host(object): host_data[var] = e[var] host_data['FEATURES'] = list() - features = db.query('SELECT FEATURE FROM HOST_FEATURES NATURAL JOIN FEATURES WHERE UUID=$uuid', vars={'uuid':uuid}) + features = db.query('SELECT FEATURE\ + FROM HOST_FEATURES NATURAL JOIN FEATURES\ + WHERE UUID=$uuid', vars={'uuid':uuid}) for f in features: host_data['FEATURES'].append(f['FEATURE']) host_data['ACCEPT_KEYWORDS'] = list() - keywords = db.query('SELECT KEYWORD FROM GLOBAL_KEYWORDS NATURAL JOIN KEYWORDS WHERE UUID=$uuid', vars={'uuid':uuid}) + keywords = db.query('SELECT KEYWORD\ + FROM GLOBAL_KEYWORDS NATURAL JOIN KEYWORDS\ + WHERE UUID=$uuid', vars={'uuid':uuid}) for k in keywords: host_data['ACCEPT_KEYWORDS'].append(k['KEYWORD']) host_data['USE'] = list() - useflags = db.query('SELECT USEFLAG FROM GLOBAL_USEFLAGS NATURAL JOIN USEFLAGS WHERE UUID=$uuid', vars={'uuid':uuid}) + useflags = db.query('SELECT USEFLAG\ + FROM GLOBAL_USEFLAGS NATURAL JOIN USEFLAGS\ + WHERE UUID=$uuid', vars={'uuid':uuid}) for u in useflags: host_data['USE'].append(u['USEFLAG']) host_data['LANG'] = list() - lang = db.query('SELECT LANG FROM HOST_LANG NATURAL JOIN LANG WHERE UUID=$uuid', vars={'uuid':uuid}) + lang = db.query('SELECT LANG\ + FROM HOST_LANG NATURAL JOIN LANG\ + WHERE UUID=$uuid', vars={'uuid':uuid}) for l in lang: host_data['LANG'].append(l['LANG']) host_data['GENTOO_MIRRORS'] = list() - mirrors = db.query('SELECT MIRROR FROM HOST_MIRRORS NATURAL JOIN GENTOO_MIRRORS WHERE UUID=$uuid', vars={'uuid':uuid}) + mirrors = db.query('SELECT MIRROR\ + FROM HOST_MIRRORS NATURAL JOIN GENTOO_MIRRORS\ + WHERE UUID=$uuid', vars={'uuid':uuid}) for m in mirrors: host_data['GENTOO_MIRRORS'].append(m['MIRROR']) host_data['PACKAGES'] = dict() - packages = db.query('SELECT CAT, PKG, VER FROM INSTALLED_PACKAGES NATURAL JOIN PACKAGES WHERE UUID=$uuid ORDER BY CAT, PKG, VER', vars={'uuid':uuid}) + packages = db.query('SELECT CAT, PKG, VER\ + FROM INSTALLED_PACKAGES NATURAL JOIN PACKAGES\ + WHERE UUID=$uuid ORDER BY CAT, PKG, VER', vars={'uuid':uuid}) for p in packages: cpv = p['CAT'] + '/' + p['PKG'] + '-' + p['VER'] host_data['PACKAGES'][cpv] = dict() diff --git a/server/index.py b/server/index.py index 2204bd3..808759c 100644 --- a/server/index.py +++ b/server/index.py @@ -2,6 +2,7 @@ from web import form from config import render, db +# package search form search_form = form.Form( form.Textbox('cat', value = 'any', description = 'Category'), form.Textbox('pkg', value = 'any', description = 'Package'), diff --git a/server/kwd.py b/server/kwd.py index 779ac61..d9b30e2 100644 --- a/server/kwd.py +++ b/server/kwd.py @@ -4,13 +4,18 @@ from config import render, db class Keyword(object): def GET(self): - keyword_count = db.query('SELECT KEYWORD, COUNT(DISTINCT IPKEY) AS PACKAGES, COUNT(DISTINCT UUID) AS HOSTS FROM GLOBAL_KEYWORDS NATURAL JOIN KEYWORDS NATURAL JOIN INSTALLED_PACKAGES GROUP BY KEYWORD') + keyword_count = db.query('SELECT KEYWORD,\ + COUNT(DISTINCT IPKEY) AS PACKAGES,\ + COUNT(DISTINCT UUID) AS HOSTS\ + FROM GLOBAL_KEYWORDS NATURAL JOIN KEYWORDS\ + NATURAL JOIN INSTALLED_PACKAGES GROUP BY KEYWORD') keyword_data = dict() for t in keyword_count: keyword_data[t['KEYWORD']] = {'HOSTS':t['HOSTS'], 'PACKAGES':t['PACKAGES']} if helpers.is_json_request(): return helpers.serialize(keyword_data) else: + # generate plot x_ticklabels = keyword_data.keys() y_values = [ keyword_data[k]['PACKAGES'] for k in x_ticklabels ] keyword_plot = helpers.barchart(title = 'Installed packages per keyword', diff --git a/server/lang.py b/server/lang.py index de6c625..5052378 100644 --- a/server/lang.py +++ b/server/lang.py @@ -4,7 +4,8 @@ from config import render, db class Lang(object): def GET(self): - lang_count = db.query('SELECT LANG,COUNT(UUID) AS HOSTS FROM HOST_LANG NATURAL JOIN LANG GROUP BY LANG') + lang_count = db.query('SELECT LANG,COUNT(UUID) AS HOSTS\ + FROM HOST_LANG NATURAL JOIN LANG GROUP BY LANG') lang_data = dict() for t in lang_count: lang_data[t['LANG']] = {'HOSTS':t['HOSTS']} diff --git a/server/mirror.py b/server/mirror.py index e701404..4055c09 100644 --- a/server/mirror.py +++ b/server/mirror.py @@ -4,7 +4,8 @@ from config import render, db class Mirror(object): def GET(self): - mirror_count = db.query('SELECT MIRROR,COUNT(UUID) AS HOSTS FROM HOST_MIRRORS NATURAL JOIN GENTOO_MIRRORS GROUP BY MIRROR') + mirror_count = db.query('SELECT MIRROR,COUNT(UUID) AS HOSTS\ + FROM HOST_MIRRORS NATURAL JOIN GENTOO_MIRRORS GROUP BY MIRROR') mirror_data = dict() for t in mirror_count: mirror_data[t['MIRROR']] = {'HOSTS':t['HOSTS']} diff --git a/server/package.py b/server/package.py index aa037e5..e73a139 100644 --- a/server/package.py +++ b/server/package.py @@ -24,6 +24,9 @@ class Package(object): return config.internalerror() def __GET(self, top): + """ + Get category + """ p_query = db.query('SELECT COUNT(DISTINCT UUID) AS HOST_COUNT, \ COUNT(DISTINCT CAT) AS C_COUNT, \ COUNT(DISTINCT CAT, PKG) AS CP_COUNT, \ @@ -44,6 +47,9 @@ class Package(object): return render.package(p_data) def __GET_C(self, top, cat): + """ + Get category/package + """ p_query = db.query('SELECT COUNT(DISTINCT UUID) AS HOST_COUNT, \ COUNT(DISTINCT CAT, PKG) AS CP_COUNT, \ COUNT(DISTINCT CAT, PKG, VER) AS CPV_COUNT\ @@ -63,6 +69,9 @@ class Package(object): return render.package_c(cat, p_data) def __GET_CP(self, top, cat, pkg): + """ + Get category/package-version + """ p_query = db.query('SELECT COUNT(DISTINCT UUID) AS HOST_COUNT, \ COUNT(DISTINCT CAT, PKG, VER) AS CPV_COUNT\ FROM INSTALLED_PACKAGES RIGHT OUTER JOIN PACKAGES\ @@ -94,6 +103,9 @@ class Package(object): return render.package_cpv(cat, pkg, ver, p_data) def __top(self, count, *args): + """ + Find top entries + """ t_list = list() if len(args) == 0: tc_query = db.query('SELECT CAT, COUNT(DISTINCT UUID) AS HOST_COUNT\ diff --git a/server/repo.py b/server/repo.py index 7be99ac..f129fa0 100644 --- a/server/repo.py +++ b/server/repo.py @@ -4,7 +4,9 @@ from config import render, db class Repo(object): def GET(self): - repo_count = db.query('select REPO,COUNT(DISTINCT IPKEY) AS PACKAGES,COUNT(DISTINCT UUID) AS HOSTS from INSTALLED_PACKAGES natural join REPOSITORIES group by REPO') + repo_count = db.query('SELECT REPO,COUNT(DISTINCT IPKEY) AS PACKAGES,\ + COUNT(DISTINCT UUID) AS HOSTS\ + FROM INSTALLED_PACKAGES NATURAL JOIN REPOSITORIES GROUP BY REPO') repo_data = dict() for t in repo_count: repo_data[t['REPO']] = {'HOSTS':t['HOSTS'], 'PACKAGES':t['PACKAGES']} diff --git a/server/search.py b/server/search.py index d3d35d5..5543047 100644 --- a/server/search.py +++ b/server/search.py @@ -49,6 +49,9 @@ class Search(object): return render.search(search_tuples) def _build_query(self, where, having): + """ + Build SELECT clause + """ sep = ' ' query = '' query += 'SELECT' + sep + ','.join(what) + sep @@ -66,6 +69,9 @@ class Search(object): return query.strip() def _build_where(self): + """ + Build WHERE clause + """ where = [] cat = string.lower(self.args.cat) if cat != 'any': @@ -85,6 +91,9 @@ class Search(object): return where def _build_having(self): + """ + Build HAVING clause + """ having = [] if self.min_hosts != -1: having.append('HOSTS>=$min_hosts') diff --git a/server/tests/test_host.py b/server/tests/test_host.py index b781a09..1b68050 100644 --- a/server/tests/test_host.py +++ b/server/tests/test_host.py @@ -7,14 +7,23 @@ from app import app class TestHost(unittest.TestCase): def setUp(self): + """ + Initialize browser + """ self.b = app.browser() def test_basic(self): + """ + Test /host + """ self.b.open('/host') self.assertEqual(self.b.path, '/host') self.assertEqual(self.b.status, 404) def test_get(self): + """ + Test GET + """ uri = '/host/' + str(uuid.uuid4()) self.b.open(uri) self.assertEqual(self.b.path, uri) @@ -25,6 +34,9 @@ class TestHost(unittest.TestCase): self.assertEqual(self.b.status, 404) def test_post_empty(self): + """ + Test empty POST + """ str_uuid = str(uuid.uuid4()) uri = '/host/' + str_uuid # post with empty string @@ -47,6 +59,9 @@ class TestHost(unittest.TestCase): self.assertEqual(self.b.status, 500) def test_post_bad(self): + """ + Test bad POST + """ str_uuid = str(uuid.uuid4()) uri = '/host/' + str_uuid # different uuid in payload @@ -61,6 +76,9 @@ class TestHost(unittest.TestCase): self.assertTrue('Invalid uuid' in self.b.data) def test_post_get(self): + """ + Test GET using POST + """ str_uuid = str(uuid.uuid4()) uri = '/host/' + str_uuid payload = { diff --git a/server/tests/test_index.py b/server/tests/test_index.py index f77a60d..0fdc740 100644 --- a/server/tests/test_index.py +++ b/server/tests/test_index.py @@ -5,17 +5,29 @@ from app import app class TestIndex(unittest.TestCase): def setUp(self): + """ + Initialize browser + """ self.b = app.browser() self.b.open('/') def test_basic(self): + """ + Test / + """ self.assertEqual(self.b.path, '/') self.assertEqual(self.b.status, 200) def test_content(self): + """ + Test html + """ self.assertTrue('Welcome to the gentoostats webapp' in self.b.data) def test_hosts(self): + """ + Test host count from html + """ self.assertTrue('Number of hosts' in self.b.data) lines = self.b.data.split('\n') for line in lines: -- cgit v1.2.3-65-gdbad