Uit Hack42
Ga naar: navigatie, zoeken
 
(6 tussenliggende versies door dezelfde gebruiker niet weergegeven)
Regel 2: Regel 2:
 
|Naam=RomanRotate
 
|Naam=RomanRotate
 
|Eigenaar=Stoneshop, Dvanzuijlekom, WitchDoc,  
 
|Eigenaar=Stoneshop, Dvanzuijlekom, WitchDoc,  
|Status=AF
+
|Status=Afgerond
 
|Skills=Madness
 
|Skills=Madness
 
|Samenvatting=Roman numbering log rotation
 
|Samenvatting=Roman numbering log rotation
 
}}
 
}}
Small bit of python code to provide Roman numbered log rotation
+
 
 +
This;
 +
<pre>
 +
18:34 <@dvanzuijlekom> zo kwam ik een tijd geleden een machine tegen waar iemand handmatig een soort logrotate had ingeregeld
 +
18:35 <@dvanzuijlekom> resultaat: logfile.log, logfile.log.1, logfile.log.1.1 logfile.log.1.1.1
 +
                      logfile.log.1.1.1.1....logfile.log.1.1.1.1.1.1.1.1.1.1.1.1.1
 +
18:39 <@Stoneshop> initieel wat romeinse invloeden, maar niet op de juiste manier voortgezet
 +
18:42 <@dvanzuijlekom> oh wauw, dat zou best gaaf zijn eigenlijk
 +
</pre>
 +
 
 +
Was an incentive enough to create this bit of python code which provides Roman numbered log rotation
 +
 
 +
For recent updates check [https://github.com/Hack42/RomanRotate Github]
 +
 
  
 
<pre>
 
<pre>
Regel 26: Regel 39:
 
   """
 
   """
 
   assert(isinstance(input, int)), "expected integer, got %s" % type(input)
 
   assert(isinstance(input, int)), "expected integer, got %s" % type(input)
   assert(0 < input < 4000), "Argument must be between 1 and 3999"   
+
   assert(-1 < input < 4000), "Argument must be between 0 and 3999"   
 
   ints = (1000, 900,  500, 400, 100,  90, 50,  40, 10,  9,  5,  4,  1)
 
   ints = (1000, 900,  500, 400, 100,  90, 50,  40, 10,  9,  5,  4,  1)
 
   nums = ('M',  'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
 
   nums = ('M',  'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
Regel 42: Regel 55:
 
   """
 
   """
 
   assert(isinstance(input, basestring)), "expected string, got %s" % type(input)
 
   assert(isinstance(input, basestring)), "expected string, got %s" % type(input)
   assert(re.match(r'^[MDCLXVI]+$', input)), "not a valid roman numeral: %s" % input
+
   assert(re.match(r'^[MDCLXVI]*$', input)), "not a valid roman numeral: %s" % input
 
   input = input.upper()
 
   input = input.upper()
 
   nums = ['M', 'D', 'C', 'L', 'X', 'V', 'I']
 
   nums = ['M', 'D', 'C', 'L', 'X', 'V', 'I']
Regel 64: Regel 77:
  
 
def keys(value):
 
def keys(value):
     if re.match(r'([MDCLXVI]+)', value):
+
     if re.match(r'([MDCLXVI]*)', value):
 
         debug("Roman: %s, Decimal %s" % (value, rom2dec(value)))
 
         debug("Roman: %s, Decimal %s" % (value, rom2dec(value)))
 
         return((rom2dec(value), value))
 
         return((rom2dec(value), value))
 
     else:
 
     else:
 
         return((value, dec2rom(value)))
 
         return((value, dec2rom(value)))
 +
 +
def usage():
 +
    print """
 +
    Usage:          %s [-v] [-h] [-d delimiter] [-l] [-t] file [file]
 +
    Description:    Performs logrotation with roman numbering.
 +
 +
    -v              Verbose, show debug output
 +
    -h              Help, show this usage
 +
    -d delimiter    delimiter between filename and roman extension
 +
                    deault; '.'
 +
    -l              List the rotates files ordered by number
 +
    -t              Reverse rotation or list
 +
                    Attention: this might cause loss of data in the most recent logfile!
 +
 +
    file            the filename without numbers, i.e. "logfile.log" or "/path/to/logfile.log"
 +
    """ % sys.argv[0]
  
 
class FileList(set):
 
class FileList(set):
     def __init__(self, directory, filename):
+
     def __init__(self, directory, filename, delimiter):
 
         if(directory!=''):
 
         if(directory!=''):
 
             self._directory = directory
 
             self._directory = directory
Regel 77: Regel 106:
 
             self._directory = '.'
 
             self._directory = '.'
 
         self._filename = filename
 
         self._filename = filename
 +
        self._delimiter = delimiter
 
         debug('Getting files for %s in directory %s' % (self._filename, self._directory))
 
         debug('Getting files for %s in directory %s' % (self._filename, self._directory))
 
         for file in os.listdir(self._directory):
 
         for file in os.listdir(self._directory):
 
             try:
 
             try:
                 parts = re.split(r'(%s\.)([MCXDVIL]+)' % self._filename, file)
+
                 parts = re.split(r'(%s)([%s]*)([MCXDVIL]*)' % (self._filename, self._delimiter), file)
                 if len(parts) > 1:
+
                 if parts[1] == self._filename:
                     debug('Adding: %s' % file)
+
                     debug('Adding: %s %s' % (file, parts))
                     self.add(keys(parts[2]) + (parts[1], file,))
+
                     self.add(keys(parts[3]) + (parts[1], file,))
 
             except Exception, err:
 
             except Exception, err:
 +
                debug(err)
 
                 debug('Ignoring: %s' % file)
 
                 debug('Ignoring: %s' % file)
 
                 pass
 
                 pass
Regel 96: Regel 127:
 
     listOnly = False
 
     listOnly = False
 
     reverse = False
 
     reverse = False
     optlist, args = getopt.getopt(sys.argv[1:], 'lthv')
+
    delimiter = '.'
 +
     optlist, args = getopt.getopt(sys.argv[1:], 'lthvd:')
 
     for option, value in optlist:
 
     for option, value in optlist:
 
         if(option == '-v'):
 
         if(option == '-v'):
Regel 104: Regel 136:
 
         if(option == '-t'):
 
         if(option == '-t'):
 
             reverse = True
 
             reverse = True
 +
        if(option == '-d'):
 +
            delimiter = optarg
 
         if(option == '-h'):
 
         if(option == '-h'):
 
             usage()
 
             usage()
 +
            exit
 
     debug('Verbose is on')
 
     debug('Verbose is on')
 
     debug('Filenames: %s' % args)
 
     debug('Filenames: %s' % args)
 
     for item in args:
 
     for item in args:
 
         debug('Processing: %s' % item)
 
         debug('Processing: %s' % item)
         myList = FileList(os.path.dirname(item), os.path.basename(item))
+
         myList = FileList(os.path.dirname(item), os.path.basename(item), delimiter)
 
         if listOnly:
 
         if listOnly:
 
             for file in myList.sort(reverse):
 
             for file in myList.sort(reverse):
Regel 116: Regel 151:
 
         else:
 
         else:
 
             for file in myList.sort(not reverse):
 
             for file in myList.sort(not reverse):
                 if reverse:
+
                 number = dec2rom(file[0] - (+1 if reverse else -1))
                    debug('renaming %s to %s.' % (file[3], "%s%s" % (file[2], dec2rom(file[0]-1))))
+
                filename = file[2] + (('.' + number) if number != '' else '')
                    os.rename(file[3], "%s%s" % (file[2], dec2rom(file[0]-1)))
+
                 debug('renaming %s to %s.' % (file[3], "%s" % filename))
                 else:
+
                os.rename(file[3], "%s" % filename)
                    debug('renaming %s to %s.' % (file[3], "%s%s" % (file[2], dec2rom(file[0]+1))))
 
                    os.rename(file[3], "%s%s" % (file[2], dec2rom(file[0]+1)))
 
 
</pre>
 
</pre>
 +
 +
<s>The code could be cleaned up a little and the usage method is missing but rumour has it it's already running in production (which is, of course, the best testing environment).</s>
 +
 +
First revision; added Usage function and optional delimiter character. Solved bug 1; The core file (without any numbering) is now included in the renaming.

Huidige versie van 10 sep 2013 om 00:06

Project: RomanRotate
Schroefje24.png
Schroefje24.png
Schroefje24.png
Schroefje24.png
RomanRotate Picture.jpg

RomanRotate

Naam RomanRotate
Door Stoneshop, Dvanzuijlekom, WitchDoc
Status Afgerond
Madskillz Madness
Doel / Omschrijving
Roman numbering log rotation
Alle Projecten - Project Toevoegen
File:RomanRotate_Picture.jpg noez


This;

18:34 <@dvanzuijlekom> zo kwam ik een tijd geleden een machine tegen waar iemand handmatig een soort logrotate had ingeregeld
18:35 <@dvanzuijlekom> resultaat: logfile.log, logfile.log.1, logfile.log.1.1 logfile.log.1.1.1 
                       logfile.log.1.1.1.1....logfile.log.1.1.1.1.1.1.1.1.1.1.1.1.1
18:39 <@Stoneshop> initieel wat romeinse invloeden, maar niet op de juiste manier voortgezet
18:42 <@dvanzuijlekom> oh wauw, dat zou best gaaf zijn eigenlijk

Was an incentive enough to create this bit of python code which provides Roman numbered log rotation

For recent updates check Github


#!/usr/bin/env python

import sys
import os
import re
import getopt

def debug(argv):
    global verbose
    if verbose:
        print >>sys.stderr, "DBG: %s" % argv

def dec2rom(input):
   """
   Convert a decimal to Roman numerals.
   """
   assert(isinstance(input, int)), "expected integer, got %s" % type(input)
   assert(-1 < input < 4000), "Argument must be between 0 and 3999"   
   ints = (1000, 900,  500, 400, 100,  90, 50,  40, 10,  9,   5,  4,   1)
   nums = ('M',  'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
   result = ""
   for i in range(len(ints)):
      count = int(input / ints[i])
      result += nums[i] * count
      input -= ints[i] * count
   return result


def rom2dec(input):
   """
   Convert a roman numeral to a decimal.
   """
   assert(isinstance(input, basestring)), "expected string, got %s" % type(input)
   assert(re.match(r'^[MDCLXVI]*$', input)), "not a valid roman numeral: %s" % input
   input = input.upper()
   nums = ['M', 'D', 'C', 'L', 'X', 'V', 'I']
   ints = [1000, 500, 100, 50,  10,  5,   1]
   retValue = 0
   for i in range(len(input)):
      value = ints[nums.index(input[i])]
      # If the next place holds a larger number, this value is negative.
      try:
         if ints[nums.index(input[i +1])] > value:
            value *= -1
      except IndexError:
         # there is no next place.
         pass
      retValue += value
   # Easiest test for validity...
   if dec2rom(retValue) == input:
      return retValue
   else:
      raise ValueError, 'input is not a valid roman numeral: %s' % input

def keys(value):
    if re.match(r'([MDCLXVI]*)', value):
        debug("Roman: %s, Decimal %s" % (value, rom2dec(value)))
        return((rom2dec(value), value))
    else:
        return((value, dec2rom(value)))

def usage():
    print """
    Usage:          %s [-v] [-h] [-d delimiter] [-l] [-t] file [file]
    Description:    Performs logrotation with roman numbering.

    -v              Verbose, show debug output
    -h              Help, show this usage
    -d delimiter    delimiter between filename and roman extension
                    deault; '.'
    -l              List the rotates files ordered by number
    -t              Reverse rotation or list
                    Attention: this might cause loss of data in the most recent logfile!

    file            the filename without numbers, i.e. "logfile.log" or "/path/to/logfile.log"
    """ % sys.argv[0]

class FileList(set):
    def __init__(self, directory, filename, delimiter):
        if(directory!=''):
            self._directory = directory
        else:
            self._directory = '.'
        self._filename = filename
        self._delimiter = delimiter
        debug('Getting files for %s in directory %s' % (self._filename, self._directory))
        for file in os.listdir(self._directory):
            try:
                parts = re.split(r'(%s)([%s]*)([MCXDVIL]*)' % (self._filename, self._delimiter), file)
                if parts[1] == self._filename:
                    debug('Adding: %s %s' % (file, parts))
                    self.add(keys(parts[3]) + (parts[1], file,))
            except Exception, err:
                debug(err)
                debug('Ignoring: %s' % file)
                pass

    def sort(self, reverse=False):
       return sorted(self, key=lambda file: file[0], reverse=reverse)

if __name__ == "__main__":
    global verbose
    verbose = False
    listOnly = False
    reverse = False
    delimiter = '.'
    optlist, args = getopt.getopt(sys.argv[1:], 'lthvd:')
    for option, value in optlist:
        if(option == '-v'):
            verbose = True
        if(option == '-l'):
            listOnly = True
        if(option == '-t'):
            reverse = True
        if(option == '-d'):
            delimiter = optarg
        if(option == '-h'):
            usage()
            exit
    debug('Verbose is on')
    debug('Filenames: %s' % args)
    for item in args:
        debug('Processing: %s' % item)
        myList = FileList(os.path.dirname(item), os.path.basename(item), delimiter)
        if listOnly:
            for file in myList.sort(reverse):
                print file[3]
        else:
            for file in myList.sort(not reverse):
                number = dec2rom(file[0] - (+1 if reverse else -1))
                filename = file[2] + (('.' + number) if number != '' else '')
                debug('renaming %s to %s.' % (file[3], "%s" % filename))
                os.rename(file[3], "%s" % filename)

The code could be cleaned up a little and the usage method is missing but rumour has it it's already running in production (which is, of course, the best testing environment).

First revision; added Usage function and optional delimiter character. Solved bug 1; The core file (without any numbering) is now included in the renaming.