#1557: colouring ampersand breaks XML
[redakcja.git] / apps / wiki / models.py
index a4dc794..7cb20c6 100644 (file)
@@ -3,11 +3,13 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+from django.db import models
 import re
 import os
 import vstorage
 from vstorage import DocumentNotFound
 from wiki import settings, constants
 import re
 import os
 import vstorage
 from vstorage import DocumentNotFound
 from wiki import settings, constants
+from slughifi import slughifi
 from django.utils.translation import ugettext_lazy as _
 
 from django.http import Http404
 from django.utils.translation import ugettext_lazy as _
 
 from django.http import Http404
@@ -16,6 +18,26 @@ import logging
 logger = logging.getLogger("fnp.wiki")
 
 
 logger = logging.getLogger("fnp.wiki")
 
 
+# _PCHARS_DICT = dict(zip((ord(x) for x in u"ĄĆĘŁŃÓŚŻŹąćęłńóśżź "), u"ACELNOSZZacelnoszz_"))
+_PCHARS_DICT = dict(zip((ord(x) for x in u" "), u"_"))
+
+# I know this is barbaric, but I didn't find a better solution ;(
+def split_name(name):
+    parts = name.translate(_PCHARS_DICT).split('__')
+    return parts
+
+def join_name(*parts, **kwargs):
+    name = u'__'.join(p.translate(_PCHARS_DICT) for p in parts)
+    logger.info("JOIN %r -> %r", parts, name)
+    return name
+
+def normalize_name(name):
+    """
+    >>> normalize_name("gąska".decode('utf-8'))
+    u'g\u0105ska'
+    """
+    return unicode(name).translate(_PCHARS_DICT)
+
 STAGE_TAGS_RE = re.compile(r'^#stage-finished: (.*)$', re.MULTILINE)
 
 
 STAGE_TAGS_RE = re.compile(r'^#stage-finished: (.*)$', re.MULTILINE)
 
 
@@ -31,13 +53,16 @@ class DocumentStorage(object):
         text, rev = self.vstorage.page_text_by_tag(name, tag)
         return Document(self, name=name, text=text, revision=rev)
 
         text, rev = self.vstorage.page_text_by_tag(name, tag)
         return Document(self, name=name, text=text, revision=rev)
 
+    def revert(self, name, revision, **commit_args):
+        self.vstorage.revert(name, revision, **commit_args)
+
     def get_or_404(self, *args, **kwargs):
         try:
             return self.get(*args, **kwargs)
         except DocumentNotFound:
             raise Http404
 
     def get_or_404(self, *args, **kwargs):
         try:
             return self.get(*args, **kwargs)
         except DocumentNotFound:
             raise Http404
 
-    def put(self, document, author, comment, parent):
+    def put(self, document, author, comment, parent=None):
         self.vstorage.save_text(
                 title=document.name,
                 text=document.text,
         self.vstorage.save_text(
                 title=document.name,
                 text=document.text,
@@ -47,15 +72,14 @@ class DocumentStorage(object):
 
         return document
 
 
         return document
 
-    def create_document(self, id, text, title=None):
-        if title is None:
-            title = id.title()
+    def create_document(self, text, name):
+        title = u', '.join(p.title() for p in split_name(name))
 
         if text is None:
             text = u''
 
 
         if text is None:
             text = u''
 
-        document = Document(self, name=id, text=text, title=title)
-        return self.put(document, u"<wiki>", u"Document created.", None)
+        document = Document(self, name=name, text=text, title=title)
+        return self.put(document, u"<wiki>", u"Document created.")
 
     def delete(self, name, author, comment):
         self.vstorage.delete_page(name, author, comment)
 
     def delete(self, name, author, comment):
         self.vstorage.delete_page(name, author, comment)
@@ -72,6 +96,9 @@ class DocumentStorage(object):
             changeset['description'] = STAGE_TAGS_RE.sub(stage_desc, changeset['description'])
             yield changeset
 
             changeset['description'] = STAGE_TAGS_RE.sub(stage_desc, changeset['description'])
             yield changeset
 
+    def doc_meta(self, title, revision=None):
+        return self.vstorage.page_meta(title, revision)
+
 
 
 class Document(object):
 
 
 class Document(object):
@@ -103,25 +130,35 @@ class Document(object):
                 except ValueError:
                     continue
 
                 except ValueError:
                     continue
 
-        gallery = result.get('gallery', self.name.replace(' ', '_'))
+        gallery = result.get('gallery', slughifi(self.name.replace(' ', '_')))
 
         if gallery.startswith('/'):
             gallery = os.path.basename(gallery)
 
         result['gallery'] = gallery
 
         if gallery.startswith('/'):
             gallery = os.path.basename(gallery)
 
         result['gallery'] = gallery
-
-        if 'title' not in result:
-            result['title'] = self.name.title()
-
         return result
 
     def info(self):
         return self.storage.vstorage.page_meta(self.name, self.revision)
 
         return result
 
     def info(self):
         return self.storage.vstorage.page_meta(self.name, self.revision)
 
-
 def getstorage():
     return DocumentStorage(settings.REPOSITORY_PATH)
 
 #
 # Django models
 #
 def getstorage():
     return DocumentStorage(settings.REPOSITORY_PATH)
 
 #
 # Django models
 #
+
+class Theme(models.Model):
+    name = models.CharField(_('name'), max_length=50, unique=True)
+
+    class Meta:
+        ordering = ('name',)
+        verbose_name = _('theme')
+        verbose_name_plural = _('themes')
+
+    def __unicode__(self):
+        return self.name
+
+    def __repr__(self):
+        return "Theme(name=%r)" % self.name
+