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
20b53ba7
Commit
20b53ba7
authored
Nov 13, 2014
by
christopher lee
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pylinted known lint
parent
d04082c2
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
57 additions
and
33 deletions
+57
-33
edxval/admin.py
+4
-4
edxval/api.py
+4
-1
edxval/models.py
+13
-4
edxval/serializers.py
+3
-3
edxval/tests/__init__.py
+6
-0
edxval/tests/test_api.py
+1
-1
edxval/tests/test_views.py
+16
-16
edxval/urls.py
+0
-1
edxval/views.py
+10
-3
No files found.
edxval/admin.py
View file @
20b53ba7
...
@@ -6,21 +6,21 @@ from django.contrib import admin
...
@@ -6,21 +6,21 @@ from django.contrib import admin
from
.models
import
Video
,
Profile
,
EncodedVideo
,
Subtitle
,
CourseVideo
from
.models
import
Video
,
Profile
,
EncodedVideo
,
Subtitle
,
CourseVideo
class
ProfileAdmin
(
admin
.
ModelAdmin
):
class
ProfileAdmin
(
admin
.
ModelAdmin
):
# pylint: disable=C0111
list_display
=
(
'id'
,
'profile_name'
,
'extension'
,
'width'
,
'height'
)
list_display
=
(
'id'
,
'profile_name'
,
'extension'
,
'width'
,
'height'
)
list_display_links
=
(
'id'
,
'profile_name'
)
list_display_links
=
(
'id'
,
'profile_name'
)
admin_order_field
=
'profile_name'
admin_order_field
=
'profile_name'
class
EncodedVideoInline
(
admin
.
TabularInline
):
class
EncodedVideoInline
(
admin
.
TabularInline
):
# pylint: disable=C0111
model
=
EncodedVideo
model
=
EncodedVideo
class
CourseVideoInline
(
admin
.
TabularInline
):
class
CourseVideoInline
(
admin
.
TabularInline
):
# pylint: disable=C0111
model
=
CourseVideo
model
=
CourseVideo
extra
=
0
extra
=
0
verbose_name
=
"Course"
verbose_name
=
"Course"
verbose_name_plural
=
"Courses"
verbose_name_plural
=
"Courses"
class
VideoAdmin
(
admin
.
ModelAdmin
):
class
VideoAdmin
(
admin
.
ModelAdmin
):
# pylint: disable=C0111
list_display
=
(
list_display
=
(
'id'
,
'edx_video_id'
,
'client_video_id'
,
'duration'
'id'
,
'edx_video_id'
,
'client_video_id'
,
'duration'
)
)
...
...
edxval/api.py
View file @
20b53ba7
...
@@ -196,9 +196,12 @@ def get_urls_for_profiles(edx_video_id, profiles):
...
@@ -196,9 +196,12 @@ def get_urls_for_profiles(edx_video_id, profiles):
if
encoded_video
[
"profile"
]
in
profiles
:
if
encoded_video
[
"profile"
]
in
profiles
:
profiles_to_urls
[
encoded_video
[
"profile"
]]
=
encoded_video
[
"url"
]
profiles_to_urls
[
encoded_video
[
"profile"
]]
=
encoded_video
[
"url"
]
return
profiles_to_urls
return
profiles_to_urls
def
get_url_for_profile
(
edx_video_id
,
profile
):
def
get_url_for_profile
(
edx_video_id
,
profile
):
"""
Uses get_urls_for_profile to obtain a single profile
"""
return
get_urls_for_profiles
(
edx_video_id
,
[
profile
])[
profile
]
return
get_urls_for_profiles
(
edx_video_id
,
[
profile
])[
profile
]
def
get_videos_for_course
(
course_id
):
def
get_videos_for_course
(
course_id
):
...
...
edxval/models.py
View file @
20b53ba7
...
@@ -11,7 +11,7 @@ class Profile(models.Model)
...
@@ -11,7 +11,7 @@ class Profile(models.Model)
unique=True,
unique=True,
validators=[
validators=[
RegexValidator(
RegexValidator(
regex=r
'^[a-zA-Z0-9
\
-]*$'
,
regex=r
egex
,
message='profile_name has invalid characters',
message='profile_name has invalid characters',
code='invalid profile_name'
code='invalid profile_name'
),
),
...
@@ -32,7 +32,7 @@ from django.core.validators import MinValueValidator, RegexValidator
...
@@ -32,7 +32,7 @@ from django.core.validators import MinValueValidator, RegexValidator
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
url_regex
=
r'^[a-zA-Z0-9\-_]*$'
URL_REGEX
=
r'^[a-zA-Z0-9\-_]*$'
class
Profile
(
models
.
Model
):
class
Profile
(
models
.
Model
):
...
@@ -47,7 +47,7 @@ class Profile(models.Model):
...
@@ -47,7 +47,7 @@ class Profile(models.Model):
unique
=
True
,
unique
=
True
,
validators
=
[
validators
=
[
RegexValidator
(
RegexValidator
(
regex
=
url_regex
,
regex
=
URL_REGEX
,
message
=
'profile_name has invalid characters'
,
message
=
'profile_name has invalid characters'
,
code
=
'invalid profile_name'
code
=
'invalid profile_name'
),
),
...
@@ -73,7 +73,7 @@ class Video(models.Model):
...
@@ -73,7 +73,7 @@ class Video(models.Model):
unique
=
True
,
unique
=
True
,
validators
=
[
validators
=
[
RegexValidator
(
RegexValidator
(
regex
=
url_regex
,
regex
=
URL_REGEX
,
message
=
'edx_video_id has invalid characters'
,
message
=
'edx_video_id has invalid characters'
,
code
=
'invalid edx_video_id'
code
=
'invalid edx_video_id'
),
),
...
@@ -83,6 +83,9 @@ class Video(models.Model):
...
@@ -83,6 +83,9 @@ class Video(models.Model):
duration
=
models
.
FloatField
(
validators
=
[
MinValueValidator
(
0
)])
duration
=
models
.
FloatField
(
validators
=
[
MinValueValidator
(
0
)])
def
get_absolute_url
(
self
):
def
get_absolute_url
(
self
):
"""
Returns the full url link to the edx_video_id
"""
return
reverse
(
'video-detail'
,
args
=
[
self
.
edx_video_id
])
return
reverse
(
'video-detail'
,
args
=
[
self
.
edx_video_id
])
def
__str__
(
self
):
def
__str__
(
self
):
...
@@ -155,10 +158,16 @@ class Subtitle(models.Model):
...
@@ -155,10 +158,16 @@ class Subtitle(models.Model):
return
'
%
s Subtitle for
%
s'
%
(
self
.
language
,
self
.
video
)
return
'
%
s Subtitle for
%
s'
%
(
self
.
language
,
self
.
video
)
def
get_absolute_url
(
self
):
def
get_absolute_url
(
self
):
"""
Returns the full url link to the edx_video_id
"""
return
reverse
(
'subtitle-content'
,
args
=
[
self
.
video
.
edx_video_id
,
self
.
language
])
return
reverse
(
'subtitle-content'
,
args
=
[
self
.
video
.
edx_video_id
,
self
.
language
])
@property
@property
def
content_type
(
self
):
def
content_type
(
self
):
"""
Sjson is returned as application/json, otherwise text/plain
"""
if
self
.
fmt
==
'sjson'
:
if
self
.
fmt
==
'sjson'
:
return
'application/json'
return
'application/json'
else
:
else
:
...
...
edxval/serializers.py
View file @
20b53ba7
...
@@ -14,7 +14,7 @@ class ProfileSerializer(serializers.ModelSerializer):
...
@@ -14,7 +14,7 @@ class ProfileSerializer(serializers.ModelSerializer):
"""
"""
Serializer for Profile object.
Serializer for Profile object.
"""
"""
class
Meta
:
# pylint: disable= C0111
class
Meta
:
# pylint: disable=
C1001,
C0111
model
=
Profile
model
=
Profile
fields
=
(
fields
=
(
"profile_name"
,
"profile_name"
,
...
@@ -32,7 +32,7 @@ class EncodedVideoSerializer(serializers.ModelSerializer):
...
@@ -32,7 +32,7 @@ class EncodedVideoSerializer(serializers.ModelSerializer):
"""
"""
profile
=
serializers
.
SlugRelatedField
(
slug_field
=
"profile_name"
)
profile
=
serializers
.
SlugRelatedField
(
slug_field
=
"profile_name"
)
class
Meta
:
# pylint: disable= C0111
class
Meta
:
# pylint: disable=
C1001,
C0111
model
=
EncodedVideo
model
=
EncodedVideo
fields
=
(
fields
=
(
"created"
,
"created"
,
...
@@ -107,7 +107,7 @@ class VideoSerializer(serializers.ModelSerializer):
...
@@ -107,7 +107,7 @@ class VideoSerializer(serializers.ModelSerializer):
courses
=
CourseSerializer
(
many
=
True
,
read_only
=
False
)
courses
=
CourseSerializer
(
many
=
True
,
read_only
=
False
)
url
=
serializers
.
SerializerMethodField
(
'get_url'
)
url
=
serializers
.
SerializerMethodField
(
'get_url'
)
class
Meta
:
# pylint: disable=C0111
class
Meta
:
# pylint: disable=C
1001, C
0111
model
=
Video
model
=
Video
lookup_field
=
"edx_video_id"
lookup_field
=
"edx_video_id"
exclude
=
(
'id'
,)
exclude
=
(
'id'
,)
...
...
edxval/tests/__init__.py
View file @
20b53ba7
...
@@ -17,9 +17,15 @@ class APIAuthTestCase(APITestCase):
...
@@ -17,9 +17,15 @@ class APIAuthTestCase(APITestCase):
self
.
_login
()
self
.
_login
()
def
_logout
(
self
):
def
_logout
(
self
):
"""
Logs out API user
"""
self
.
client
.
logout
()
self
.
client
.
logout
()
def
_login
(
self
,
unauthorized
=
False
):
def
_login
(
self
,
unauthorized
=
False
):
"""
Logs in user for test if authorized
"""
if
unauthorized
:
if
unauthorized
:
username
=
password
=
'unauthorized'
username
=
password
=
'unauthorized'
else
:
else
:
...
...
edxval/tests/test_api.py
View file @
20b53ba7
...
@@ -67,7 +67,7 @@ class CreateVideoTest(TestCase):
...
@@ -67,7 +67,7 @@ class CreateVideoTest(TestCase):
video_data
=
dict
(
video_data
=
dict
(
encoded_videos
=
[
encoded_videos
=
[
dict
(
dict
(
profile
=
constants
.
PROFILE_DICT_MOBILE
,
profile
=
constants
.
PROFILE_DICT_MOBILE
,
**
constants
.
ENCODED_VIDEO_DICT_MOBILE
**
constants
.
ENCODED_VIDEO_DICT_MOBILE
)
)
],
],
...
...
edxval/tests/test_views.py
View file @
20b53ba7
...
@@ -631,13 +631,13 @@ class SubtitleDetailTest(APIAuthTestCase):
...
@@ -631,13 +631,13 @@ class SubtitleDetailTest(APIAuthTestCase):
self
.
assertEqual
(
len
(
video
),
1
)
self
.
assertEqual
(
len
(
video
),
1
)
self
.
assertEqual
(
len
(
video
[
0
]
.
get
(
"subtitles"
)),
2
)
self
.
assertEqual
(
len
(
video
[
0
]
.
get
(
"subtitles"
)),
2
)
st
=
video
[
0
][
'subtitles'
][
0
]
video_subtitles
=
video
[
0
][
'subtitles'
][
0
]
response
=
self
.
client
.
get
(
st
[
'content_url'
])
response
=
self
.
client
.
get
(
video_subtitles
[
'content_url'
])
self
.
assertEqual
(
response
.
content
,
constants
.
SUBTITLE_DICT_SRT
[
'content'
])
self
.
assertEqual
(
response
.
content
,
constants
.
SUBTITLE_DICT_SRT
[
'content'
])
self
.
assertEqual
(
response
[
'Content-Type'
],
'text/plain'
)
self
.
assertEqual
(
response
[
'Content-Type'
],
'text/plain'
)
st
=
video
[
0
][
'subtitles'
][
1
]
video_subtitles
=
video
[
0
][
'subtitles'
][
1
]
response
=
self
.
client
.
get
(
st
[
'content_url'
])
response
=
self
.
client
.
get
(
video_subtitles
[
'content_url'
])
self
.
assertEqual
(
response
.
content
,
constants
.
SUBTITLE_DICT_SJSON
[
'content'
])
self
.
assertEqual
(
response
.
content
,
constants
.
SUBTITLE_DICT_SJSON
[
'content'
])
self
.
assertEqual
(
response
[
'Content-Type'
],
'application/json'
)
self
.
assertEqual
(
response
[
'Content-Type'
],
'application/json'
)
...
@@ -651,16 +651,16 @@ class SubtitleDetailTest(APIAuthTestCase):
...
@@ -651,16 +651,16 @@ class SubtitleDetailTest(APIAuthTestCase):
)
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
video
=
response
.
data
video
=
response
.
data
st
=
video
[
'subtitles'
][
0
]
video_subtitles
=
video
[
'subtitles'
][
0
]
url
=
reverse
(
'subtitle-detail'
,
kwargs
=
{
'video__edx_video_id'
:
video
[
'edx_video_id'
],
'language'
:
st
[
'language'
]})
url
=
reverse
(
'subtitle-detail'
,
kwargs
=
{
'video__edx_video_id'
:
video
[
'edx_video_id'
],
'language'
:
video_subtitles
[
'language'
]})
st
[
'content'
]
=
'testing 123'
video_subtitles
[
'content'
]
=
'testing 123'
response
=
self
.
client
.
put
(
response
=
self
.
client
.
put
(
url
,
st
,
format
=
'json'
url
,
video_subtitles
,
format
=
'json'
)
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
self
.
client
.
get
(
st
[
'content_url'
])
.
content
,
'testing 123'
)
self
.
assertEqual
(
self
.
client
.
get
(
video_subtitles
[
'content_url'
])
.
content
,
'testing 123'
)
def
test_update_json_subtitle
(
self
):
def
test_update_json_subtitle
(
self
):
"""
"""
...
@@ -672,20 +672,20 @@ class SubtitleDetailTest(APIAuthTestCase):
...
@@ -672,20 +672,20 @@ class SubtitleDetailTest(APIAuthTestCase):
)
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
video
=
response
.
data
video
=
response
.
data
st
=
video
[
'subtitles'
][
1
]
video_subtitles
=
video
[
'subtitles'
][
1
]
url
=
reverse
(
'subtitle-detail'
,
kwargs
=
{
'video__edx_video_id'
:
video
[
'edx_video_id'
],
'language'
:
st
[
'language'
]})
url
=
reverse
(
'subtitle-detail'
,
kwargs
=
{
'video__edx_video_id'
:
video
[
'edx_video_id'
],
'language'
:
video_subtitles
[
'language'
]})
st
[
'content'
]
=
'testing 123'
video_subtitles
[
'content'
]
=
'testing 123'
response
=
self
.
client
.
put
(
response
=
self
.
client
.
put
(
url
,
st
,
format
=
'json'
url
,
video_subtitles
,
format
=
'json'
)
)
# not in json format
# not in json format
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
)
st
[
'content'
]
=
"""{"start": "00:00:00"
video_subtitles
[
'content'
]
=
"""{"start": "00:00:00"
}"""
}"""
response
=
self
.
client
.
put
(
response
=
self
.
client
.
put
(
url
,
st
,
format
=
'json'
url
,
video_subtitles
,
format
=
'json'
)
)
self
.
assertEqual
(
self
.
client
.
get
(
st
[
'content_url'
])
.
content
,
'{"start": "00:00:00"}'
)
self
.
assertEqual
(
self
.
client
.
get
(
video_subtitles
[
'content_url'
])
.
content
,
'{"start": "00:00:00"}'
)
edxval/urls.py
View file @
20b53ba7
...
@@ -3,7 +3,6 @@ Url file for django app edxval.
...
@@ -3,7 +3,6 @@ Url file for django app edxval.
"""
"""
from
django.conf.urls
import
patterns
,
url
from
django.conf.urls
import
patterns
,
url
from
django.conf
import
settings
from
edxval
import
views
from
edxval
import
views
...
...
edxval/views.py
View file @
20b53ba7
...
@@ -15,6 +15,7 @@ from edxval.serializers import (
...
@@ -15,6 +15,7 @@ from edxval.serializers import (
SubtitleSerializer
SubtitleSerializer
)
)
class
ReadRestrictedDjangoModelPermissions
(
DjangoModelPermissions
):
class
ReadRestrictedDjangoModelPermissions
(
DjangoModelPermissions
):
"""Extending DjangoModelPermissions to allow us to restrict read access.
"""Extending DjangoModelPermissions to allow us to restrict read access.
...
@@ -40,9 +41,12 @@ class MultipleFieldLookupMixin(object):
...
@@ -40,9 +41,12 @@ class MultipleFieldLookupMixin(object):
based on a `lookup_fields` attribute, instead of the default single field filtering.
based on a `lookup_fields` attribute, instead of the default single field filtering.
"""
"""
def
get_object
(
self
):
def
get_object
(
self
):
"""
Returns an object instance that should be used for detail views.
"""
queryset
=
self
.
get_queryset
()
# Get the base queryset
queryset
=
self
.
get_queryset
()
# Get the base queryset
queryset
=
self
.
filter_queryset
(
queryset
)
# Apply any filter backends
queryset
=
self
.
filter_queryset
(
queryset
)
# Apply any filter backends
filter
=
{}
filter
=
{}
# pylint: disable=W0622
for
field
in
self
.
lookup_fields
:
for
field
in
self
.
lookup_fields
:
filter
[
field
]
=
self
.
kwargs
[
field
]
filter
[
field
]
=
self
.
kwargs
[
field
]
return
get_object_or_404
(
queryset
,
**
filter
)
# Lookup the object
return
get_object_or_404
(
queryset
,
**
filter
)
# Lookup the object
...
@@ -106,11 +110,14 @@ class SubtitleDetail(MultipleFieldLookupMixin, generics.RetrieveUpdateDestroyAPI
...
@@ -106,11 +110,14 @@ class SubtitleDetail(MultipleFieldLookupMixin, generics.RetrieveUpdateDestroyAPI
serializer_class
=
SubtitleSerializer
serializer_class
=
SubtitleSerializer
def
_last_modified_subtitle
(
request
,
edx_video_id
,
language
):
def
_last_modified_subtitle
(
request
,
edx_video_id
,
language
):
# pylint: disable=W0613
"""
Returns the last modified subtitle
"""
return
Subtitle
.
objects
.
get
(
video__edx_video_id
=
edx_video_id
,
language
=
language
)
.
modified
return
Subtitle
.
objects
.
get
(
video__edx_video_id
=
edx_video_id
,
language
=
language
)
.
modified
@last_modified
(
last_modified_func
=
_last_modified_subtitle
)
@last_modified
(
last_modified_func
=
_last_modified_subtitle
)
def
get_subtitle
(
request
,
edx_video_id
,
language
):
def
get_subtitle
(
request
,
edx_video_id
,
language
):
# pylint: disable=W0613
"""
"""
Return content of subtitle by id
Return content of subtitle by id
"""
"""
...
...
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