Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
f9de9623
Commit
f9de9623
authored
Jul 13, 2012
by
Bridger Maxwell
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master' into course_start
parents
60da2304
214d03c1
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
22 additions
and
1068 deletions
+22
-1068
common/djangoapps/static_replace.py
+4
-1
common/lib/xmodule/xmodule/xml_module.py
+1
-5
lms/djangoapps/certificates/views.py
+3
-3
lms/djangoapps/simplewiki/models copy.py
+0
-367
lms/djangoapps/simplewiki/views copy.py
+0
-525
lms/djangoapps/simplewiki/views_attachments.py
+0
-153
lms/envs/common.py
+1
-1
lms/static/sass/sass_old/courseware/_sequence-nav.scss
+13
-13
No files found.
common/djangoapps/static_replace.py
View file @
f9de9623
...
...
@@ -9,6 +9,9 @@ def replace(static_url, prefix=None):
prefix
=
prefix
+
'/'
quote
=
static_url
.
group
(
'quote'
)
if
staticfiles_storage
.
exists
(
static_url
.
group
(
'rest'
)):
return
static_url
.
group
(
0
)
else
:
url
=
staticfiles_storage
.
url
(
prefix
+
static_url
.
group
(
'rest'
))
return
""
.
join
([
quote
,
url
,
quote
])
...
...
@@ -20,7 +23,7 @@ def replace_urls(text, staticfiles_prefix=None, replace_prefix='/static/'):
return
re
.
sub
(
r"""
(?x) # flags=re.VERBOSE
(?P<quote>\\?['"]) # the opening quotes
{prefix}
# the prefix
(?P<prefix>{prefix})
# the prefix
(?P<rest>.*?) # everything else in the url
(?P=quote) # the first matching closing quote
"""
.
format
(
prefix
=
replace_prefix
),
replace_url
,
text
)
common/lib/xmodule/xmodule/xml_module.py
View file @
f9de9623
...
...
@@ -172,12 +172,8 @@ class XmlDescriptor(XModuleDescriptor):
log
.
debug
(
'filepath=
%
s, resources_fs=
%
s'
%
(
filepath
,
system
.
resources_fs
))
try
:
with
system
.
resources_fs
.
open
(
filepath
)
as
file
:
try
:
definition_xml
=
cls
.
file_to_xml
(
file
)
except
:
log
.
exception
(
"Failed to parse xml in file
%
s"
%
filepath
)
raise
except
ResourceNotFoundError
:
except
(
ResourceNotFoundError
,
etree
.
XMLSyntaxError
):
log
.
exception
(
'Unable to load file contents at path
%
s'
%
filepath
)
return
{
'data'
:
'Error loading file contents at path
%
s'
%
filepath
}
...
...
lms/djangoapps/certificates/views.py
View file @
f9de9623
import
json
import
logging
import
settings
import
uuid
from
django.conf
import
settings
...
...
@@ -13,8 +12,9 @@ import courseware.grades as grades
from
certificates.models
import
GeneratedCertificate
,
certificate_state_for_student
,
revoke_certificate
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
from
student.models
import
UserProfile
from
student.survey_questions
import
exit_survey_list_for_student
from
student.views
import
student_took_survey
,
record_exit_survey
#TODO: Finish migrating these changes from stable
# from student.survey_questions import exit_survey_list_for_student
# from student.views import student_took_survey, record_exit_survey
log
=
logging
.
getLogger
(
"mitx.certificates"
)
...
...
lms/djangoapps/simplewiki/models copy.py
deleted
100644 → 0
View file @
60da2304
import
difflib
import
os
from
django
import
forms
from
django.contrib.auth.models
import
User
from
django.core.urlresolvers
import
reverse
from
django.db
import
models
from
django.db.models
import
signals
from
django.utils.translation
import
ugettext_lazy
as
_
from
markdown
import
markdown
from
wiki_settings
import
*
from
util.cache
import
cache
class
ShouldHaveExactlyOneRootSlug
(
Exception
):
pass
class
Article
(
models
.
Model
):
"""Wiki article referring to Revision model for actual content.
'slug' and 'parent' field should be maintained centrally, since users
aren't allowed to change them, anyways.
"""
title
=
models
.
CharField
(
max_length
=
512
,
verbose_name
=
_
(
'Article title'
),
blank
=
False
)
slug
=
models
.
SlugField
(
max_length
=
100
,
verbose_name
=
_
(
'slug'
),
help_text
=
_
(
'Letters, numbers, underscore and hyphen.'
),
blank
=
True
)
created_by
=
models
.
ForeignKey
(
User
,
verbose_name
=
_
(
'Created by'
),
blank
=
True
,
null
=
True
)
created_on
=
models
.
DateTimeField
(
auto_now_add
=
1
)
modified_on
=
models
.
DateTimeField
(
auto_now_add
=
1
)
parent
=
models
.
ForeignKey
(
'self'
,
verbose_name
=
_
(
'Parent article slug'
),
help_text
=
_
(
'Affects URL structure and possibly inherits permissions'
),
null
=
True
,
blank
=
True
)
locked
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'Locked for editing'
))
permissions
=
models
.
ForeignKey
(
'Permission'
,
verbose_name
=
_
(
'Permissions'
),
blank
=
True
,
null
=
True
,
help_text
=
_
(
'Permission group'
))
current_revision
=
models
.
OneToOneField
(
'Revision'
,
related_name
=
'current_rev'
,
blank
=
True
,
null
=
True
,
editable
=
True
)
related
=
models
.
ManyToManyField
(
'self'
,
verbose_name
=
_
(
'Related articles'
),
symmetrical
=
True
,
help_text
=
_
(
'Sets a symmetrical relation other articles'
),
blank
=
True
,
null
=
True
)
def
attachments
(
self
):
return
ArticleAttachment
.
objects
.
filter
(
article__exact
=
self
)
@classmethod
def
get_root
(
cls
):
"""Return the root article, which should ALWAYS exist..
except the very first time the wiki is loaded, in which
case the user is prompted to create this article."""
try
:
return
Article
.
objects
.
filter
(
slug__exact
=
""
)[
0
]
except
:
raise
ShouldHaveExactlyOneRootSlug
()
def
get_url
(
self
):
"""Return the Wiki URL for an article"""
url
=
self
.
slug
+
"/"
if
self
.
parent_id
:
parent_url
=
cache
.
get
(
"wiki_url-"
+
str
(
self
.
parent_id
))
if
parent_url
is
None
:
parent_url
=
self
.
parent
.
get_url
()
url
=
parent_url
+
url
cache
.
set
(
"wiki_url-"
+
str
(
self
.
id
),
url
,
60
*
60
)
return
url
def
get_abs_url
(
self
):
"""Return the absolute path for an article. This is necessary in cases
where the template system isn't used for generating URLs..."""
# TODO: Remove and create a reverse() lookup.
return
WIKI_BASE
+
self
.
get_url
()
@models.permalink
def
get_absolute_url
(
self
):
return
(
'wiki_view'
,
[
self
.
get_url
()])
@classmethod
def
get_url_reverse
(
cls
,
path
,
article
,
return_list
=
[]):
"""Lookup a URL and return the corresponding set of articles
in the path."""
if
path
==
[]:
return
return_list
+
[
article
]
# Lookup next child in path
try
:
a
=
Article
.
objects
.
get
(
parent__exact
=
article
,
slug__exact
=
str
(
path
[
0
]))
return
cls
.
get_url_reverse
(
path
[
1
:],
a
,
return_list
+
[
article
])
except
Exception
,
e
:
return
None
def
can_read
(
self
,
user
):
""" Check read permissions and return True/False."""
if
user
.
is_superuser
:
return
True
if
self
.
permissions
:
perms
=
self
.
permissions
.
can_read
.
all
()
return
perms
.
count
()
==
0
or
(
user
in
perms
)
else
:
return
self
.
parent
.
can_read
(
user
)
if
self
.
parent
else
True
def
can_write
(
self
,
user
):
""" Check write permissions and return True/False."""
if
user
.
is_superuser
:
return
True
if
self
.
permissions
:
perms
=
self
.
permissions
.
can_write
.
all
()
return
perms
.
count
()
==
0
or
(
user
in
perms
)
else
:
return
self
.
parent
.
can_write
(
user
)
if
self
.
parent
else
True
def
can_write_l
(
self
,
user
):
"""Check write permissions and locked status"""
if
user
.
is_superuser
:
return
True
return
not
self
.
locked
and
self
.
can_write
(
user
)
def
can_attach
(
self
,
user
):
return
self
.
can_write_l
(
user
)
and
(
WIKI_ALLOW_ANON_ATTACHMENTS
or
not
user
.
is_anonymous
())
def
__unicode__
(
self
):
if
self
.
slug
==
''
and
not
self
.
parent
:
return
unicode
(
_
(
'Root article'
))
else
:
return
self
.
get_url
()
class
Meta
:
unique_together
=
((
'slug'
,
'parent'
),)
verbose_name
=
_
(
'Article'
)
verbose_name_plural
=
_
(
'Articles'
)
def
get_attachment_filepath
(
instance
,
filename
):
"""Store file, appending new extension for added security"""
dir_
=
WIKI_ATTACHMENTS
+
instance
.
article
.
get_url
()
dir_
=
'/'
.
join
(
filter
(
lambda
x
:
x
!=
''
,
dir_
.
split
(
'/'
)))
if
not
os
.
path
.
exists
(
WIKI_ATTACHMENTS_ROOT
+
dir_
):
os
.
makedirs
(
WIKI_ATTACHMENTS_ROOT
+
dir_
)
return
dir_
+
'/'
+
filename
+
'.upload'
class
ArticleAttachment
(
models
.
Model
):
article
=
models
.
ForeignKey
(
Article
,
verbose_name
=
_
(
'Article'
))
file
=
models
.
FileField
(
max_length
=
255
,
upload_to
=
get_attachment_filepath
,
verbose_name
=
_
(
'Attachment'
))
uploaded_by
=
models
.
ForeignKey
(
User
,
blank
=
True
,
verbose_name
=
_
(
'Uploaded by'
),
null
=
True
)
uploaded_on
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Upload date'
))
def
download_url
(
self
):
return
reverse
(
'wiki_view_attachment'
,
args
=
(
self
.
article
.
get_url
(),
self
.
filename
()))
def
filename
(
self
):
return
'.'
.
join
(
self
.
file
.
name
.
split
(
'/'
)[
-
1
]
.
split
(
'.'
)[:
-
1
])
def
get_size
(
self
):
try
:
size
=
self
.
file
.
size
except
OSError
:
size
=
0
return
size
def
filename
(
self
):
return
'.'
.
join
(
self
.
file
.
name
.
split
(
'/'
)[
-
1
]
.
split
(
'.'
)[:
-
1
])
def
is_image
(
self
):
fname
=
self
.
filename
()
.
split
(
'.'
)
if
len
(
fname
)
>
1
and
fname
[
-
1
]
.
lower
()
in
WIKI_IMAGE_EXTENSIONS
:
return
True
return
False
def
get_thumb
(
self
):
return
self
.
get_thumb_impl
(
*
WIKI_IMAGE_THUMB_SIZE
)
def
get_thumb_small
(
self
):
return
self
.
get_thumb_impl
(
*
WIKI_IMAGE_THUMB_SIZE_SMALL
)
def
mk_thumbs
(
self
):
self
.
mk_thumb
(
*
WIKI_IMAGE_THUMB_SIZE
,
**
{
'force'
:
True
})
self
.
mk_thumb
(
*
WIKI_IMAGE_THUMB_SIZE_SMALL
,
**
{
'force'
:
True
})
def
mk_thumb
(
self
,
width
,
height
,
force
=
False
):
"""Requires Python Imaging Library (PIL)"""
if
not
self
.
get_size
():
return
False
if
not
self
.
is_image
():
return
False
base_path
=
os
.
path
.
dirname
(
self
.
file
.
path
)
orig_name
=
self
.
filename
()
.
split
(
'.'
)
thumb_filename
=
"
%
s__thumb__
%
d_
%
d.
%
s"
%
(
'.'
.
join
(
orig_name
[:
-
1
]),
width
,
height
,
orig_name
[
-
1
])
thumb_filepath
=
"
%
s
%
s
%
s"
%
(
base_path
,
os
.
sep
,
thumb_filename
)
if
force
or
not
os
.
path
.
exists
(
thumb_filepath
):
try
:
import
Image
img
=
Image
.
open
(
self
.
file
.
path
)
img
.
thumbnail
((
width
,
height
),
Image
.
ANTIALIAS
)
img
.
save
(
thumb_filepath
)
except
IOError
:
return
False
return
True
def
get_thumb_impl
(
self
,
width
,
height
):
"""Requires Python Imaging Library (PIL)"""
if
not
self
.
get_size
():
return
False
if
not
self
.
is_image
():
return
False
self
.
mk_thumb
(
width
,
height
)
orig_name
=
self
.
filename
()
.
split
(
'.'
)
thumb_filename
=
"
%
s__thumb__
%
d_
%
d.
%
s"
%
(
'.'
.
join
(
orig_name
[:
-
1
]),
width
,
height
,
orig_name
[
-
1
])
thumb_url
=
settings
.
MEDIA_URL
+
WIKI_ATTACHMENTS
+
self
.
article
.
get_url
()
+
'/'
+
thumb_filename
return
thumb_url
def
__unicode__
(
self
):
return
self
.
filename
()
class
Revision
(
models
.
Model
):
article
=
models
.
ForeignKey
(
Article
,
verbose_name
=
_
(
'Article'
))
revision_text
=
models
.
CharField
(
max_length
=
255
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Description of change'
))
revision_user
=
models
.
ForeignKey
(
User
,
verbose_name
=
_
(
'Modified by'
),
blank
=
True
,
null
=
True
,
related_name
=
'wiki_revision_user'
)
revision_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Revision date'
))
contents
=
models
.
TextField
(
verbose_name
=
_
(
'Contents (Use MarkDown format)'
))
contents_parsed
=
models
.
TextField
(
editable
=
False
,
blank
=
True
,
null
=
True
)
counter
=
models
.
IntegerField
(
verbose_name
=
_
(
'Revision#'
),
default
=
1
,
editable
=
False
)
previous_revision
=
models
.
ForeignKey
(
'self'
,
blank
=
True
,
null
=
True
,
editable
=
False
)
# Deleted has three values. 0 is normal, non-deleted. 1 is if it was deleted by a normal user. It should
# be a NEW revision, so that it appears in the history. 2 is a special flag that can be applied or removed
# from a normal revision. It means it has been admin-deleted, and can only been seen by an admin. It doesn't
# show up in the history.
deleted
=
models
.
IntegerField
(
verbose_name
=
_
(
'Deleted group'
),
default
=
0
)
def
get_user
(
self
):
return
self
.
revision_user
if
self
.
revision_user
else
_
(
'Anonymous'
)
# Called after the deleted fied has been changed (between 0 and 2). This bypasses the normal checks put in
# save that update the revision or reject the save if contents haven't changed
def
adminSetDeleted
(
self
,
deleted
):
self
.
deleted
=
deleted
super
(
Revision
,
self
)
.
save
()
def
save
(
self
,
**
kwargs
):
# Check if contents have changed... if not, silently ignore save
if
self
.
article
and
self
.
article
.
current_revision
:
if
self
.
deleted
==
0
and
self
.
article
.
current_revision
.
contents
==
self
.
contents
:
return
else
:
import
datetime
self
.
article
.
modified_on
=
datetime
.
datetime
.
now
()
self
.
article
.
save
()
# Increment counter according to previous revision
previous_revision
=
Revision
.
objects
.
filter
(
article
=
self
.
article
)
.
order_by
(
'-counter'
)
if
previous_revision
.
count
()
>
0
:
if
previous_revision
.
count
()
>
previous_revision
[
0
]
.
counter
:
self
.
counter
=
previous_revision
.
count
()
+
1
else
:
self
.
counter
=
previous_revision
[
0
]
.
counter
+
1
else
:
self
.
counter
=
1
if
(
self
.
article
.
current_revision
and
self
.
article
.
current_revision
.
deleted
==
0
):
self
.
previous_revision
=
self
.
article
.
current_revision
# Create pre-parsed contents - no need to parse on-the-fly
ext
=
WIKI_MARKDOWN_EXTENSIONS
ext
+=
[
"wikipath(base_url=
%
s)"
%
reverse
(
'wiki_view'
,
args
=
(
'/'
,))]
self
.
contents_parsed
=
markdown
(
self
.
contents
,
extensions
=
ext
,
safe_mode
=
'escape'
,)
super
(
Revision
,
self
)
.
save
(
**
kwargs
)
def
delete
(
self
,
**
kwargs
):
"""If a current revision is deleted, then regress to the previous
revision or insert a stub, if no other revisions are available"""
article
=
self
.
article
if
article
.
current_revision
==
self
:
prev_revision
=
Revision
.
objects
.
filter
(
article__exact
=
article
,
pk__not
=
self
.
pk
)
.
order_by
(
'-counter'
)
if
prev_revision
:
article
.
current_revision
=
prev_revision
[
0
]
article
.
save
()
else
:
r
=
Revision
(
article
=
article
,
revision_user
=
article
.
created_by
)
r
.
contents
=
unicode
(
_
(
'Auto-generated stub'
))
r
.
revision_text
=
unicode
(
_
(
'Auto-generated stub'
))
r
.
save
()
article
.
current_revision
=
r
article
.
save
()
super
(
Revision
,
self
)
.
delete
(
**
kwargs
)
def
get_diff
(
self
):
if
(
self
.
deleted
==
1
):
yield
"Article Deletion"
return
if
self
.
previous_revision
:
previous
=
self
.
previous_revision
.
contents
.
splitlines
(
1
)
else
:
previous
=
[]
# Todo: difflib.HtmlDiff would look pretty for our history pages!
diff
=
difflib
.
unified_diff
(
previous
,
self
.
contents
.
splitlines
(
1
))
# let's skip the preamble
diff
.
next
();
diff
.
next
();
diff
.
next
()
for
d
in
diff
:
yield
d
def
__unicode__
(
self
):
return
"r
%
d"
%
self
.
counter
class
Meta
:
verbose_name
=
_
(
'article revision'
)
verbose_name_plural
=
_
(
'article revisions'
)
class
Permission
(
models
.
Model
):
permission_name
=
models
.
CharField
(
max_length
=
255
,
verbose_name
=
_
(
'Permission name'
))
can_write
=
models
.
ManyToManyField
(
User
,
blank
=
True
,
null
=
True
,
related_name
=
'write'
,
help_text
=
_
(
'Select none to grant anonymous access.'
))
can_read
=
models
.
ManyToManyField
(
User
,
blank
=
True
,
null
=
True
,
related_name
=
'read'
,
help_text
=
_
(
'Select none to grant anonymous access.'
))
def
__unicode__
(
self
):
return
self
.
permission_name
class
Meta
:
verbose_name
=
_
(
'Article permission'
)
verbose_name_plural
=
_
(
'Article permissions'
)
class
RevisionForm
(
forms
.
ModelForm
):
contents
=
forms
.
CharField
(
label
=
_
(
'Contents'
),
widget
=
forms
.
Textarea
(
attrs
=
{
'rows'
:
8
,
'cols'
:
50
}))
class
Meta
:
model
=
Revision
fields
=
[
'contents'
,
'revision_text'
]
class
RevisionFormWithTitle
(
forms
.
ModelForm
):
title
=
forms
.
CharField
(
label
=
_
(
'Title'
))
class
Meta
:
model
=
Revision
fields
=
[
'title'
,
'contents'
,
'revision_text'
]
class
CreateArticleForm
(
RevisionForm
):
title
=
forms
.
CharField
(
label
=
_
(
'Title'
))
class
Meta
:
model
=
Revision
fields
=
[
'title'
,
'contents'
,]
def
set_revision
(
sender
,
*
args
,
**
kwargs
):
"""Signal handler to ensure that a new revision is always chosen as the
current revision - automatically. It simplifies stuff greatly. Also
stores previous revision for diff-purposes"""
instance
=
kwargs
[
'instance'
]
created
=
kwargs
[
'created'
]
if
created
and
instance
.
article
:
instance
.
article
.
current_revision
=
instance
instance
.
article
.
save
()
signals
.
post_save
.
connect
(
set_revision
,
Revision
)
lms/djangoapps/simplewiki/views copy.py
deleted
100644 → 0
View file @
60da2304
# -*- coding: utf-8 -*-
from
django.conf
import
settings
as
settings
from
django.contrib.auth.decorators
import
login_required
from
django.core.context_processors
import
csrf
from
django.core.urlresolvers
import
reverse
from
django.db.models
import
Q
from
django.http
import
HttpResponse
,
HttpResponseRedirect
from
django.utils
import
simplejson
from
django.utils.translation
import
ugettext_lazy
as
_
from
mitxmako.shortcuts
import
render_to_response
from
models
import
Revision
,
Article
,
CreateArticleForm
,
RevisionFormWithTitle
,
RevisionForm
import
wiki_settings
def
view
(
request
,
wiki_url
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
perm_err
=
check_permissions
(
request
,
article
,
check_read
=
True
,
check_deleted
=
True
)
if
perm_err
:
return
perm_err
d
=
{
'wiki_article'
:
article
,
'wiki_article_revision'
:
article
.
current_revision
,
'wiki_write'
:
article
.
can_write_l
(
request
.
user
),
'wiki_attachments_write'
:
article
.
can_attach
(
request
.
user
),
'wiki_current_revision_deleted'
:
not
(
article
.
current_revision
.
deleted
==
0
),
'wiki_title'
:
article
.
title
+
" - MITX 6.002x Wiki"
}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_view.html'
,
d
)
def
view_revision
(
request
,
revision_number
,
wiki_url
,
revision
=
None
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
try
:
revision
=
Revision
.
objects
.
get
(
counter
=
int
(
revision_number
),
article
=
article
)
except
:
d
=
{
'wiki_article'
:
article
,
'wiki_err_norevision'
:
revision_number
,}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_error.html'
,
d
)
perm_err
=
check_permissions
(
request
,
article
,
check_read
=
True
,
check_deleted
=
True
,
revision
=
revision
)
if
perm_err
:
return
perm_err
d
=
{
'wiki_article'
:
article
,
'wiki_article_revision'
:
revision
,
'wiki_write'
:
article
.
can_write_l
(
request
.
user
),
'wiki_attachments_write'
:
article
.
can_attach
(
request
.
user
),
'wiki_current_revision_deleted'
:
not
(
revision
.
deleted
==
0
),
}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_view.html'
,
d
)
def
root_redirect
(
request
):
try
:
root
=
Article
.
get_root
()
except
:
err
=
not_found
(
request
,
'/'
)
return
err
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
root
.
get_url
())))
def
create
(
request
,
wiki_url
):
url_path
=
get_url_path
(
wiki_url
)
if
url_path
!=
[]
and
url_path
[
0
]
.
startswith
(
'_'
):
d
=
{
'wiki_err_keyword'
:
True
,
'wiki_url'
:
'/'
.
join
(
url_path
)
}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_error.html'
,
d
)
# Lookup path
try
:
# Ensure that the path exists...
root
=
Article
.
get_root
()
# Remove root slug if present in path
if
url_path
and
root
.
slug
==
url_path
[
0
]:
url_path
=
url_path
[
1
:]
path
=
Article
.
get_url_reverse
(
url_path
[:
-
1
],
root
)
if
not
path
:
d
=
{
'wiki_err_noparent'
:
True
,
'wiki_url_parent'
:
'/'
.
join
(
url_path
[:
-
1
])
}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_error.html'
,
d
)
perm_err
=
check_permissions
(
request
,
path
[
-
1
],
check_locked
=
False
,
check_write
=
True
,
check_deleted
=
True
)
if
perm_err
:
return
perm_err
# Ensure doesn't already exist
article
=
Article
.
get_url_reverse
(
url_path
,
root
)
if
article
:
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
article
[
-
1
]
.
get_url
(),)))
# TODO: Somehow this doesnt work...
#except ShouldHaveExactlyOneRootSlug, (e):
except
:
if
Article
.
objects
.
filter
(
parent
=
None
)
.
count
()
>
0
:
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
'/'
,)))
# Root not found...
path
=
[]
url_path
=
[
""
]
if
request
.
method
==
'POST'
:
f
=
CreateArticleForm
(
request
.
POST
)
if
f
.
is_valid
():
article
=
Article
()
article
.
slug
=
url_path
[
-
1
]
if
not
request
.
user
.
is_anonymous
():
article
.
created_by
=
request
.
user
article
.
title
=
f
.
cleaned_data
.
get
(
'title'
)
if
path
!=
[]:
article
.
parent
=
path
[
-
1
]
a
=
article
.
save
()
new_revision
=
f
.
save
(
commit
=
False
)
if
not
request
.
user
.
is_anonymous
():
new_revision
.
revision_user
=
request
.
user
new_revision
.
article
=
article
new_revision
.
save
()
import
django.db
as
db
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
article
.
get_url
(),)))
else
:
f
=
CreateArticleForm
(
initial
=
{
'title'
:
request
.
GET
.
get
(
'wiki_article_name'
,
url_path
[
-
1
]),
'contents'
:
_
(
'Headline
\n
===
\n\n
'
)})
d
=
{
'wiki_form'
:
f
,
'wiki_write'
:
True
,
'create_article'
:
True
,
}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_edit.html'
,
d
)
def
edit
(
request
,
wiki_url
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
# Check write permissions
perm_err
=
check_permissions
(
request
,
article
,
check_write
=
True
,
check_locked
=
True
,
check_deleted
=
False
)
if
perm_err
:
return
perm_err
if
wiki_settings
.
WIKI_ALLOW_TITLE_EDIT
:
EditForm
=
RevisionFormWithTitle
else
:
EditForm
=
RevisionForm
if
request
.
method
==
'POST'
:
f
=
EditForm
(
request
.
POST
)
if
f
.
is_valid
():
new_revision
=
f
.
save
(
commit
=
False
)
new_revision
.
article
=
article
if
request
.
POST
.
__contains__
(
'delete'
):
if
(
article
.
current_revision
.
deleted
==
1
):
#This article has already been deleted. Redirect
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
article
.
get_url
(),)))
new_revision
.
contents
=
""
new_revision
.
deleted
=
1
elif
not
new_revision
.
get_diff
():
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
article
.
get_url
(),)))
if
not
request
.
user
.
is_anonymous
():
new_revision
.
revision_user
=
request
.
user
new_revision
.
save
()
if
wiki_settings
.
WIKI_ALLOW_TITLE_EDIT
:
new_revision
.
article
.
title
=
f
.
cleaned_data
[
'title'
]
new_revision
.
article
.
save
()
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
article
.
get_url
(),)))
else
:
startContents
=
article
.
current_revision
.
contents
if
(
article
.
current_revision
.
deleted
==
0
)
else
'Headline
\n
===
\n\n
'
f
=
EditForm
({
'contents'
:
startContents
,
'title'
:
article
.
title
})
d
=
{
'wiki_form'
:
f
,
'wiki_write'
:
True
,
'wiki_article'
:
article
,
'wiki_title'
:
article
.
title
,
'wiki_attachments_write'
:
article
.
can_attach
(
request
.
user
),
'create_article'
:
False
,
}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_edit.html'
,
d
)
def
history
(
request
,
wiki_url
,
page
=
1
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
perm_err
=
check_permissions
(
request
,
article
,
check_read
=
True
,
check_deleted
=
False
)
if
perm_err
:
print
"returned error "
,
perm_err
return
perm_err
page_size
=
10
try
:
p
=
int
(
page
)
except
ValueError
:
p
=
1
history
=
Revision
.
objects
.
filter
(
article__exact
=
article
)
.
order_by
(
'-counter'
)
.
select_related
(
'previous_revision__counter'
,
'revision_user'
,
'wiki_article'
)
if
request
.
method
==
'POST'
:
if
wiki_settings
.
WIKI_REQUIRE_LOGIN_EDIT
and
not
request
.
user
.
is_authenticated
():
return
HttpResponseRedirect
(
'/'
)
if
request
.
POST
.
__contains__
(
'revision'
):
#They selected a version, but they can be either deleting or changing the version
perm_err
=
check_permissions
(
request
,
article
,
check_write
=
True
,
check_locked
=
True
)
if
perm_err
:
return
perm_err
redirectURL
=
reverse
(
'wiki_view'
,
args
=
(
article
.
get_url
(),))
try
:
r
=
int
(
request
.
POST
[
'revision'
])
revision
=
Revision
.
objects
.
get
(
id
=
r
)
if
request
.
POST
.
__contains__
(
'change'
):
article
.
current_revision
=
revision
article
.
save
()
elif
request
.
POST
.
__contains__
(
'view'
):
redirectURL
=
reverse
(
'wiki_view_revision'
,
args
=
(
revision
.
counter
,
article
.
get_url
(),))
#The rese of these are admin functions
elif
request
.
POST
.
__contains__
(
'delete'
)
and
request
.
user
.
is_superuser
:
if
(
revision
.
deleted
==
0
):
revision
.
adminSetDeleted
(
2
)
elif
request
.
POST
.
__contains__
(
'restore'
)
and
request
.
user
.
is_superuser
:
if
(
revision
.
deleted
==
2
):
revision
.
adminSetDeleted
(
0
)
elif
request
.
POST
.
__contains__
(
'delete_all'
)
and
request
.
user
.
is_superuser
:
Revision
.
objects
.
filter
(
article__exact
=
article
,
deleted
=
0
)
.
update
(
deleted
=
2
)
elif
request
.
POST
.
__contains__
(
'lock_article'
):
print
"changing locked article "
,
article
.
locked
article
.
locked
=
not
article
.
locked
print
"changed locked article "
,
article
.
locked
article
.
save
()
except
:
pass
finally
:
return
HttpResponseRedirect
(
redirectURL
)
#
#
# <input type="submit" name="delete" value="Delete revision"/>
# <input type="submit" name="restore" value="Restore revision"/>
# <input type="submit" name="delete_all" value="Delete all revisions">
# %else:
# <input type="submit" name="delete_article" value="Delete all revisions">
#
page_count
=
(
history
.
count
()
+
(
page_size
-
1
))
/
page_size
if
p
>
page_count
:
p
=
1
beginItem
=
(
p
-
1
)
*
page_size
next_page
=
p
+
1
if
page_count
>
p
else
None
prev_page
=
p
-
1
if
p
>
1
else
None
d
=
{
'wiki_page'
:
p
,
'wiki_next_page'
:
next_page
,
'wiki_prev_page'
:
prev_page
,
'wiki_write'
:
article
.
can_write_l
(
request
.
user
),
'wiki_attachments_write'
:
article
.
can_attach
(
request
.
user
),
'wiki_article'
:
article
,
'wiki_title'
:
article
.
title
,
'wiki_history'
:
history
[
beginItem
:
beginItem
+
page_size
],
'show_delete_revision'
:
request
.
user
.
is_superuser
,}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_history.html'
,
d
)
def
revision_feed
(
request
,
page
=
1
):
page_size
=
10
try
:
p
=
int
(
page
)
except
ValueError
:
p
=
1
history
=
Revision
.
objects
.
order_by
(
'-revision_date'
)
.
select_related
(
'revision_user'
,
'article'
,
'previous_revision'
)
page_count
=
(
history
.
count
()
+
(
page_size
-
1
))
/
page_size
if
p
>
page_count
:
p
=
1
beginItem
=
(
p
-
1
)
*
page_size
next_page
=
p
+
1
if
page_count
>
p
else
None
prev_page
=
p
-
1
if
p
>
1
else
None
d
=
{
'wiki_page'
:
p
,
'wiki_next_page'
:
next_page
,
'wiki_prev_page'
:
prev_page
,
'wiki_history'
:
history
[
beginItem
:
beginItem
+
page_size
],
'show_delete_revision'
:
request
.
user
.
is_superuser
,}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_revision_feed.html'
,
d
)
def
search_articles
(
request
):
# blampe: We should check for the presence of other popular django search
# apps and use those if possible. Only fall back on this as a last resort.
# Adding some context to results (eg where matches were) would also be nice.
# todo: maybe do some perm checking here
if
request
.
method
==
'POST'
:
querystring
=
request
.
POST
[
'value'
]
.
strip
()
else
:
querystring
=
""
results
=
Article
.
objects
.
all
()
if
request
.
user
.
is_superuser
:
results
=
results
.
order_by
(
'current_revision__deleted'
)
else
:
results
=
results
.
filter
(
current_revision__deleted
=
0
)
if
querystring
:
for
queryword
in
querystring
.
split
():
# Basic negation is as fancy as we get right now
if
queryword
[
0
]
==
'-'
and
len
(
queryword
)
>
1
:
results
.
_search
=
lambda
x
:
results
.
exclude
(
x
)
queryword
=
queryword
[
1
:]
else
:
results
.
_search
=
lambda
x
:
results
.
filter
(
x
)
results
=
results
.
_search
(
Q
(
current_revision__contents__icontains
=
queryword
)
|
\
Q
(
title__icontains
=
queryword
))
results
=
results
.
select_related
(
'current_revision__deleted'
)
results
=
sorted
(
results
,
key
=
lambda
article
:
(
article
.
current_revision
.
deleted
,
article
.
get_url
()
.
lower
())
)
if
len
(
results
)
==
1
and
querystring
:
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
results
[
0
]
.
get_url
(),)))
else
:
d
=
{
'wiki_search_results'
:
results
,
'wiki_search_query'
:
querystring
,}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_searchresults.html'
,
d
)
def
search_add_related
(
request
,
wiki_url
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
perm_err
=
check_permissions
(
request
,
article
,
check_read
=
True
)
if
perm_err
:
return
perm_err
search_string
=
request
.
GET
.
get
(
'query'
,
None
)
self_pk
=
request
.
GET
.
get
(
'self'
,
None
)
if
search_string
:
results
=
[]
related
=
Article
.
objects
.
filter
(
title__istartswith
=
search_string
)
others
=
article
.
related
.
all
()
if
self_pk
:
related
=
related
.
exclude
(
pk
=
self_pk
)
if
others
:
related
=
related
.
exclude
(
related__in
=
others
)
related
=
related
.
order_by
(
'title'
)[:
10
]
for
item
in
related
:
results
.
append
({
'id'
:
str
(
item
.
id
),
'value'
:
item
.
title
,
'info'
:
item
.
get_url
()})
else
:
results
=
[]
json
=
simplejson
.
dumps
({
'results'
:
results
})
return
HttpResponse
(
json
,
mimetype
=
'application/json'
)
def
add_related
(
request
,
wiki_url
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
perm_err
=
check_permissions
(
request
,
article
,
check_write
=
True
,
check_locked
=
True
)
if
perm_err
:
return
perm_err
try
:
related_id
=
request
.
POST
[
'id'
]
rel
=
Article
.
objects
.
get
(
id
=
related_id
)
has_already
=
article
.
related
.
filter
(
id
=
related_id
)
.
count
()
if
has_already
==
0
and
not
rel
==
article
:
article
.
related
.
add
(
rel
)
article
.
save
()
except
:
pass
finally
:
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
article
.
get_url
(),)))
def
remove_related
(
request
,
wiki_url
,
related_id
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
perm_err
=
check_permissions
(
request
,
article
,
check_write
=
True
,
check_locked
=
True
)
if
perm_err
:
return
perm_err
try
:
rel_id
=
int
(
related_id
)
rel
=
Article
.
objects
.
get
(
id
=
rel_id
)
article
.
related
.
remove
(
rel
)
article
.
save
()
except
:
pass
finally
:
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
article
.
get_url
(),)))
def
random_article
(
request
):
from
random
import
randint
num_arts
=
Article
.
objects
.
count
()
article
=
Article
.
objects
.
all
()[
randint
(
0
,
num_arts
-
1
)]
return
HttpResponseRedirect
(
reverse
(
'wiki_view'
,
args
=
(
article
.
get_url
(),)))
def
encode_err
(
request
,
url
):
d
=
{
'wiki_err_encode'
:
True
}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_error.html'
,
d
)
def
not_found
(
request
,
wiki_url
):
"""Generate a NOT FOUND message for some URL"""
d
=
{
'wiki_err_notfound'
:
True
,
'wiki_url'
:
wiki_url
}
d
.
update
(
csrf
(
request
))
return
render_to_response
(
'simplewiki_error.html'
,
d
)
def
get_url_path
(
url
):
"""Return a list of all actual elements of a url, safely ignoring
double-slashes (//) """
return
filter
(
lambda
x
:
x
!=
''
,
url
.
split
(
'/'
))
def
fetch_from_url
(
request
,
url
):
"""Analyze URL, returning the article and the articles in its path
If something goes wrong, return an error HTTP response"""
err
=
None
article
=
None
path
=
None
url_path
=
get_url_path
(
url
)
try
:
root
=
Article
.
get_root
()
except
:
err
=
not_found
(
request
,
'/'
)
return
(
article
,
path
,
err
)
if
url_path
and
root
.
slug
==
url_path
[
0
]:
url_path
=
url_path
[
1
:]
path
=
Article
.
get_url_reverse
(
url_path
,
root
)
if
not
path
:
err
=
not_found
(
request
,
'/'
+
'/'
.
join
(
url_path
))
else
:
article
=
path
[
-
1
]
return
(
article
,
path
,
err
)
def
check_permissions
(
request
,
article
,
check_read
=
False
,
check_write
=
False
,
check_locked
=
False
,
check_deleted
=
False
,
revision
=
None
):
read_err
=
check_read
and
not
article
.
can_read
(
request
.
user
)
write_err
=
check_write
and
not
article
.
can_write
(
request
.
user
)
locked_err
=
check_locked
and
article
.
locked
if
revision
==
None
:
revision
=
article
.
current_revision
deleted_err
=
check_deleted
and
not
(
revision
.
deleted
==
0
)
if
(
request
.
user
.
is_superuser
):
deleted_err
=
False
locked_err
=
False
if
read_err
or
write_err
or
locked_err
or
deleted_err
:
d
=
{
'wiki_article'
:
article
,
'wiki_err_noread'
:
read_err
,
'wiki_err_nowrite'
:
write_err
,
'wiki_err_locked'
:
locked_err
,
'wiki_err_deleted'
:
deleted_err
,}
d
.
update
(
csrf
(
request
))
# TODO: Make this a little less jarring by just displaying an error
# on the current page? (no such redirect happens for an anon upload yet)
# benjaoming: I think this is the nicest way of displaying an error, but
# these errors shouldn't occur, but rather be prevented on the other pages.
return
render_to_response
(
'simplewiki_error.html'
,
d
)
else
:
return
None
####################
# LOGIN PROTECTION #
####################
if
wiki_settings
.
WIKI_REQUIRE_LOGIN_VIEW
:
view
=
login_required
(
view
)
history
=
login_required
(
history
)
search_articles
=
login_required
(
search_articles
)
root_redirect
=
login_required
(
root_redirect
)
revision_feed
=
login_required
(
revision_feed
)
random_article
=
login_required
(
random_article
)
search_add_related
=
login_required
(
search_add_related
)
not_found
=
login_required
(
not_found
)
view_revision
=
login_required
(
view_revision
)
if
wiki_settings
.
WIKI_REQUIRE_LOGIN_EDIT
:
create
=
login_required
(
create
)
edit
=
login_required
(
edit
)
add_related
=
login_required
(
add_related
)
remove_related
=
login_required
(
remove_related
)
if
wiki_settings
.
WIKI_CONTEXT_PREPROCESSORS
:
settings
.
TEMPLATE_CONTEXT_PROCESSORS
+=
wiki_settings
.
WIKI_CONTEXT_PREPROCESSORS
lms/djangoapps/simplewiki/views_attachments.py
deleted
100644 → 0
View file @
60da2304
import
os
from
django.contrib.auth.decorators
import
login_required
from
django.core.servers.basehttp
import
FileWrapper
from
django.db.models.fields.files
import
FieldFile
from
django.http
import
HttpResponse
,
HttpResponseForbidden
,
Http404
from
django.template
import
loader
,
Context
from
models
import
ArticleAttachment
,
get_attachment_filepath
from
views
import
check_permissions
,
fetch_from_url
from
wiki_settings
import
(
WIKI_ALLOW_ANON_ATTACHMENTS
,
WIKI_ALLOW_ATTACHMENTS
,
WIKI_ATTACHMENTS_MAX
,
WIKI_ATTACHMENTS_ROOT
,
WIKI_ATTACHMENTS_ALLOWED_EXTENSIONS
,
WIKI_REQUIRE_LOGIN_VIEW
,
WIKI_REQUIRE_LOGIN_EDIT
,
)
def
add_attachment
(
request
,
wiki_url
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
perm_err
=
check_permissions
(
request
,
article
,
check_write
=
True
,
check_locked
=
True
)
if
perm_err
:
return
perm_err
if
not
WIKI_ALLOW_ATTACHMENTS
or
(
not
WIKI_ALLOW_ANON_ATTACHMENTS
and
request
.
user
.
is_anonymous
()):
return
HttpResponseForbidden
()
if
request
.
method
==
'POST'
:
if
request
.
FILES
.
__contains__
(
'attachment'
):
attachment
=
ArticleAttachment
()
if
not
request
.
user
.
is_anonymous
():
attachment
.
uploaded_by
=
request
.
user
attachment
.
article
=
article
file
=
request
.
FILES
[
'attachment'
]
file_rel_path
=
get_attachment_filepath
(
attachment
,
file
.
name
)
chunk_size
=
request
.
upload_handlers
[
0
]
.
chunk_size
filefield
=
FieldFile
(
attachment
,
attachment
.
file
,
file_rel_path
)
attachment
.
file
=
filefield
file_path
=
WIKI_ATTACHMENTS_ROOT
+
attachment
.
file
.
name
if
not
request
.
POST
.
__contains__
(
'overwrite'
)
and
os
.
path
.
exists
(
file_path
):
c
=
Context
({
'overwrite_warning'
:
True
,
'wiki_article'
:
article
,
'filename'
:
file
.
name
})
t
=
loader
.
get_template
(
'simplewiki_updateprogressbar.html'
)
return
HttpResponse
(
t
.
render
(
c
))
if
file
.
size
>
WIKI_ATTACHMENTS_MAX
:
c
=
Context
({
'too_big'
:
True
,
'max_size'
:
WIKI_ATTACHMENTS_MAX
,
'wiki_article'
:
article
,
'file'
:
file
})
t
=
loader
.
get_template
(
'simplewiki_updateprogressbar.html'
)
return
HttpResponse
(
t
.
render
(
c
))
def
get_extension
(
fname
):
return
attachment
.
file
.
name
.
split
(
'.'
)[
-
2
]
if
WIKI_ATTACHMENTS_ALLOWED_EXTENSIONS
and
not
\
get_extension
(
attachment
.
file
.
name
)
in
WIKI_ATTACHMENTS_ALLOWED_EXTENSIONS
:
c
=
Context
({
'extension_err'
:
True
,
'extensions'
:
WIKI_ATTACHMENTS_ALLOWED_EXTENSIONS
,
'wiki_article'
:
article
,
'file'
:
file
})
t
=
loader
.
get_template
(
'simplewiki_updateprogressbar.html'
)
return
HttpResponse
(
t
.
render
(
c
))
# Remove existing attachments
# TODO: Move this until AFTER having removed file.
# Current problem is that Django's FileField delete() method
# automatically deletes files
for
a
in
article
.
attachments
():
if
file_rel_path
==
a
.
file
.
name
:
a
.
delete
()
def
receive_file
():
destination
=
open
(
file_path
,
'wb+'
)
size
=
file
.
size
cnt
=
0
c
=
Context
({
'started'
:
True
,})
t
=
loader
.
get_template
(
'simplewiki_updateprogressbar.html'
)
yield
t
.
render
(
c
)
for
chunk
in
file
.
chunks
():
cnt
+=
1
destination
.
write
(
chunk
)
c
=
Context
({
'progress_width'
:
(
cnt
*
chunk_size
)
/
size
,
'wiki_article'
:
article
,})
t
=
loader
.
get_template
(
'simplewiki_updateprogressbar.html'
)
yield
t
.
render
(
c
)
c
=
Context
({
'finished'
:
True
,
'wiki_article'
:
article
,})
t
=
loader
.
get_template
(
'simplewiki_updateprogressbar.html'
)
destination
.
close
()
attachment
.
save
()
yield
t
.
render
(
c
)
return
HttpResponse
(
receive_file
())
return
HttpResponse
(
''
)
# Taken from http://www.djangosnippets.org/snippets/365/
def
send_file
(
request
,
filepath
):
"""
Send a file through Django without loading the whole file into
memory at once. The FileWrapper will turn the file object into an
iterator for chunks of 8KB.
"""
filename
=
filepath
wrapper
=
FileWrapper
(
file
(
filename
))
response
=
HttpResponse
(
wrapper
,
content_type
=
'text/plain'
)
response
[
'Content-Length'
]
=
os
.
path
.
getsize
(
filename
)
return
response
def
view_attachment
(
request
,
wiki_url
,
file_name
):
(
article
,
path
,
err
)
=
fetch_from_url
(
request
,
wiki_url
)
if
err
:
return
err
perm_err
=
check_permissions
(
request
,
article
,
check_read
=
True
)
if
perm_err
:
return
perm_err
attachment
=
None
for
a
in
article
.
attachments
():
if
get_attachment_filepath
(
a
,
file_name
)
==
a
.
file
.
name
:
attachment
=
a
if
attachment
:
filepath
=
WIKI_ATTACHMENTS_ROOT
+
attachment
.
file
.
name
if
os
.
path
.
exists
(
filepath
):
return
send_file
(
request
,
filepath
)
raise
Http404
()
####################
# LOGIN PROTECTION #
####################
if
WIKI_REQUIRE_LOGIN_VIEW
:
view_attachment
=
login_required
(
view_attachment
)
if
WIKI_REQUIRE_LOGIN_EDIT
or
not
WIKI_ALLOW_ANON_ATTACHMENTS
:
add_attachment
=
login_required
(
add_attachment
)
lms/envs/common.py
View file @
f9de9623
...
...
@@ -186,7 +186,7 @@ if os.path.isdir(DATA_DIR):
# should no longer be added to STATICFILES
(
course_dir
,
DATA_DIR
/
course_dir
)
for
course_dir
in
os
.
listdir
(
DATA_DIR
)
if
os
.
path
.
isdir
(
course_dir
)
if
os
.
path
.
isdir
(
DATA_DIR
/
course_dir
)
]
# Locale/Internationalization
...
...
lms/static/sass/sass_old/courseware/_sequence-nav.scss
View file @
f9de9623
...
...
@@ -89,57 +89,57 @@ nav.sequence-nav {
//video
&
.seq_video_inactive
{
@extend
.inactive
;
background-image
:
url('../
../
images/sequence-nav/video-icon-normal.png')
;
background-image
:
url('../images/sequence-nav/video-icon-normal.png')
;
background-position
:
center
;
}
&
.seq_video_visited
{
@extend
.visited
;
background-image
:
url('../
../
images/sequence-nav/video-icon-visited.png')
;
background-image
:
url('../images/sequence-nav/video-icon-visited.png')
;
background-position
:
center
;
}
&
.seq_video_active
{
@extend
.active
;
background-image
:
url('../
../
images/sequence-nav/video-icon-current.png')
;
background-image
:
url('../images/sequence-nav/video-icon-current.png')
;
background-position
:
center
;
}
//other
&
.seq_other_inactive
{
@extend
.inactive
;
background-image
:
url('../
../
images/sequence-nav/document-icon-normal.png')
;
background-image
:
url('../images/sequence-nav/document-icon-normal.png')
;
background-position
:
center
;
}
&
.seq_other_visited
{
@extend
.visited
;
background-image
:
url('../
../
images/sequence-nav/document-icon-visited.png')
;
background-image
:
url('../images/sequence-nav/document-icon-visited.png')
;
background-position
:
center
;
}
&
.seq_other_active
{
@extend
.active
;
background-image
:
url('../
../
images/sequence-nav/document-icon-current.png')
;
background-image
:
url('../images/sequence-nav/document-icon-current.png')
;
background-position
:
center
;
}
//vertical & problems
&
.seq_vertical_inactive
,
&
.seq_problem_inactive
{
@extend
.inactive
;
background-image
:
url('../
../
images/sequence-nav/list-icon-normal.png')
;
background-image
:
url('../images/sequence-nav/list-icon-normal.png')
;
background-position
:
center
;
}
&
.seq_vertical_visited
,
&
.seq_problem_visited
{
@extend
.visited
;
background-image
:
url('../
../
images/sequence-nav/list-icon-visited.png')
;
background-image
:
url('../images/sequence-nav/list-icon-visited.png')
;
background-position
:
center
;
}
&
.seq_vertical_active
,
&
.seq_problem_active
{
@extend
.active
;
background-image
:
url('../
../
images/sequence-nav/list-icon-current.png')
;
background-image
:
url('../images/sequence-nav/list-icon-current.png')
;
background-position
:
center
;
}
...
...
@@ -229,7 +229,7 @@ nav.sequence-nav {
&
.prev
{
a
{
background-image
:
url('../
../
images/sequence-nav/previous-icon.png')
;
background-image
:
url('../images/sequence-nav/previous-icon.png')
;
&
:hover
{
background-color
:
$cream
;
...
...
@@ -239,7 +239,7 @@ nav.sequence-nav {
&
.next
{
a
{
background-image
:
url('../
../
images/sequence-nav/next-icon.png')
;
background-image
:
url('../images/sequence-nav/next-icon.png')
;
&
:hover
{
background-color
:
$cream
;
...
...
@@ -310,7 +310,7 @@ section.course-content {
&
.prev
{
a
{
background-image
:
url('../
../
images/sequence-nav/previous-icon.png')
;
background-image
:
url('../images/sequence-nav/previous-icon.png')
;
border-right
:
1px
solid
darken
(
#f6efd4
,
20%
);
&
:hover
{
...
...
@@ -321,7 +321,7 @@ section.course-content {
&
.next
{
a
{
background-image
:
url('../
../
images/sequence-nav/next-icon.png')
;
background-image
:
url('../images/sequence-nav/next-icon.png')
;
&
:hover
{
background-color
:
none
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment