Implemented, mode, owner and ctime/mtime support

This commit is contained in:
Jonas Borgström 2010-10-19 22:03:47 +02:00
parent 7e288c0b5c
commit 0839e6bed3
2 changed files with 59 additions and 4 deletions

View File

@ -11,7 +11,8 @@ import msgpack
from .chunkifier import chunkify
from .cache import Cache, NS_ARCHIVES, NS_CHUNKS
from .bandstore import BandStore
from .helpers import location_validator, pretty_size, LevelFilter
from .helpers import location_validator, pretty_size, LevelFilter, \
uid2user, user2uid, gid2group, group2gid
CHUNK_SIZE = 55001
@ -110,6 +111,14 @@ class Archive(object):
raise Exception('Invalid chunk checksum')
data = zlib.decompress(data)
fd.write(data)
os.chmod(path, item['mode'])
uid = user2uid(item['user']) or item['uid']
gid = group2gid(item['group']) or item['gid']
try:
os.chown(path, uid, gid)
except OSError:
pass
os.utime(path, (item['ctime'], item['mtime']))
def verify(self):
for item in self.items:
@ -189,7 +198,13 @@ class Archive(object):
for chunk in chunkify(fd, CHUNK_SIZE, 30):
size += len(chunk)
chunks.append(self.add_chunk(*self.cache.add_chunk(chunk)))
self.items.append({'type': 'FILE', 'path': path, 'chunks': chunks, 'size': size})
self.items.append({
'type': 'FILE', 'path': path, 'chunks': chunks, 'size': size,
'mode': st.st_mode,
'uid': st.st_uid, 'user': uid2user(st.st_uid),
'gid': st.st_gid, 'group': gid2group(st.st_gid),
'ctime': st.st_ctime, 'mtime': st.st_mtime,
})
class Archiver(object):

View File

@ -1,10 +1,51 @@
import logging
import argparse
import re
import grp
import pwd
def memoize(function):
cache = {}
def decorated_function(*args):
try:
return cache[args]
except KeyError:
val = function(*args)
cache[args] = val
return val
return decorated_function
@memoize
def uid2user(uid):
try:
return pwd.getpwuid(uid).pw_name
except KeyError:
return None
@memoize
def user2uid(user):
try:
return pwd.getpwnam(user).pw_uid
except KeyError:
return None
@memoize
def gid2group(gid):
try:
return grp.getgrgid(gid).gr_name
except KeyError:
return None
@memoize
def group2gid(group):
try:
return grp.getgrnam(group).gr_gid
except KeyError:
return None
class LevelFilter(logging.Filter):
"""Filter that counts record levels
"""
def __init__(self, *args, **kwargs):
logging.Filter.__init__(self, *args, **kwargs)
self.count = {}
@ -15,7 +56,6 @@ class LevelFilter(logging.Filter):
return record
class Location(object):
loc_re = re.compile(r'^((?:(?P<user>[^@]+)@)?(?P<host>[^:]+):)?'