[svn] commit: r2188 - /branches/tingting-loadzone/src/lib/python/isc/datasrc/master.py

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Jun 21 03:10:30 UTC 2010


Author: shentingting
Date: Mon Jun 21 03:10:30 2010
New Revision: 2188

Log:
modifying the code after shane reviewed, I corrected some spelling mistakes and change threading stuff to printing periodically

Modified:
    branches/tingting-loadzone/src/lib/python/isc/datasrc/master.py

Modified: branches/tingting-loadzone/src/lib/python/isc/datasrc/master.py
==============================================================================
--- branches/tingting-loadzone/src/lib/python/isc/datasrc/master.py (original)
+++ branches/tingting-loadzone/src/lib/python/isc/datasrc/master.py Mon Jun 21 03:10:30 2010
@@ -123,22 +123,23 @@
 #   MasterFileError
 #########################################################################
 def parse_ttl(s):
-    group = re.split('([0-9]+[wdhms]?)', s, 0, re.I)
     sum = 0
-    for el in group:
-        if not el:
+    if not isttl(s):
+        raise MasterFileError('Invalid TTL: ' + s)
+    for ttl_expr in re.findall('\d+[wdhms]?', s, re.I):
+        if re.match('\d+$', ttl_expr):
+            ttl = int(ttl_expr[:])
+            sum += ttl
             continue
-        m = re.match('([0-9]+)(.*)', el)
-        if not m:
-            raise MasterFileError('Invalid TTL: ' + s)
-        ttl, suffix = int(m.group(1)), m.group(2)
-        if suffix.lower() == 'w':
+        ttl = int(ttl_expr[:-1])
+        suffix = ttl_expr[-1].lower()
+        if suffix == 'w':
             ttl *= 604800
-        elif suffix.lower() == 'd':
+        elif suffix == 'd':
             ttl *= 86400
-        elif suffix.lower() == 'h':
+        elif suffix == 'h':
             ttl *= 3600
-        elif suffix.lower() == 'm':
+        elif suffix == 'm':
             ttl *= 60
         sum += ttl
     return str(sum)
@@ -205,7 +206,13 @@
         self.__initial_origin = initial_origin
         self.__origin = initial_origin
         self.__datafile = filename
-        self.__filesize = os.stat(filename).st_size
+
+        try:
+            self.__zonefile = open(filename, 'r')
+        except:
+            raise MasterFileError("Could not open " + filename)
+        self.__filesize = os.fstat(self.__zonefile.fileno()).st_size
+
         self.__cur = 0
         self.__numback = 0
         self.__verbose = verbose
@@ -216,12 +223,14 @@
 
     def __status(self):
         interval = time.time() - MasterFile.__init_time
-        percent = (self.__cur * 100)/self.__filesize
-        sys.stdout.write("\r%s" % (80 * " "))
-        sys.stdout.write("\r%d RR(s) loaded in %d second(s)(%.2f%% of %s%s)"\
+        if self.__filesize ==0:
+            percent = 100
+        else:
+            percent = (self.__cur * 100)/self.__filesize
+
+        sys.stdout.write("\r" + (80 * " "))
+        sys.stdout.write("\r%d RR(s) loaded in %d second(s) (%.2f%% of %s%s)"\
                 % (MasterFile.__records_num, interval, percent, MasterFile.__file_type, self.__datafile))
-        self.__t = threading.Timer(1.0, self.__status)
-        self.__t.start()
 
     def __del__(self):
         if self.__zonefile:
@@ -290,21 +299,26 @@
     # throws:
     #   MasterFileError
     #########################################################################
-    __filename = re.compile('[\"\']*([^\'\"]+)[\"\']*')
+    __include_syntax1 = re.compile('\s+(\S+)(?:\s+(\S+))?$', re.I)
+    __include_syntax2 = re.compile('\s+"([^"]+)"(?:\s+(\S+))?$', re.I)
+    __include_syntax3 = re.compile("\s+'([^']+)'(?:\s+(\S+))?$", re.I)
     def __include(self, s):
-        list = s.split()
-        file, origin = "", ""
-        if re.match('\$include', list[0], re.I):
-            if len(list) != 2 and len(list) != 3:
-                raise MasterFileError('Invalid $include formal')
-            m = self.__filename.match(list[1])
-            if m:
-                file = m.group(1)
-            if len(list) == 3:
-                if not isname(list[2]):
-                    raise MasterFileError('Invalid $include formal')
-                origin = self.__statedname(list[2], s)
-        if origin == "":
+        if not s.lower().startswith('$include'):
+            return "", ""
+        s = s[len('$include'):]
+        m =self. __include_syntax1.match(s)
+        if not m:
+            m = self.__include_syntax2.match(s)
+        if not m:
+            m = self.__include_syntax3.match(s)
+        if not m:
+            raise MasterFileError('Invalid $include format')
+        file = m.group(1)
+        if m.group(2):
+            if not isname(m.group(2)):
+                raise MasterFileError('Invalid $include format (invalid origin)')
+            origin = self.__statedname(m.group(2), s)
+        else:
             origin = self.__origin
         return file, origin
 
@@ -339,6 +353,9 @@
     # returns:
     #   empty list if parse failed, else name, ttl, class, type, rdata
     #########################################################################
+    def __getttl(self):
+        return MasterFile.__ttl or MasterFile.__lastttl
+
     def __three(self, record, curname):
         ret = ''
         list = record.split()
@@ -347,7 +364,7 @@
         if istype(list[2]) and not istype(list[1]):
             if isclass(list[1]) and not isttl(list[0]) and isname(list[0]):
                 rrclass = list[1]
-                ttl = MasterFile.__ttl or MasterFile.__lastttl
+                ttl = self.__getttl()
                 name = list[0]
             elif not isclass(list[1]) and isttl(list[1]) and isname(list[0]):
                 rrclass = self.__rrclass
@@ -387,7 +404,7 @@
             rrtype = list[1]
             if list[0].lower() == 'rrsig':
                 name = curname
-                ttl = MasterFile.__ttl or MasterFile.__lastttl
+                ttl = self.__getttl()
                 rrtype = list[0]
                 rdata = ' '.join(list[1:])
             elif isttl(list[0]):
@@ -396,34 +413,19 @@
                 rdata = ' '.join(list[2:])
             elif isname(list[0]):
                 name = list[0]
-                ttl = MasterFile.__ttl or MasterFile.__lastttl
+                ttl = self.__getttl()
                 rdata = ' '.join(list[2:])
             else:
                 raise MasterFileError("Cannot parse RR: " + record)
 
             ret = name, ttl, rrclass, rrtype, rdata
         return ret
+
     ########################################################################
-    # print status information, the info include:
-    # filename
-    # datasource location
-    # the count of rrdata
-    #######################################################################
-    def verbose(self):
-        self.__t = threading.Timer(0.0, self.__status)
-        self.__t.daemon = True
-        self.__t.start()
-
-    ########################################################################
-    #close timer
+    #close verbose
     ######################################################################
     def closeverbose(self):
-        interval = time.time() - MasterFile.__init_time
-        percent = (self.__cur * 100)/self.__filesize
-        sys.stdout.write("\r%s" % (80 * " "))
-        sys.stdout.write("\r%d RR(s) loaded in %.2f second(s)(%.2f%% of %s%s)"\
-                % (MasterFile.__records_num, interval, percent, MasterFile.__file_type, self.__datafile))
-        self.__t.cancel()
+        self.__status()
 
     #########################################################################
     # zonedata: generator function to parse a zone master file and return
@@ -431,23 +433,36 @@
     #########################################################################
     def zonedata(self):
         name = ''
+        last_status = 0.0
+        flag = 1
 
         for record, size in records(self.__zonefile):
+            if self.__verbose:
+                now = time.time()
+                if flag == 1:
+                    self.__status()
+                    flag = 0
+                if now - last_status >= 1.0:
+                    self.__status()
+                    last_status = now
+
             self.__cur += size
             if self.__directive(record):
                 continue
 
             incl, suborigin = self.__include(record)
             if incl:
-                percent = (self.__cur * 100)/self.__filesize
+                if self.__filesize == 0:
+                    percent = 100
+                else:
+                    percent = (self.__cur * 100)/self.__filesize
                 if self.__verbose:
-                    sys.stdout.write("\r%s" % (80 * " "))
-                    sys.stdout.write("\rincluding \"%s\" from \"%s\"\n" % (incl, self.__datafile))
+                    sys.stdout.write("\r" + (80 * " "))
+                    sys.stdout.write("\rIncluding \"%s\" from \"%s\"\n" % (incl, self.__datafile))
                 MasterFile.__file_level += 1
                 MasterFile.__file_type = "included "
                 sub = MasterFile(incl, suborigin, self.__verbose)
-                if self.__verbose:
-                    sub.verbose()
+
                 for rrname, ttl, rrclass, rrtype, rdata in sub.zonedata():
                     yield (rrname, ttl, rrclass, rrtype, rdata)
                 if self.__verbose:
@@ -477,7 +492,7 @@
             if not result:
                 first, rdata = pop(record)
                 if istype(first):
-                    result = name, MasterFile.__ttl or MasterFile.__lastttl, self.__rrclass, first, rdata
+                    result = name, self.__getttl(), self.__rrclass, first, rdata
 
             if not result:
                 raise MasterFileError("Cannot parse RR: " + record)
@@ -487,9 +502,6 @@
 
             if rrclass.lower() != 'in':
                 raise MasterFileError("CH and HS zones not supported")
-
-#            if not ttl:
-#                raise MasterFileError("No TTL specified; zone rejected")
 
             # add origin to rdata containing names, if necessary
             if rrtype.lower() in ('cname', 'dname', 'ns', 'ptr'):
@@ -538,7 +550,10 @@
         self.__origin = self.__initial_origin
         cur_value = self.__cur
         old_location = self.__zonefile.tell()
+        old_verbose = self.__verbose
+        self.__verbose = 0
         self.__zonefile.seek(0)
+
         for name, ttl, rrclass, rrtype, rdata in self.zonedata():
             if rrtype.lower() == 'soa':
                 break
@@ -548,6 +563,7 @@
         if rrtype.lower() != 'soa':
             raise MasterFileError("No SOA found")
         self.__name = name
+        self.__verbose = old_verbose
         return name
 
     #########################################################################




More information about the bind10-changes mailing list