Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-val
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-val
Commits
244197e3
Commit
244197e3
authored
May 18, 2017
by
muhammad-ammar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add support in model for multiple video image urls
parent
9a878df0
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
115 additions
and
3 deletions
+115
-3
.travis.yml
+0
-1
edxval/migrations/0005_videoimage.py
+1
-0
edxval/models.py
+61
-0
edxval/tests/test_api.py
+52
-1
setup.py
+1
-1
No files found.
.travis.yml
View file @
244197e3
...
@@ -10,6 +10,5 @@ script:
...
@@ -10,6 +10,5 @@ script:
branches
:
branches
:
only
:
only
:
-
master
-
master
-
ammar/course-rerun-import-export
after_success
:
after_success
:
coveralls
coveralls
edxval/migrations/0005_videoimage.py
View file @
244197e3
...
@@ -21,6 +21,7 @@ class Migration(migrations.Migration):
...
@@ -21,6 +21,7 @@ class Migration(migrations.Migration):
(
'created'
,
model_utils
.
fields
.
AutoCreatedField
(
default
=
django
.
utils
.
timezone
.
now
,
verbose_name
=
'created'
,
editable
=
False
)),
(
'created'
,
model_utils
.
fields
.
AutoCreatedField
(
default
=
django
.
utils
.
timezone
.
now
,
verbose_name
=
'created'
,
editable
=
False
)),
(
'modified'
,
model_utils
.
fields
.
AutoLastModifiedField
(
default
=
django
.
utils
.
timezone
.
now
,
verbose_name
=
'modified'
,
editable
=
False
)),
(
'modified'
,
model_utils
.
fields
.
AutoLastModifiedField
(
default
=
django
.
utils
.
timezone
.
now
,
verbose_name
=
'modified'
,
editable
=
False
)),
(
'image'
,
edxval
.
models
.
CustomizableImageField
(
null
=
True
,
blank
=
True
)),
(
'image'
,
edxval
.
models
.
CustomizableImageField
(
null
=
True
,
blank
=
True
)),
(
'generated_images'
,
edxval
.
models
.
ListField
()),
(
'course_video'
,
models
.
OneToOneField
(
related_name
=
'video_image'
,
to
=
'edxval.CourseVideo'
)),
(
'course_video'
,
models
.
OneToOneField
(
related_name
=
'video_image'
,
to
=
'edxval.CourseVideo'
)),
],
],
options
=
{
options
=
{
...
...
edxval/models.py
View file @
244197e3
...
@@ -12,12 +12,14 @@ invalid profile_name will be returned.
...
@@ -12,12 +12,14 @@ invalid profile_name will be returned.
"""
"""
from
contextlib
import
closing
from
contextlib
import
closing
import
json
import
logging
import
logging
import
os
import
os
from
uuid
import
uuid4
from
uuid
import
uuid4
from
django.db
import
models
from
django.db
import
models
from
django.dispatch
import
receiver
from
django.dispatch
import
receiver
from
django.core.exceptions
import
ValidationError
from
django.core.validators
import
MinValueValidator
,
RegexValidator
from
django.core.validators
import
MinValueValidator
,
RegexValidator
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
...
@@ -28,6 +30,7 @@ from edxval.utils import video_image_path, get_video_image_storage
...
@@ -28,6 +30,7 @@ from edxval.utils import video_image_path, get_video_image_storage
logger
=
logging
.
getLogger
(
__name__
)
# pylint: disable=C0103
logger
=
logging
.
getLogger
(
__name__
)
# pylint: disable=C0103
URL_REGEX
=
r'^[a-zA-Z0-9\-_]*$'
URL_REGEX
=
r'^[a-zA-Z0-9\-_]*$'
LIST_MAX_ITEMS
=
3
class
ModelFactoryWithValidation
(
object
):
class
ModelFactoryWithValidation
(
object
):
...
@@ -199,12 +202,70 @@ class CustomizableImageField(models.ImageField):
...
@@ -199,12 +202,70 @@ class CustomizableImageField(models.ImageField):
return
name
,
path
,
args
,
kwargs
return
name
,
path
,
args
,
kwargs
class
ListField
(
models
.
TextField
):
"""
ListField use to store and retrieve list data.
"""
__metaclass__
=
models
.
SubfieldBase
def
get_prep_value
(
self
,
value
):
"""
Converts a list to its json represetation to store in database as text.
"""
return
json
.
dumps
(
value
)
def
to_python
(
self
,
value
):
"""
Converts the value into a list.
"""
if
not
value
:
value
=
[]
# If a list is set then validated its items
if
isinstance
(
value
,
list
):
return
self
.
validate
(
value
)
else
:
# try to de-serialize value and expect list and then validate
try
:
py_list
=
json
.
loads
(
value
)
if
not
isinstance
(
py_list
,
list
):
raise
TypeError
self
.
validate
(
py_list
)
except
(
ValueError
,
TypeError
):
raise
ValidationError
(
u'Must be a valid list of strings.'
)
return
py_list
def
validate
(
self
,
value
):
"""
Validate data before saving to database.
Arguemtns:
value(list): list to be validated
Returns:
list if validation is successful
Raises:
ValidationError
"""
if
len
(
value
)
>
LIST_MAX_ITEMS
:
raise
ValidationError
(
u'list must not contain more than {} items.'
.
format
(
LIST_MAX_ITEMS
))
if
all
(
isinstance
(
item
,
str
)
for
item
in
value
)
is
False
:
raise
ValidationError
(
u'list must only contain strings.'
)
return
value
class
VideoImage
(
TimeStampedModel
):
class
VideoImage
(
TimeStampedModel
):
"""
"""
Image model for course video.
Image model for course video.
"""
"""
course_video
=
models
.
OneToOneField
(
CourseVideo
,
related_name
=
"video_image"
)
course_video
=
models
.
OneToOneField
(
CourseVideo
,
related_name
=
"video_image"
)
image
=
CustomizableImageField
()
image
=
CustomizableImageField
()
generated_images
=
ListField
()
@classmethod
@classmethod
def
create_or_update
(
cls
,
course_video
,
file_name
,
image_data
=
None
):
def
create_or_update
(
cls
,
course_video
,
file_name
,
image_data
=
None
):
...
...
edxval/tests/test_api.py
View file @
244197e3
...
@@ -7,6 +7,7 @@ import mock
...
@@ -7,6 +7,7 @@ import mock
from
mock
import
patch
from
mock
import
patch
from
lxml
import
etree
from
lxml
import
etree
from
django.core.exceptions
import
ValidationError
from
django.core.files.images
import
ImageFile
from
django.core.files.images
import
ImageFile
from
django.test
import
TestCase
from
django.test
import
TestCase
from
django.db
import
DatabaseError
from
django.db
import
DatabaseError
...
@@ -14,7 +15,7 @@ from django.core.urlresolvers import reverse
...
@@ -14,7 +15,7 @@ from django.core.urlresolvers import reverse
from
rest_framework
import
status
from
rest_framework
import
status
from
ddt
import
ddt
,
data
,
unpack
from
ddt
import
ddt
,
data
,
unpack
from
edxval.models
import
Profile
,
Video
,
EncodedVideo
,
CourseVideo
,
VideoImage
from
edxval.models
import
Profile
,
Video
,
EncodedVideo
,
CourseVideo
,
VideoImage
,
LIST_MAX_ITEMS
from
edxval
import
api
as
api
from
edxval
import
api
as
api
from
edxval.api
import
(
from
edxval.api
import
(
SortDirection
,
SortDirection
,
...
@@ -1335,3 +1336,53 @@ class CourseVideoImageTest(TestCase):
...
@@ -1335,3 +1336,53 @@ class CourseVideoImageTest(TestCase):
does_not_course_id
does_not_course_id
)
)
)
)
def
test_video_image_urls_field
(
self
):
"""
Test `VideoImage.generated_images` field works as expected.
"""
image_urls
=
[
'video-images/a.png'
,
'video-images/b.png'
]
# an empty list should be returned when there is no value for urls
self
.
assertEqual
(
self
.
course_video
.
video_image
.
generated_images
,
[])
# set a list with data and expect the same list to be returned
course_video
=
CourseVideo
.
objects
.
create
(
video
=
self
.
video
,
course_id
=
'course101'
)
video_image
=
VideoImage
.
objects
.
create
(
course_video
=
course_video
)
video_image
.
generated_images
=
image_urls
video_image
.
save
()
self
.
assertEqual
(
video_image
.
generated_images
,
image_urls
)
self
.
assertEqual
(
course_video
.
video_image
.
generated_images
,
image_urls
)
def
test_video_image_urls_field_validation
(
self
):
"""
Test `VideoImage.generated_images` field validation.
"""
course_video
=
CourseVideo
.
objects
.
create
(
video
=
self
.
video
,
course_id
=
'course101'
)
video_image
=
VideoImage
.
objects
.
create
(
course_video
=
course_video
)
# expect a validation error if we try to set a list with more than 3 items
with
self
.
assertRaises
(
ValidationError
)
as
set_exception
:
video_image
.
generated_images
=
[
'a'
,
'b'
,
'c'
,
'd'
]
self
.
assertEqual
(
set_exception
.
exception
.
message
,
u'list must not contain more than {} items.'
.
format
(
LIST_MAX_ITEMS
)
)
# expect a validation error if we try to a list with non-string items
with
self
.
assertRaises
(
ValidationError
)
as
set_exception
:
video_image
.
generated_images
=
[
'a'
,
1
,
2
]
self
.
assertEqual
(
set_exception
.
exception
.
message
,
u'list must only contain strings.'
)
# expect a validation error if we try to set non list data
exception_messages
=
set
()
for
item
in
(
'a string'
,
555
,
{
'a'
:
1
},
(
1
,),
video_image
):
with
self
.
assertRaises
(
ValidationError
)
as
set_exception
:
video_image
.
generated_images
=
item
exception_messages
.
add
(
set_exception
.
exception
.
message
)
self
.
assertEqual
(
len
(
exception_messages
),
1
)
self
.
assertEqual
(
exception_messages
.
pop
(),
u'Must be a valid list of strings.'
)
setup.py
View file @
244197e3
...
@@ -39,7 +39,7 @@ def load_requirements(*requirements_paths):
...
@@ -39,7 +39,7 @@ def load_requirements(*requirements_paths):
setup
(
setup
(
name
=
'edxval'
,
name
=
'edxval'
,
version
=
'0.0.1
5
'
,
version
=
'0.0.1
4
'
,
author
=
'edX'
,
author
=
'edX'
,
url
=
'http://github.com/edx/edx-val'
,
url
=
'http://github.com/edx/edx-val'
,
description
=
'edx-val'
,
description
=
'edx-val'
,
...
...
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