+++ /dev/null
-from django.contrib import admin
-
-from dvcs import models
-
-
-class TagAdmin(admin.ModelAdmin):
- list_display = ['name', 'slug', 'ordering']
-
-admin.site.register(models.Tag, TagAdmin)
-admin.site.register(models.Document)
-admin.site.register(models.Change)
+++ /dev/null
-[
- {
- "pk": 1,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 1,
- "name": "Autokorekta",
- "slug": "first_correction"
- }
- },
- {
- "pk": 2,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 2,
- "name": "Tagowanie",
- "slug": "tagging"
- }
- },
- {
- "pk": 3,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 3,
- "name": "Korekta",
- "slug": "proofreading"
- }
- },
- {
- "pk": 4,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 4,
- "name": "Sprawdzenie przypis\u00f3w \u017ar\u00f3d\u0142a",
- "slug": "annotation-proofreading"
- }
- },
- {
- "pk": 5,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 5,
- "name": "Uwsp\u00f3\u0142cze\u015bnienie",
- "slug": "modernisation"
- }
- },
- {
- "pk": 6,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 6,
- "name": "Przypisy",
- "slug": "annotations"
- }
- },
- {
- "pk": 7,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 7,
- "name": "Motywy",
- "slug": "themes"
- }
- },
- {
- "pk": 8,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 8,
- "name": "Ostateczna redakcja literacka",
- "slug": "editor-proofreading"
- }
- },
- {
- "pk": 9,
- "model": "dvcs.tag",
- "fields": {
- "ordering": 9,
- "name": "Ostateczna redakcja techniczna",
- "slug": "technical-editor-proofreading"
- }
- }
-]
+++ /dev/null
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
- def forwards(self, orm):
-
- # Adding model 'Tag'
- db.create_table('dvcs_tag', (
- ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
- ('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
- ('slug', self.gf('django.db.models.fields.SlugField')(db_index=True, max_length=64, unique=True, null=True, blank=True)),
- ('ordering', self.gf('django.db.models.fields.IntegerField')()),
- ))
- db.send_create_signal('dvcs', ['Tag'])
-
- # Adding model 'Change'
- db.create_table('dvcs_change', (
- ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
- ('author', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)),
- ('author_name', self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True)),
- ('author_email', self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True)),
- ('patch', self.gf('django.db.models.fields.TextField')(blank=True)),
- ('tree', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dvcs.Document'])),
- ('revision', self.gf('django.db.models.fields.IntegerField')(db_index=True)),
- ('parent', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='children', null=True, blank=True, to=orm['dvcs.Change'])),
- ('merge_parent', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='merge_children', null=True, blank=True, to=orm['dvcs.Change'])),
- ('description', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
- ('created_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, db_index=True)),
- ('publishable', self.gf('django.db.models.fields.BooleanField')(default=False)),
- ))
- db.send_create_signal('dvcs', ['Change'])
-
- # Adding unique constraint on 'Change', fields ['tree', 'revision']
- db.create_unique('dvcs_change', ['tree_id', 'revision'])
-
- # Adding M2M table for field tags on 'Change'
- db.create_table('dvcs_change_tags', (
- ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
- ('change', models.ForeignKey(orm['dvcs.change'], null=False)),
- ('tag', models.ForeignKey(orm['dvcs.tag'], null=False))
- ))
- db.create_unique('dvcs_change_tags', ['change_id', 'tag_id'])
-
- # Adding model 'Document'
- db.create_table('dvcs_document', (
- ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
- ('creator', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='created_documents', null=True, to=orm['auth.User'])),
- ('head', self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['dvcs.Change'], null=True, blank=True)),
- ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)),
- ('stage', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dvcs.Tag'], null=True, blank=True)),
- ))
- db.send_create_signal('dvcs', ['Document'])
-
- if not db.dry_run:
- from django.core.management import call_command
- call_command("loaddata", "stages.json")
-
-
- def backwards(self, orm):
-
- # Removing unique constraint on 'Change', fields ['tree', 'revision']
- db.delete_unique('dvcs_change', ['tree_id', 'revision'])
-
- # Deleting model 'Tag'
- db.delete_table('dvcs_tag')
-
- # Deleting model 'Change'
- db.delete_table('dvcs_change')
-
- # Removing M2M table for field tags on 'Change'
- db.delete_table('dvcs_change_tags')
-
- # Deleting model 'Document'
- db.delete_table('dvcs_document')
-
-
- models = {
- 'auth.group': {
- 'Meta': {'object_name': 'Group'},
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- 'auth.permission': {
- 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- 'auth.user': {
- 'Meta': {'object_name': 'User'},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- 'contenttypes.contenttype': {
- 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- 'dvcs.change': {
- 'Meta': {'ordering': "('created_at',)", 'unique_together': "(['tree', 'revision'],)", 'object_name': 'Change'},
- 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
- 'author_email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'author_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}),
- 'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'merge_parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'merge_children'", 'null': 'True', 'blank': 'True', 'to': "orm['dvcs.Change']"}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'children'", 'null': 'True', 'blank': 'True', 'to': "orm['dvcs.Change']"}),
- 'patch': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'publishable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'revision': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
- 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dvcs.Tag']", 'symmetrical': 'False'}),
- 'tree': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dvcs.Document']"})
- },
- 'dvcs.document': {
- 'Meta': {'object_name': 'Document'},
- 'creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'created_documents'", 'null': 'True', 'to': "orm['auth.User']"}),
- 'head': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dvcs.Change']", 'null': 'True', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'stage': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dvcs.Tag']", 'null': 'True', 'blank': 'True'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
- },
- 'dvcs.tag': {
- 'Meta': {'ordering': "['ordering']", 'object_name': 'Tag'},
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
- 'ordering': ('django.db.models.fields.IntegerField', [], {}),
- 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
- }
- }
-
- complete_apps = ['dvcs']
from datetime import datetime
from django.db import models
+from django.db.models.base import ModelBase
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from mercurial import mdiff, simplemerge
_object_cache = {}
class Meta:
+ abstract = True
ordering = ['ordering']
def __unicode__(self):
author_name = models.CharField(max_length=128, null=True, blank=True)
author_email = models.CharField(max_length=128, null=True, blank=True)
patch = models.TextField(blank=True)
- tree = models.ForeignKey('Document')
revision = models.IntegerField(db_index=True)
parent = models.ForeignKey('self',
default=datetime.now)
publishable = models.BooleanField(default=False)
- tags = models.ManyToManyField(Tag)
-
class Meta:
+ abstract = True
ordering = ('created_at',)
unique_together = ['tree', 'revision']
if self.parent is None and self.merge_parent is not None:
return self.apply_to(self.merge_parent.materialize())
- changes = Change.objects.exclude(parent=None).filter(
- tree=self.tree,
+ changes = self.tree.change_set.exclude(parent=None).filter(
revision__lte=self.revision).order_by('revision')
text = u''
for change in changes:
self.tree.commit(text=self.materialize(), **kwargs)
+def create_tag_model(model):
+ name = model.__name__ + 'Tag'
+ attrs = {
+ '__module__': model.__module__,
+ }
+ return type(name, (Tag,), attrs)
+
+
+def create_change_model(model):
+ name = model.__name__ + 'Change'
+
+ attrs = {
+ '__module__': model.__module__,
+ 'tree': models.ForeignKey(model, related_name='change_set'),
+ 'tags': models.ManyToManyField(model.tag_model, related_name='change_set'),
+ }
+ 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,
+ 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,
+ help_text=_("This document's current head."),
+ editable=False).contribute_to_class(model, 'head')
+
+ return model
+
+
+
class Document(models.Model):
"""
File in repository.
"""
+ __metaclass__ = DocumentMeta
+
creator = models.ForeignKey(User, null=True, blank=True, editable=False,
related_name="created_documents")
- head = models.ForeignKey(Change,
- null=True, blank=True, default=None,
- help_text=_("This document's current head."),
- editable=False)
user = models.ForeignKey(User, null=True, blank=True)
- stage = models.ForeignKey(Tag, null=True, blank=True)
+
+ class Meta:
+ abstract = True
def __unicode__(self):
return u"{0}, HEAD: {1}".format(self.id, self.head_id)
else:
parent = kwargs['parent']
if not isinstance(parent, Change):
- parent = Change.objects.get(pk=kwargs['parent'])
+ parent = self.change_set.objects.get(pk=kwargs['parent'])
if 'patch' not in kwargs:
if 'text' not in kwargs:
if not isinstance(instance, Document):
return
if created:
- instance.head = Change.objects.create(
+ instance.head = instance.change_model.objects.create(
revision=-1,
author=instance.creator,
patch=Change.make_patch('', ''),
admin.site.register(models.Book, BookAdmin)
admin.site.register(models.Chunk)
admin.site.register(models.Theme)
+
+admin.site.register(models.Chunk.tag_model)
--- /dev/null
+[
+ {
+ "pk": 1,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 1,
+ "name": "Autokorekta",
+ "slug": "first_correction"
+ }
+ },
+ {
+ "pk": 2,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 2,
+ "name": "Tagowanie",
+ "slug": "tagging"
+ }
+ },
+ {
+ "pk": 3,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 3,
+ "name": "Korekta",
+ "slug": "proofreading"
+ }
+ },
+ {
+ "pk": 4,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 4,
+ "name": "Sprawdzenie przypis\u00f3w \u017ar\u00f3d\u0142a",
+ "slug": "annotation-proofreading"
+ }
+ },
+ {
+ "pk": 5,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 5,
+ "name": "Uwsp\u00f3\u0142cze\u015bnienie",
+ "slug": "modernisation"
+ }
+ },
+ {
+ "pk": 6,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 6,
+ "name": "Przypisy",
+ "slug": "annotations"
+ }
+ },
+ {
+ "pk": 7,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 7,
+ "name": "Motywy",
+ "slug": "themes"
+ }
+ },
+ {
+ "pk": 8,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 8,
+ "name": "Ostateczna redakcja literacka",
+ "slug": "editor-proofreading"
+ }
+ },
+ {
+ "pk": 9,
+ "model": "wiki.chunktag",
+ "fields": {
+ "ordering": 9,
+ "name": "Ostateczna redakcja techniczna",
+ "slug": "technical-editor-proofreading"
+ }
+ }
+]
from django import forms
from django.utils.translation import ugettext_lazy as _
-from dvcs.models import Tag
from wiki.constants import MASTERS
from wiki.models import Book, Chunk
"""
id = forms.CharField(widget=forms.HiddenInput)
- tag = forms.ModelChoiceField(queryset=Tag.objects.all())
+ tag = forms.ModelChoiceField(queryset=Chunk.tag_model.objects.all())
revision = forms.IntegerField(widget=forms.HiddenInput)
)
stage_completed = forms.ModelChoiceField(
- queryset=Tag.objects.all(),
+ queryset=Chunk.tag_model.objects.all(),
required=False,
label=_(u"Completed"),
help_text=_(u"If you completed a life cycle stage, select it."),
Form used for editing a chunk.
"""
user = forms.ModelChoiceField(queryset=
- User.objects.annotate(count=Count('document')).
+ User.objects.annotate(count=Count('chunk')).
order_by('-count', 'last_name', 'first_name'))
from django import http
+from django.db.models import Count
from django.utils import simplejson as json
from django.utils.functional import Promise
from datetime import datetime
return wrapper
-class BookChunks(object):
- """
- Yields the chunks of a book.
- """
+class ChunksList(object):
+ def __init__(self, chunk_qs):
+ self.chunk_qs = chunk_qs.annotate(
+ book_length=Count('book__chunk')).select_related(
+ 'book', 'stage__name',
+ 'user')
- def __init__(self, book):
- self.book = book
+ self.book_ids = [x['book_id'] for x in chunk_qs.values('book_id')]
+
+ def __getitem__(self, key):
+ if isinstance(key, slice):
+ return self.get_slice(key)
+ elif isinstance(key, int):
+ return self.get_slice(slice(key, key+1))[0]
+ else:
+ raise TypeError('Unsupported list index. Must be a slice or an int.')
+
+ def __len__(self):
+ return len(self.book_ids)
+
+ def get_slice(self, slice_):
+ book_ids = self.book_ids[slice_]
+ chunk_qs = self.chunk_qs.filter(book__in=book_ids)
- @property
- def chunks(self):
- return self.book.chunk_set.all()
+ chunks_list = []
+ book = None
+ for chunk in chunk_qs:
+ if chunk.book != book:
+ book = chunk.book
+ chunks_list.append(ChoiceChunks(book, [chunk], chunk.book_length))
+ else:
+ chunks_list[-1].chunks.append(chunk)
+ return chunks_list
-class ChoiceChunks(BookChunks):
+class ChoiceChunks(object):
"""
Associates the given chunks iterable for a book.
"""
chunks = None
- def __init__(self, book, chunks):
+ def __init__(self, book, chunks, book_length):
self.book = book
self.chunks = chunks
+ self.book_length = book_length
--- /dev/null
+# encoding: utf-8
+import datetime
+import os.path
+import cPickle
+import re
+import urllib
+
+from django.conf import settings
+from django.db import models
+from mercurial import mdiff, hg, ui
+from south.db import db
+from south.v2 import SchemaMigration
+
+from slughifi import slughifi
+
+META_REGEX = re.compile(r'\s*<!--\s(.*?)-->', re.DOTALL | re.MULTILINE)
+STAGE_TAGS_RE = re.compile(r'^#stage-finished: (.*)$', re.MULTILINE)
+AUTHOR_RE = re.compile(r'\s*(.*?)\s*<(.*)>\s*')
+
+
+def urlunquote(url):
+ """Unqotes URL
+
+ # >>> urlunquote('Za%C5%BC%C3%B3%C5%82%C4%87_g%C4%99%C5%9Bl%C4%85_ja%C5%BA%C5%84')
+ # u'Za\u017c\xf3\u0142\u0107_g\u0119\u015bl\u0105 ja\u017a\u0144'
+ """
+ return unicode(urllib.unquote(url), 'utf-8', 'ignore')
+
+
+def split_name(name):
+ parts = name.split('__')
+ return parts
+
+
+def file_to_title(fname):
+ """ Returns a title-like version of a filename. """
+ parts = (p.replace('_', ' ').title() for p in fname.split('__'))
+ return ' / '.join(parts)
+
+
+def make_patch(src, dst):
+ if isinstance(src, unicode):
+ src = src.encode('utf-8')
+ if isinstance(dst, unicode):
+ dst = dst.encode('utf-8')
+ return cPickle.dumps(mdiff.textdiff(src, dst))
+
+
+def plain_text(text):
+ return re.sub(META_REGEX, '', text, 1)
+
+
+def gallery(slug, text):
+ result = {}
+
+ m = re.match(META_REGEX, text)
+ if m:
+ for line in m.group(1).split('\n'):
+ try:
+ k, v = line.split(':', 1)
+ result[k.strip()] = v.strip()
+ except ValueError:
+ continue
+
+ gallery = result.get('gallery', slughifi(slug))
+
+ if gallery.startswith('/'):
+ gallery = os.path.basename(gallery)
+
+ return gallery
+
+
+def migrate_file_from_hg(orm, fname, entry):
+ fname = urlunquote(fname)
+ print fname
+ if fname.endswith('.xml'):
+ fname = fname[:-4]
+ title = file_to_title(fname)
+ fname = slughifi(fname)
+ # create all the needed objects
+ # what if it already exists?
+ book = orm.Book.objects.create(
+ title=title,
+ slug=fname)
+ chunk = orm.Chunk.objects.create(
+ book=book,
+ number=1,
+ slug='1')
+ head = orm['wiki.ChunkChange'].objects.create(
+ tree=chunk,
+ revision=-1,
+ patch=make_patch('', ''),
+ created_at=datetime.datetime.fromtimestamp(entry.filectx(0).date()[0]),
+ description=''
+ )
+ chunk.head = head
+ try:
+ chunk.stage = orm['wiki.ChunkTag'].objects.order_by('ordering')[0]
+ except IndexError:
+ chunk.stage = None
+ old_data = ''
+
+ maxrev = entry.filerev()
+ gallery_link = None
+
+ for rev in xrange(maxrev + 1):
+ fctx = entry.filectx(rev)
+ data = fctx.data()
+ gallery_link = gallery(fname, data)
+ data = plain_text(data)
+
+ # get tags from description
+ description = fctx.description().decode("utf-8", 'replace')
+ tags = STAGE_TAGS_RE.findall(description)
+ tags = [orm['wiki.ChunkTag'].objects.get(slug=slug.strip()) for slug in tags]
+
+ if tags:
+ max_ordering = max(tags, key=lambda x: x.ordering).ordering
+ try:
+ chunk.stage = orm['wiki.ChunkTag'].objects.filter(ordering__gt=max_ordering).order_by('ordering')[0]
+ except IndexError:
+ chunk.stage = None
+
+ description = STAGE_TAGS_RE.sub('', description)
+
+ author = author_name = author_email = None
+ author_desc = fctx.user().decode("utf-8", 'replace')
+ m = AUTHOR_RE.match(author_desc)
+ if m:
+ try:
+ author = orm['auth.User'].objects.get(username=m.group(1), email=m.group(2))
+ except orm['auth.User'].DoesNotExist:
+ author_name = m.group(1)
+ author_email = m.group(2)
+ else:
+ author_name = author_desc
+
+ head = orm['wiki.ChunkChange'].objects.create(
+ tree=chunk,
+ revision=rev + 1,
+ patch=make_patch(old_data, data),
+ created_at=datetime.datetime.fromtimestamp(fctx.date()[0]),
+ description=description,
+ author=author,
+ author_name=author_name,
+ author_email=author_email,
+ parent=chunk.head
+ )
+ head.tags = tags
+ chunk.head = head
+ old_data = data
+
+ chunk.save()
+ if gallery_link:
+ book.gallery = gallery_link
+ book.save()
+
+
+def migrate_from_hg(orm):
+ try:
+ hg_path = settings.WIKI_REPOSITORY_PATH
+ except:
+ pass
+
+ print 'migrate from', hg_path
+ repo = hg.repository(ui.ui(), hg_path)
+ tip = repo['tip']
+ for fname in tip:
+ if fname.startswith('.'):
+ continue
+ migrate_file_from_hg(orm, fname, tip[fname])
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'Book'
+ db.create_table('wiki_book', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=128, db_index=True)),
+ ('gallery', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
+ ('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='children', null=True, to=orm['wiki.Book'])),
+ ('parent_number', self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True)),
+ ('last_published', self.gf('django.db.models.fields.DateTimeField')(null=True)),
+ ('_list_html', self.gf('django.db.models.fields.TextField')(null=True)),
+ ))
+ db.send_create_signal('wiki', ['Book'])
+
+ # Adding model 'Chunk'
+ db.create_table('wiki_chunk', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('creator', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='created_documents', null=True, to=orm['auth.User'])),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)),
+ ('book', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['wiki.Book'])),
+ ('number', self.gf('django.db.models.fields.IntegerField')()),
+ ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50, db_index=True)),
+ ('comment', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
+ ('stage', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['wiki.ChunkTag'], null=True, blank=True)),
+ ('head', self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['wiki.ChunkChange'], null=True, blank=True)),
+ ))
+ db.send_create_signal('wiki', ['Chunk'])
+
+ # Adding unique constraint on 'Chunk', fields ['book', 'number']
+ db.create_unique('wiki_chunk', ['book_id', 'number'])
+
+ # Adding unique constraint on 'Chunk', fields ['book', 'slug']
+ db.create_unique('wiki_chunk', ['book_id', 'slug'])
+
+ # Adding model 'ChunkTag'
+ db.create_table('wiki_chunktag', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
+ ('slug', self.gf('django.db.models.fields.SlugField')(db_index=True, max_length=64, unique=True, null=True, blank=True)),
+ ('ordering', self.gf('django.db.models.fields.IntegerField')()),
+ ))
+ db.send_create_signal('wiki', ['ChunkTag'])
+
+ # Adding model 'ChunkChange'
+ db.create_table('wiki_chunkchange', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)),
+ ('author_name', self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True)),
+ ('author_email', self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True)),
+ ('patch', self.gf('django.db.models.fields.TextField')(blank=True)),
+ ('revision', self.gf('django.db.models.fields.IntegerField')(db_index=True)),
+ ('parent', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='children', null=True, blank=True, to=orm['wiki.ChunkChange'])),
+ ('merge_parent', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='merge_children', null=True, blank=True, to=orm['wiki.ChunkChange'])),
+ ('description', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
+ ('created_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, db_index=True)),
+ ('publishable', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('tree', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['wiki.Chunk'])),
+ ))
+ db.send_create_signal('wiki', ['ChunkChange'])
+
+ # Adding unique constraint on 'ChunkChange', fields ['tree', 'revision']
+ db.create_unique('wiki_chunkchange', ['tree_id', 'revision'])
+
+ # Adding M2M table for field tags on 'ChunkChange'
+ db.create_table('wiki_chunkchange_tags', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('chunkchange', models.ForeignKey(orm['wiki.chunkchange'], null=False)),
+ ('chunktag', models.ForeignKey(orm['wiki.chunktag'], null=False))
+ ))
+ db.create_unique('wiki_chunkchange_tags', ['chunkchange_id', 'chunktag_id'])
+
+ if not db.dry_run:
+ from django.core.management import call_command
+ call_command("loaddata", "stages.json")
+
+ migrate_from_hg(orm)
+
+ def backwards(self, orm):
+
+ # Removing unique constraint on 'ChunkChange', fields ['tree', 'revision']
+ db.delete_unique('wiki_chunkchange', ['tree_id', 'revision'])
+
+ # Removing unique constraint on 'Chunk', fields ['book', 'slug']
+ db.delete_unique('wiki_chunk', ['book_id', 'slug'])
+
+ # Removing unique constraint on 'Chunk', fields ['book', 'number']
+ db.delete_unique('wiki_chunk', ['book_id', 'number'])
+
+ # Deleting model 'Book'
+ db.delete_table('wiki_book')
+
+ # Deleting model 'Chunk'
+ db.delete_table('wiki_chunk')
+
+ # Deleting model 'ChunkTag'
+ db.delete_table('wiki_chunktag')
+
+ # Deleting model 'ChunkChange'
+ db.delete_table('wiki_chunkchange')
+
+ # Removing M2M table for field tags on 'ChunkChange'
+ db.delete_table('wiki_chunkchange_tags')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'wiki.book': {
+ 'Meta': {'ordering': "['parent_number', 'title']", 'object_name': 'Book'},
+ '_list_html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'gallery': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_published': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['wiki.Book']"}),
+ 'parent_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128', 'db_index': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+ },
+ 'wiki.chunk': {
+ 'Meta': {'ordering': "['number']", 'unique_together': "[['book', 'number'], ['book', 'slug']]", 'object_name': 'Chunk'},
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['wiki.Book']"}),
+ 'comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'created_documents'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'head': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['wiki.ChunkChange']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'number': ('django.db.models.fields.IntegerField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+ 'stage': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['wiki.ChunkTag']", 'null': 'True', 'blank': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
+ },
+ 'wiki.chunkchange': {
+ 'Meta': {'ordering': "('created_at',)", 'unique_together': "(['tree', 'revision'],)", 'object_name': 'ChunkChange'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+ 'author_email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
+ 'author_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}),
+ 'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'merge_parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'merge_children'", 'null': 'True', 'blank': 'True', 'to': "orm['wiki.ChunkChange']"}),
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'children'", 'null': 'True', 'blank': 'True', 'to': "orm['wiki.ChunkChange']"}),
+ 'patch': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'publishable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'revision': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['wiki.ChunkTag']", 'symmetrical': 'False'}),
+ 'tree': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['wiki.Chunk']"})
+ },
+ 'wiki.chunktag': {
+ 'Meta': {'ordering': "['ordering']", 'object_name': 'ChunkTag'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'ordering': ('django.db.models.fields.IntegerField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
+ },
+ 'wiki.theme': {
+ 'Meta': {'ordering': "('name',)", 'object_name': 'Theme'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'})
+ }
+ }
+
+ complete_apps = ['wiki']
+++ /dev/null
-# encoding: utf-8
-import datetime
-import os.path
-import cPickle
-import re
-import urllib
-
-from django.conf import settings
-from django.db import models
-from mercurial import mdiff, hg, ui
-from south.db import db
-from south.v2 import SchemaMigration
-
-from slughifi import slughifi
-
-META_REGEX = re.compile(r'\s*<!--\s(.*?)-->', re.DOTALL | re.MULTILINE)
-STAGE_TAGS_RE = re.compile(r'^#stage-finished: (.*)$', re.MULTILINE)
-AUTHOR_RE = re.compile(r'\s*(.*?)\s*<(.*)>\s*')
-
-
-def urlunquote(url):
- """Unqotes URL
-
- # >>> urlunquote('Za%C5%BC%C3%B3%C5%82%C4%87_g%C4%99%C5%9Bl%C4%85_ja%C5%BA%C5%84')
- # u'Za\u017c\xf3\u0142\u0107_g\u0119\u015bl\u0105 ja\u017a\u0144'
- """
- return unicode(urllib.unquote(url), 'utf-8', 'ignore')
-
-
-def split_name(name):
- parts = name.split('__')
- return parts
-
-
-def file_to_title(fname):
- """ Returns a title-like version of a filename. """
- parts = (p.replace('_', ' ').title() for p in fname.split('__'))
- return ' / '.join(parts)
-
-
-def make_patch(src, dst):
- if isinstance(src, unicode):
- src = src.encode('utf-8')
- if isinstance(dst, unicode):
- dst = dst.encode('utf-8')
- return cPickle.dumps(mdiff.textdiff(src, dst))
-
-
-def plain_text(text):
- return re.sub(META_REGEX, '', text, 1)
-
-
-def gallery(slug, text):
- result = {}
-
- m = re.match(META_REGEX, text)
- if m:
- for line in m.group(1).split('\n'):
- try:
- k, v = line.split(':', 1)
- result[k.strip()] = v.strip()
- except ValueError:
- continue
-
- gallery = result.get('gallery', slughifi(slug))
-
- if gallery.startswith('/'):
- gallery = os.path.basename(gallery)
-
- return gallery
-
-
-def migrate_file_from_hg(orm, fname, entry):
- fname = urlunquote(fname)
- print fname
- if fname.endswith('.xml'):
- fname = fname[:-4]
- title = file_to_title(fname)
- fname = slughifi(fname)
- # create all the needed objects
- # what if it already exists?
- book = orm.Book.objects.create(
- title=title,
- slug=fname)
- chunk = orm.Chunk.objects.create(
- book=book,
- number=1,
- slug='1')
- head = orm['dvcs.Change'].objects.create(
- tree=chunk,
- revision=-1,
- patch=make_patch('', ''),
- created_at=datetime.datetime.fromtimestamp(entry.filectx(0).date()[0]),
- description=''
- )
- chunk.head = head
- try:
- chunk.stage = orm['dvcs.Tag'].objects.order_by('ordering')[0]
- except IndexError:
- chunk.stage = None
- old_data = ''
-
- maxrev = entry.filerev()
- gallery_link = None
-
- for rev in xrange(maxrev + 1):
- fctx = entry.filectx(rev)
- data = fctx.data()
- gallery_link = gallery(fname, data)
- data = plain_text(data)
-
- # get tags from description
- description = fctx.description().decode("utf-8", 'replace')
- tags = STAGE_TAGS_RE.findall(description)
- tags = [orm['dvcs.Tag'].objects.get(slug=slug.strip()) for slug in tags]
-
- if tags:
- max_ordering = max(tags, key=lambda x: x.ordering).ordering
- try:
- chunk.stage = orm['dvcs.Tag'].objects.filter(ordering__gt=max_ordering).order_by('ordering')[0]
- except IndexError:
- chunk.stage = None
-
- description = STAGE_TAGS_RE.sub('', description)
-
- author = author_name = author_email = None
- author_desc = fctx.user().decode("utf-8", 'replace')
- m = AUTHOR_RE.match(author_desc)
- if m:
- try:
- author = orm['auth.User'].objects.get(username=m.group(1), email=m.group(2))
- except orm['auth.User'].DoesNotExist:
- author_name = m.group(1)
- author_email = m.group(2)
- else:
- author_name = author_desc
-
- head = orm['dvcs.Change'].objects.create(
- tree=chunk,
- revision=rev + 1,
- patch=make_patch(old_data, data),
- created_at=datetime.datetime.fromtimestamp(fctx.date()[0]),
- description=description,
- author=author,
- author_name=author_name,
- author_email=author_email,
- parent=chunk.head
- )
- head.tags = tags
- chunk.head = head
- old_data = data
-
- chunk.save()
- if gallery_link:
- book.gallery = gallery_link
- book.save()
-
-
-def migrate_from_hg(orm):
- try:
- hg_path = settings.WIKI_REPOSITORY_PATH
- except:
- pass
-
- print 'migrate from', hg_path
- repo = hg.repository(ui.ui(), hg_path)
- tip = repo['tip']
- for fname in tip:
- if fname.startswith('.'):
- continue
- migrate_file_from_hg(orm, fname, tip[fname])
-
-
-class Migration(SchemaMigration):
-
- depends_on = [
- ('dvcs', '0001_initial'),
- ]
-
- def forwards(self, orm):
-
- # Adding model 'Book'
- db.create_table('wiki_book', (
- ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
- ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
- ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=128, db_index=True)),
- ('gallery', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
- ('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='children', null=True, to=orm['wiki.Book'])),
- ('parent_number', self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True)),
- ('last_published', self.gf('django.db.models.fields.DateTimeField')(null=True)),
- ('_list_html', self.gf('django.db.models.fields.TextField')(null=True)),
- ))
- db.send_create_signal('wiki', ['Book'])
-
- # Adding model 'Chunk'
- db.create_table('wiki_chunk', (
- ('document_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['dvcs.Document'], unique=True, primary_key=True)),
- ('book', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['wiki.Book'])),
- ('number', self.gf('django.db.models.fields.IntegerField')()),
- ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50, db_index=True)),
- ('comment', self.gf('django.db.models.fields.CharField')(max_length=255)),
- ))
- db.send_create_signal('wiki', ['Chunk'])
-
- # Adding unique constraint on 'Chunk', fields ['book', 'number']
- db.create_unique('wiki_chunk', ['book_id', 'number'])
-
- # Adding unique constraint on 'Chunk', fields ['book', 'slug']
- db.create_unique('wiki_chunk', ['book_id', 'slug'])
-
- if not db.dry_run:
- migrate_from_hg(orm)
-
- def backwards(self, orm):
-
- # Removing unique constraint on 'Chunk', fields ['book', 'slug']
- db.delete_unique('wiki_chunk', ['book_id', 'slug'])
-
- # Removing unique constraint on 'Chunk', fields ['book', 'number']
- db.delete_unique('wiki_chunk', ['book_id', 'number'])
-
- # Deleting model 'Book'
- db.delete_table('wiki_book')
-
- # Deleting model 'Chunk'
- db.delete_table('wiki_chunk')
-
-
- models = {
- 'auth.group': {
- 'Meta': {'object_name': 'Group'},
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- 'auth.permission': {
- 'Meta': {'ordering': "('content_type__app_label', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- 'auth.user': {
- 'Meta': {'object_name': 'User'},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- 'contenttypes.contenttype': {
- 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- 'dvcs.change': {
- 'Meta': {'ordering': "('created_at',)", 'unique_together': "(['tree', 'revision'],)", 'object_name': 'Change'},
- 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
- 'author_email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'author_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}),
- 'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'merge_parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'merge_children'", 'null': 'True', 'blank': 'True', 'to': "orm['dvcs.Change']"}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'children'", 'null': 'True', 'blank': 'True', 'to': "orm['dvcs.Change']"}),
- 'patch': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'publishable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'revision': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
- 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dvcs.Tag']", 'symmetrical': 'False'}),
- 'tree': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dvcs.Document']"})
- },
- 'dvcs.document': {
- 'Meta': {'object_name': 'Document'},
- 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
- 'head': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dvcs.Change']", 'null': 'True', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'stage': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dvcs.Tag']", 'null': 'True'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
- },
- 'dvcs.tag': {
- 'Meta': {'ordering': "['ordering']", 'object_name': 'Tag'},
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
- 'ordering': ('django.db.models.fields.IntegerField', [], {}),
- 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
- },
- 'wiki.book': {
- 'Meta': {'ordering': "['parent_number', 'title']", 'object_name': 'Book'},
- '_list_html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
- 'gallery': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_published': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['wiki.Book']"}),
- 'parent_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128', 'db_index': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
- },
- 'wiki.chunk': {
- 'Meta': {'ordering': "['number']", 'unique_together': "[['book', 'number'], ['book', 'slug']]", 'object_name': 'Chunk', '_ormbases': ['dvcs.Document']},
- 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['wiki.Book']"}),
- 'comment': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'document_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['dvcs.Document']", 'unique': 'True', 'primary_key': 'True'}),
- 'number': ('django.db.models.fields.IntegerField', [], {}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'})
- },
- 'wiki.theme': {
- 'Meta': {'ordering': "('name',)", 'object_name': 'Theme'},
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'})
- }
- }
-
- complete_apps = ['wiki']
else:
return cls.objects.get(book__slug=slug, slug=chunk)
- def pretty_name(self):
+ def pretty_name(self, book_length=None):
title = self.book.title
if self.comment:
title += ", %s" % self.comment
- count = len(self.book)
- if count > 1:
- title += " (%d/%d)" % (self.number, len(self.book))
+ if book_length > 1:
+ title += " (%d/%d)" % (self.number, book_length)
return title
def split(self, slug, comment='', creator=None):
{% block leftcolumn %}
<form enctype="multipart/form-data" method="POST" action="">
+ {% csrf_token %}
{{ form.as_p }}
<p><button type="submit">{% trans "Append book" %}</button></p>
{% if need_fixing %}
<tr><td></td><td>
<form method="POST" action="">
+ {% csrf_token %}
{% if choose_master %}
{{ form.master }}
{% endif %}
<button id="publish-button" type="submit">
<span>{% trans "Publish" %}</span></button>
<img src="{{ STATIC_URL }}img/angel-right.png" style="vertical-align: middle" />
- </form></form></p>
+ </form></p>
{% else %}
{% trans "This book cannot be published yet" %}
{% endif %}
{% block leftcolumn %}
<form enctype="multipart/form-data" method="POST" action="">
+ {% csrf_token %}
{{ form.as_p }}
<p><button type="submit">{% trans "Save" %}</button></p>
{% block leftcolumn %}
<form enctype="multipart/form-data" method="POST" action="">
+ {% csrf_token %}
{{ form.as_p }}
<p><button type="submit">{% trans "Add chunk" %}</button></p>
{% block leftcolumn %}
<form enctype="multipart/form-data" method="POST" action="">
+ {% csrf_token %}
{{ form.as_p }}
<p><button type="submit">{% trans "Save" %}</button></p>
{% endif %}
{% for item in books %}
{% with item.book as book %}
-
- {% ifequal book.chunk_set.count 1 %}
+
+ {% ifequal item.book_length 1 %}
+ {% with item.chunks.0 as chunk %}
<tr>
<td><a target="_blank" href="{% url wiki_book book.slug %}">[B]</a></td>
- <td><a href="{% url wiki_chunk_edit book.slug book.0.slug %}">[c]</a></td>
+ <td><a href="{% url wiki_chunk_edit book.slug chunk.slug %}">[c]</a></td>
<td><a target="_blank"
href="{% url wiki_editor book.slug %}">
{{ book.title }}</a></td>
- <td>({{ book.0.stage }})</td>
- <td>{% if book.0.user %}<a href="{% url wiki_user book.0.user.username %}">{{ book.0.user.first_name }} {{ book.0.user.last_name }}</a>{% endif %}</td>
+ <td>({{ chunk.stage }})</td>
+ <td>{% if chunk.user %}<a href="{% url wiki_user chunk.user.username %}">{{ chunk.user.first_name }} {{ chunk.user.last_name }}</a>{% endif %}</td>
</tr>
+ {% endwith %}
{% else %}
<tr>
<td><a target="_blank" href="{% url wiki_book book.slug %}">[B]</a></td>
{% load i18n %}
<div id="pubmark_dialog" class="dialog" data-ui-jsclass="PubmarkDialog">
<form method="POST" action="#">
+ {% csrf_token %}
{% for field in forms.pubmark.visible_fields %}
<p>{{ field.label_tag }} {{ field }} <span data-ui-error-for="{{ field.name }}"> </span></p>
<p>{{ field.help_text }}</p>
{% load i18n %}
<div id="revert_dialog" class="dialog" data-ui-jsclass="RevertDialog">
<form method="POST" action="">
+ {% csrf_token %}
<p>{{ forms.text_revert.comment.label }}</p>
<p class="help_text">
{{ forms.text_revert.comment.help_text}}
{% load i18n %}
<div id="save_dialog" class="dialog" data-ui-jsclass="SaveDialog">
<form method="POST" action="">
+ {% csrf_token %}
<p>{{ forms.text_save.comment.label }}</p>
<p class="help_text">
{{ forms.text_save.comment.help_text}}
{% load i18n %}
<div id="add_tag_dialog" class="dialog" data-ui-jsclass="AddTagDialog">
<form method="POST" action="#">
+ {% csrf_token %}
{% for field in forms.add_tag.visible_fields %}
<p>{{ field.label_tag }} {{ field }} <span data-ui-error-for="{{ field.name }}"> </span></p>
<p>{{ field.help_text }}</p>
from __future__ import absolute_import
+from django.db.models import Count
from django.core.urlresolvers import reverse
from django.contrib.comments.models import Comment
from django.template.defaultfilters import stringfilter
from django import template
from django.utils.translation import ugettext as _
-from wiki.models import Book
-from dvcs.models import Change
+from wiki.models import Book, Chunk
register = template.Library()
def changes_wall(max_len):
- qs = Change.objects.filter(revision__gt=-1).order_by('-created_at').select_related()
+ qs = Chunk.change_model.objects.filter(revision__gt=-1).order_by('-created_at')
+ qs = qs.defer('patch')
+ qs = qs.select_related('author', 'tree')
+ #qs = qs.annotate(book_length=Count('chunk__book__chunk'))
qs = qs[:max_len]
for item in qs:
tag = 'stage' if item.tags.count() else 'change'
- chunk = item.tree.chunk
+ chunk = item.tree
w = WallItem(tag)
w.title = chunk.pretty_name()
w.summary = item.description
@active_tab('all')
@never_cache
def document_list(request):
+ chunks_list = helpers.ChunksList(Chunk.objects.order_by(
+ 'book__title', 'book', 'number'))
+
return direct_to_template(request, 'wiki/document_list.html', extra_context={
- 'books': [helpers.BookChunks(b) for b in Book.objects.all()],
+ 'books': chunks_list,
+ #'books': [helpers.BookChunks(b) for b in Book.objects.all().select_related()],
'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
key=lambda x: x[1]['time'], reverse=True),
})
@active_tab('unassigned')
@never_cache
def unassigned(request):
- chunks = Chunk.objects.filter(user=None).order_by('book__title', 'book', 'number')
- books = []
- book = None
- for chunk in chunks:
- if chunk.book != book:
- book = chunk.book
- books.append(helpers.ChoiceChunks(book, [chunk]))
- else:
- books[-1].chunks.append(chunk)
+ chunks_list = helpers.ChunksList(Chunk.objects.filter(
+ user=None).order_by('book__title', 'book__id', 'number'))
return direct_to_template(request, 'wiki/document_list.html', extra_context={
- 'books': books,
+ 'books': chunks_list,
'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
key=lambda x: x[1]['time'], reverse=True),
})
else:
user = get_object_or_404(User, username=username)
- chunks = Chunk.objects.filter(user=user).order_by('book__title', 'number')
- books = []
- book = None
- for chunk in chunks:
- if chunk.book != book:
- book = chunk.book
- books.append(helpers.ChoiceChunks(book, [chunk]))
- else:
- books[-1].chunks.append(chunk)
+ chunks_list = helpers.ChunksList(Chunk.objects.filter(
+ user=user).order_by('book__title', 'book', 'number'))
return direct_to_template(request, 'wiki/document_list.html', extra_context={
- 'books': books,
+ 'books': chunks_list,
'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
key=lambda x: x[1]['time'], reverse=True),
})
@active_tab('users')
def users(request):
return direct_to_template(request, 'wiki/user_list.html', extra_context={
- 'users': User.objects.all().annotate(count=Count('document')).order_by(
+ 'users': User.objects.all().annotate(count=Count('chunk')).order_by(
'-count', 'last_name', 'first_name'),
})
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.load_template_source',
- 'django.template.loaders.app_directories.load_template_source',
-# 'django.template.loaders.eggs.load_template_source',
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
)
TEMPLATE_CONTEXT_PROCESSORS = (
- "django.core.context_processors.auth",
+ "django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"redakcja.context_processors.settings", # this is instead of media