from datetime import date
from functools import wraps
+from os.path import join
+from os import listdir, stat
+from shutil import move, rmtree
+from django.conf import settings
+import re
+import filecmp
from django.db.models import Count
return date(*[int(p) for p in isodate.split('-')])
except (AttributeError, TypeError, ValueError):
raise ValueError("Not a date in ISO format.")
+
+
+class GalleryMerger(object):
+ def __init__(self, dest_gallery, src_gallery):
+ assert isinstance(dest_gallery, str)
+ assert isinstance(src_gallery, str)
+ self.dest = dest_gallery
+ self.src = src_gallery
+ self.dest_size = None
+ self.src_size = None
+ self.num_deleted = 0
+
+ @staticmethod
+ def path(gallery):
+ return join(settings.MEDIA_ROOT, settings.IMAGE_DIR, gallery)
+
+ @staticmethod
+ def get_prefix(name):
+ m = re.match(r"^([0-9])-", name)
+ if m:
+ return int(m.groups()[0])
+ return None
+
+ @staticmethod
+ def set_prefix(name, prefix, always=False):
+ m = not always and re.match(r"^([0-9])-", name)
+ return "%1d-%s" % (prefix, m and name[2:] or name)
+
+ def merge(self):
+ if not self.dest:
+ return self.src
+ if not self.src:
+ return self.dest
+
+ files = listdir(self.path(self.dest))
+ self.dest_size = len(files)
+ files_other = listdir(self.path(self.src))
+ self.src_size = len(files_other)
+
+ if files and files_other:
+ print "compare %s with %s" % (files[-1], files_other[0])
+ if filecmp.cmp(
+ join(self.path(self.dest), files[-1]),
+ join(self.path(self.src), files_other[0]),
+ False
+ ):
+ files_other.pop(0)
+ self.num_deleted = 1
+
+ prefixes = {}
+ renamed_files = {}
+ renamed_files_other = {}
+ last_pfx = -1
+
+ # check if all elements of my files have a prefix
+ files_prefixed = True
+ for f in files:
+ p = self.get_prefix(f)
+ if p:
+ if p > last_pfx: last_pfx = p
+ else:
+ files_prefixed = False
+ break
+
+ # if not, add a 0 prefix to them
+ if not files_prefixed:
+ prefixes[0] = 0
+ for f in files:
+ renamed_files[f] = self.set_prefix(f, 0, True)
+
+ # two cases here - either all are prefixed or not.
+ files_other_prefixed = True
+ for f in files_other:
+ pfx = self.get_prefix(f)
+ if pfx is not None:
+ if not pfx in prefixes:
+ last_pfx += 1
+ prefixes[pfx] = last_pfx
+ renamed_files_other[f] = self.set_prefix(f, prefixes[pfx])
+ else:
+ # ops, not all files here were prefixed.
+ files_other_prefixed = False
+ break
+
+ # just set a 1- prefix to all of them
+ if not files_other_prefixed:
+ for f in files_other:
+ renamed_files_other[f] = self.set_prefix(f, 1, True)
+
+ # finally, move / rename files.
+ from nose.tools import set_trace
+ # set_trace()
+ for frm, to in renamed_files.items():
+ move(join(self.path(self.dest), frm),
+ join(self.path(self.dest), to))
+ for frm, to in renamed_files_other.items():
+ move(join(self.path(self.src), frm),
+ join(self.path(self.dest), to))
+
+ rmtree(join(self.path(self.src)))
+ return self.dest
import apiclient
-from catalogue.helpers import cached_in_field
+from catalogue.helpers import cached_in_field, GalleryMerger
from catalogue.models import BookPublishRecord, ChunkPublishRecord
from catalogue.signals import post_publish
from catalogue.tasks import refresh_instance, book_content_updated
number += 1
assert not other.chunk_set.exists()
- self.append_gallery(other, len_other)
-
- other.delete()
-
-
- def append_gallery(self, other, len_other):
- if self.gallery is None:
- self.gallery = other.gallery
- return
- if other.gallery is None:
- return
-
- def get_prefix(name):
- m = re.match(r"^([0-9])-", name)
- if m:
- return int(m.groups()[0])
- return None
-
- def set_prefix(name, prefix, always=False):
- m = not always and re.match(r"^([0-9])-", name)
- return "%1d-%s" % (prefix, m and name[2:] or name)
-
- files = os.listdir(os.path.join(settings.MEDIA_ROOT,
- settings.IMAGE_DIR, self.gallery))
- files_other = os.listdir(os.path.join(settings.MEDIA_ROOT,
- settings.IMAGE_DIR, other.gallery))
-
- prefixes = {}
- renamed_files = {}
- renamed_files_other = {}
- last_pfx = -1
-
- # check if all elements of my files have a prefix
- files_prefixed = True
- for f in files:
- p = get_prefix(f)
- if p:
- if p > last_pfx: last_pfx = p
- else:
- files_prefixed = False
- break
-
- # if not, add a 0 prefix to them
- if not files_prefixed:
- prefixes[0] = 0
- for f in files:
- renamed_files[f] = set_prefix(f, 0, True)
-
- # two cases here - either all are prefixed or not.
- files_other_prefixed = True
- for f in files_other:
- pfx = get_prefix(f)
- if pfx is not None:
- if not pfx in prefixes:
- last_pfx += 1
- prefixes[pfx] = last_pfx
- renamed_files_other[f] = set_prefix(f, prefixes[pfx])
- else:
- # ops, not all files here were prefixed.
- files_other_prefixed = False
- break
-
- # just set a 1- prefix to all of them
- if not files_other_prefixed:
- for f in files_other:
- renamed_files_other[f] = set_prefix(f, 1, True)
-
- # finally, move / rename files.
- for frm, to in renamed_files.items():
- shutil.move(os.path.join(settings.MEDIA_ROOT, settings.IMAGE_DIR, self.gallery, frm),
- os.path.join(settings.MEDIA_ROOT, settings.IMAGE_DIR, self.gallery, to))
- for frm, to in renamed_files_other.items():
- shutil.move(os.path.join(settings.MEDIA_ROOT, settings.IMAGE_DIR, other.gallery, frm),
- os.path.join(settings.MEDIA_ROOT, settings.IMAGE_DIR, self.gallery, to))
+ gm = GalleryMerger(self.gallery, other.gallery)
+ self.gallery = gm.merge()
# and move the gallery starts
- num_files = len(files)
+ num_files = gm.dest_size
for chunk in self[len(self) - len_other:]:
- chunk.gallery_start += num_files
+ chunk.gallery_start += gm.dest_size - gm.num_deleted
chunk.save()
-
+
+ other.delete()
@transaction.commit_on_success
c.gallery_start = 0
c = self.book2[1]
c.gallery_start = 2
- import nose.tools; nose.tools.set_trace()
+
self.make_gallery(self.book1, {
'1-0001_1l' : 'aa',
'1-0001_2r' : 'bb',
})
self.make_gallery(self.book2, {
- '1-0001_1l' : 'ee',
+ '1-0001_1l' : 'dd', # the same, should not be moved
'1-0001_2r' : 'ff',
'2-0002_1l' : 'gg',
'2-0002_2r' : 'hh',
'1-0001_2r',
'1-0002_1l',
'1-0002_2r',
- '2-0001_1l',
+ # '2-0001_1l',
'2-0001_2r',
'3-0002_1l',
'3-0002_2r',
])
- self.assertEqual((4, 6), (self.book1[2].gallery_start, self.book1[3].gallery_start))
+ self.assertEqual((3, 5), (self.book1[2].gallery_start, self.book1[3].gallery_start))
def test_none_indexed(self):
def test_none_indexed(self):
+ import nose.tools
self.book2 = Book.create(self.user, 'book 2', slug='book2')
self.make_gallery(self.book1, {
'1-0001_1l' : 'aa',
import tempfile
CATALOGUE_REPO_PATH = tempfile.mkdtemp(prefix='redakcja-repo')
+MEDIA_ROOT = tempfile.mkdtemp(prefix='media-root')
USE_CELERY = False
INSTALLED_APPS += ('django_nose', 'dvcs.tests')
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
+#TEST_MODULES = ('catalogue')
+
TEST_MODULES = ('catalogue', 'dvcs.tests', 'wiki', 'toolbar')
COVER_APPS = ('catalogue', 'dvcs', 'wiki', 'toolbar')
NOSE_ARGS = (