--- AttachFile.py 2005-01-16 14:35:08.642080009 +1300 +++ AttachFile_backup_with_dia.py 2005-01-16 14:36:17.776347814 +1300 @@ -23,7 +23,7 @@ @license: GNU GPL, see COPYING for details. """ -import os, mimetypes, time, urllib +import cgi, os, mimetypes, string, socket, sys, time, urllib, re from MoinMoin import config, user, util, wikiutil from MoinMoin.Page import Page from MoinMoin.util import MoinMoinNoFooter, filesys @@ -141,6 +141,25 @@ log.add(request, pagename, request.remote_addr, time.time(), urllib.quote(filename), action) +def _backup_file(fpath): + """Move the file `fpath` to `fpath,nnn` where `nnn` is one plus `mmm`, where + `mmm` is the highest number for which `fpath.mmm` exists, or 000 if no + such file exists.""" + + # find the right sequence number + dirname, basename = os.path.split(fpath) + backup_re = re.compile(r'^%s\,(?P\d\d\d)$' % basename) + backups = filter(backup_re.match, os.listdir(dirname)) + backups.sort() + if backups == []: + seq_no = 0 + else: + highest = backups[-1] + seq_no = int(backup_re.match(highest).group('seq')) + 1 + + # do the move + new_name = "%s,%03d" % (fpath, seq_no) + os.rename(fpath, new_name) def _access_file(pagename, request): """ Check form parameter `target` and return a tuple of @@ -175,6 +194,10 @@ files = os.listdir(attach_dir) files.sort() + # filter out backup files + backup_re = re.compile(r'.*\,\d\d\d$') + files = filter(lambda x: not backup_re.match(x), files) + str = "" if files: if showheader: @@ -317,9 +340,9 @@ return request.write('

' + _("New Attachment") + '

' + -_("""An upload will never overwrite an existing file. If there is a name -conflict, you have to rename the file that you want to upload. -Otherwise, if "Rename to" is left blank, the original filename will be used.""") + '

') +_("""When uploading under a filename for which an attachment already exists, +the old version is stored - ask the administrator to recover it.

+

If "Rename to" is left blank, the original filename will be used.""") + '

') request.write("""
@@ -448,25 +471,42 @@ target = target + ext # get directory, and possibly create it - attach_dir = getAttachDir(pagename, create=1) + attach_dir = getAttachDir(pagename, create=1) + # save file fpath = os.path.join(attach_dir, target) if os.path.exists(fpath): - msg = _("Attachment '%(target)s' (remote name '%(filename)s') already exists.") % { - 'target': target, 'filename': filename} - else: - stream = open(fpath, 'wb') - try: - stream.write(filecontent) - finally: - stream.close() - os.chmod(fpath, 0666 & config.umask) + _backup_file(fpath) - bytes = len(filecontent) - msg = _("Attachment '%(target)s' (remote name '%(filename)s')" - " with %(bytes)d bytes saved.") % { - 'target': target, 'filename': filename, 'bytes': bytes} - _addLogEntry(request, 'ATTNEW', pagename, target) + stream = open(fpath, 'wb') + try: + stream.write(filecontent) + finally: + stream.close() + os.chmod(fpath, 0666 & config.umask) + + extra = '' + if fpath.endswith('.dia'): + outputfile = os.path.join(os.getcwd(), fpath.replace('.dia','.svg')) + inputfile = os.path.join(os.getcwd(), fpath) + + pipes = os.popen3('/bin/sh') + pipes[0].write('''dia -e %(output)s -t svg -n %(input)s +exit +''' % {'output' : outputfile, 'input' : inputfile}) + pipes[0].flush() + res = pipes[1].readlines() + res = res + pipes[2].readlines() + pipes[0].close() + pipes[1].close() + pipes[2].close() + extra = 'processed %s to %s' % (inputfile, outputfile) + + bytes = len(filecontent) + msg = _("Attachment '%(target)s' (remote name '%(filename)s')" + " with %(bytes)d bytes saved. %(extra)s") % { + 'target': target, 'filename': filename, 'bytes': bytes, 'extra' : extra} + _addLogEntry(request, 'ATTNEW', pagename, target) # return attachment list upload_form(pagename, request, msg) @@ -511,7 +551,9 @@ if not filename: return # error msg already sent in _access_file # delete file - os.remove(fpath) + if os.path.exists(fpath): + _backup_file(fpath) + _addLogEntry(request, 'ATTDEL', pagename, filename) upload_form(pagename, request, msg=_("Attachment '%(filename)s' deleted.") % {'filename': filename})