diff --git a/settings.py b/settings.py index 2de81fe2be..46c0d3e04e 100644 --- a/settings.py +++ b/settings.py @@ -92,13 +92,14 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', - 'django.contrib.admin', +# 'django.contrib.admin', 'courseware', 'auth', 'django.contrib.humanize', 'static_template_view', 'textbook', 'staticbook', + 'simplewiki', # Uncomment the next line to enable the admin: # 'django.contrib.admin', # Uncomment the next line to enable admin documentation: diff --git a/simplewiki/__init__.py b/simplewiki/__init__.py new file mode 100644 index 0000000000..cdbd556dad --- /dev/null +++ b/simplewiki/__init__.py @@ -0,0 +1,6 @@ +import sys, os + +# allow mdx_* parsers to be just dropped in the simplewiki folder +module_path = os.path.abspath(os.path.dirname(__file__)) +if module_path not in sys.path: + sys.path.append(module_path) diff --git a/simplewiki/admin.py b/simplewiki/admin.py new file mode 100644 index 0000000000..573da56d6d --- /dev/null +++ b/simplewiki/admin.py @@ -0,0 +1,59 @@ +from django.contrib import admin +from django import forms +from django.utils.translation import ugettext as _ +from models import Article, Revision, Permission, ArticleAttachment + +class RevisionInline(admin.TabularInline): + model = Revision + extra = 1 + +class RevisionAdmin(admin.ModelAdmin): + list_display = ('article', '__unicode__', 'revision_date', 'revision_user', 'revision_text') + search_fields = ('article', 'counter') + +class AttachmentAdmin(admin.ModelAdmin): + list_display = ('article', '__unicode__', 'uploaded_on', 'uploaded_by') + +class ArticleAdminForm(forms.ModelForm): + def clean(self): + cleaned_data = self.cleaned_data + if cleaned_data.get("slug").startswith('_'): + raise forms.ValidationError(_('Slug cannot start with _ character.' + 'Reserved for internal use.')) + if not self.instance.pk: + parent = cleaned_data.get("parent") + slug = cleaned_data.get("slug") + if Article.objects.filter(slug__exact=slug, parent__exact=parent): + raise forms.ValidationError(_('Article slug and parent must be ' + 'unique together.')) + return cleaned_data + class Meta: + model = Article + +class ArticleAdmin(admin.ModelAdmin): + list_display = ('created_by', 'slug', 'modified_on', 'parent') + search_fields = ('slug',) + prepopulated_fields = {'slug': ('title',) } + inlines = [RevisionInline] + form = ArticleAdminForm + save_on_top = True + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if db_field.name == 'current_revision': + # Try to determine the id of the article being edited + id = request.path.split('/') + import re + if len(id) > 0 and re.match(r"\d+", id[-2]): + kwargs["queryset"] = Revision.objects.filter(article=id[-2]) + return db_field.formfield(**kwargs) + else: + db_field.editable = False + return db_field.formfield(**kwargs) + return super(ArticleAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) + +class PermissionAdmin(admin.ModelAdmin): + search_fields = ('article', 'counter') + +admin.site.register(Article, ArticleAdmin) +admin.site.register(Revision, RevisionAdmin) +admin.site.register(Permission, PermissionAdmin) +admin.site.register(ArticleAttachment, AttachmentAdmin) \ No newline at end of file diff --git a/simplewiki/mdx_camelcase.py b/simplewiki/mdx_camelcase.py new file mode 100644 index 0000000000..1b979520ab --- /dev/null +++ b/simplewiki/mdx_camelcase.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python + +''' +WikiLink Extention for Python-Markdown +====================================== + +Converts CamelCase words to relative links. Requires Python-Markdown 1.6+ + +Basic usage: + + >>> import markdown + >>> text = "Some text with a WikiLink." + >>> md = markdown.markdown(text, ['wikilink']) + >>> md + '\\n
Some text with a WikiLink.\\n
\\n\\n\\n' + +To define custom settings the simple way: + + >>> md = markdown.markdown(text, + ... ['wikilink(base_url=/wiki/,end_url=.html,html_class=foo)'] + ... ) + >>> md + '\\nSome text with a WikiLink.\\n
\\n\\n\\n' + +Custom settings the complex way: + + >>> md = markdown.Markdown(text, + ... extensions = ['wikilink'], + ... extension_configs = {'wikilink': [ + ... ('base_url', 'http://example.com/'), + ... ('end_url', '.html'), + ... ('html_class', '') ]}, + ... encoding='utf8', + ... safe_mode = True) + >>> str(md) + '\\nSome text with a WikiLink.\\n
\\n\\n\\n' + +Use MetaData with mdx_meta.py (Note the blank html_class in MetaData): + + >>> text = """wiki_base_url: http://example.com/ + ... wiki_end_url: .html + ... wiki_html_class: + ... + ... Some text with a WikiLink.""" + >>> md = markdown.Markdown(text, ['meta', 'wikilink']) + >>> str(md) + '\\nSome text with a WikiLink.\\n
\\n\\n\\n' + +From the command line: + + python markdown.py -x wikilink(base_url=http://example.com/,end_url=.html,html_class=foo) src.txt + +By [Waylan Limberg](http://achinghead.com/). + +Project website: http://achinghead.com/markdown-wikilinks/ +Contact: waylan [at] gmail [dot] com + +License: [BSD](http://www.opensource.org/licenses/bsd-license.php) + +Version: 0.4 (Oct 14, 2006) + +Dependencies: +* [Python 2.3+](http://python.org) +* [Markdown 1.6+](http://www.freewisdom.org/projects/python-markdown/) +* For older dependencies use [WikiLink Version 0.3] +(http://code.limberg.name/svn/projects/py-markdown-ext/wikilinks/tags/release-0.3/) +''' + +import markdown + +class CamelCaseExtension(markdown.Extension): + def __init__(self, configs): + # set extension defaults + self.config = { + 'base_url' : ['/', 'String to append to beginning or URL.'], + 'end_url' : ['/', 'String to append to end of URL.'], + 'html_class' : ['wikilink', 'CSS hook. Leave blank for none.'] + } + + # Override defaults with user settings + for key, value in configs : + # self.config[key][0] = value + self.setConfig(key, value) + + def add_inline(self, md, name, klass, re): + pattern = klass(re) + pattern.md = md + pattern.ext = self + md.inlinePatterns.add(name, pattern, "
+
+ mypic.jpg becomes
+
+Requires Python-Markdown 1.6+
+'''
+
+import simplewiki.settings as settings
+import markdown
+
+class ImageExtension(markdown.Extension):
+ def __init__(self, configs):
+ for key, value in configs :
+ self.setConfig(key, value)
+
+ def add_inline(self, md, name, klass, re):
+ pattern = klass(re)
+ pattern.md = md
+ pattern.ext = self
+ md.inlinePatterns.add(name, pattern, "http://www.metacafe.com/watch/yt-tZMsrrQCnx8/pycon_2008_django_sprint_room/
' +>>> s = "`http://www.metacafe.com/watch/yt-tZMsrrQCnx8/pycon_2008_django_sprint_room/`" +>>> markdown.markdown(s, ['video']) +u'http://www.metacafe.com/watch/yt-tZMsrrQCnx8/pycon_2008_django_sprint_room/
+
+ {% if wiki_article %}
+
+
+
+ {% endif %}
+
+
+
{% trans "This article has been locked" %}
+ {% endif %} ++ {% trans "Last modified" %}: {{ wiki_article.modified_on|date }}, {{ wiki_article.modified_on|time }} +
+ {% endif %} ++ {% for rel in wiki_article.related.all %} + + {% endfor %} +
+ {% else %} +({% trans "none" %})
+ {% endif %} + {% if wiki_write %} + + {% endif %} + +({% trans "none" %})
+ {% endif %} + + {% if wiki_attachments_write %} + + + {% endif %} + ++The page you requested could not be found. +Click here to create it. +
+{% else %} ++Or maybe rather: Congratulations! It seems that there's no root +article, which is probably because you just installed simple-wiki +and your installation is working. Now you can create the root article. +Click here to create it. +
+{% endif %} +{% else %} + +{% if wiki_err_noparent %} ++You cannot create this page, because its parent +does not exist. Click here +to create it. +
+{% else %} + +{% if wiki_err_keyword %} ++The page you're trying to create {{wiki_url}} starts with _, which is reserved for internal use. +
+{% else %} + +{% if wiki_err_locked %} ++The article you are trying to modify is locked. +
+{% else %} + +{% if wiki_err_noread %} ++You do not have access to read this article. +
+{% else %} + +{% if wiki_err_nowrite %} ++You do not have access to edit this article. +
+{% else %} + +{% if wiki_err_noanon %} ++Anonymous attachments are not allowed. Try logging in. +
+{% else %} + +{% if wiki_err_create %} ++You do not have access to create this article. +
+{% else %} + +{% if wiki_err_encode %} ++The url you requested could not be handled by the wiki. +Probably you used a bad character in the URL. +Only use digits, English letters, underscore and dash. For instance +/wiki/An_Article-1 +
+ + +{% else %} ++An error has occured. +
+ + +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endif %} + +` tags in the HTML output. For example, this input: + + * Bird + * Magic + +will turn into: + +
Bird
Magic
+
+
+It's worth noting that it's possible to trigger an ordered list by
+accident, by writing something like this:
+
+ 1986. What a great season.
+
+In other words, a *number-period-space* sequence at the beginning of a
+line. To avoid this, you can backslash-escape the period:
+
+ 1986\. What a great season.
+
+
+
+### Code Blocks
+
+Pre-formatted code blocks are used for writing about programming or
+markup source code. Rather than forming normal paragraphs, the lines
+of a code block are interpreted literally. Markdown wraps a code block
+in both `` and `` tags.
+
+To produce a code block in Markdown, simply indent every line of the
+block by at least 4 spaces or 1 tab. For example, given this input:
+
+ This is a normal paragraph:
+
+ This is a code block.
+
+Markdown will generate:
+
+ This is a normal paragraph:
+
+ This is a code block.
+
+
+One level of indentation -- 4 spaces or 1 tab -- is removed from each
+line of the code block. For example, this:
+
+ Here is an example of AppleScript:
+
+ tell application "Foo"
+ beep
+ end tell
+
+will turn into:
+
+ Here is an example of AppleScript:
+
+ tell application "Foo"
+ beep
+ end tell
+
+
+A code block continues until it reaches a line that is not indented
+(or the end of the article).
+
+Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
+are automatically converted into HTML entities. This makes it very
+easy to include example HTML source code using Markdown -- just paste
+it and indent it, and Markdown will handle the hassle of encoding the
+ampersands and angle brackets. For example, this:
+
+
+
+will turn into:
+
+ <div class="footer">
+ © 2004 Foo Corporation
+ </div>
+
+
+Regular Markdown syntax is not processed within code blocks. E.g.,
+asterisks are just literal asterisks within a code block. This means
+it's also easy to use Markdown to write about Markdown's own syntax.
+
+
+
+### Horizontal Rules
+
+You can produce a horizontal rule tag (`
`) by placing three or
+more hyphens, asterisks, or underscores on a line by themselves. If you
+wish, you may use spaces between the hyphens or asterisks. Each of the
+following lines will produce a horizontal rule:
+
+ * * *
+
+ ***
+
+ *****
+
+ - - -
+
+ ---------------------------------------
+
+
+## Span Elements
+
+### Links
+
+Markdown supports two style of links: *inline* and *reference*.
+
+In both styles, the link text is delimited by [square brackets].
+
+To create an inline link, use a set of regular parentheses immediately
+after the link text's closing square bracket. Inside the parentheses,
+put the URL where you want the link to point, along with an *optional*
+title for the link, surrounded in quotes. For example:
+
+ This is [an example](http://example.com/ "Title") inline link.
+
+ [This link](http://example.net/) has no title attribute.
+
+Will produce:
+
+ This is
+ an example inline link.
+
+ This link has no
+ title attribute.
+
+If you're referring to a local resource on the same server, you can
+use relative paths:
+
+ See my [About](/about/) page for details.
+
+Reference-style links use a second set of square brackets, inside
+which you place a label of your choosing to identify the link:
+
+ This is [an example][id] reference-style link.
+
+You can optionally use a space to separate the sets of brackets:
+
+ This is [an example] [id] reference-style link.
+
+Then, anywhere in the document, you define your link label like this,
+on a line by itself:
+
+ [id]: http://example.com/ "Optional Title Here"
+
+That is:
+
+* Square brackets containing the link identifier (optionally
+ indented from the left margin using up to three spaces);
+* followed by a colon;
+* followed by one or more spaces (or tabs);
+* followed by the URL for the link;
+* optionally followed by a title attribute for the link, enclosed
+ in double or single quotes, or enclosed in parentheses.
+
+The following three link definitions are equivalent:
+
+ [foo]: http://example.com/ "Optional Title Here"
+ [foo]: http://example.com/ 'Optional Title Here'
+ [foo]: http://example.com/ (Optional Title Here)
+
+**Note:** There is a known bug in Markdown.pl 1.0.1 which prevents
+single quotes from being used to delimit link titles.
+
+The link URL may, optionally, be surrounded by angle brackets:
+
+ [id]: "Optional Title Here"
+
+You can put the title attribute on the next line and use extra spaces
+or tabs for padding, which tends to look better with longer URLs:
+
+ [id]: http://example.com/longish/path/to/resource/here
+ "Optional Title Here"
+
+Link definitions are only used for creating links during Markdown
+processing, and are stripped from your document in the HTML output.
+
+Link definition names may consist of letters, numbers, spaces, and
+punctuation -- but they are *not* case sensitive. E.g. these two
+links:
+
+ [link text][a]
+ [link text][A]
+
+are equivalent.
+
+The *implicit link name* shortcut allows you to omit the name of the
+link, in which case the link text itself is used as the name.
+Just use an empty set of square brackets -- e.g., to link the word
+"Google" to the google.com web site, you could simply write:
+
+ [Google][]
+
+And then define the link:
+
+ [Google]: http://google.com/
+
+Because link names may contain spaces, this shortcut even works for
+multiple words in the link text:
+
+ Visit [Daring Fireball][] for more information.
+
+And then define the link:
+
+ [Daring Fireball]: http://daringfireball.net/
+
+Link definitions can be placed anywhere in your Markdown document. I
+tend to put them immediately after each paragraph in which they're
+used, but if you want, you can put them all at the end of your
+document, sort of like footnotes.
+
+Here's an example of reference links in action:
+
+ I get 10 times more traffic from [Google] [1] than from
+ [Yahoo] [2] or [MSN] [3].
+
+ [1]: http://google.com/ "Google"
+ [2]: http://search.yahoo.com/ "Yahoo Search"
+ [3]: http://search.msn.com/ "MSN Search"
+
+Using the implicit link name shortcut, you could instead write:
+
+ I get 10 times more traffic from [Google][] than from
+ [Yahoo][] or [MSN][].
+
+ [google]: http://google.com/ "Google"
+ [yahoo]: http://search.yahoo.com/ "Yahoo Search"
+ [msn]: http://search.msn.com/ "MSN Search"
+
+Both of the above examples will produce the following HTML output:
+
+ I get 10 times more traffic from Google than from
+ Yahoo
+ or MSN.
+
+For comparison, here is the same paragraph written using
+Markdown's inline link style:
+
+ I get 10 times more traffic from [Google](http://google.com/ "Google")
+ than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
+ [MSN](http://search.msn.com/ "MSN Search").
+
+The point of reference-style links is not that they're easier to
+write. The point is that with reference-style links, your document
+source is vastly more readable. Compare the above examples: using
+reference-style links, the paragraph itself is only 81 characters
+long; with inline-style links, it's 176 characters; and as raw HTML,
+it's 234 characters. In the raw HTML, there's more markup than there
+is text.
+
+With Markdown's reference-style links, a source document much more
+closely resembles the final output, as rendered in a browser. By
+allowing you to move the markup-related metadata out of the paragraph,
+you can add links without interrupting the narrative flow of your
+prose.
+
+### Emphasis
+
+Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
+emphasis. Text wrapped with one `*` or `_` will be wrapped with an
+HTML `` tag; double `*`'s or `_`'s will be wrapped with an HTML
+`` tag. E.g., this input:
+
+ *single asterisks*
+
+ _single underscores_
+
+ **double asterisks**
+
+ __double underscores__
+
+will produce:
+
+ single asterisks
+
+ single underscores
+
+ double asterisks
+
+ double underscores
+
+You can use whichever style you prefer; the lone restriction is that
+the same character must be used to open and close an emphasis span.
+
+Emphasis can be used in the middle of a word:
+
+ un*frigging*believable
+
+But if you surround an `*` or `_` with spaces, it'll be treated as a
+literal asterisk or underscore.
+
+To produce a literal asterisk or underscore at a position where it
+would otherwise be used as an emphasis delimiter, you can backslash
+escape it:
+
+ \*this text is surrounded by literal asterisks\*
+
+
+### Code
+
+To indicate a span of code, wrap it with backtick quotes (`` ` ``).
+Unlike a pre-formatted code block, a code span indicates code within a
+normal paragraph. For example:
+
+ Use the `printf()` function.
+
+will produce:
+
+ Use the printf() function.
+
+To include a literal backtick character within a code span, you can use
+multiple backticks as the opening and closing delimiters:
+
+ ``There is a literal backtick (`) here.``
+
+which will produce this:
+
+ There is a literal backtick (`) here.
+
+The backtick delimiters surrounding a code span may include spaces --
+one after the opening, one before the closing. This allows you to place
+literal backtick characters at the beginning or end of a code span:
+
+ A single backtick in a code span: `` ` ``
+
+ A backtick-delimited string in a code span: `` `foo` ``
+
+will produce:
+
+ A single backtick in a code span: `
+
+ A backtick-delimited string in a code span: `foo`
+
+With a code span, ampersands and angle brackets are encoded as HTML
+entities automatically, which makes it easy to include example HTML
+tags. Markdown will turn this:
+
+ Please don't use any `