Skip to content
This repository has been archived by the owner on Jan 28, 2020. It is now read-only.

Commit

Permalink
Merge branch 'rc/0.11.0' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
pwilkins committed Sep 23, 2015
2 parents bbf9450 + 1cca1b9 commit e38fb13
Show file tree
Hide file tree
Showing 63 changed files with 2,812 additions and 577 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ develop-eggs/
/dist/
downloads/
eggs/
lib/
lib64/
parts/
sdist/
Expand Down
9 changes: 0 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ RUN pip install -r requirements.txt &&\
RUN pip3 install -r requirements.txt &&\
pip3 install -r test_requirements.txt

# Install node development and production packages
RUN mkdir /node
COPY package.json /node/package.json
RUN cd /node &&\
npm install &&\
npm install --production

# Add project
COPY . /src
WORKDIR /src
Expand All @@ -45,8 +38,6 @@ RUN ./manage.py collectstatic --noinput
RUN apt-get clean && apt-get purge
USER mitodl

# Setup node environment
ENV PATH /src/node_modules/.bin:/node/node_modules/.bin:$PATH
# Set pip cache folder, as it is breaking pip when it is on a shared volume
ENV XDG_CACHE_HOME /tmp/.cache

Expand Down
25 changes: 24 additions & 1 deletion RELEASE.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
Release Notes
-------------

Version 0.11.0
==============

- Reorganized Learning Resource panel to use three tabs.
- Added datatable proof-of-concept.
- Added REST api view to get and delete a course.
- Added calls to ``get_conn()`` where ``conn`` is used implicitly.
- Added more detail to confirmation message for delete vocabulary.
- Moved ``Save`` button to right of the term for edit term inside
taxonomy panel.
- Switched Django local storage to overwrite.
- Implemented ``page_size`` parameter to allow users to set page size.
- Fixed spacing between ``edit`` and ``delete`` buttons.
- Removed /node directory, and removed symlinks from node_modules.
- Added elasticsearch-dsl and added it alongside Haystack for now.
- Added ``Save and Close`` button to learning resource panel.
- Added tests for listing page.
- Removed lib/ from ``.gitignore``.
- Switched to minimized javascript for libraries.
- Added REST API view to list courses in repository.
- Removed react-addons bower package, addons actually live in react package.
- Fixed pagination links.
- Increased requirejs timeout.

Version 0.10.1
==============

- Fixed exact repository search bug
- Fixed clear export bug


Version 0.10.0
==============

Expand Down
45 changes: 45 additions & 0 deletions apiary.apib
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,51 @@ Create a repository by providing its JSON representation.
"create_date": "2015-06-22"
}

## Group Courses

## Course Collection [/repositories/{repo_slug}/courses/]

### List All Courses [GET]

+ Response 200 (application/json)

{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"org": "MITx",
"course_number": "1.Mech",
"run": "1T2010"
}
]
}

## Course [/repositories/{repo_slug}/courses/{course_id}/]

+ Parameters
+ repo_slug: `physics-1` (string, required) - slug for the repository
+ course_id: `1` (number, required) - ID of the course

### Retrieve a Course [GET]

+ Response 200 (application/json)

{
"id": 1,
"org": "MITx",
"course_number": "1.Mech",
"run": "1T2010"
}

### Delete Course [DELETE]

Deletes a course, all learning resources and static assets in it.

+ Response 204 (application/json)

## Group SearchResults

## SearchResult Collection [/repositories/{repo_slug}/search/{?q,sortby,selected_facets}]
Expand Down
1 change: 0 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"modernizr": "~2.8.3",
"retina.js": "~1.3.0",
"react": "0.13.3",
"react-addons": "0.1.2",
"select2": "~4.0.0",
"select2-bootstrap-theme": "~0.1.0-beta.4",
"lodash": "~3.9.3",
Expand Down
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ web:
build: .
command: >
/bin/bash -c '
sleep 3;
npm install --production;
python manage.py migrate;
sleep 3 &&
npm install --production --no-bin-links &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:$PORT'
volumes:
- .:/src
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
project = u'LORE'
copyright = u'2015, MIT Office of Digital Learning'

version = '0.1'
release = '0.1.0'
version = '0.11.0'
release = '0.11.0'

exclude_patterns = ['_build']
pygments_style = 'sphinx'
Expand Down
7 changes: 6 additions & 1 deletion importer/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
create_static_asset,
get_video_sub,
join_description_paths,
get_resources,
)
from learningresources.models import StaticAsset, course_asset_basepath
from search.utils import index_resources

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -119,7 +121,6 @@ def import_course(bundle, repo_id, user_id, static_dir):
learningresources.models.Course
"""
src = bundle.course

course = create_course(
org=src.attrib["org"],
repo_id=repo_id,
Expand All @@ -130,6 +131,10 @@ def import_course(bundle, repo_id, user_id, static_dir):
import_static_assets(course, static_dir)
import_children(course, src, None, '')
populate_xanalytics_fields.delay(course.id)
# This triggers a bulk indexing of all LearningResource instances
# for the course at once.
index_resources(
get_resources(repo_id).filter(course__id=course.id))
return course


Expand Down
2 changes: 0 additions & 2 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ module.exports = function(config) {

// list of files to exclude from coverage and testing
exclude: [
"ui/static/ui/js/listing.js",
"ui/static/ui/js/csrf.js"
],

// preprocess matching files before serving them to the browser
Expand Down
2 changes: 1 addition & 1 deletion learningresources/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def get_resources(repo_id):
list (list of learningresources.LearningResource): List of resources
"""
return LearningResource.objects.select_related(
"learning_resource_type").filter(
"learning_resource_type", "course__repository").filter(
course__repository__id=repo_id).order_by("title")


Expand Down
5 changes: 5 additions & 0 deletions learningresources/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
update_description_path
)
from learningresources.models import Repository, StaticAsset
from search.utils import clear_index, refresh_index

log = logging.getLogger(__name__)
# Using the md5 hasher speeds up tests.
Expand Down Expand Up @@ -86,6 +87,7 @@ def create_resource(self, **kwargs):
def setUp(self):
"""set up"""
super(LoreTestCase, self).setUp()
clear_index()
self.user = User.objects.create_user(
username=self.USERNAME, password=self.PASSWORD
)
Expand Down Expand Up @@ -123,6 +125,7 @@ def setUp(self):
self.client = Client()

self.login(username=self.USERNAME)
refresh_index()

def tearDown(self):
"""Clean up Elasticsearch and static assets between tests."""
Expand All @@ -131,6 +134,8 @@ def tearDown(self):
for key, _ in haystack.connections.connections_info.items():
haystack.connections.reload(key)
call_command('clear_index', interactive=False, verbosity=0)
clear_index()
refresh_index()

def _make_archive(self, path, make_zip=False, ext=None):
"""
Expand Down
2 changes: 1 addition & 1 deletion learningresources/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def test_static_asset_filename_length(self):
FILE_PATH_MAX_LENGTH -
# minus the length of the base path of the Django storage and
# the base path of the file location temporary dir
len(os.path.join(base_path, temp_dir_path)) -
len('/'.join([base_path, temp_dir_path])) -
# minus 1 for the extra "/" to joint the paths
1
)
Expand Down
13 changes: 9 additions & 4 deletions lore/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from django.core.exceptions import ImproperlyConfigured
import yaml

VERSION = '0.10.1'
VERSION = '0.11.0'

CONFIG_PATHS = [
os.environ.get('LORE_CONFIG', ''),
Expand Down Expand Up @@ -207,7 +207,10 @@ def get_var(name, default):
)
COMPRESS_PRECOMPILERS = (
('text/requirejs', 'requirejs.RequireJSCompiler'),
('text/jsx', 'node_modules/.bin/jsx < {infile} > {outfile}')
(
'text/jsx',
'node node_modules/react-tools/bin/jsx < {infile} > {outfile}'
),
)
COMPRESS_OFFLINE = get_var('LORE_COMPRESS_OFFLINE', False)
COMPRESS_ENABLED = get_var('LORE_COMPRESS_ENABLED', not DEBUG)
Expand Down Expand Up @@ -237,7 +240,9 @@ def get_var(name, default):
if LORE_USE_S3:
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
else:
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
# by default use django.core.files.storage.FileSystemStorage with
# overwrite feature
DEFAULT_FILE_STORAGE = 'storages.backends.overwrite.OverwriteStorage'


# Lore preview settings
Expand Down Expand Up @@ -342,7 +347,7 @@ def get_var(name, default):
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'PAGE_SIZE': 20,
'DEFAULT_PAGINATION_CLASS': 'rest.pagination.LorePagination',
'UPLOADED_FILES_USE_URL': False,
}

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ djangorestframework==3.2.2
dj-database-url==0.3.0
dj-static==0.0.6
elasticsearch==1.6.0
elasticsearch-dsl==0.0.8
git+https://github.com/bpeschier/django-compressor-requirejs@889d5edc4f2acaa961c170084f1171c700649519#egg=githubdjango-compressor-requirejs-develop==0.4.1-odl
psycopg2==2.6.1
PyYAML==3.11
Expand Down
16 changes: 16 additions & 0 deletions rest/pagination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Pagination classes for Lore's REST API.
"""

from __future__ import unicode_literals

from rest_framework.pagination import PageNumberPagination


class LorePagination(PageNumberPagination):
"""
Pagination class for Lore's REST API.
"""
page_size = 20
page_size_query_param = 'page_size'
max_page_size = 1000
17 changes: 17 additions & 0 deletions rest/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,20 @@ def has_permission(self, request, view):
username = view.kwargs['username']

return request.user.username == username


class ImportCoursePermission(BasePermission):
"""
Checks that the user has permission to import a course.
The same permission is used to check if the user can delete a course.
"""
def has_permission(self, request, view):
try:
repo = get_repo(view.kwargs['repo_slug'], request.user.id)
except NotFound:
raise Http404()
except PermissionDenied:
return False
if request.method in SAFE_METHODS:
return True
return RepoPermission.import_course[0] in get_perms(request.user, repo)
18 changes: 18 additions & 0 deletions rest/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from taxonomy.models import Vocabulary, Term
from learningresources.models import (
Repository,
Course,
LearningResource,
StaticAsset,
LearningResourceType,
Expand Down Expand Up @@ -61,6 +62,23 @@ class Meta:
)


class CourseSerializer(ModelSerializer):
"""Serializer for Course."""

class Meta:
# pylint: disable=missing-docstring
model = Course
fields = (
'id',
'org',
'course_number',
'run',
)
read_only_fields = (
'id',
)


class VocabularySerializer(ModelSerializer):
"""Serializer for Vocabulary."""

Expand Down
Loading

0 comments on commit e38fb13

Please sign in to comment.