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
80af538d
Commit
80af538d
authored
Oct 18, 2013
by
Don Mitchell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
URLencode $ and . in location.name when used as key
parent
d15bfb67
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
58 additions
and
18 deletions
+58
-18
common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py
+40
-18
common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py
+18
-0
No files found.
common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py
View file @
80af538d
...
@@ -9,6 +9,7 @@ from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundErr
...
@@ -9,6 +9,7 @@ from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundErr
from
xmodule.modulestore.locator
import
BlockUsageLocator
from
xmodule.modulestore.locator
import
BlockUsageLocator
from
xmodule.modulestore.mongo
import
draft
from
xmodule.modulestore.mongo
import
draft
from
xmodule.modulestore
import
Location
from
xmodule.modulestore
import
Location
import
urllib
class
LocMapperStore
(
object
):
class
LocMapperStore
(
object
):
...
@@ -149,7 +150,7 @@ class LocMapperStore(object):
...
@@ -149,7 +150,7 @@ class LocMapperStore(object):
else
:
else
:
branch
=
entry
[
'draft_branch'
]
branch
=
entry
[
'draft_branch'
]
usage_id
=
entry
[
'block_map'
]
.
get
(
location
.
name
)
usage_id
=
entry
[
'block_map'
]
.
get
(
self
.
_encode_for_mongo
(
location
.
name
)
)
if
usage_id
is
None
:
if
usage_id
is
None
:
if
add_entry_if_missing
:
if
add_entry_if_missing
:
usage_id
=
self
.
_add_to_block_map
(
location
,
location_id
,
entry
[
'block_map'
])
usage_id
=
self
.
_add_to_block_map
(
location
,
location_id
,
entry
[
'block_map'
])
...
@@ -206,7 +207,7 @@ class LocMapperStore(object):
...
@@ -206,7 +207,7 @@ class LocMapperStore(object):
candidate
[
'_id'
][
'org'
],
candidate
[
'_id'
][
'org'
],
candidate
[
'_id'
][
'course'
],
candidate
[
'_id'
][
'course'
],
category
,
category
,
old_name
,
self
.
_decode_from_mongo
(
old_name
)
,
revision
)
revision
)
return
None
return
None
...
@@ -241,13 +242,14 @@ class LocMapperStore(object):
...
@@ -241,13 +242,14 @@ class LocMapperStore(object):
# turn maps from cursor to list
# turn maps from cursor to list
map_list
=
list
(
maps
)
map_list
=
list
(
maps
)
encoded_location_name
=
self
.
_encode_for_mongo
(
location
.
name
)
# check whether there's already a usage_id for this location (and it agrees w/ any passed in or found)
# check whether there's already a usage_id for this location (and it agrees w/ any passed in or found)
for
map_entry
in
map_list
:
for
map_entry
in
map_list
:
if
(
location
.
name
in
map_entry
[
'block_map'
]
and
if
(
encoded_location_
name
in
map_entry
[
'block_map'
]
and
location
.
category
in
map_entry
[
'block_map'
][
location
.
name
]):
location
.
category
in
map_entry
[
'block_map'
][
encoded_location_
name
]):
if
usage_id
is
None
:
if
usage_id
is
None
:
usage_id
=
map_entry
[
'block_map'
][
location
.
name
][
location
.
category
]
usage_id
=
map_entry
[
'block_map'
][
encoded_location_
name
][
location
.
category
]
elif
usage_id
!=
map_entry
[
'block_map'
][
location
.
name
][
location
.
category
]:
elif
usage_id
!=
map_entry
[
'block_map'
][
encoded_location_
name
][
location
.
category
]:
raise
DuplicateItemError
(
usage_id
,
self
,
'location_map'
)
raise
DuplicateItemError
(
usage_id
,
self
,
'location_map'
)
computed_usage_id
=
usage_id
computed_usage_id
=
usage_id
...
@@ -256,8 +258,8 @@ class LocMapperStore(object):
...
@@ -256,8 +258,8 @@ class LocMapperStore(object):
for
map_entry
in
map_list
:
for
map_entry
in
map_list
:
if
computed_usage_id
is
None
:
if
computed_usage_id
is
None
:
computed_usage_id
=
self
.
_add_to_block_map
(
location
,
location_id
,
map_entry
[
'block_map'
])
computed_usage_id
=
self
.
_add_to_block_map
(
location
,
location_id
,
map_entry
[
'block_map'
])
elif
(
location
.
name
not
in
map_entry
[
'block_map'
]
or
elif
(
encoded_location_
name
not
in
map_entry
[
'block_map'
]
or
location
.
category
not
in
map_entry
[
'block_map'
][
location
.
name
]):
location
.
category
not
in
map_entry
[
'block_map'
][
encoded_location_
name
]):
alt_usage_id
=
self
.
_verify_uniqueness
(
computed_usage_id
,
map_entry
[
'block_map'
])
alt_usage_id
=
self
.
_verify_uniqueness
(
computed_usage_id
,
map_entry
[
'block_map'
])
if
alt_usage_id
!=
computed_usage_id
:
if
alt_usage_id
!=
computed_usage_id
:
if
usage_id
is
not
None
:
if
usage_id
is
not
None
:
...
@@ -271,7 +273,7 @@ class LocMapperStore(object):
...
@@ -271,7 +273,7 @@ class LocMapperStore(object):
True
True
)
)
map_entry
[
'block_map'
]
.
setdefault
(
location
.
name
,
{})[
location
.
category
]
=
computed_usage_id
map_entry
[
'block_map'
]
.
setdefault
(
encoded_location_
name
,
{})[
location
.
category
]
=
computed_usage_id
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
return
computed_usage_id
return
computed_usage_id
...
@@ -293,10 +295,11 @@ class LocMapperStore(object):
...
@@ -293,10 +295,11 @@ class LocMapperStore(object):
location_id
=
self
.
_interpret_location_course_id
(
old_course_id
,
location
)
location_id
=
self
.
_interpret_location_course_id
(
old_course_id
,
location
)
maps
=
self
.
location_map
.
find
(
location_id
)
maps
=
self
.
location_map
.
find
(
location_id
)
encoded_location_name
=
self
.
_encode_for_mongo
(
location
.
name
)
for
map_entry
in
maps
:
for
map_entry
in
maps
:
# handle noop of renaming to same name
# handle noop of renaming to same name
if
(
location
.
name
in
map_entry
[
'block_map'
]
and
if
(
encoded_location_
name
in
map_entry
[
'block_map'
]
and
map_entry
[
'block_map'
][
location
.
name
]
.
get
(
location
.
category
)
==
usage_id
):
map_entry
[
'block_map'
][
encoded_location_
name
]
.
get
(
location
.
category
)
==
usage_id
):
continue
continue
alt_usage_id
=
self
.
_verify_uniqueness
(
usage_id
,
map_entry
[
'block_map'
])
alt_usage_id
=
self
.
_verify_uniqueness
(
usage_id
,
map_entry
[
'block_map'
])
if
alt_usage_id
!=
usage_id
:
if
alt_usage_id
!=
usage_id
:
...
@@ -307,8 +310,8 @@ class LocMapperStore(object):
...
@@ -307,8 +310,8 @@ class LocMapperStore(object):
else
:
else
:
raise
DuplicateItemError
(
usage_id
,
self
,
'location_map'
)
raise
DuplicateItemError
(
usage_id
,
self
,
'location_map'
)
if
location
.
category
in
map_entry
[
'block_map'
]
.
setdefault
(
location
.
name
,
{}):
if
location
.
category
in
map_entry
[
'block_map'
]
.
setdefault
(
encoded_location_
name
,
{}):
map_entry
[
'block_map'
][
location
.
name
][
location
.
category
]
=
usage_id
map_entry
[
'block_map'
][
encoded_location_
name
][
location
.
category
]
=
usage_id
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
return
usage_id
return
usage_id
...
@@ -323,12 +326,13 @@ class LocMapperStore(object):
...
@@ -323,12 +326,13 @@ class LocMapperStore(object):
location_id
=
self
.
_interpret_location_course_id
(
old_course_id
,
location
)
location_id
=
self
.
_interpret_location_course_id
(
old_course_id
,
location
)
maps
=
self
.
location_map
.
find
(
location_id
)
maps
=
self
.
location_map
.
find
(
location_id
)
encoded_location_name
=
self
.
_encode_for_mongo
(
location
.
name
)
for
map_entry
in
maps
:
for
map_entry
in
maps
:
if
location
.
category
in
map_entry
[
'block_map'
]
.
setdefault
(
location
.
name
,
{}):
if
location
.
category
in
map_entry
[
'block_map'
]
.
setdefault
(
encoded_location_
name
,
{}):
if
len
(
map_entry
[
'block_map'
][
location
.
name
])
==
1
:
if
len
(
map_entry
[
'block_map'
][
encoded_location_
name
])
==
1
:
del
map_entry
[
'block_map'
][
location
.
name
]
del
map_entry
[
'block_map'
][
encoded_location_
name
]
else
:
else
:
del
map_entry
[
'block_map'
][
location
.
name
][
location
.
category
]
del
map_entry
[
'block_map'
][
encoded_location_
name
][
location
.
category
]
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
def
_add_to_block_map
(
self
,
location
,
location_id
,
block_map
):
def
_add_to_block_map
(
self
,
location
,
location_id
,
block_map
):
...
@@ -341,7 +345,8 @@ class LocMapperStore(object):
...
@@ -341,7 +345,8 @@ class LocMapperStore(object):
usage_id
=
self
.
_verify_uniqueness
(
location
.
category
+
location
.
name
[:
3
],
block_map
)
usage_id
=
self
.
_verify_uniqueness
(
location
.
category
+
location
.
name
[:
3
],
block_map
)
else
:
else
:
usage_id
=
location
.
name
usage_id
=
location
.
name
block_map
.
setdefault
(
location
.
name
,
{})[
location
.
category
]
=
usage_id
encoded_location_name
=
self
.
_encode_for_mongo
(
location
.
name
)
block_map
.
setdefault
(
encoded_location_name
,
{})[
location
.
category
]
=
usage_id
self
.
location_map
.
update
(
location_id
,
{
'$set'
:
{
'block_map'
:
block_map
}})
self
.
location_map
.
update
(
location_id
,
{
'$set'
:
{
'block_map'
:
block_map
}})
return
usage_id
return
usage_id
...
@@ -386,3 +391,20 @@ class LocMapperStore(object):
...
@@ -386,3 +391,20 @@ class LocMapperStore(object):
name
+=
str
(
randint
(
0
,
9
))
name
+=
str
(
randint
(
0
,
9
))
return
self
.
_verify_uniqueness
(
name
,
block_map
)
return
self
.
_verify_uniqueness
(
name
,
block_map
)
return
name
return
name
def
_encode_for_mongo
(
self
,
fieldname
):
"""
Fieldnames in mongo cannot have periods nor dollar signs. So encode them.
:param fieldname: an atomic field name. Note, don't pass structured paths as it will flatten them
"""
for
char
in
[
"."
,
"$"
]:
fieldname
=
fieldname
.
replace
(
char
,
'
%
{:02x}'
.
format
(
ord
(
char
)))
return
fieldname
def
_decode_from_mongo
(
self
,
fieldname
):
"""
The inverse of _encode_for_mongo
:param fieldname: with period and dollar escaped
"""
return
urllib
.
unquote
(
fieldname
)
common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py
View file @
80af538d
...
@@ -324,6 +324,24 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -324,6 +324,24 @@ class TestLocationMapper(unittest.TestCase):
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
self
.
assertEqual
(
prob_location
,
Location
(
'i4x'
,
org
,
course
,
'problem'
,
'abc123'
))
self
.
assertEqual
(
prob_location
,
Location
(
'i4x'
,
org
,
course
,
'problem'
,
'abc123'
))
def
test_special_chars
(
self
):
"""
Test locations which have special characters
"""
# afaik, location.check_list prevents $ in all fields
org
=
'foo.org.edu'
course
=
'bar.course-4'
name
=
'baz.run_4-3'
old_style_course_id
=
'{}/{}/{}'
.
format
(
org
,
course
,
name
)
location
=
Location
(
'i4x'
,
org
,
course
,
'course'
,
name
)
prob_locator
=
loc_mapper
()
.
translate_location
(
old_style_course_id
,
location
,
add_entry_if_missing
=
True
)
reverted_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
self
.
assertEqual
(
location
,
reverted_location
)
def
test_add_block
(
self
):
def
test_add_block
(
self
):
"""
"""
Test add_block_location_translator(location, old_course_id=None, usage_id=None)
Test add_block_location_translator(location, old_course_id=None, usage_id=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