2011-11-03 01:11:10 +03:00
|
|
|
#=======================================================================
|
|
|
|
|
|
|
|
|
|
__version__ = '''0.0.01'''
|
2011-12-09 01:25:12 +04:00
|
|
|
__sub_version__ = '''20111209012407'''
|
2011-11-03 01:11:10 +03:00
|
|
|
__copyright__ = '''(c) Alex A. Naanou 2011'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#-----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import json
|
2011-12-06 22:03:01 +04:00
|
|
|
import zipfile
|
2011-11-10 18:43:46 +04:00
|
|
|
import uuid
|
2011-11-03 01:11:10 +03:00
|
|
|
|
2011-11-10 18:43:46 +04:00
|
|
|
from itertools import izip, izip_longest
|
|
|
|
|
|
|
|
|
|
from pli.logictypes import ANY, OR
|
2011-11-03 01:11:10 +03:00
|
|
|
|
2011-11-10 19:17:38 +04:00
|
|
|
from pprint import pprint
|
|
|
|
|
|
2011-11-03 01:11:10 +03:00
|
|
|
|
|
|
|
|
#-----------------------------------------------------------------------
|
|
|
|
|
|
2011-11-10 18:43:46 +04:00
|
|
|
CONFIG_NAME = 'test_config.json'
|
2011-11-11 01:41:56 +04:00
|
|
|
##CONFIG_NAME = 'tmp_config.json'
|
2011-11-03 01:11:10 +03:00
|
|
|
|
|
|
|
|
config = json.load(open(CONFIG_NAME))
|
|
|
|
|
|
2011-11-10 18:43:46 +04:00
|
|
|
RAW = OR(
|
|
|
|
|
'NEF', 'nef',
|
|
|
|
|
'CRW', 'crw',
|
|
|
|
|
'CR2', 'cr2',
|
|
|
|
|
'X3F', 'x3f'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
JPEG = OR(
|
|
|
|
|
'JPG', 'jpg',
|
|
|
|
|
'JPEG', 'jpeg'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
PSD = OR(
|
|
|
|
|
'PSD', 'psd'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
TIFF = OR(
|
|
|
|
|
'TIFF', 'tiff',
|
|
|
|
|
'TIF', 'tif'
|
2011-11-03 01:11:10 +03:00
|
|
|
)
|
|
|
|
|
|
2011-11-10 18:43:46 +04:00
|
|
|
XMP = OR(
|
|
|
|
|
'XMP', 'xmp'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
ITEM = OR(RAW, JPEG, PSD, TIFF, XMP)
|
|
|
|
|
|
|
|
|
|
TYPES = {
|
|
|
|
|
'raw': RAW,
|
|
|
|
|
'jpeg': JPEG,
|
|
|
|
|
'psd': PSD,
|
|
|
|
|
'tiff': TIFF,
|
|
|
|
|
'xmp': XMP,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-11-03 01:11:10 +03:00
|
|
|
SUBTREE_CLASSES = {
|
|
|
|
|
'preview': 'preview',
|
|
|
|
|
'preview (RAW)': 'RAW preview',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#-----------------------------------------------------------------------
|
|
|
|
|
|
2011-11-10 18:43:46 +04:00
|
|
|
##!!! we will need to normalize the paths to one single scheme (either relative or absolute)...
|
|
|
|
|
def list_files(root, sub_trees=SUBTREE_CLASSES, type=ITEM):
|
2011-11-03 01:11:10 +03:00
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
for path, dirs, files in os.walk(root):
|
2011-11-10 18:43:46 +04:00
|
|
|
path = path.split(os.path.sep)
|
2011-11-03 01:11:10 +03:00
|
|
|
# process files...
|
|
|
|
|
for f in files:
|
2011-11-10 18:43:46 +04:00
|
|
|
name, ext = os.path.splitext(f)
|
|
|
|
|
# we need the extension wothout the dot...
|
|
|
|
|
ext = ext[1:]
|
2011-11-03 01:11:10 +03:00
|
|
|
# filter by ext...
|
2011-11-10 18:43:46 +04:00
|
|
|
if ext == type:
|
|
|
|
|
yield path, name, ext
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# XXX need to split duplicate named raw files and corresponding
|
|
|
|
|
# previews...
|
|
|
|
|
def index_by_name(file_list, types=TYPES.items()):
|
|
|
|
|
'''
|
|
|
|
|
format:
|
|
|
|
|
{
|
|
|
|
|
<name>: {
|
2011-11-10 19:38:43 +04:00
|
|
|
<type>: [
|
2011-11-10 20:04:34 +04:00
|
|
|
(<path>, <orig-ext>),
|
2011-11-10 18:43:46 +04:00
|
|
|
...
|
|
|
|
|
],
|
|
|
|
|
...
|
|
|
|
|
},
|
|
|
|
|
...
|
|
|
|
|
}
|
|
|
|
|
'''
|
|
|
|
|
res = {}
|
|
|
|
|
for path, name, ext in file_list:
|
|
|
|
|
# normalize extension...
|
2011-11-10 19:38:43 +04:00
|
|
|
orig_ext, ext = ext, types[types.index((ANY, ext))][0]
|
2011-11-10 18:43:46 +04:00
|
|
|
if name not in res:
|
|
|
|
|
# create a name...
|
|
|
|
|
res[name] = {}
|
|
|
|
|
if ext not in res[name]:
|
|
|
|
|
# create an extension...
|
|
|
|
|
res[name][ext] = []
|
|
|
|
|
# general case...
|
2011-11-10 19:38:43 +04:00
|
|
|
res[name][ext] += [(path, orig_ext)]
|
2011-11-10 18:43:46 +04:00
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# for this to work correctly it must:
|
|
|
|
|
# - return unique paths
|
|
|
|
|
# - non of the returnd paths can be a strict subset of any other...
|
|
|
|
|
##!!!
|
|
|
|
|
def split_common(paths):
|
|
|
|
|
'''
|
2011-11-10 19:52:34 +04:00
|
|
|
build a common path tree...
|
2011-11-10 18:43:46 +04:00
|
|
|
'''
|
|
|
|
|
# pass 1: build list of common paths (None for all differences)
|
|
|
|
|
# NOTE: we may have stray common path elements but we do
|
|
|
|
|
# not care abut anything after a None...
|
|
|
|
|
index = izip_longest(*paths)
|
|
|
|
|
common = []
|
|
|
|
|
for s in index:
|
|
|
|
|
next = []
|
|
|
|
|
for i in s:
|
|
|
|
|
if s.count(i) > 1:
|
|
|
|
|
next += [i]
|
|
|
|
|
else:
|
|
|
|
|
next += [None]
|
|
|
|
|
common += [next]
|
|
|
|
|
# pass 2: cap each common section with a unique element...
|
|
|
|
|
common = [ list(e) for e in izip(*common)]
|
|
|
|
|
for c, p in izip(common, paths):
|
|
|
|
|
if None in c:
|
|
|
|
|
i = c.index(None)
|
|
|
|
|
if len(p) <= i:
|
|
|
|
|
# NOTE: this is the case when we have a None
|
|
|
|
|
# because a path just ended... i.e. there
|
|
|
|
|
# was no different element to split at...
|
|
|
|
|
# XXX do we need to break here?
|
|
|
|
|
# XXX one way to go here is to simply ignore
|
|
|
|
|
# such paths...
|
2011-11-10 19:02:26 +04:00
|
|
|
del c[i]
|
2011-11-10 18:43:46 +04:00
|
|
|
continue
|
|
|
|
|
# in-place update and truncate the common path...
|
|
|
|
|
c[i] = p[i]
|
|
|
|
|
del c[i+1:]
|
|
|
|
|
return common
|
|
|
|
|
|
|
|
|
|
# in essance this need to replace image name with a GID and split up
|
|
|
|
|
# images that are identically named into seporate GIDs...
|
|
|
|
|
def split_images(index):
|
|
|
|
|
'''
|
2011-11-10 19:47:45 +04:00
|
|
|
This will split groups that contain multiple raw files.
|
|
|
|
|
|
|
|
|
|
Groups are split to contain one raw each.
|
|
|
|
|
|
2011-12-04 21:40:13 +04:00
|
|
|
Each image will be grouped to the raw that contains the largest
|
2011-11-10 19:47:45 +04:00
|
|
|
matching sub-path, starting from root.
|
|
|
|
|
|
|
|
|
|
Resulting groups will have a gid as it's key
|
|
|
|
|
|
|
|
|
|
This will fail for any files that live in a common sub-path of any
|
|
|
|
|
two or more raw files.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NOTE: in the case there are two raw files in one path, then we will
|
|
|
|
|
favor the deeper / longer mathch.
|
2011-11-10 18:43:46 +04:00
|
|
|
'''
|
|
|
|
|
for name, data in index.items():
|
|
|
|
|
# this will not let us lose the name of the image...
|
|
|
|
|
data['name'] = name
|
2011-11-11 01:41:56 +04:00
|
|
|
raw = data.get('raw', [])
|
2011-11-10 18:43:46 +04:00
|
|
|
if len(raw) > 1:
|
2011-11-10 19:38:43 +04:00
|
|
|
common = split_common([r for r, e in raw])
|
2011-11-10 18:43:46 +04:00
|
|
|
# prepare the return structure...
|
|
|
|
|
res = []
|
|
|
|
|
for path in raw:
|
|
|
|
|
res += [{
|
2011-11-10 19:50:58 +04:00
|
|
|
'gid': str(uuid.uuid4()),
|
2011-11-10 18:43:46 +04:00
|
|
|
'name': name,
|
2011-11-10 19:17:38 +04:00
|
|
|
'raw': [path],
|
2011-11-10 18:43:46 +04:00
|
|
|
}]
|
|
|
|
|
# start splitting the data...
|
2011-11-10 19:38:43 +04:00
|
|
|
for t, paths in data.items():
|
2011-11-10 19:02:26 +04:00
|
|
|
# skip non-type fields...
|
2011-11-10 19:38:43 +04:00
|
|
|
if t not in TYPES:
|
2011-11-10 18:43:46 +04:00
|
|
|
continue
|
2011-11-10 19:38:43 +04:00
|
|
|
if t == 'raw':
|
2011-11-10 19:17:38 +04:00
|
|
|
continue
|
|
|
|
|
# start the work...
|
2011-11-10 19:38:43 +04:00
|
|
|
for path, ext in paths:
|
2011-11-10 19:02:26 +04:00
|
|
|
matches = []
|
2011-11-10 18:43:46 +04:00
|
|
|
for i, c in enumerate(common):
|
2011-11-10 19:17:38 +04:00
|
|
|
# use matching path head to match targets...
|
2011-11-10 18:43:46 +04:00
|
|
|
if path[:len(c)] == c:
|
2011-11-10 19:02:26 +04:00
|
|
|
matches += [(len(c), i)]
|
|
|
|
|
# multiple matches...
|
|
|
|
|
if len(matches) > 1:
|
2011-11-10 19:38:43 +04:00
|
|
|
# longest match wins...
|
2011-11-10 19:02:26 +04:00
|
|
|
matches.sort(key=lambda e: e[0])
|
|
|
|
|
if matches[0][0] == matches[1][0]:
|
|
|
|
|
# XXX we could try and use a different
|
|
|
|
|
# strategy...
|
|
|
|
|
##!!! do a better error...
|
|
|
|
|
raise Exception, 'got two targets with same score, can\'t decide where to put the file.'
|
|
|
|
|
del matches[1:]
|
2011-11-10 18:43:46 +04:00
|
|
|
if len(matches) == 1:
|
2011-11-10 19:02:26 +04:00
|
|
|
i = matches[0][1]
|
2011-11-10 18:43:46 +04:00
|
|
|
# we found a location...
|
2011-11-10 19:38:43 +04:00
|
|
|
if t not in res[i]:
|
|
|
|
|
res[i][t] = []
|
|
|
|
|
res[i][t] += [(path, ext)]
|
2011-11-10 18:43:46 +04:00
|
|
|
else:
|
2011-11-11 01:51:56 +04:00
|
|
|
##!!! we sometimes fall into here for odd reasons (use tmp_config.json)
|
2011-11-11 01:41:56 +04:00
|
|
|
# output orphan/ungrouped images...
|
|
|
|
|
# NOTE: these images can be located in a
|
|
|
|
|
# different place or are orgonized in a
|
|
|
|
|
# different way...
|
2011-11-12 02:02:29 +04:00
|
|
|
print '%%%%%%', path, name, ext
|
2011-11-11 01:41:56 +04:00
|
|
|
gid = str(uuid.uuid4())
|
|
|
|
|
yield gid, {
|
|
|
|
|
'gid': gid,
|
|
|
|
|
'name': name,
|
|
|
|
|
t: [(path, ext)],
|
|
|
|
|
}
|
2011-11-10 18:43:46 +04:00
|
|
|
|
|
|
|
|
# yield the results...
|
|
|
|
|
for e in res:
|
2011-11-10 19:17:38 +04:00
|
|
|
yield e['gid'], e
|
2011-11-10 18:43:46 +04:00
|
|
|
else:
|
2011-11-10 19:50:58 +04:00
|
|
|
gid = data['gid'] = str(uuid.uuid4())
|
2011-11-10 19:47:45 +04:00
|
|
|
yield gid, data
|
2011-11-03 01:11:10 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-12-06 22:03:01 +04:00
|
|
|
#-----------------------------------------------------------------------
|
|
|
|
|
# XXX is this a good way to serialize the actual data in the fs???
|
|
|
|
|
|
|
|
|
|
# NOTE: these will work with any topoloy and create a flat index...
|
|
|
|
|
def save_file_index(index, path, flat_index=False, ext='.json'):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
2011-12-07 03:25:38 +04:00
|
|
|
root_index = {}
|
2011-12-06 22:03:01 +04:00
|
|
|
for k, v in index.items():
|
|
|
|
|
if not flat_index:
|
|
|
|
|
d = k[:2]
|
|
|
|
|
if not os.path.exists(os.path.join(path, d)):
|
|
|
|
|
os.mkdir(os.path.join(path, d))
|
2011-12-07 03:25:38 +04:00
|
|
|
p = os.path.join(path, d, k + ext)
|
2011-12-06 22:03:01 +04:00
|
|
|
else:
|
2011-12-07 03:25:38 +04:00
|
|
|
p = os.path.join(path, k + ext)
|
|
|
|
|
json.dump(v, file(p, 'w'), indent=4, separators=(', ', ': '))
|
|
|
|
|
root_index[k] = p
|
2011-12-08 16:46:30 +04:00
|
|
|
## print '.',
|
2011-12-07 03:25:38 +04:00
|
|
|
return root_index
|
2011-12-06 22:03:01 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_file_index(path, ext='.json', pack_ext='.pack'):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
d = {}
|
|
|
|
|
for p, _, files in os.walk(path):
|
|
|
|
|
for f in files:
|
|
|
|
|
# handle single files...
|
|
|
|
|
if f.endswith(ext):
|
2011-12-06 22:21:59 +04:00
|
|
|
d[os.path.splitext(f)[0]] = json.load(file(os.path.join(p, f)))
|
2011-12-06 22:03:01 +04:00
|
|
|
# handle packs...
|
|
|
|
|
elif f.endswith(pack_ext):
|
|
|
|
|
pack = zipfile.ZipFile(os.path.join(p, f))
|
|
|
|
|
# load elements form the pack...
|
|
|
|
|
for name in pack.namelist():
|
|
|
|
|
if name.endswith(ext):
|
2011-12-06 22:21:59 +04:00
|
|
|
d[os.path.splitext(name)[0]] = json.loads(pack.read(name))
|
2011-12-06 22:03:01 +04:00
|
|
|
return d
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# XXX should we remove empty dirs here???
|
|
|
|
|
def pack_file_index(path, ext='.json', pack_ext='.pack', keep_files=False, keep_dirs=False):
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
NOTE: if keep_files is True, keep_dirs option will be ignored.
|
|
|
|
|
'''
|
2011-12-08 16:35:31 +04:00
|
|
|
z = zipfile.ZipFile(os.path.join(path, 'index' + pack_ext), 'a', compression=zipfile.ZIP_DEFLATED)
|
2011-12-06 22:03:01 +04:00
|
|
|
for p, _, files in os.walk(path):
|
|
|
|
|
for f in files:
|
|
|
|
|
if f.endswith(ext):
|
|
|
|
|
z.write(os.path.join(p, f), os.path.split(f)[-1])
|
|
|
|
|
if not keep_files:
|
|
|
|
|
os.remove(os.path.join(p, f))
|
|
|
|
|
# XXX this will not remove empty dirs (push one
|
|
|
|
|
# level up for that...)
|
|
|
|
|
if not keep_dirs and p != path:
|
|
|
|
|
##!!! check if dir is empty....
|
|
|
|
|
try:
|
|
|
|
|
# NOTE: this will fail for non-empty dirs...
|
|
|
|
|
os.rmdir(os.path.join(p))
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
z.close()
|
2011-12-09 01:25:12 +04:00
|
|
|
|
|
|
|
|
##!!! get path by name helper...
|
2011-12-06 22:03:01 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#-----------------------------------------------------------------------
|
|
|
|
|
##!!! add a lazy dict-like object that reads and writes (optional) the fs...
|
|
|
|
|
|
|
|
|
|
import pli.pattern.mixin.mapping as mapping
|
2011-12-08 16:23:47 +04:00
|
|
|
import pli.objutils as objutils
|
2011-12-06 22:03:01 +04:00
|
|
|
|
|
|
|
|
# XXX might be good to do a path index...
|
|
|
|
|
class Index(mapping.Mapping):
|
2011-12-06 22:21:59 +04:00
|
|
|
__json_ext__ = '.json'
|
|
|
|
|
__pack_ext__ = '.pack'
|
|
|
|
|
|
2011-12-06 22:03:01 +04:00
|
|
|
def __init__(self, path):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
self._path = path
|
|
|
|
|
def __getitem__(self, name):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
2011-12-06 22:21:59 +04:00
|
|
|
ext = self.__json_ext__
|
|
|
|
|
pack_ext = self.__pack_ext__
|
2011-12-06 22:03:01 +04:00
|
|
|
file_name = name + ext
|
|
|
|
|
# build probable locations...
|
|
|
|
|
locations = (
|
|
|
|
|
file_name,
|
|
|
|
|
# look in a directory...
|
|
|
|
|
os.path.join(name[:2], file_name),
|
|
|
|
|
)
|
|
|
|
|
# look of the file directly...
|
|
|
|
|
for n in locations:
|
|
|
|
|
if os.path.exists(os.path.join(self._path, n)):
|
|
|
|
|
return json.load(file(os.path.join(self._path, n)))
|
|
|
|
|
# try and locate a file in a pack...
|
2011-12-06 22:21:59 +04:00
|
|
|
for p, _, files in os.walk(self._path):
|
|
|
|
|
# files are searched sorted by their name...
|
|
|
|
|
files.sort()
|
2011-12-06 22:03:01 +04:00
|
|
|
for f in files:
|
|
|
|
|
## ##!!! do we need to look in odd named directories...
|
|
|
|
|
## if f == file_name:
|
|
|
|
|
## return json.load(file(os.path.join(p, file_name)))
|
|
|
|
|
if f.endswith(pack_ext):
|
|
|
|
|
z = zipfile.ZipFile(os.path.join(p, f))
|
|
|
|
|
if file_name in z.namelist():
|
|
|
|
|
return json.loads(z.read(file_name))
|
|
|
|
|
raise KeyError, name
|
2011-12-08 16:23:47 +04:00
|
|
|
def __setitem__(self, name, value):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
raise NotImplementedError
|
2011-12-06 22:03:01 +04:00
|
|
|
def __delitem__(self, name):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
2011-12-06 22:21:59 +04:00
|
|
|
raise NotImplementedError
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
visited = []
|
|
|
|
|
packs = []
|
|
|
|
|
ext = self.__json_ext__
|
|
|
|
|
pack_ext = self.__pack_ext__
|
|
|
|
|
for p, _, files in os.walk(self._path):
|
|
|
|
|
for f in files:
|
|
|
|
|
if f.endswith(ext) and f not in visited:
|
|
|
|
|
visited += [f]
|
|
|
|
|
yield os.path.splitext(f)[0]
|
|
|
|
|
elif f.endswith(pack_ext):
|
|
|
|
|
packs += [os.path.join(p, f)]
|
|
|
|
|
for pack in packs:
|
|
|
|
|
z = zipfile.ZipFile(pack)
|
|
|
|
|
for name in z.namelist():
|
|
|
|
|
if name not in visited:
|
|
|
|
|
visited += [name]
|
|
|
|
|
yield os.path.splitext(name)[0]
|
2011-12-06 22:03:01 +04:00
|
|
|
|
|
|
|
|
|
2011-12-09 01:25:12 +04:00
|
|
|
REMOVED = object()
|
|
|
|
|
|
2011-12-08 16:23:47 +04:00
|
|
|
class IndexWithCache(Index):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
objutils.createonaccess('_cache', dict)
|
|
|
|
|
|
2011-12-08 16:46:30 +04:00
|
|
|
__sync__ = False
|
|
|
|
|
|
2011-12-08 16:23:47 +04:00
|
|
|
def __getitem__(self, name):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
if name in self._cache:
|
2011-12-09 01:25:12 +04:00
|
|
|
res = self._cache[name]
|
|
|
|
|
if res is REMOVED:
|
|
|
|
|
raise KeyError, name
|
|
|
|
|
return res
|
2011-12-08 16:23:47 +04:00
|
|
|
res = self._cache[name] = super(IndexWithCache, self).__getitem__(name)
|
|
|
|
|
return res
|
|
|
|
|
def __setitem__(self, name, value):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
self._cache[name] = value
|
2011-12-08 16:46:30 +04:00
|
|
|
if self.__sync__:
|
|
|
|
|
self.cache_flush(name)
|
2011-12-08 16:23:47 +04:00
|
|
|
##!!!
|
|
|
|
|
def __delitem__(self, name):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
2011-12-09 01:25:12 +04:00
|
|
|
self._cache[name] = REMOVED
|
|
|
|
|
if self.__sync__:
|
|
|
|
|
self.cache_flush(name)
|
2011-12-08 16:23:47 +04:00
|
|
|
def __iter__(self):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
cache = self._cache
|
|
|
|
|
for e in cache:
|
|
|
|
|
yield e
|
|
|
|
|
for e in super(IndexWithCache, self).__iter__():
|
|
|
|
|
if e not in cache:
|
|
|
|
|
yield e
|
|
|
|
|
|
|
|
|
|
# cache management...
|
2011-12-09 01:25:12 +04:00
|
|
|
##!!! removed items will not get flushed yet...
|
|
|
|
|
# XXX to make removing elements history compatible, one way to go
|
|
|
|
|
# is to write a specifc value to the file, thus making it
|
|
|
|
|
# shadow the original value...
|
2011-12-08 16:46:30 +04:00
|
|
|
def cache_flush(self, *keys):
|
2011-12-08 16:23:47 +04:00
|
|
|
'''
|
|
|
|
|
'''
|
2011-12-08 16:46:30 +04:00
|
|
|
if keys == ():
|
|
|
|
|
return save_file_index(self._cache, self._path)
|
|
|
|
|
flush = {}
|
|
|
|
|
for k in keys:
|
2011-12-09 01:25:12 +04:00
|
|
|
if k is REMOVED:
|
|
|
|
|
# remove file...
|
|
|
|
|
## raise NotImplementedError
|
|
|
|
|
##!!!
|
|
|
|
|
continue
|
2011-12-08 16:46:30 +04:00
|
|
|
flush[k] = self[k]
|
|
|
|
|
return save_file_index(flush, self._path)
|
2011-12-08 16:23:47 +04:00
|
|
|
def cache_drop(self):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
del self._cache
|
|
|
|
|
|
2011-12-06 22:03:01 +04:00
|
|
|
|
2011-12-08 16:35:31 +04:00
|
|
|
|
2011-11-03 01:11:10 +03:00
|
|
|
#-----------------------------------------------------------------------
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
lst = list(list_files(config['ARCHIVE_ROOT']))
|
|
|
|
|
|
|
|
|
|
print len(lst)
|
|
|
|
|
|
2011-11-10 18:43:46 +04:00
|
|
|
index = index_by_name(list_files(config['ARCHIVE_ROOT']))
|
|
|
|
|
|
|
|
|
|
print len(index)
|
|
|
|
|
|
|
|
|
|
index = list(split_images(index_by_name(list_files(config['ARCHIVE_ROOT']))))
|
|
|
|
|
|
2011-12-06 22:03:01 +04:00
|
|
|
l = len(index)
|
|
|
|
|
|
|
|
|
|
index = dict(index)
|
|
|
|
|
|
|
|
|
|
print l, len(index)
|
2011-11-03 01:11:10 +03:00
|
|
|
|
2011-11-10 19:50:58 +04:00
|
|
|
json.dump(index, file(os.path.join('test', 'filelist.json'), 'w'))
|
|
|
|
|
|
|
|
|
|
|
2011-11-03 01:11:10 +03:00
|
|
|
|
2011-12-07 03:25:38 +04:00
|
|
|
root_index = save_file_index(index, os.path.join('test', 'index'), flat_index=False)
|
|
|
|
|
|
2011-12-08 16:35:31 +04:00
|
|
|
## ##!!! this is not used in anything yet...
|
|
|
|
|
## json.dump(root_index, file(os.path.join('test', 'index', 'file_index.json'), 'w'))
|
2011-12-06 22:03:01 +04:00
|
|
|
|
|
|
|
|
pack_file_index(os.path.join('test', 'index'), keep_files=False)
|
|
|
|
|
|
|
|
|
|
d = load_file_index(os.path.join('test', 'index'))
|
|
|
|
|
|
|
|
|
|
|
2011-12-07 03:25:38 +04:00
|
|
|
print len(d)
|
2011-12-06 22:03:01 +04:00
|
|
|
|
2011-12-07 03:25:38 +04:00
|
|
|
k = d.keys()[0]
|
2011-12-06 22:03:01 +04:00
|
|
|
|
2011-12-07 03:25:38 +04:00
|
|
|
i = Index(os.path.join('test', 'index'))
|
|
|
|
|
|
|
|
|
|
print len(i)
|
|
|
|
|
|
2011-12-08 16:35:31 +04:00
|
|
|
## print i[k]
|
|
|
|
|
|
|
|
|
|
ic = IndexWithCache(os.path.join('test', 'index'))
|
|
|
|
|
|
|
|
|
|
print ic[k]
|
|
|
|
|
|
|
|
|
|
ic['000000000000000000000000000000000'] = {}
|
|
|
|
|
|
|
|
|
|
ic.cache_flush()
|
|
|
|
|
|
|
|
|
|
pack_file_index(ic._path, keep_files=False)
|
2011-12-07 03:25:38 +04:00
|
|
|
|
2011-12-08 16:46:30 +04:00
|
|
|
ic.__sync__ = True
|
|
|
|
|
|
|
|
|
|
ic['111111111111111111111111111111111'] = {}
|
|
|
|
|
|
|
|
|
|
pack_file_index(ic._path, keep_files=False)
|
|
|
|
|
|
2011-12-07 03:25:38 +04:00
|
|
|
os.remove(os.path.join('test', 'index', 'index.pack'))
|
2011-12-06 22:03:01 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-11-03 01:11:10 +03:00
|
|
|
|
|
|
|
|
#=======================================================================
|
|
|
|
|
# vim:set ts=4 sw=4 nowrap :
|