Mercurial > p > roundup > code
comparison roundup/backends/blobfiles.py @ 2941:94c8d60c827a maint-0.7
merge from HEAD
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Mon, 22 Nov 2004 02:38:24 +0000 |
| parents | 0fe0452338ba |
| children | d29673626906 |
comparison
equal
deleted
inserted
replaced
| 2939:e8d22f8ff35a | 2941:94c8d60c827a |
|---|---|
| 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" | 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" |
| 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, | 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, |
| 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 17 # | 17 # |
| 18 #$Id: blobfiles.py,v 1.12.2.3 2004-11-11 06:09:43 richard Exp $ | 18 #$Id: blobfiles.py,v 1.12.2.4 2004-11-22 02:38:24 richard Exp $ |
| 19 '''This module exports file storage for roundup backends. | 19 '''This module exports file storage for roundup backends. |
| 20 Files are stored into a directory hierarchy. | 20 Files are stored into a directory hierarchy. |
| 21 ''' | 21 ''' |
| 22 __docformat__ = 'restructuredtext' | 22 __docformat__ = 'restructuredtext' |
| 23 | 23 |
| 35 num_files = num_files + files_in_dir(full_filename) | 35 num_files = num_files + files_in_dir(full_filename) |
| 36 return num_files | 36 return num_files |
| 37 | 37 |
| 38 class FileStorage: | 38 class FileStorage: |
| 39 """Store files in some directory structure""" | 39 """Store files in some directory structure""" |
| 40 def filename(self, classname, nodeid, property=None): | 40 def filename(self, classname, nodeid, property=None, create=False): |
| 41 '''Determine what the filename for the given node and optionally | 41 '''Determine what the filename for the given node and optionally |
| 42 property is. | 42 property is. |
| 43 | 43 |
| 44 Try a variety of different filenames - the file could be in the | 44 Try a variety of different filenames - the file could be in the |
| 45 usual place, or it could be in a temp file pre-commit *or* it | 45 usual place, or it could be in a temp file pre-commit *or* it |
| 53 name = '%s%s'%(classname, nodeid) | 53 name = '%s%s'%(classname, nodeid) |
| 54 | 54 |
| 55 # have a separate subdir for every thousand messages | 55 # have a separate subdir for every thousand messages |
| 56 subdir = str(int(nodeid) / 1000) | 56 subdir = str(int(nodeid) / 1000) |
| 57 filename = os.path.join(self.dir, 'files', classname, subdir, name) | 57 filename = os.path.join(self.dir, 'files', classname, subdir, name) |
| 58 if os.path.exists(filename): | 58 if create or os.path.exists(filename): |
| 59 return filename | 59 return filename |
| 60 | 60 |
| 61 # try .tmp | 61 # try .tmp |
| 62 filename = filename + '.tmp' | 62 filename = filename + '.tmp' |
| 63 if os.path.exists(filename): | 63 if os.path.exists(filename): |
| 80 '''Store the content of the file in the database. The property may be | 80 '''Store the content of the file in the database. The property may be |
| 81 None, in which case the filename does not indicate which property | 81 None, in which case the filename does not indicate which property |
| 82 is being saved. | 82 is being saved. |
| 83 ''' | 83 ''' |
| 84 # determine the name of the file to write to | 84 # determine the name of the file to write to |
| 85 name = self.filename(classname, nodeid, property) | 85 name = self.filename(classname, nodeid, property, create=True) |
| 86 | 86 |
| 87 # make sure the file storage dir exists | 87 # make sure the file storage dir exists |
| 88 if not os.path.exists(os.path.dirname(name)): | 88 if not os.path.exists(os.path.dirname(name)): |
| 89 os.makedirs(os.path.dirname(name)) | 89 os.makedirs(os.path.dirname(name)) |
| 90 | 90 |
| 91 # save to a temp file | 91 # save to a temp file |
| 92 name = name + '.tmp' | 92 name = name + '.tmp' |
| 93 | 93 |
| 94 # save off the rename action | 94 # make sure we don't register the rename action more than once |
| 95 self.transactions.append((self.doStoreFile, (classname, nodeid, | 95 if not os.path.exists(name): |
| 96 property))) | 96 # save off the rename action |
| 97 | 97 self.transactions.append((self.doStoreFile, (classname, nodeid, |
| 98 property))) | |
| 98 open(name, 'wb').write(content) | 99 open(name, 'wb').write(content) |
| 99 | 100 |
| 100 def getfile(self, classname, nodeid, property): | 101 def getfile(self, classname, nodeid, property): |
| 101 '''Get the content of the file in the database. | 102 '''Get the content of the file in the database. |
| 102 ''' | 103 ''' |
| 119 '''Store the file as part of a transaction commit. | 120 '''Store the file as part of a transaction commit. |
| 120 ''' | 121 ''' |
| 121 # determine the name of the file to write to | 122 # determine the name of the file to write to |
| 122 name = self.filename(classname, nodeid, property) | 123 name = self.filename(classname, nodeid, property) |
| 123 | 124 |
| 124 if not os.path.exists(name+".tmp"): | 125 # the file is currently ".tmp" - move it to its real name to commit |
| 125 return | 126 if name.endswith('.tmp'): |
| 127 # creation | |
| 128 dstname = os.path.splitext(name)[0] | |
| 129 else: | |
| 130 # edit operation | |
| 131 dstname = name | |
| 132 name = name + '.tmp' | |
| 126 | 133 |
| 127 # content is being updated (and some platforms, eg. win32, won't | 134 # content is being updated (and some platforms, eg. win32, won't |
| 128 # let us rename over the top of the old file) | 135 # let us rename over the top of the old file) |
| 129 if os.path.exists(name): | 136 if os.path.exists(dstname): |
| 130 os.remove(name) | 137 os.remove(dstname) |
| 131 | 138 |
| 132 # the file is currently ".tmp" - move it to its real name to commit | 139 os.rename(name, dstname) |
| 133 os.rename(name+".tmp", name) | |
| 134 | 140 |
| 135 # return the classname, nodeid so we reindex this content | 141 # return the classname, nodeid so we reindex this content |
| 136 return (classname, nodeid) | 142 return (classname, nodeid) |
| 137 | 143 |
| 138 def rollbackStoreFile(self, classname, nodeid, property, **databases): | 144 def rollbackStoreFile(self, classname, nodeid, property, **databases): |
