Mercurial > hatta-flask
changeset 2388:7494411224d8
Make the subdirectories repo work with memory commits
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Sun, 12 May 2013 11:02:44 +0200 |
| parents | 759f2d6f2edf |
| children | 199d47f5d776 |
| files | hatta/storage.py |
| diffstat | 1 files changed, 66 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/hatta/storage.py Sun May 12 09:43:24 2013 +0200 +++ b/hatta/storage.py Sun May 12 11:02:44 2013 +0200 @@ -212,14 +212,14 @@ other_data = filetip.filectx(other).data() return merge_func(parent_data, other_data, data) - def save_data(self, title, data, author=None, comment=None, parent=None): + def save_data(self, title, data, author=None, comment=None, parent_rev=None): """Save a new revision of the page. If the data is None, deletes it.""" _ = self._ user = (author or _(u'anon')).encode('utf-8') text = (comment or _(u'comment')).encode('utf-8') repo_file = self._title_to_file(title) - parent, other = self._get_parents(repo_file, parent) + parent, other = self._get_parents(repo_file, parent_rev) if data is None: if title not in self: raise error.ForbiddenErr() @@ -229,16 +229,16 @@ data = self._merge(repo_file, parent, other, data) except ValueError: text = _(u'failed merge of edit conflict').encode('utf-8') - def del_filectxfn(repo, memctx, path): - raise IOError() def filectxfn(repo, memctx, path): + if data is None: + raise IOError() return mercurial.context.memfilectx(path, data, False, False, None) ctx = mercurial.context.memctx( repo=self.repo, parents=(parent, other), text=text, files=[repo_file], - filectxfn=del_filectxfn if data is None else filectxfn, + filectxfn=filectxfn, user=user, ) self.repo.commitctx(ctx) @@ -423,10 +423,27 @@ # TODO: make them configurable index = "Index" - def _title_to_file(self, title): + def _is_directory(self, repo_path): + """Checks whether the path is a directory in the repository.""" + + # XXX This is not a very fast way of checking it. + # Maybe there is a better way. + if not repo_path: + return True + dir_path = repo_path + '/' + for repo_file in self._changectx(): + if repo_file.startswith(dir_path): + return True + return False + + def _title_to_file(self, title, force_directory=False, force_file=False): """ Modified escaping allowing (some) slashes and spaces. If the entry is a directory, use an index file. + + If ``force_directory`` is ``True``, always use an index file. + If ``force_file`` is ``True``, never use an index file. + If both are true, undefined. """ title = unicode(title).strip() @@ -434,7 +451,7 @@ escaped = self.periods_re.sub('%2E', escaped) escaped = self.slashes_re.sub('%2F', escaped) path = os.path.join(self.repo_prefix, escaped) - if os.path.isdir(os.path.join(self.repo_path, path)): + if not force_file and (self._is_directory(path) or force_directory): path = os.path.join(path, self.index) if page.page_mime(title) == 'text/x-wiki' and self.extension: path += self.extension @@ -447,53 +464,50 @@ filepath = os.path.dirname(filepath) return super(WikiSubdirectoryStorage, self)._file_to_title(filepath) - def turn_into_subdirectory(self, path): - """Turn a single-file page into an index page inside a subdirectory.""" + def save_data(self, title, data, author=u'', comment=u'', parent_rev=None): + """Save the file and make the subdirectories if needed.""" _ = self._ - self._check_path(path) - dir_path = os.path.dirname(path) - if not os.path.isdir(dir_path): - self.turn_into_subdirectory(dir_path) - if not os.path.exists(path): - os.mkdir(path) - return - try: - temp_dir = tempfile.mkdtemp(dir=self.path) - temp_path = os.path.join(temp_dir, 'saved') - mercurial.commands.rename(self.ui, self.repo, path, temp_path) - os.makedirs(path) - index_path = os.path.join(path, self.index) - mercurial.commands.rename(self.ui, self.repo, temp_path, - index_path) - finally: - try: - os.rmdir(temp_dir) - except OSError: - pass - def repo_path(path): - return path[len(self.repo_path)+1:] - files = [repo_path(index_path), repo_path(path)] - self._commit(files, _(u"made subdirectory page"), "<wiki>") - - @locked_repo - def save_file(self, title, file_name, author=u'', comment=u'', - parent=None): - """Save the file and make the subdirectories if needed.""" - - path = self._file_path(title) - dir_path = os.path.dirname(path) - if not os.path.isdir(dir_path): - self.turn_into_subdirectory(dir_path) - try: - os.makedirs(os.path.join(self.repo_path, dir_path)) - except OSError, e: - if e.errno != errno.EEXIST: - # "File exists" - raise - super(WikiSubdirectoryStorage, self).save_file(title, file_name, - author, comment, parent) - + user = (author or _(u'anon')).encode('utf-8') + text = (comment or _(u'comment')).encode('utf-8') + repo_file = self._title_to_file(title) + files = [repo_file] + dir_path = None + new_dir_path = None + if os.path.basename(repo_file) != self.index: + # Move a colliding file out of the way. + dir_path = os.path.dirname(repo_file) + if dir_path in self._changectx(): + new_dir_path = os.path.join(dir_path, self.index) + files.extend([dir_path, new_dir_path]) + dir_data = self._changectx()[dir_path].data() + parent, other = self._get_parents(repo_file, parent_rev) + if data is None: + if title not in self: + raise error.ForbiddenErr() + else: + if other is not None: + try: + data = self._merge(repo_file, parent, other, data) + except ValueError: + text = _(u'failed merge of edit conflict').encode('utf-8') + def filectxfn(repo, memctx, path): + if data is None or path == dir_path: + raise IOError() + if path == new_dir_path: + return mercurial.context.memfilectx(path, dir_data, + False, False, dir_path) + return mercurial.context.memfilectx(path, data, False, False, None) + ctx = mercurial.context.memctx( + repo=self.repo, + parents=(parent, other), + text=text, + files=files, + filectxfn=filectxfn, + user=user, + ) + self.repo.commitctx(ctx) + self._tips = {} def all_pages(self): """Iterate over the titles of all pages in the wiki."""
