check-mirrors return-mirrorlist.py,1.15,1.16

Michael Patrick McGrath (mmcgrath) fedora-extras-commits at redhat.com
Wed Aug 30 02:21:19 UTC 2006


Author: mmcgrath

Update of /cvs/fedora/check-mirrors
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv2059

Modified Files:
	return-mirrorlist.py 
Log Message:
Added better stats, also now takes top=x stat.

Fixed bug where no mirrors were returned if a no mirrors were found.  Should
have returned canonical



Index: return-mirrorlist.py
===================================================================
RCS file: /cvs/fedora/check-mirrors/return-mirrorlist.py,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- return-mirrorlist.py	11 Aug 2006 16:23:01 -0000	1.15
+++ return-mirrorlist.py	30 Aug 2006 02:21:16 -0000	1.16
@@ -20,12 +20,17 @@
 #      note: - maintaining the abovelist will become a royal bitch.
 # - Note, this script does have some dependancies on the file list
 #    This should be removed in later versions
-
+# - Top has SQL Injection issues. needs an isint()
 debug = False
 
+import os
+import sys
+import GeoIP
+import ConfigParser
+import cgi
+import sqlite
+
 # prettier errors
-print 'Content-type: text/plain'
-print
 
 # the errors might be in broken html - but at least you aren't chasing
 # through logs for them.
@@ -38,13 +43,6 @@
 VERSION = '0.2'
 
 
-import os
-import sys
-import GeoIP
-import ConfigParser
-import cgi
-import sqlite
-
 # - separate cgi script needed to return the proper geoip-based file for
 #    the requesting client's country, if it exists, otherwise return the global
 #    file.
@@ -52,44 +50,37 @@
 class ConfigHolder(object):
     pass
 
-class RepoDB:
-    def __init__(self, db):
-        (self.dbconn, self.dbcursor) = self.connect(db)
-        return None
-
-    def connect(self, db):
-        try:
-            conn = sqlite.connect(db)
-            cursor = conn.cursor()
-        except sqlite.Error, errmsg:
-            errorprint('Failed to connect to database: %s' % db)
-            errorprint('Err: %s ' % errmsg)
-            return None, None
+class Mirrors:
+    def __init__(self, db, repo, arch, country, showinvalid):
+        self.db=db
+        self.repo=repo
+        self.arch=arch
+        self.country=country
+        self.countrySQL=self.getCountry()
+        self.invalidSQL=self.showInvalid(showinvalid)
+
+    def getCountry(self):
+        if self.country.lower() == 'global':
+            return ''
         else:
-            return(conn, cursor)
-    
-    def getMirrors(self, repo, arch, country):
-#        if(arch.lower() != 'i386' || arch.lower() != 'ppc' || arch.lower() != 'x86_64'):
-#            print "# %s is not a valid arch" % arch
-#            return False
-            
-        if country.lower() == 'global':
-            countrysql = ""
+            return "and country='%s'" % self.country
+        
+    def showInvalid(self, showinvalid):
+        if showinvalid:
+            return ''
         else:
-            countrysql = "and country='%s'" % country
-        try:
-            self.dbcursor.execute('SELECT url FROM mirrors where valid=1 and repo="%s" and arch="%s" %s;' % (repo, arch, countrysql))
-        except sqlite.Error, err:
-            print "%s" % err
-
+            return 'and valid="1"'
+            
+    def getMirrors(self, repo, arch, country):
+        rows = self.db.selectQuery('SELECT url FROM mirrors where repo="%s" and arch="%s" %s %s;' % (repo, arch, self.invalidSQL, self.countrySQL))
         dataList = []
-        for row in self.dbcursor.fetchall():
+        for row in rows:
             dataList.append([ item for item in row])
         return dataList
 
-    def printMirrors(self, repo, arch, country):
+    def printMirrors(self):
         """ Print mirrors """
-        rows = self.getMirrors(repo, arch, country)
+        rows = self.getMirrors(self.repo, self.arch, self.country)
         results = 0
         for row in rows:
             for field in row:
@@ -97,29 +88,81 @@
                 results = results + 1
 
         if results == 0:
-            print "# No results found for country: %s\n# Defaulting to global" % country
-            self.printMirrors(repo, arch, 'global')
+            if self.country != 'global':
+                print '# No results found for country: %s\n# Defaulting to global' % self.country
+                self.printMirrors(repo, arch, 'global')
+            else:
+                print '# no mirrors found, using default'
+                return False
         else:
             return True
-            
+
+    def topMirrors(self, int):
+        """ Return the top n mirrors """
+        return self.db.selectQuery('''select url, (successes*100)/(failures+successes) as uptime from mirrors where repo='%s' and arch='%s' %s %s order by uptime desc limit '%s';''' % (self.repo, self.arch, self.invalidSQL, self.countrySQL, int))
+
+    def printTopMirrors(self, int):
+        """ Prints the top n mirrors """
+        results = 0
+        for row in self.topMirrors(int):
+            results = results + 1
+            print '%s # %s%%' % (row[0], row[1])
+        if results == 0:
+            print '# no results found, using default'
+            return False
+        else:
+            return True
+
     def printStats(self):
         """ Print statistical information about the mirrors """
+        htmlprint('<br><a href="?repo=%s&arch=%s&country=%s">No Stats</a>' % (self.repo, self.arch, self.country))
+        htmlprint('<br><a href="?repo=%s&arch=%s&stats=1&country=%s&showinvalid=1">Show invalid</a>' % (self.repo, self.arch, self.country))
+        htmlprint('<br><a href="?repo=%s&arch=%s&stats=1&country=%s">Valid only</a>' % (self.repo, self.arch, self.country))
+        rows = self.db.selectQuery('select *, (successes*100)/(failures+successes) as uptime from mirrors where repo="%s" and arch="%s" %s %s order by uptime desc;' % (self.repo, self.arch, self.invalidSQL, self.countrySQL))
+        htmlprint('<!-- Begin Statistical information -->')
+        for row in rows.fetchall():
+            htmlprint('<table>')
+            htmlprint('    <tr><th>URL:</th><th>%s</th></tr>' % row[4])
+            htmlprint('    <tr><td>Country:</td><td>%s</td></tr>' % row[3])
+            htmlprint('    <tr><td>Last Good:</td><td>%s</td></tr>' % row[8])
+            htmlprint('    <tr><td>Uptime</td><td>%i%%</td></tr>' % row[9])
+            htmlprint('    <tr><td>Valid</td><td>%i</td></tr>' % row[7])
+            htmlprint('</table>')
+        htmlprint('<!-- END Statistical information -->')
+        
+        return True
+        
+def htmlprint(str):
+    """ Why did I even bother with this? """
+    print "%s" % str
+
+class RepoDB:
+    def __init__(self, db):
+        self.db=db
+        (self.dbconn, self.dbcursor)= self.connect()
+        return None
+
+    def connect(self):
         try:
-            self.dbcursor.execute('SELECT * FROM mirrors;')
-        except sqlite.Error, err:
-            print "%s" % err
+            conn = sqlite.connect(self.db)
+            cursor = conn.cursor()
+        except sqlite.Error, errmsg:
+            errorprint('Failed to connect to database: %s' % db)
+            errorprint('Err: %s ' % errmsg)
+            return None, None
+        else:
+            return(conn, cursor)
 
-        for row in self.dbcursor.fetchall():
-            totalChecks = row[5] + row[6] * 1.0
-            good = 0.0
-            good = (row[6] / totalChecks * 1.0) * 100
-            print '# %s' % row[4]
-            print '# Country: %s' % row[3]
-            print '# Last Good: %s' % row[8]
-            print '# Uptime: %i%%' % good
-            print '# Valid: %i' % row[7]
-            print '# -----------------------------------'
-        return True
+    def selectQuery(self, query):
+        """ Run query and return the results """
+        try:
+            self.dbcursor.execute(query)
+        except sqlite.Error, err:
+            if debug == True:
+                print "%s" % err
+                print "Query: %s" % query
+                sys.exit(1)
+        return self.dbcursor
 
     def close(self):
         self.dbconn.cursor()
@@ -131,6 +174,7 @@
     config = ConfigHolder()
     config.paths = {}
     config.prefixes = {}
+    config.canonical = {}
     config.dbpath = ""
     
     for section in conf.sections():
@@ -139,6 +183,10 @@
             continue
         if conf.has_option(section, 'outputpath'):
             config.paths[section] = conf.get(section, 'outputpath')
+
+        if conf.has_option(section, 'canonical'):
+            config.canonical[section] = conf.get(section, 'canonical')
+
         if conf.has_option(section, 'file_prefix'):
             config.prefixes[section] = conf.get(section, 'file_prefix')
         else:
@@ -172,11 +220,16 @@
     
     
 def main():
-    config = get_config(CONFIG)
     form = cgi.FieldStorage()
+    if form.has_key('stats'):
+        print 'Content-type: text/html'
+    else:
+        print 'Content-type: text/plain'
+    print
+    
+    config = get_config(CONFIG)
     errors = sanity_check(config, form)
     DB = RepoDB(config.dbpath)
-    
     if errors:
         for error in errors:
             print '%s' % error
@@ -192,7 +245,7 @@
     
     lists_path = config.paths[repo]
     prefix = config.prefixes[repo]
-
+    canonical = config.canonical[repo]
     # get geoip resolution
     # if country-specific file exists
        # open and return
@@ -224,6 +277,7 @@
         if country_list[0] != 'global' and not os.path.exists(rp):
             country_list = ['global']
 
+
     for country in country_list:
         return_file = '%s/%s-%s-%s.txt' % (lists_path, prefix, country, arch)
         rp = os.path.realpath(return_file)
@@ -238,9 +292,19 @@
 #            continue
 
         print '# repo = %s country = %s arch = %s ' % (repo, country, arch)
-        DB.printMirrors(repo, arch, country)
+
+        mirrors = Mirrors(DB, repo, arch, country, form.has_key('showinvalid'))
+        
+        
         if form.has_key('stats'):
-            DB.printStats()
+            mirrors.printStats()
+        else:
+            if form.has_key('top'):
+                if not mirrors.printTopMirrors(form['top'].value):
+                    print canonical
+            else:
+                if not mirrors.printMirrors():
+                    print canonical
             
 #        fo = open(return_file, 'r')
 #        for line in fo.readlines():




More information about the fedora-extras-commits mailing list