Skip to content
This repository has been archived by the owner on Aug 26, 2022. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ubernostrum committed Apr 5, 2012
2 parents f41128e + 58056d9 commit 7b27747
Show file tree
Hide file tree
Showing 41 changed files with 473 additions and 3,511 deletions.
2 changes: 1 addition & 1 deletion apps/demos/templates/demos/devderby_landing.html
Expand Up @@ -34,7 +34,7 @@
<section id="content-main" class="full" role="main">
<header id="derby-head">
<p class="presents"><a href="{{ url('demos') }}">{{_("Mozilla Demo Studio")}}</a> {{_("presents")}}</p>
<h1>{{_("Dev Derby")}}</h1>
<h1><a href="{{url('demos_devderby_landing')}}">{{_("Dev Derby")}}</a></h1>
<h2>{% trans title=tag_meta(current_challenge_tag_name, "short_title") %}Show us what you can do with {{ title }}{% endtrans %}</h2>
<p class="info">{{_("Join the Dev Derby now and submit your demo to win an Android phone or other prizes.")}}</p>
<p class="submit">{% trans %}<a href="{{ submit_url }}"><b>Submit</b> Your Demo</a>{% endtrans %}</p>
Expand Down
2 changes: 1 addition & 1 deletion apps/demos/templates/demos/devderby_rules.html
Expand Up @@ -29,7 +29,7 @@
<section id="content-main" class="full" role="main">
<header id="derby-head">
<p class="presents"><a href="{{ url('demos') }}">{{_("Mozilla Demo Studio")}}</a> {{_("presents")}}</p>
<h1>Dev Derby</h1>
<h1><a href="{{url('demos_devderby_landing')}}">Dev Derby</a></h1>
<h2>Dev Derby Contest Official Rules</h2>
</header>

Expand Down
2 changes: 1 addition & 1 deletion apps/demos/templates/demos/devderby_tag.html
Expand Up @@ -31,7 +31,7 @@
<section id="content-main" class="full" role="main">
<header id="derby-head">
<p class="presents"><a href="{{ url('demos') }}">{{_("Mozilla Demo Studio")}}</a> {{_("presents")}}</p>
<h1>{{_("Dev Derby")}}</h1>
<h1><a href="{{url('demos_devderby_landing')}}">{{_("Dev Derby")}}</a></h1>
<h2><span>{{ tag_meta(tag, 'dateline') }}</span> {{ tag_meta(tag, 'short_title') }}</h2>
</header>

Expand Down
1 change: 1 addition & 0 deletions apps/docs/templates/docs/docs.html
Expand Up @@ -70,6 +70,7 @@ <h2>New Wiki Feature Preview</h2>
<li>
<ul class="cols-4">
<li><a href="{{ url('wiki.new_document') }}">New page</a></li>
<li><a href="{{ url('wiki.new_document') }}?slug=Template:">New template</a></li>
<li><a href="{{ url('wiki.all_documents') }}">List all pages</a></li>
<li><a href="{{ url('wiki.list_review') }}">Pages for review</a></li>
</ul>
Expand Down
67 changes: 60 additions & 7 deletions apps/wiki/content.py
@@ -1,7 +1,5 @@
import logging
import re
from urllib import urlencode
import bleach

import html5lib
from html5lib.filters._base import Filter as html5lib_Filter
Expand All @@ -20,7 +18,9 @@

# List of tags supported for section editing. A subset of everything that could
# be considered an HTML5 section
SECTION_EDIT_TAGS = ('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'section')
SECTION_TAGS = ('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'section')

HEAD_TAGS = ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')


def parse(src):
Expand Down Expand Up @@ -117,7 +117,7 @@ def __iter__(self):
# Pass 2: Sprinkle in IDs where they're missing
for token in buffer:
if ('StartTag' == token['type'] and
token['name'] in SECTION_EDIT_TAGS):
token['name'] in SECTION_TAGS):
attrs = dict(token['data'])
id = attrs.get('id', None)
if not id:
Expand All @@ -142,7 +142,7 @@ def __iter__(self):
yield token

if ('StartTag' == token['type'] and
token['name'] in SECTION_EDIT_TAGS):
token['name'] in SECTION_TAGS):
attrs = dict(token['data'])
id = attrs.get('id', None)
if id:
Expand Down Expand Up @@ -173,6 +173,58 @@ def __iter__(self):
yield t


class SectionTOCFilter(html5lib_Filter):
"""Filter which builds a TOC tree of sections with headers"""
def __init__(self, source):
html5lib_Filter.__init__(self, source)
self.level = 1
self.in_header = False

def __iter__(self):
input = html5lib_Filter.__iter__(self)

for token in input:
if ('StartTag' == token['type'] and token['name'] in HEAD_TAGS):
self.in_header = True
out = ()
level_match = re.compile(r'^h(\d)$').match(token['name'])
level = int(level_match.group(1))
if level > self.level:
diff = level - self.level
for i in range(diff):
out += ({'type': 'StartTag', 'name': 'ol',
'data': {}},)
self.level = level
elif level < self.level:
diff = self.level - level
for i in range(diff):
out += ({'type': 'EndTag', 'name': 'li'},
{'type': 'EndTag', 'name': 'ol'})
self.level = level
attrs = dict(token['data'])
id = attrs.get('id', None)
if id:
out += (
{'type': 'StartTag', 'name': 'li', 'data': {}},
{'type': 'StartTag', 'name': 'a',
'data': {
'rel': 'internal',
'href': '#%s' % id,
}},
)
for t in out:
yield t
elif ('Characters' == token['type'] and self.in_header):
yield token
elif ('EndTag' == token['type'] and token['name'] in HEAD_TAGS):
self.in_header = False
level_match = re.compile(r'^h(\d)$').match(token['name'])
level = int(level_match.group(1))
out = ({'type': 'EndTag', 'name': 'a'},)
for t in out:
yield t


class SectionFilter(html5lib_Filter):
"""Filter which can either extract the fragment representing a section by
ID, or substitute a replacement stream for a section. Loosely based on
Expand Down Expand Up @@ -328,7 +380,7 @@ def __iter__(self):
continue

attrs = dict(token['data'])
if attrs.get('class','') != 'script':
if attrs.get('class', '') != 'script':
yield token
continue

Expand All @@ -353,7 +405,8 @@ def __iter__(self):
ds_call = '%s("%s")' % (m.group(1), m.group(2))

# template("template name", [ "params" ])
wt_re = re.compile(r'''^template\(['"]([^'"]+)['"],\s*\[([^\]]+)]''', re.I)
wt_re = re.compile(
r'''^template\(['"]([^'"]+)['"],\s*\[([^\]]+)]''', re.I)
m = wt_re.match(ds_call)
if m:
ds_call = '%s(%s)' % (m.group(1), m.group(2).strip())
Expand Down
2 changes: 1 addition & 1 deletion apps/wiki/forms.py
Expand Up @@ -70,7 +70,7 @@ class DocumentForm(forms.ModelForm):
'max_length': TITLE_LONG})
slug = StrippedCharField(min_length=2, max_length=255,
required=False,
widget=forms.HiddenInput(),
widget=forms.TextInput(),
label=_lazy(u'Slug:'),
help_text=_lazy(u'Article URL'),
error_messages={'required': SLUG_REQUIRED,
Expand Down
@@ -1,22 +1,34 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from south.v2 import DataMigration
from django.db import models

class Migration(SchemaMigration):
class Migration(DataMigration):

def forwards(self, orm):

# Removing unique constraint on 'Document', fields ['locale', 'title']
db.delete_unique('wiki_document', ['locale', 'title'])
# We could import this from the wiki model, but migrations need to live
# independently from models and their changes. So, this is necessary
# redundancy.
permissions = (
("add_template_document", "Can add Template:* document"),
("change_template_document", "Can change Template:* document"),
)

def forwards(self, orm):
"Write your forwards methods here."
ct = orm['contenttypes.ContentType'].objects.get(app_label='wiki',
model='document')
for p in self.permissions:
perm, created = orm['auth.permission'].objects.get_or_create(
content_type=ct, codename=p[0], defaults=dict(name=p[1]))

def backwards(self, orm):

# Adding unique constraint on 'Document', fields ['locale', 'title']
db.create_unique('wiki_document', ['locale', 'title'])

"Write your backwards methods here."
ct = orm['contenttypes.ContentType'].objects.get(app_label='wiki',
model='document')
for p in self.permissions:
orm['auth.permission'].objects.filter(content_type=ct,
codename=p[0]).delete()

models = {
'auth.group': {
Expand All @@ -25,6 +37,12 @@ def backwards(self, orm):
'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.message': {
'Meta': {'object_name': 'Message'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.TextField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'_message_set'", 'to': "orm['auth.User']"})
},
'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'}),
Expand Down Expand Up @@ -66,19 +84,6 @@ def backwards(self, orm):
'secret': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
},
'taggit.tag': {
'Meta': {'object_name': 'Tag'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'})
},
'taggit.taggeditem': {
'Meta': {'object_name': 'TaggedItem'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
},
'wiki.document': {
'Meta': {'unique_together': "(('parent', 'locale'), ('slug', 'locale'))", 'object_name': 'Document'},
'category': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
Expand All @@ -88,11 +93,19 @@ def backwards(self, orm):
'is_localizable': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
'is_template': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
'locale': ('sumo.models.LocaleField', [], {'default': "'en-US'", 'max_length': '7', 'db_index': 'True'}),
'mindtouch_page_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_index': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'translations'", 'null': 'True', 'to': "orm['wiki.Document']"}),
'related_documents': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['wiki.Document']", 'through': "orm['wiki.RelatedDocument']", 'symmetrical': 'False'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'})
},
'wiki.documenttag': {
'Meta': {'object_name': 'DocumentTag'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'})
},
'wiki.editortoolbar': {
'Meta': {'object_name': 'EditorToolbar'},
'code': ('django.db.models.fields.TextField', [], {'max_length': '2000'}),
Expand Down Expand Up @@ -152,14 +165,23 @@ def backwards(self, orm):
'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['wiki.Document']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
'is_mindtouch_migration': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
'keywords': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'mindtouch_old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True', 'db_index': 'True'}),
'reviewed': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'reviewer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reviewed_revisions'", 'null': 'True', 'to': "orm['auth.User']"}),
'significance': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
'summary': ('django.db.models.fields.TextField', [], {}),
'tags': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'})
},
'wiki.taggeddocument': {
'Meta': {'object_name': 'TaggedDocument'},
'content_object': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['wiki.Document']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['wiki.DocumentTag']"})
}
}

complete_apps = ['wiki']
complete_apps = ['auth', 'contenttypes', 'wiki']
23 changes: 20 additions & 3 deletions apps/wiki/models.py
Expand Up @@ -198,6 +198,16 @@ def _inherited(parent_attr, direct_attr):
class DocumentManager(ManagerBase):
"""Manager for Documents, assists for queries"""

def allows_add_by(self, user, slug):
"""Determine whether the user can create a document with the given
slug. Mainly for enforcing Template: editing permissions"""
if (slug.startswith(TEMPLATE_TITLE_PREFIX) and
not user.has_perm('wiki.add_template_document')):
return False
# NOTE: We could enforce wiki.add_document here, but it's implicitly
# assumed everyone is allowed.
return True

def filter_for_list(self, locale=None, category=None, tag=None,
tag_name=None):
docs = self.order_by('title')
Expand Down Expand Up @@ -319,6 +329,10 @@ class Document(NotificationsMixin, ModelBase):
# title and locale as well as a combined (title, locale) one.
class Meta(object):
unique_together = (('parent', 'locale'), ('slug', 'locale'))
permissions = (
("add_template_document", "Can add Template:* document"),
("change_template_document", "Can change Template:* document"),
)

def _existing(self, attr, value):
"""Return an existing doc (if any) in this locale whose `attr` attr is
Expand Down Expand Up @@ -629,9 +643,9 @@ def allows_revision_by(self, user):
docs may have different permissions.
"""
# TODO: Add tests for templateness or whatever is required.
# Leaving this method signature untouched for now in case we do need
# to use it in the future. ~james
if (self.slug.startswith(TEMPLATE_TITLE_PREFIX) and
not user.has_perm('wiki.change_template_document')):
return False
return True

def allows_editing_by(self, user):
Expand All @@ -642,6 +656,9 @@ def allows_editing_by(self, user):
Revision, the Document fields can only be edited by privileged users.
"""
if (self.slug.startswith(TEMPLATE_TITLE_PREFIX) and
not user.has_perm('wiki.change_template_document')):
return False
return (not self.current_revision or
user.has_perm('wiki.change_document'))

Expand Down
17 changes: 6 additions & 11 deletions apps/wiki/templates/wiki/document.html
Expand Up @@ -33,7 +33,7 @@ <h1 class="page-title">{{ document.title }}</h1>
{% if request.user.is_authenticated() %}
<li class="page-watch"><a href="{{ url('wiki.document_watch', document.full_path) }}">{{_('Watch')}}</a></li>
{% endif %}
{% if document.allows_editing_by(request.user) %}
{% if document.allows_editing_by(request.user) or document.allows_revision_by(request.user) %}
<li class="page-edit"><a href="{{ url('wiki.edit_document', document.full_path) }}">{{_('Edit')}}</a></li>
{% endif %}
</ul>
Expand Down Expand Up @@ -90,25 +90,20 @@ <h1 class="page-title">{{ document.title }}</h1>
{% endif %}

<div id="wikiArticle" class="page-content boxed">
{#
<div id="article-nav">
{% if toc_html %}
<div id="article-nav">
<div class="page-toc">
<h2>Table of Contents</h2>
<ol>
<li><a href="#Lorum_Ipsum">Lorum Ipsum</a>
<ol>
<li><a href="#Dolor_Sit_Amet">Dolor Sit Amet</a></li>
</ol>
</li>
<li><a href="#Another_Heading">Another Heading</a></li>
{{ toc_html|safe }}
</ol>
</div>
<ul class="page-anchors">
<li class="anchor-tags"><a href="#page-tags">Tags</a></li>
<li class="anchor-files"><a href="#page-files">Files</a></li>
</ul>
</div>
#}
</div>
{% endif %}
{% if not fallback_reason %}
{% if document.is_template %}
<pre class="brush: js">{{ document_html }}</pre>
Expand Down
1 change: 0 additions & 1 deletion apps/wiki/templates/wiki/edit_document.html
Expand Up @@ -106,7 +106,6 @@ <h1>{{ _('Editing <em>{title}</em>')|fe(title=revision.title) }}</h1>
<li><label>{{_('Title:')}}</label> {{ revision_form.title | safe }}</li>
<li><label>{{_('Slug:')}}</label> {{ revision_form.slug | safe }}</li>
<li><label>{{_('Tags:')}}</label> {{ revision_form.tags | safe }}</li>
<li><label>{{_('Keywords:')}}</label> {{ revision_form.keywords | safe }}</li>
</ul>
{% endif %}

Expand Down

0 comments on commit 7b27747

Please sign in to comment.