- local = self.materialize().encode('utf-8')
- base = other.parent.materialize().encode('utf-8')
- remote = other.materialize().encode('utf-8')
-
- merge = simplemerge.Merge3Text(base, local, remote)
- result = ''.join(merge.merge_lines())
- merge_node = self.children.create(
- merge_parent=other, tree=self.tree,
- author=author,
- author_name=author_name,
- author_email=author_email,
- description=description)
- merge_node.data.save('', ContentFile(result))
- return merge_node
-
- def revert(self, **kwargs):
- """ commit this version of a doc as new head """
- self.tree.commit(text=self.materialize(), **kwargs)
-
- def set_publishable(self, publishable):
- self.publishable = publishable
- self.save()
- post_publishable.send(sender=self, publishable=publishable)
-
-
-def create_tag_model(model):
- name = model.__name__ + 'Tag'
-
- class Meta(Tag.Meta):
- app_label = model._meta.app_label
-
- if hasattr(model, 'TagMeta'):
- for attr, value in model.TagMeta.__dict__.items():
- setattr(Meta, attr, value)
-
- attrs = {
- '__module__': model.__module__,
- 'Meta': Meta,
- }
- return type(name, (Tag,), attrs)
-
-
-def create_change_model(model):
- name = model.__name__ + 'Change'
- repo = GzipFileSystemStorage(location=model.REPO_PATH)
-
- class Meta(Change.Meta):
- app_label = model._meta.app_label
-
- attrs = {
- '__module__': model.__module__,
- 'tree': models.ForeignKey(model, related_name='change_set', verbose_name=_('document')),
- 'tags': models.ManyToManyField(model.tag_model, verbose_name=_('tags'), related_name='change_set'),
- 'data': models.FileField(_('data'), upload_to=data_upload_to, storage=repo),
- 'Meta': Meta,
- }
- return type(name, (Change,), attrs)
-
-
-class DocumentMeta(ModelBase):
- "Metaclass for Document models."
- def __new__(cls, name, bases, attrs):
-
- model = super(DocumentMeta, cls).__new__(cls, name, bases, attrs)
- if not model._meta.abstract:
- # create a real Tag object and `stage' fk
- model.tag_model = create_tag_model(model)
- models.ForeignKey(model.tag_model, verbose_name=_('stage'),
- null=True, blank=True).contribute_to_class(model, 'stage')
-
- # create real Change model and `head' fk
- model.change_model = create_change_model(model)
-
- models.ForeignKey(model.change_model,
- null=True, blank=True, default=None,
- verbose_name=_('head'),
- help_text=_("This document's current head."),
- editable=False).contribute_to_class(model, 'head')
-
- models.ForeignKey(User, null=True, blank=True, editable=False,
- verbose_name=_('creator'), related_name="created_%s" % name.lower()
- ).contribute_to_class(model, 'creator')
-
- return model
-
-
-class Document(models.Model):
- """File in repository. Subclass it to use version control in your app."""
-
- __metaclass__ = DocumentMeta
-
- # default repository path
- REPO_PATH = os.path.join(settings.MEDIA_ROOT, 'dvcs')
-
- user = models.ForeignKey(User, null=True, blank=True,
- verbose_name=_('user'), help_text=_('Work assignment.'))
-
- class Meta:
- abstract = True