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
85e6c233
Commit
85e6c233
authored
Sep 26, 2012
by
Chris Dodge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
work-in-flight for uploading/serving of static content for courses
parent
702c26ea
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
113 additions
and
7 deletions
+113
-7
cms/djangoapps/contentstore/views.py
+77
-5
cms/envs/common.py
+2
-1
cms/envs/dev.py
+11
-0
cms/templates/course_index.html
+3
-0
cms/urls.py
+3
-1
common/djangoapps/cache_toolbox/core.py
+17
-0
No files found.
cms/djangoapps/contentstore/views.py
View file @
85e6c233
...
@@ -2,14 +2,16 @@ from util.json_request import expect_json
...
@@ -2,14 +2,16 @@ from util.json_request import expect_json
import
json
import
json
import
logging
import
logging
import
sys
import
sys
import
mimetypes
from
collections
import
defaultdict
from
collections
import
defaultdict
from
django.http
import
HttpResponse
,
Http404
from
django.http
import
HttpResponse
,
Http404
,
HttpResponseBadRequest
,
HttpResponseForbidden
from
django.contrib.auth.decorators
import
login_required
from
django.contrib.auth.decorators
import
login_required
from
django.core.context_processors
import
csrf
from
django.core.context_processors
import
csrf
from
django_future.csrf
import
ensure_csrf_cookie
from
django_future.csrf
import
ensure_csrf_cookie
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.conf
import
settings
from
django.conf
import
settings
from
django
import
forms
from
xmodule.modulestore
import
Location
from
xmodule.modulestore
import
Location
from
xmodule.x_module
import
ModuleSystem
from
xmodule.x_module
import
ModuleSystem
...
@@ -26,6 +28,13 @@ from functools import partial
...
@@ -26,6 +28,13 @@ from functools import partial
from
itertools
import
groupby
from
itertools
import
groupby
from
operator
import
attrgetter
from
operator
import
attrgetter
from
xmodule.contentstore.django
import
contentstore
from
xmodule.contentstore
import
StaticContent
#from django.core.cache import cache
from
cache_toolbox.core
import
set_cached_content
,
get_cached_content
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
...
@@ -89,9 +98,19 @@ def course_index(request, org, course, name):
...
@@ -89,9 +98,19 @@ def course_index(request, org, course, name):
raise
Http404
# TODO (vshnayder): better error
raise
Http404
# TODO (vshnayder): better error
# TODO (cpennington): These need to be read in from the active user
# TODO (cpennington): These need to be read in from the active user
course
=
modulestore
()
.
get_item
(
location
)
_course
=
modulestore
()
.
get_item
(
location
)
weeks
=
course
.
get_children
()
weeks
=
_course
.
get_children
()
return
render_to_response
(
'course_index.html'
,
{
'weeks'
:
weeks
})
upload_asset_callback_url
=
"/{org}/{course}/course/{name}/upload_asset"
.
format
(
org
=
org
,
course
=
course
,
name
=
name
)
return
render_to_response
(
'course_index.html'
,
{
'weeks'
:
weeks
,
'upload_asset_callback_url'
:
upload_asset_callback_url
})
@login_required
@login_required
...
@@ -115,12 +134,13 @@ def edit_item(request):
...
@@ -115,12 +134,13 @@ def edit_item(request):
lms_link
=
"{lms_base}/courses/{course_id}/jump_to/{location}"
.
format
(
lms_link
=
"{lms_base}/courses/{course_id}/jump_to/{location}"
.
format
(
lms_base
=
settings
.
LMS_BASE
,
lms_base
=
settings
.
LMS_BASE
,
# TODO: These will need to be changed to point to the particular instance of this problem in the particular course
# TODO: These will need to be changed to point to the particular instance of this problem in the particular course
course_id
=
modulestore
()
.
get_containing_courses
(
item
.
location
)[
0
]
.
id
,
course_id
=
modulestore
()
.
get_containing_courses
(
item
.
location
)[
0
]
.
id
,
location
=
item
.
location
,
location
=
item
.
location
,
)
)
else
:
else
:
lms_link
=
None
lms_link
=
None
return
render_to_response
(
'unit.html'
,
{
return
render_to_response
(
'unit.html'
,
{
'contents'
:
item
.
get_html
(),
'contents'
:
item
.
get_html
(),
'js_module'
:
item
.
js_module_name
,
'js_module'
:
item
.
js_module_name
,
...
@@ -390,3 +410,55 @@ def clone_item(request):
...
@@ -390,3 +410,55 @@ def clone_item(request):
modulestore
()
.
update_children
(
parent_location
,
parent
.
definition
.
get
(
'children'
,
[])
+
[
new_item
.
location
.
url
()])
modulestore
()
.
update_children
(
parent_location
,
parent
.
definition
.
get
(
'children'
,
[])
+
[
new_item
.
location
.
url
()])
return
HttpResponse
()
return
HttpResponse
()
'''
cdodge: this method allows for POST uploading of files into the course asset library, which will
be supported by GridFS in MongoDB.
'''
#@login_required
#@ensure_csrf_cookie
def
upload_asset
(
request
,
org
,
course
,
coursename
):
if
request
.
method
!=
'POST'
:
# (cdodge) @todo: Is there a way to do a - say - 'raise Http400'?
return
HttpResponseBadRequest
()
# construct a location from the passed in path
location
=
[
'i4x'
,
org
,
course
,
'course'
,
coursename
]
if
not
has_access
(
request
.
user
,
location
):
return
HttpResponseForbidden
()
# Does the course actually exist?!?
try
:
item
=
modulestore
()
.
get_item
(
location
)
except
:
# no return it as a Bad Request response
logging
.
error
(
'Could not find course'
+
location
)
return
HttpResponseBadRequest
()
# compute a 'filename' which is similar to the location formatting, we're using the 'filename'
# nomenclature since we're using a FileSystem paradigm here. We're just imposing
# the Location string formatting expectations to keep things a bit more consistent
name
=
request
.
FILES
[
'file'
]
.
name
mime_type
=
request
.
FILES
[
'file'
]
.
content_type
filedata
=
request
.
FILES
[
'file'
]
.
read
()
file_location
=
StaticContent
.
compute_location_filename
(
org
,
course
,
name
)
content
=
StaticContent
(
file_location
,
name
,
mime_type
,
filedata
)
# first commit to the DB
contentstore
()
.
update
(
content
)
# then update the cache so we're not serving up stale content
set_cached_content
(
content
)
return
HttpResponse
(
'Upload completed'
)
class
UploadFileForm
(
forms
.
Form
):
title
=
forms
.
CharField
(
max_length
=
50
)
file
=
forms
.
FileField
()
cms/envs/common.py
View file @
85e6c233
...
@@ -118,6 +118,7 @@ TEMPLATE_LOADERS = (
...
@@ -118,6 +118,7 @@ TEMPLATE_LOADERS = (
)
)
MIDDLEWARE_CLASSES
=
(
MIDDLEWARE_CLASSES
=
(
'contentserver.middleware.StaticContentServer'
,
'django.middleware.cache.UpdateCacheMiddleware'
,
'django.middleware.cache.UpdateCacheMiddleware'
,
'django.middleware.common.CommonMiddleware'
,
'django.middleware.common.CommonMiddleware'
,
'django.contrib.sessions.middleware.SessionMiddleware'
,
'django.contrib.sessions.middleware.SessionMiddleware'
,
...
@@ -130,7 +131,7 @@ MIDDLEWARE_CLASSES = (
...
@@ -130,7 +131,7 @@ MIDDLEWARE_CLASSES = (
'track.middleware.TrackMiddleware'
,
'track.middleware.TrackMiddleware'
,
'mitxmako.middleware.MakoMiddleware'
,
'mitxmako.middleware.MakoMiddleware'
,
'django.middleware.transaction.TransactionMiddleware'
,
'django.middleware.transaction.TransactionMiddleware'
)
)
############################ SIGNAL HANDLERS ################################
############################ SIGNAL HANDLERS ################################
...
...
cms/envs/dev.py
View file @
85e6c233
...
@@ -28,6 +28,17 @@ MODULESTORE = {
...
@@ -28,6 +28,17 @@ MODULESTORE = {
}
}
}
}
# cdodge: This is the specifier for the MongoDB (using GridFS) backed static content store
# This is for static content for courseware, not system static content (e.g. javascript, css, edX branding, etc)
CONTENTSTORE
=
{
'ENGINE'
:
'xmodule.contentstore.mongo.MongoContentStore'
,
'OPTIONS'
:
{
'host'
:
'localhost'
,
'db'
:
'xcontent'
,
}
}
DATABASES
=
{
DATABASES
=
{
'default'
:
{
'default'
:
{
'ENGINE'
:
'django.db.backends.sqlite3'
,
'ENGINE'
:
'django.db.backends.sqlite3'
,
...
...
cms/templates/course_index.html
View file @
85e6c233
...
@@ -7,8 +7,11 @@
...
@@ -7,8 +7,11 @@
<
%
include
file=
"widgets/navigation.html"
/>
<
%
include
file=
"widgets/navigation.html"
/>
<
%
include
file=
"widgets/upload_assets.html"
/>
<section
class=
"main-content"
>
<section
class=
"main-content"
>
</section>
</section>
</section>
</section>
</
%
block>
</
%
block>
cms/urls.py
View file @
85e6c233
...
@@ -17,7 +17,9 @@ urlpatterns = ('',
...
@@ -17,7 +17,9 @@ urlpatterns = ('',
'contentstore.views.course_index'
,
name
=
'course_index'
),
'contentstore.views.course_index'
,
name
=
'course_index'
),
url
(
r'^github_service_hook$'
,
'github_sync.views.github_post_receive'
),
url
(
r'^github_service_hook$'
,
'github_sync.views.github_post_receive'
),
url
(
r'^preview/modx/(?P<preview_id>[^/]*)/(?P<location>.*?)/(?P<dispatch>[^/]*)$'
,
url
(
r'^preview/modx/(?P<preview_id>[^/]*)/(?P<location>.*?)/(?P<dispatch>[^/]*)$'
,
'contentstore.views.preview_dispatch'
,
name
=
'preview_dispatch'
)
'contentstore.views.preview_dispatch'
,
name
=
'preview_dispatch'
),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<coursename>[^/]+)/upload_asset$'
,
'contentstore.views.upload_asset'
,
name
=
'upload_asset'
)
)
)
# User creation and updating views
# User creation and updating views
...
...
common/djangoapps/cache_toolbox/core.py
View file @
85e6c233
...
@@ -10,6 +10,7 @@ Core methods
...
@@ -10,6 +10,7 @@ Core methods
from
django.core.cache
import
cache
from
django.core.cache
import
cache
from
django.db
import
DEFAULT_DB_ALIAS
from
django.db
import
DEFAULT_DB_ALIAS
from
xmodule.contentstore
import
StaticContent
from
.
import
app_settings
from
.
import
app_settings
...
@@ -107,3 +108,19 @@ def instance_key(model, instance_or_pk):
...
@@ -107,3 +108,19 @@ def instance_key(model, instance_or_pk):
model
.
_meta
.
module_name
,
model
.
_meta
.
module_name
,
getattr
(
instance_or_pk
,
'pk'
,
instance_or_pk
),
getattr
(
instance_or_pk
,
'pk'
,
instance_or_pk
),
)
)
def
content_key
(
filename
):
return
'content:
%
s'
%
(
filename
)
def
set_cached_content
(
content
):
cache
.
set
(
content_key
(
content
.
filename
),
content
)
def
get_cached_content
(
filename
):
return
cache
.
get
(
content_key
(
filename
))
#def set_cached_content(filename, content_type, data):
# cache.set(content_key(filename), (filename, content_type, data))
#def get_cached_content(filename):
# return cache.get(content_key(filename))
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