This is version . It is not the current version, and thus it cannot be edited.
[Back to current version]   [Restore this version]

Fed up with the occasional spam attacks, I've written a Python script to undo changes from a given name or IP address, when using the VersioningFileProvider.

Its a bit convoluted, I've no time to make it better, but it may be of interest. You really should back up your pages directory, save the script as unspam.py and then run as
python unspam.py /pathto/pages.dir 61.145.233.118
or
python unspam.py /pathto/pages.dir BadPersonName

You'll have to restart to clear the CachingProvider cache if you're using it.

import sys
import os
import os.path
import re
import shutil

class PropertiesLine:
  def __init__(self, line):
    match = re.match(r'^(\d*).(.*)=(.*)', line)
    if match != None:
      self.version, self.tag, self.value = match.groups()
      self.version = int(self.version)
    else:
      self.tag = self.version = self.value = None
  def __repr__(self):
    return '%s.%s=%s' % (self.version, self.tag, self.value)
    
def parseLine(line):
  return PropertiesLine(line)
  
def moveFile(src, dest):
  print 'moving %s to %s' % (src, dest)
  shutil.copy2(src, dest)
  os.remove(src)
  
def deleteFile(src):
  print 'deleting %s' % src
  os.remove(src)

class PropertiesFile:
  def __init__(self, filename):
    self.filename = filename
    file = open(self.filename)
    try:
       self.lines = file.readlines()
    finally:
      file.close()
  
  def latestEdit(self):
    latestVersion = -1
    result = None
    for line in self.lines:
      pLine = parseLine(line)
      if pLine.version > latestVersion:
        latestVersion = pLine.version
        result = pLine
    return result
    
  def removeVersion(self, version):
    self.lines = filter(lambda x: parseLine(x).version != version, self.lines)
    
  def save(self):
    file = open(self.filename, 'w')
    try:
       file.writelines(self.lines)
    finally:
      file.close()    
      
class Page:
  def __init__(self, filename):
    self.filename = filename
    self.dir, self.file = os.path.split(filename)
    self.name = os.path.splitext(self.file)[0]
    propertiesFilename = os.path.join(self.historyDir(), 'page.properties')
    if os.path.exists(propertiesFilename):
      self.propertiesFile = PropertiesFile(propertiesFilename)
    else:
      self.propertiesFile = None
      
  def versionFilename(self, version):
    return os.path.join(self.historyDir(), str(version) + '.txt')
   
  def historyDir(self):
    return os.path.join(self.dir, 'OLD', self.name)
    
  def isLastEditBy(self, name):
    if self.propertiesFile == None:
      return 0
    latestEdit = self.propertiesFile.latestEdit()
    return latestEdit.value == name
    
  def latestVersion(self):
    if self.propertiesFile == None:
      return -1
    return self.propertiesFile.latestEdit().version
    
  def undoLastEdit(self):
    if self.propertiesFile == None:
      return
    latestVersion = self.latestVersion()
    versionToRestore = latestVersion - 1
    backupFile = os.path.join(self.historyDir(), 'spam-deleted-' + str(latestVersion)) + '.txt'
    moveFile(self.filename, backupFile)
    if versionToRestore >= 1:
      moveFile(self.versionFilename(versionToRestore), self.filename)
    self.propertiesFile.removeVersion(latestVersion)
    self.propertiesFile.save()
      
  def __repr__(self):
    return 'Page %s' % (self.name)
       
class Site:
  def __init__(self, dir):
    self.dir = dir
    self.pages = []
    for filename in os.listdir(dir):
      root, ext = os.path.splitext(filename)
      if ext == '.txt':
        self.pages.append(Page(os.path.join(dir, filename)))
  
  def undoEditsBy(self, name):
    for page in self.pagesWithLastEditBy(name):
      page.undoLastEdit()
      
  def pagesWithLastEditBy(self, name):
    for page in self.pages:
      if page.isLastEditBy(name):
        yield page
        
if __name__ == "__main__":
  if len(sys.argv) == 2:
    dir = '.'
    name = sys.argv[1]
  else:
    dir = sys.argv[1]
    name = sys.argv[2]
  Site(dir).undoEditsBy(name)

  

Add new attachment

Only authorized users are allowed to upload new attachments.
« This particular version was published on 25-May-2005 01:37 by DuncanMcGregor.