From cfe553304cb01d55e06e4b9f7de85428b4f61487 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 12:00:05 -0400 Subject: [PATCH 01/32] Removed link to wiki settings until we have a better integration with notifications. --- lms/templates/wiki/includes/article_menu.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lms/templates/wiki/includes/article_menu.html b/lms/templates/wiki/includes/article_menu.html index 5088ae9570..9faab31831 100644 --- a/lms/templates/wiki/includes/article_menu.html +++ b/lms/templates/wiki/includes/article_menu.html @@ -35,6 +35,10 @@ %endif %endfor + +<%doc> +The settings link has been disabled because the notifications app hasn't been integrated yet and those are the only useful settings. + %if not user.is_anonymous():
  • @@ -43,4 +47,6 @@
  • %endif + + From f68a97a63fe314770d00158bc5b3a3f419bea20c Mon Sep 17 00:00:00 2001 From: Kyle Fiedler Date: Tue, 21 Aug 2012 13:54:58 -0400 Subject: [PATCH 02/32] Added changes to wiki 404 and fixed CMS Sass --- cms/static/sass/_base.scss | 5 ++++ lms/static/sass/course/wiki/_wiki.scss | 33 ++++++++++++++++++++++++++ lms/templates/wiki/wiki-404.html | 5 ++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index 7d16f0c6f9..8d14bcff6b 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -14,6 +14,11 @@ $yellow: #fff8af; $cream: #F6EFD4; $border-color: #ddd; +// edX colors +$blue: rgb(29,157,217); +$pink: rgb(182,37,104); + + @mixin hide-text { background-color: transparent; border: 0; diff --git a/lms/static/sass/course/wiki/_wiki.scss b/lms/static/sass/course/wiki/_wiki.scss index 43769c93a6..a666607efb 100644 --- a/lms/static/sass/course/wiki/_wiki.scss +++ b/lms/static/sass/course/wiki/_wiki.scss @@ -767,6 +767,39 @@ section.wiki { text-decoration: none; } } + + .missing { + max-width: 400px; + margin: lh(2) auto; + display: block; + overflow: hidden; + background: $pink; + padding: lh(); + @include box-shadow(inset 0 0 0 1px lighten($pink, 10%)); + border: 1px solid darken($pink, 15%); + + p { + color: #fff; + + a { + display: block; + background: darken($pink, 8%); + margin: lh() (-(lh())) (-(lh())); + padding: lh(); + border-top: 1px solid darken($pink, 15%); + color: #fff; + font-weight: bold; + font-size: em(18); + @include transition; + text-align: center; + -webkit-font-smoothing: antialiased; + + &:hover { + background: darken($pink, 12%); + } + } + } + } } .modal-backdrop { diff --git a/lms/templates/wiki/wiki-404.html b/lms/templates/wiki/wiki-404.html index a18ea3786a..f44937c2e6 100644 --- a/lms/templates/wiki/wiki-404.html +++ b/lms/templates/wiki/wiki-404.html @@ -10,9 +10,8 @@ {% block wiki_contents %} -
    -

    This article was not found, and neither was the parent. Go back to the main wiki article.

    - +
    +

    This article was not found, and neither was its parent article. Go back to the main wiki article

    {% endblock %} From 6ce69e28aefa6386b11109bf2ee28388e2052dee Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 15:58:35 -0400 Subject: [PATCH 03/32] Moved the wiki 404 page into the django-wiki project. --- lms/templates/wiki/wiki-404.html | 17 ----------------- repo-requirements.txt | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 lms/templates/wiki/wiki-404.html diff --git a/lms/templates/wiki/wiki-404.html b/lms/templates/wiki/wiki-404.html deleted file mode 100644 index f44937c2e6..0000000000 --- a/lms/templates/wiki/wiki-404.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends "wiki/base.html" %} -{% load wiki_tags i18n %} -{% load url from future %} - -{% block pagetitle %}{{ article.current_revision.title }}{% endblock %} - -{% block wiki_breadcrumbs %} -{% include "wiki/includes/breadcrumbs.html" %} -{% endblock %} - -{% block wiki_contents %} - -
    -

    This article was not found, and neither was its parent article. Go back to the main wiki article

    -
    - -{% endblock %} diff --git a/repo-requirements.txt b/repo-requirements.txt index 5b50034039..1f7b1b6470 100644 --- a/repo-requirements.txt +++ b/repo-requirements.txt @@ -1,5 +1,5 @@ -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline --e git://github.com/benjaoming/django-wiki.git@e237b2ac#egg=django-wiki +-e git://github.com/benjaoming/django-wiki.git@876357a#egg=django-wiki -e common/lib/capa -e common/lib/xmodule From 954ee6ab1f46d1c8ac10c113fad4a859fe41ac98 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 17:09:24 -0400 Subject: [PATCH 04/32] Added link to list children of an article. Upgraded django-wiki version. --- lms/templates/wiki/article.html | 6 +++++- repo-requirements.txt | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lms/templates/wiki/article.html b/lms/templates/wiki/article.html index 7175219f74..57b97edc6b 100644 --- a/lms/templates/wiki/article.html +++ b/lms/templates/wiki/article.html @@ -14,7 +14,11 @@
    {% if selected_tab != "edit" %} -

    {{ article.current_revision.title }}

    +

    {{ article.current_revision.title }}

    + + {% if urlpath %} + Show all children + {% endif %} {% endif %} {% block wiki_contents_tab %} diff --git a/repo-requirements.txt b/repo-requirements.txt index 1f7b1b6470..8fc80ab9b3 100644 --- a/repo-requirements.txt +++ b/repo-requirements.txt @@ -1,5 +1,5 @@ -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline --e git://github.com/benjaoming/django-wiki.git@876357a#egg=django-wiki +-e git://github.com/benjaoming/django-wiki.git@221fca1#egg=django-wiki -e common/lib/capa -e common/lib/xmodule From 41831654ee767c925b1d49f9a35c3845426009db Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 17:44:38 -0400 Subject: [PATCH 05/32] Added link to see wiki attachment history. --- lms/templates/wiki/plugins/attachments/index.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lms/templates/wiki/plugins/attachments/index.html b/lms/templates/wiki/plugins/attachments/index.html index d448392933..464a63e5fe 100644 --- a/lms/templates/wiki/plugins/attachments/index.html +++ b/lms/templates/wiki/plugins/attachments/index.html @@ -115,7 +115,13 @@ {% if attachment.current_revision.user %}{{ attachment.current_revision.user }}{% else %}{% if user|is_moderator %}{{ attachment.current_revision.ip_address|default:"anonymous (IP not logged)" }}{% else %}{% trans "anonymous (IP logged)" %}{% endif %}{% endif %} {{ attachment.current_revision.get_size|filesizeformat }} - {{ attachment.attachmentrevision_set.all.count }} {% trans "revisions" %} + + + + + {% trans "File history" %} ({{ attachment.attachmentrevision_set.all.count }} {% trans "revisions" %}) + +
    From 82d414690be471180898fb5d038e8dcc326b4060 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 22:23:40 -0400 Subject: [PATCH 06/32] Updated to latest version of django-wiki with lots of deletion fixes. Removed child article list until it can be styled. --- lms/templates/wiki/article.html | 3 ++ lms/templates/wiki/delete.html | 62 --------------------------------- repo-requirements.txt | 2 +- 3 files changed, 4 insertions(+), 63 deletions(-) delete mode 100644 lms/templates/wiki/delete.html diff --git a/lms/templates/wiki/article.html b/lms/templates/wiki/article.html index 57b97edc6b..b524eb8d06 100644 --- a/lms/templates/wiki/article.html +++ b/lms/templates/wiki/article.html @@ -16,9 +16,12 @@ {% if selected_tab != "edit" %}

    {{ article.current_revision.title }}

    + {% comment %} + This has been disabled until we can style it. {% if urlpath %} Show all children {% endif %} + {% endcomment %} {% endif %} {% block wiki_contents_tab %} diff --git a/lms/templates/wiki/delete.html b/lms/templates/wiki/delete.html deleted file mode 100644 index acabb79aad..0000000000 --- a/lms/templates/wiki/delete.html +++ /dev/null @@ -1,62 +0,0 @@ -{% extends "wiki/base.html" %} -{% load wiki_tags i18n sekizai_tags %} -{% load url from future %} - -{% block pagetitle %}{% trans "Delete article" %}{% endblock %} - -{% block wiki_contents %} -

    {% trans "Delete" %} "{{ article.current_revision.title }}"

    - - {% if cannot_delete_root %} -

    {% trans "You cannot delete a root article." %}

    -

    {% trans "Go back" %}

    - {% else %} - - {% if cannot_delete_children %} - -

    {% trans "You cannot delete this article because you do not have permission to delete articles with children. Try to remove the children manually one-by-one." %}

    - - {% endif %} - - {% if delete_children %} - -

    {% trans "You are deleting an article. This means that its children will be deleted as well. If you choose to purge, children will also be purged!" %}

    - -

    {% trans "Articles that will be deleted" %}

    - -
      - {% for child in delete_children %} -
    • {{ child.article }}
    • - {% if delete_children_more %} -
    • {% trans "...and more!" %}
    • - {% endif %} - {% endfor %} -
    - - {% endif %} - - {% if not cannot_delete_children %} -

    {% trans "You are deleting an article. Please confirm." %}

    - -
    - {% wiki_form delete_form %} - -
    - - - {% trans "Go back" %} - - -
    -
    - {% endif %} - - {% endif %} - -{% endblock %} - diff --git a/repo-requirements.txt b/repo-requirements.txt index 8fc80ab9b3..5e385ec3e6 100644 --- a/repo-requirements.txt +++ b/repo-requirements.txt @@ -1,5 +1,5 @@ -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline --e git://github.com/benjaoming/django-wiki.git@221fca1#egg=django-wiki +-e git://github.com/benjaoming/django-wiki.git@32416cd1e#egg=django-wiki -e common/lib/capa -e common/lib/xmodule From 9e81ea3981553463ea193baf1906e0fbb5347f09 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 22:31:13 -0400 Subject: [PATCH 07/32] Added instructor tabs to wiki course nav. --- lms/djangoapps/course_wiki/course_nav.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lms/djangoapps/course_wiki/course_nav.py b/lms/djangoapps/course_wiki/course_nav.py index 1d124972c7..122f9ebb54 100644 --- a/lms/djangoapps/course_wiki/course_nav.py +++ b/lms/djangoapps/course_wiki/course_nav.py @@ -5,6 +5,7 @@ from django.http import Http404 from django.shortcuts import redirect from wiki.models import reverse as wiki_reverse +from courseware.access import has_access from courseware.courses import get_course_with_access @@ -135,7 +136,9 @@ def context_processor(request): try: course = get_course_with_access(request.user, course_id, 'load') - return {'course' : course} + staff_access = has_access(request.user, course, 'staff') + return {'course' : course, + 'staff_access': staff_access} except Http404: # We couldn't access the course for whatever reason. It is too late to change # the URL here, so we just leave the course context. The middleware shouldn't From c77d71870330e61cfd9570f4c1b5debbca06ce34 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 22:58:07 -0400 Subject: [PATCH 08/32] Updated django-wiki with delete article bug. --- repo-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo-requirements.txt b/repo-requirements.txt index baf63161a4..832bbce73d 100644 --- a/repo-requirements.txt +++ b/repo-requirements.txt @@ -1,6 +1,6 @@ -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline --e git://github.com/benjaoming/django-wiki.git@32416cd1e#egg=django-wiki +-e git://github.com/benjaoming/django-wiki.git@c43257488e#egg=django-wiki -e git://github.com/dementrock/pystache_custom.git@776973740bdaad83a3b029f96e415a7d1e8bec2f#egg=pystache_custom-dev -e common/lib/capa -e common/lib/xmodule From 9162bdb1b9809c8eaeb9619160386d4dba8a1cf4 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 23:06:45 -0400 Subject: [PATCH 09/32] Changed wiki setting so article owners can't change permissions. --- lms/envs/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lms/envs/common.py b/lms/envs/common.py index a217f0e7b9..c99423c7a1 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -318,6 +318,7 @@ WIKI_ACCOUNT_HANDLING = False WIKI_EDITOR = 'course_wiki.editors.CodeMirror' WIKI_SHOW_MAX_CHILDREN = 0 # We don't use the little menu that shows children of an article in the breadcrumb WIKI_ANONYMOUS = False # Don't allow anonymous access until the styling is figured out +WIKI_CAN_CHANGE_PERMISSIONS = lambda article, user: user.has_perm('wiki.assign') ################################# Jasmine ################################### JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/static/coffee' From eb62b80fca1943fb294bebf487789ae2b8046695 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Tue, 21 Aug 2012 23:46:26 -0400 Subject: [PATCH 10/32] Updated django-wiki with another deletion bug fix. --- repo-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo-requirements.txt b/repo-requirements.txt index 832bbce73d..750ef66920 100644 --- a/repo-requirements.txt +++ b/repo-requirements.txt @@ -1,6 +1,6 @@ -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline --e git://github.com/benjaoming/django-wiki.git@c43257488e#egg=django-wiki +-e git://github.com/benjaoming/django-wiki.git@a8dbb5f#egg=django-wiki -e git://github.com/dementrock/pystache_custom.git@776973740bdaad83a3b029f96e415a7d1e8bec2f#egg=pystache_custom-dev -e common/lib/capa -e common/lib/xmodule From a285d1a60e3fb587682f17ab4fe8844b4bf9fb3c Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Wed, 22 Aug 2012 00:07:37 -0400 Subject: [PATCH 11/32] Updated wiki preview template and django-wiki version. --- lms/templates/wiki/preview_inline.html | 17 +++++++++++++---- repo-requirements.txt | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lms/templates/wiki/preview_inline.html b/lms/templates/wiki/preview_inline.html index 9248454137..a5c6668d16 100644 --- a/lms/templates/wiki/preview_inline.html +++ b/lms/templates/wiki/preview_inline.html @@ -10,22 +10,31 @@
    {% if revision %}
    - {% trans "Previewing revision" %}: {{ revision.created }} (#{{ revision.revision_number }}) by {% if revision.user %}{{ revision.user }}{% else %}{% if user|is_moderator %}{{ revision.ip_address|default:"anonymous (IP not logged)" }}{% else %}{% trans "anonymous (IP logged)" %}{% endif %}{% endif %} + {% trans "Previewing revision" %}: + {% include "wiki/includes/revision_info.html" %}
    {% endif %} {% if merge %}
    {% trans "Previewing merge between" %}: - {{ merge1.created }} (#{{ merge1.revision_number }}) by {% if merge1.user %}{{ merge1.user }}{% else %}{% if user|is_moderator %}{{ merge1.ip_address|default:"anonymous (IP not logged)" }}{% else %}{% trans "anonymous (IP logged)" %}{% endif %}{% endif %} + {% include "wiki/includes/revision_info.html" with revision=merge1 %} {% trans "and" %} - {{ merge1.created }} (#{{ merge1.revision_number }}) by {% if merge1.user %}{{ merge1.user }}{% else %}{% if user|is_moderator %}{{ merge1.ip_address|default:"anonymous (IP not logged)" }}{% else %}{% trans "anonymous (IP logged)" %}{% endif %}{% endif %} + {% include "wiki/includes/revision_info.html" with revision=merge2 %}
    {% endif %}

    {{ title }}

    - {% wiki_render article content %} + {% if revision and revision.deleted %} +
    + This revision has been deleted. +

    Restoring to this revision will mark the article as deleted.

    +
    + {% else %} + {% wiki_render article content %} + {% endif %} +
    diff --git a/repo-requirements.txt b/repo-requirements.txt index 750ef66920..eaba29c197 100644 --- a/repo-requirements.txt +++ b/repo-requirements.txt @@ -1,6 +1,6 @@ -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline --e git://github.com/benjaoming/django-wiki.git@a8dbb5f#egg=django-wiki +-e git://github.com/benjaoming/django-wiki.git@9865b5c#egg=django-wiki -e git://github.com/dementrock/pystache_custom.git@776973740bdaad83a3b029f96e415a7d1e8bec2f#egg=pystache_custom-dev -e common/lib/capa -e common/lib/xmodule From 723519ee74dad270fe7453174072dd6a9d23af58 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Wed, 22 Aug 2012 00:55:03 -0400 Subject: [PATCH 12/32] Removed wiki/settings.html so the default one will be used. --- lms/templates/wiki/settings.html | 52 -------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 lms/templates/wiki/settings.html diff --git a/lms/templates/wiki/settings.html b/lms/templates/wiki/settings.html deleted file mode 100644 index a932a26498..0000000000 --- a/lms/templates/wiki/settings.html +++ /dev/null @@ -1,52 +0,0 @@ -{% extends "wiki/base.html" %} -{% load wiki_tags i18n %} -{% load url from future %} - -{% block pagetitle %}{% trans "Settings" %}: {{ article.current_revision.title }}{% endblock %} - -{% block wiki_breadcrumbs %} - {% include "wiki/includes/breadcrumbs.html" %} -{% endblock %} - -{% block wiki_contents %} - -
    -
    - {% if selected_tab != "edit" %} -

    {{ article.current_revision.title }}

    - {% endif %} - - {% for form in forms %} -
    -

    {{ form.settings_form_headline }}

    -
    - {% wiki_form form %} -
    -
    - -
    -
    - {% endfor %} -
    - - - - -
    -
    - {% trans "Last modified:" %}
    - {{ article.current_revision.modified }} -
    - -
    -
    - -{% endblock %} - From 0b6bf77373fe9aec22c7be46329f625ccad2d031 Mon Sep 17 00:00:00 2001 From: Arjun Singh Date: Wed, 22 Aug 2012 04:58:30 -0700 Subject: [PATCH 13/32] Adding a course-specific css class to body so that we can have course-targeted styles as a last resort --- common/lib/xmodule/xmodule/course_module.py | 4 ++++ lms/templates/courseware/courseware.html | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index 5cc4a09165..5eeb5ee11c 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -197,6 +197,10 @@ class CourseDescriptor(SequenceDescriptor): def start_date_text(self): return time.strftime("%b %d, %Y", self.start) + @property + def css_class(self): + return self.metadata.get('css_class', '') + @property def title(self): return self.display_name diff --git a/lms/templates/courseware/courseware.html b/lms/templates/courseware/courseware.html index 02149ec463..3f6588420a 100644 --- a/lms/templates/courseware/courseware.html +++ b/lms/templates/courseware/courseware.html @@ -1,6 +1,6 @@ <%inherit file="/main.html" /> <%namespace name='static' file='/static_content.html'/> -<%block name="bodyclass">courseware +<%block name="bodyclass">courseware ${course.css_class} <%block name="title">${course.number} Courseware <%block name="headextra"> From 9a21c5d4a8dadc9af882f579df5fde52b22bcb51 Mon Sep 17 00:00:00 2001 From: Arjun Singh Date: Wed, 22 Aug 2012 05:00:11 -0700 Subject: [PATCH 14/32] Adding reasoning for adding a new metadata field --- common/lib/xmodule/xmodule/course_module.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index 5eeb5ee11c..4e799a6f0d 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -197,6 +197,10 @@ class CourseDescriptor(SequenceDescriptor): def start_date_text(self): return time.strftime("%b %d, %Y", self.start) + # An extra property is used rather than the wiki_slug/number because + # there are courses that change the number for different runs. This allows + # courses to share the same css_class across runs even if they have + # different numbers. @property def css_class(self): return self.metadata.get('css_class', '') From 03248cc3241bf59787de3c95a08b113efab6a332 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Wed, 22 Aug 2012 10:09:06 -0400 Subject: [PATCH 15/32] Updated django-wiki. --- repo-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo-requirements.txt b/repo-requirements.txt index eaba29c197..787b504269 100644 --- a/repo-requirements.txt +++ b/repo-requirements.txt @@ -1,6 +1,6 @@ -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline --e git://github.com/benjaoming/django-wiki.git@9865b5c#egg=django-wiki +-e git://github.com/benjaoming/django-wiki.git@6ccd08e#egg=django-wiki -e git://github.com/dementrock/pystache_custom.git@776973740bdaad83a3b029f96e415a7d1e8bec2f#egg=pystache_custom-dev -e common/lib/capa -e common/lib/xmodule From 96f0f7cbde9f8756722526d738660086d80a85b6 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Wed, 22 Aug 2012 11:36:06 -0400 Subject: [PATCH 16/32] Changed default contents of new course wiki. --- lms/djangoapps/course_wiki/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/djangoapps/course_wiki/views.py b/lms/djangoapps/course_wiki/views.py index cfe802bbd7..aa0b286aa6 100644 --- a/lms/djangoapps/course_wiki/views.py +++ b/lms/djangoapps/course_wiki/views.py @@ -81,7 +81,7 @@ def course_wiki_redirect(request, course_id): root, course_slug, title=course.number, - content="{0}\n===\nThis is the wiki for **{1}**'s _{2}_.".format(course.number, course.org, course.title), + content="This is the wiki for **{0}**'s _{1}_.".format(course.org, course.title), user_message="Course page automatically created.", user=None, ip_address=None, From 390823bdea103e2a729b399c48519bd1783da6df Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Wed, 22 Aug 2012 11:37:01 -0400 Subject: [PATCH 17/32] Added django-wiki's requirements to requirements.txt, because they weren't being included automatically. --- requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c5cafe64b8..72b13e63ba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ django>=1.4,<1.5 pip numpy scipy -markdown +Markdown<2.3.0 pygments lxml boto @@ -43,5 +43,7 @@ django-ses django-storages django-threaded-multihost django-sekizai<0.7 +django-mptt>=0.5.3 +sorl-thumbnail networkx -r repo-requirements.txt From edefa04de108c4aa7e3d927e1cdc0847a2ebbc24 Mon Sep 17 00:00:00 2001 From: kimth Date: Wed, 22 Aug 2012 12:41:30 -0400 Subject: [PATCH 18/32] Workaround for 500 on showanswer for choiceresponse --- common/lib/capa/capa/responsetypes.py | 2 +- common/lib/xmodule/xmodule/capa_module.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index cc67389da9..b2d56b48ca 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -557,7 +557,7 @@ class ChoiceResponse(LoncapaResponse): return CorrectMap(self.answer_id, 'incorrect') def get_answers(self): - return {self.answer_id: self.correct_choices} + return {self.answer_id: list(self.correct_choices)} #----------------------------------------------------------------------------- diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index e6da87b5c6..d2ed3912a4 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -390,9 +390,19 @@ class CapaModule(XModule): raise NotFoundError('Answer is not available') else: answers = self.lcp.get_question_answers() + # answers (eg ) may have embedded images - answers = dict( (k,self.system.replace_urls(answers[k], self.metadata['data_dir'])) for k in answers ) - return {'answers': answers} + # but be careful, some problems are using non-string answer dicts + new_answers = dict() + for answer_id in answers: + try: + new_answer = {answer_id: self.system.replace_urls(answers[answer_id], self.metadata['data_dir'])} + except TypeError: + log.debug('Unable to perform URL substitution on answers[%s]: %s' % (answer_id, answers[answer_id])) + new_answer = {answer_id: answers[answer_id]} + new_answers.update(new_answer) + + return {'answers': new_answers} # Figure out if we should move these to capa_problem? def get_problem(self, get): From 3796bb4a124acb2fe74e9e0dcf1e043dabf449e7 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Wed, 22 Aug 2012 12:42:03 -0400 Subject: [PATCH 19/32] Changed title of default root wiki page to just be Wiki. --- lms/djangoapps/course_wiki/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/djangoapps/course_wiki/views.py b/lms/djangoapps/course_wiki/views.py index aa0b286aa6..e754e1cdcd 100644 --- a/lms/djangoapps/course_wiki/views.py +++ b/lms/djangoapps/course_wiki/views.py @@ -114,7 +114,7 @@ def get_or_create_root(): "===", "Visit a course wiki to add an article.")) - root = URLPath.create_root(title="edX Wiki", + root = URLPath.create_root(title="Wiki", content=starting_content) article = root.article article.group = None From 7b4c86e55cd01880bb4c6446fdfad1d93d87b91c Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Wed, 22 Aug 2012 12:42:21 -0400 Subject: [PATCH 20/32] Updated django-wiki with bug fix. --- repo-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo-requirements.txt b/repo-requirements.txt index 787b504269..6e2572a732 100644 --- a/repo-requirements.txt +++ b/repo-requirements.txt @@ -1,6 +1,6 @@ -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline --e git://github.com/benjaoming/django-wiki.git@6ccd08e#egg=django-wiki +-e git://github.com/benjaoming/django-wiki.git@afdd97d#egg=django-wiki -e git://github.com/dementrock/pystache_custom.git@776973740bdaad83a3b029f96e415a7d1e8bec2f#egg=pystache_custom-dev -e common/lib/capa -e common/lib/xmodule From 365495521e0fb81668c307d97239f79179a2d59a Mon Sep 17 00:00:00 2001 From: Victor Shnayder Date: Wed, 22 Aug 2012 12:58:46 -0400 Subject: [PATCH 21/32] Catch errors in module load * if error is in xmodule_constructor(), catch and return an ErrorModule * if error is somewhere else in get_module(), return None --- common/lib/xmodule/xmodule/error_module.py | 29 ++++++++++++- lms/djangoapps/courseware/access.py | 1 - lms/djangoapps/courseware/module_render.py | 47 ++++++++++++++++++---- lms/templates/module-error.html | 15 +++++-- 4 files changed, 80 insertions(+), 12 deletions(-) diff --git a/common/lib/xmodule/xmodule/error_module.py b/common/lib/xmodule/xmodule/error_module.py index bdd7179a0a..f8e2467910 100644 --- a/common/lib/xmodule/xmodule/error_module.py +++ b/common/lib/xmodule/xmodule/error_module.py @@ -15,18 +15,39 @@ from xmodule.errortracker import exc_info_to_str log = logging.getLogger(__name__) +# NOTE: This is not the most beautiful design in the world, but there's no good +# way to tell if the module is being used in a staff context or not. Errors that get discovered +# at course load time are turned into ErrorDescriptor objects, and automatically hidden from students. +# Unfortunately, we can also have errors when loading modules mid-request, and then we need to decide +# what to show, and the logic for that belongs in the LMS (e.g. in get_module), so the error handler +# decides whether to create a staff or not-staff module. + class ErrorModule(XModule): def get_html(self): - '''Show an error. + '''Show an error to staff. TODO (vshnayder): proper style, divs, etc. ''' # staff get to see all the details return self.system.render_template('module-error.html', { + 'staff_access' : True, 'data' : self.definition['data']['contents'], 'error' : self.definition['data']['error_msg'], }) +class NonStaffErrorModule(XModule): + def get_html(self): + '''Show an error to a student. + TODO (vshnayder): proper style, divs, etc. + ''' + # staff get to see all the details + return self.system.render_template('module-error.html', { + 'staff_access' : False, + 'data' : "", + 'error' : "", + }) + + class ErrorDescriptor(EditingDescriptor): """ Module that provides a raw editing view of broken xml. @@ -99,3 +120,9 @@ class ErrorDescriptor(EditingDescriptor): err_node = etree.SubElement(root, 'error_msg') err_node.text = self.definition['data']['error_msg'] return etree.tostring(root) + +class NonStaffErrorDescriptor(ErrorDescriptor): + """ + Module that provides non-staff error messages. + """ + module_class = NonStaffErrorModule diff --git a/lms/djangoapps/courseware/access.py b/lms/djangoapps/courseware/access.py index 281580cf33..dbe4ff376d 100644 --- a/lms/djangoapps/courseware/access.py +++ b/lms/djangoapps/courseware/access.py @@ -13,7 +13,6 @@ from xmodule.modulestore import Location from xmodule.timeparse import parse_time from xmodule.x_module import XModule, XModuleDescriptor - DEBUG_ACCESS = False log = logging.getLogger(__name__) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 65e30475f2..7967452647 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -1,5 +1,6 @@ import json import logging +import sys from django.conf import settings from django.contrib.auth.models import User @@ -15,10 +16,12 @@ from courseware.access import has_access from mitxmako.shortcuts import render_to_string from models import StudentModule, StudentModuleCache from static_replace import replace_urls +from xmodule.errortracker import exc_info_to_str from xmodule.exceptions import NotFoundError from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore from xmodule.x_module import ModuleSystem +from xmodule.error_module import ErrorDescriptor, NonStaffErrorDescriptor from xmodule_modifiers import replace_course_urls, replace_static_urls, add_histogram, wrap_xmodule log = logging.getLogger("mitx.courseware") @@ -73,6 +76,8 @@ def toc_for_course(user, request, course, active_chapter, active_section, course student_module_cache = StudentModuleCache.cache_for_descriptor_descendents( course_id, user, course, depth=2) course = get_module(user, request, course.location, student_module_cache, course_id) + if course is None: + return None chapters = list() for chapter in course.get_display_items(): @@ -131,9 +136,9 @@ def get_section(course_module, chapter, section): return section_module - def get_module(user, request, location, student_module_cache, course_id, position=None): - ''' Get an instance of the xmodule class identified by location, + """ + Get an instance of the xmodule class identified by location, setting the state based on an existing StudentModule, or creating one if none exists. @@ -146,9 +151,22 @@ def get_module(user, request, location, student_module_cache, course_id, positio - position : extra information from URL for user-specified position within module - Returns: xmodule instance + Returns: xmodule instance, or None if the user does not have access to the + module. If there's an error, will try to return an instance of ErrorModule + if possible. If not possible, return None. + """ + try: + return _get_module(user, request, location, student_module_cache, course_id, position) + except: + # Something has gone terribly wrong, but still not letting it turn into a 500. + log.exception("Error in get_module") + return None - ''' +def _get_module(user, request, location, student_module_cache, course_id, position=None): + """ + Actually implement get_module. See docstring there for details. + """ + location = Location(location) descriptor = modulestore().get_instance(course_id, location) # Short circuit--if the user shouldn't have access, bail without doing any work @@ -198,7 +216,7 @@ def get_module(user, request, location, student_module_cache, course_id, positio 'callback_url': xqueue_callback_url, 'default_queuename': xqueue_default_queuename.replace(' ', '_')} - def _get_module(location): + def inner_get_module(location): """ Delegate to get_module. It does an access check, so may return None """ @@ -214,7 +232,7 @@ def get_module(user, request, location, student_module_cache, course_id, positio xqueue=xqueue, # TODO (cpennington): Figure out how to share info between systems filestore=descriptor.system.resources_fs, - get_module=_get_module, + get_module=inner_get_module, user=user, # TODO (cpennington): This should be removed when all html from # a module is coming through get_html and is therefore covered @@ -226,7 +244,22 @@ def get_module(user, request, location, student_module_cache, course_id, positio system.set('position', position) system.set('DEBUG', settings.DEBUG) - module = descriptor.xmodule_constructor(system)(instance_state, shared_state) + try: + module = descriptor.xmodule_constructor(system)(instance_state, shared_state) + except: + log.exception("Error creating module from descriptor {0}".format(descriptor)) + + # make an ErrorDescriptor -- assuming that the descriptor's system is ok + import_system = descriptor.system + if has_access(user, location, 'staff'): + err_descriptor = ErrorDescriptor.from_xml(str(descriptor), import_system, + error_msg=exc_info_to_str(sys.exc_info())) + else: + err_descriptor = NonStaffErrorDescriptor.from_xml(str(descriptor), import_system, + error_msg=exc_info_to_str(sys.exc_info())) + + # Make an error module + return err_descriptor.xmodule_constructor(system)(None, None) module.get_html = replace_static_urls( wrap_xmodule(module.get_html, module, 'xmodule_display.html'), diff --git a/lms/templates/module-error.html b/lms/templates/module-error.html index 2a51f5b11a..8855c5be48 100644 --- a/lms/templates/module-error.html +++ b/lms/templates/module-error.html @@ -2,10 +2,19 @@

    There has been an error on the MITx servers

    We're sorry, this module is temporarily unavailable. Our staff is working to fix it as soon as possible. Please email us at technical@mitx.mit.edu to report any problems or downtime.

    -

    Details below:

    +% if staff_access: +

    Details

    -

    Error: ${error | h}

    +

    Error: +

    +${error | h}
    +
    +

    -

    Raw data: ${data | h}

    +

    Raw data: +

    ${data | h}
    +

    + +% endif From ce0bc1f7825d8f466ff0fcbe49a2715c6e7cb2a5 Mon Sep 17 00:00:00 2001 From: Victor Shnayder Date: Wed, 22 Aug 2012 13:18:33 -0400 Subject: [PATCH 22/32] Separate caches per-domain-name --- common/djangoapps/util/cache.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/djangoapps/util/cache.py b/common/djangoapps/util/cache.py index 85b8ed3369..89b5dffd5e 100644 --- a/common/djangoapps/util/cache.py +++ b/common/djangoapps/util/cache.py @@ -9,6 +9,7 @@ from functools import wraps from django.core import cache + # If we can't find a 'general' CACHE defined in settings.py, we simply fall back # to returning the default cache. This will happen with dev machines. try: @@ -41,7 +42,10 @@ def cache_if_anonymous(view_func): def _decorated(request, *args, **kwargs): if not request.user.is_authenticated(): #Use the cache - cache_key = "cache_if_anonymous." + request.path + # same view accessed through different domain names may + # return different things, so include the domain name in the key. + domain = str(request.META.get('HTTP_HOST')) + '.' + cache_key = domain + "cache_if_anonymous." + request.path response = cache.get(cache_key) if not response: response = view_func(request, *args, **kwargs) From 02f29c22c92aac3b3df47951d17043c16ad301fe Mon Sep 17 00:00:00 2001 From: Kyle Fiedler Date: Wed, 22 Aug 2012 13:41:20 -0400 Subject: [PATCH 23/32] Added stsyles for toc --- lms/static/sass/course/wiki/_wiki.scss | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lms/static/sass/course/wiki/_wiki.scss b/lms/static/sass/course/wiki/_wiki.scss index 9abe349119..e122a6f871 100644 --- a/lms/static/sass/course/wiki/_wiki.scss +++ b/lms/static/sass/course/wiki/_wiki.scss @@ -199,6 +199,17 @@ section.wiki { font-size: 0.9em; font-family: Monaco, monospace; } + + .toc { + border: 1px solid #ccc; + background-color: $sidebar-color; + padding: 20px; + margin: 10px 0; + + ul { + margin: 0; + } + } } From 82bab71ccf8e60a632852593f9831d4fb8006888 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 22 Aug 2012 14:05:12 -0400 Subject: [PATCH 24/32] First pass at branding the header logo on subdomains --- lms/djangoapps/branding/__init__.py | 42 ++++++++++++++++++++ lms/djangoapps/courseware/courses.py | 21 +++------- lms/envs/common.py | 14 ++++++- lms/envs/dev.py | 24 +++++++++++ lms/static/images/BerkeleyX-on-edx-logo.png | Bin 0 -> 5011 bytes lms/static/sass/shared/_header.scss | 7 +--- lms/templates/footer.html | 2 +- lms/templates/name_changes.html | 1 - lms/templates/navigation.html | 9 ++++- lms/templates/textbook.html | 10 ----- 10 files changed, 92 insertions(+), 38 deletions(-) create mode 100644 lms/djangoapps/branding/__init__.py create mode 100644 lms/static/images/BerkeleyX-on-edx-logo.png delete mode 100644 lms/templates/textbook.html diff --git a/lms/djangoapps/branding/__init__.py b/lms/djangoapps/branding/__init__.py new file mode 100644 index 0000000000..a19cff4d51 --- /dev/null +++ b/lms/djangoapps/branding/__init__.py @@ -0,0 +1,42 @@ + +from xmodule.modulestore.django import modulestore +from xmodule.course_module import CourseDescriptor +from django.conf import settings + + +def get_subdomain(domain): + return domain.split(".")[0] + + +def get_visible_courses(domain=None): + """ + Return the set of CourseDescriptors that should be visible in this branded instance + """ + courses = [c for c in modulestore().get_courses() + if isinstance(c, CourseDescriptor)] + courses = sorted(courses, key=lambda course: course.number) + + if domain and settings.MITX_FEATURES.get('SUBDOMAIN_COURSE_LISTINGS'): + subdomain = get_subdomain(domain) + if subdomain not in settings.COURSE_LISTINGS: + subdomain = 'default' + visible_ids = frozenset(settings.COURSE_LISTINGS[subdomain]) + return [course for course in courses if course.id in visible_ids] + else: + return courses + + +def get_logo_url(domain=None): + """ + Return the url for the branded logo image to be used + """ + if not settings.MITX_FEATURES['SUBDOMAIN_BRANDING'] or domain is None: + return '/static/images/header-logo.png' + + subdomain = get_subdomain(domain) + if subdomain not in settings.SUBDOMAIN_BRANDING: + return '/static/images/header-logo.png' + + return '/static/images/{uni}-on-edx-logo.png'.format( + uni=settings.SUBDOMAIN_BRANDING[subdomain] + ) diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index c92cbb1425..e5ef915e25 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -13,6 +13,7 @@ from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError from static_replace import replace_urls, try_staticfiles_lookup from courseware.access import has_access +import branding log = logging.getLogger(__name__) @@ -141,9 +142,10 @@ def get_course_info_section(course, section_key): raise KeyError("Invalid about key " + str(section_key)) + # TODO: Fix this such that these are pulled in as extra course-specific tabs. # arjun will address this by the end of October if no one does so prior to -# then. +# then. def get_course_syllabus_section(course, section_key): """ This returns the snippet of html to be rendered on the syllabus page, @@ -178,24 +180,11 @@ def get_courses_by_university(user, domain=None): ''' # TODO: Clean up how 'error' is done. # filter out any courses that errored. - courses = [c for c in modulestore().get_courses() - if isinstance(c, CourseDescriptor)] - courses = sorted(courses, key=lambda course: course.number) - - if domain and settings.MITX_FEATURES.get('SUBDOMAIN_COURSE_LISTINGS'): - subdomain = domain.split(".")[0] - if subdomain not in settings.COURSE_LISTINGS: - subdomain = 'default' - visible_courses = frozenset(settings.COURSE_LISTINGS[subdomain]) - else: - visible_courses = frozenset(c.id for c in courses) + visible_courses = branding.get_visible_courses(domain) universities = defaultdict(list) - for course in courses: + for course in visible_courses: if not has_access(user, course, 'see_exists'): continue - if course.id not in visible_courses: - continue universities[course.org].append(course) return universities - diff --git a/lms/envs/common.py b/lms/envs/common.py index c99423c7a1..1cc6ae8d89 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -55,9 +55,14 @@ MITX_FEATURES = { # course_ids (see dev_int.py for an example) 'SUBDOMAIN_COURSE_LISTINGS' : False, + # When True, will override certain branding with university specific values + # Expects a SUBDOMAIN_BRANDING dictionary that maps the subdomain to the + # university to use for branding purposes + 'SUBDOMAIN_BRANDING': False, + # TODO: This will be removed once course-specific tabs are in place. see # courseware/courses.py - 'ENABLE_SYLLABUS' : True, + 'ENABLE_SYLLABUS' : True, 'ENABLE_TEXTBOOK' : True, 'ENABLE_DISCUSSION' : False, @@ -66,7 +71,7 @@ MITX_FEATURES = { 'ENABLE_SQL_TRACKING_LOGS': False, 'ENABLE_LMS_MIGRATION': False, - 'DISABLE_LOGIN_BUTTON': False, # used in systems where login is automatic, eg MIT SSL + 'DISABLE_LOGIN_BUTTON': False, # used in systems where login is automatic, eg MIT SSL # extrernal access methods 'ACCESS_REQUIRE_STAFF_FOR_COURSE': False, @@ -199,6 +204,11 @@ COURSE_SETTINGS = {'6.002x_Fall_2012': {'number' : '6.002x', # TODO (vshnayder): Will probably need to change as we get real access control in. LMS_MIGRATION_ALLOWED_IPS = [] +######################## subdomain specific settings ########################### +COURSE_LISTINGS = {} +SUBDOMAIN_BRANDING = {} + + ############################### XModule Store ################################## MODULESTORE = { 'default': { diff --git a/lms/envs/dev.py b/lms/envs/dev.py index b269d293dd..d798815543 100644 --- a/lms/envs/dev.py +++ b/lms/envs/dev.py @@ -15,6 +15,8 @@ TEMPLATE_DEBUG = True MITX_FEATURES['DISABLE_START_DATES'] = True MITX_FEATURES['ENABLE_SQL_TRACKING_LOGS'] = True +MITX_FEATURES['SUBDOMAIN_COURSE_LISTINGS'] = True +MITX_FEATURES['SUBDOMAIN_BRANDING'] = True WIKI_ENABLED = True @@ -68,6 +70,28 @@ CACHE_TIMEOUT = 0 # Dummy secret key for dev SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd' +COURSE_LISTINGS = { + 'default': ['BerkeleyX/CS169.1x/2012_Fall', + 'BerkeleyX/CS188.1x/2012_Fall', + 'HarvardX/CS50x/2012', + 'HarvardX/PH207x/2012_Fall', + 'MITx/3.091x/2012_Fall', + 'MITx/6.002x/2012_Fall', + 'MITx/6.00x/2012_Fall'], + 'berkeley': ['BerkeleyX/CS169.1x/Cal_2012_Fall', + 'BerkeleyX/CS188.1x/Cal_2012_Fall'], + 'harvard': ['HarvardX/CS50x/2012H'], + 'mit': [], + 'sjsu': ['MITx/6.002x-EE98/2012_Fall_SJSU'], +} + +SUBDOMAIN_BRANDING = { + 'sjsu': 'MITx', + 'mit': 'MITx', + 'berkeley': 'BerkeleyX', + 'harvard': 'HarvardX', +} + ################################ LMS Migration ################################# MITX_FEATURES['ENABLE_LMS_MIGRATION'] = True MITX_FEATURES['ACCESS_REQUIRE_STAFF_FOR_COURSE'] = False # require that user be in the staff_* group to be able to enroll diff --git a/lms/static/images/BerkeleyX-on-edx-logo.png b/lms/static/images/BerkeleyX-on-edx-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6c5a828503a1906fa5c2bf536d8f61478a9fd9a0 GIT binary patch literal 5011 zcmaJ_c|26@`#v*vA&MwujIv}IgRzgumaVKIVul$zGsYN3LV7J_&z2TMA(dnq>uU*F zBTLFYvKt{}4PU+6_xH#9{hiM_=Xsv{b6?keJ(Hp3G3?agM_Zs)I%Ze7$nphVIpgS*T%ZJ zUk)N*ErPCCItO_=t6-oPH6ZGNsz(IgSRxt{=ry7Wa{=utyH2)QbK_P#n5IvF5 zKSkM?m_oF11S|w0BQNbN3x`7#6=mQG2t`G>6huxIE(eo6x)r723aSW2RXHWdUl;VK z8Uf>?YObUASFNKJ66!`I;#Fa=fPes*0C^c4!4(EqQBnEDAtxt&lp*a$_93DJrG5NF z{$|j@`Z*Ka@kDo=59Ajk+6m`RL_&|0{<#Hj{6Dllet#X)(SgAN(RdhKM)ud1{!TP8 z`TtYBz5mJfBbsCXtM^}t{Vd6NEX*A1hw~>mA2rTJ9ixzENWo11@Z6zIT#HD}N@+TJaFIxV>D*sO`>_`mkS8M-ItN#ui z`RCX4ALAY^{;@vR=g9AbBV%(6dLjUTlfgho%QA3y$)1JC^XYWm`uH&x1G=_TL*O=O zj$4^O187E|!b3~?0@TCa)Q;9y=(`Ypy^xt-ut8A<9;w3ztE-WBh z3kvh?>EAOB4yS5X=VrURV(y1!2K4O6C#waxERXIi2OJ*O1Y}N;Gk5b|nCyjIcycLO z+r@jDoi^J>Am+z1?BDc;xq|m-BCS9geQE%xpK{4cv z4>!!&086`J_70zaEU;R4RE8z%IM@w)hH{5Xs+M{o<24F)HFV^)z|H zCE8!ADda&XYOs}*$xD?9WGsE;m33KL9$^~H8%eYV-penp2>eD~Hn&DXYC~{^ihK%6%hp0s^F_(O9FRVXL^C)hXk|Lk81+BRE_{dHY4*jIxGt~(o1+BDNJ2UKR3oW z$mgvuQO{+2*4DGc<^9`8HaXFxF)c-*!#B{Es%?!A$Llmn{FpSV0?*JijAT5_DFG98hP zbJ3eg3aZoym=^CMU4=CZ7Mpk}3->rXtnAIMlz0Y+B|P3h*;Y_SzAu>QFK*;pkQ~6PPeiG^Go;7#Np%Ht$KdR#^}7mA{~kT%iZ+YRIsw zPMCsI%H3`Iis2KSy3L9npeV7$XPqsnw@4p0W6eP3rBjQv#h@X}B6|4;mJnrIrjVWj+W##gwtdpqxTh`u_I&Bh??UWX5SNG@p z?C{~6;-CQA8_(o=Ecpr=xB9M?ei#k&OEBM47?RH3`^LD3fO<+g5V(_Wo#)FE%7aD# zqVee0g5cNmdJ*i5d{dQkEQuq5(bwbG;Jxlmd0zgf*}H=6O9eiU+zYPbl~j;UYW>`! zcW_-JYdER#BYn?OgO#0UFl_#4y0c64IE4KEnBY#Wb;MxdO6fSB|H1bnz5LUc z6$Q59!8-c@+u%JhYHfPb7RTa-lF%$7KMEPk_U7ryEH;-X(R&Fk`;qsN`kN{aZWg1o zOJ*x9%)#j>Vl}t-$sf*+ppRfMMqZl0VCfzxGU3bvD#INm5 z>NoZDj_+#0FFIZ>mh_IL(A&<`?qs=csie|^Kn!k&Cub(avbIL1_2zIZjBko z+*g+D+6sOym(@1HaO~%8FX)g>NkAik?(S*I_3%eGCt+i(tMik)inR@%jdek)6xJdw z#OQCS(dufsOE-Zkl@pbEoateQ3f%X{rF>sW041hCdVeVJj9HWPl+_{mrA~GWN}1QI z#%dtWHkh$Np5a>w{a%ob@q9c$io5Nv-+yQ|&zE@|pTSuK>Q93{y48Jh-bO4*DQa^C zrO0?EEwXso-zm$Mlnolil zj(1LBvT5CK`ThF(4>92qjWgL<5-E?5nH@;edum#{;|yMXXxT`M z=B>#5f=W)4EATaHa2nm4fY#h!;t{xbRzr+QdOYusGon(t-9WGbzZ&VJotR`11pQE+If&~7@EgE8j;dU75uGsi1CYSR9HnEm)oI? zILB~JH8E81k(xdxr@x3**|n}d{{~5go6XK6b*Z2Q`@1)r7u}l_oReNdS~jB#=jOG& zQ$_d$GCyd*Oneg_+26r^UTDGMeZNGFR(v5=Y@5%W}!2yxSA&~}_r09h`y~SM!J=KujjI{~Hv@~}w zz4lnci_XIGXl%h|@M8ayC8hauD$E~Cq_snIip!_y?8Pwm8@zI7hsU(@f5dW0e$7p- zXC%viYuy==bfzD`3K1)Ua;XJ0}IB@XQWJe*BI0>7`sp z0gTH2UhqTt>3BqiaSIcN5ftPBMJq*5;jYX)Th2ev_U><0+$ zNa-)}mgV`ObCZu7S6go!Qwx$H3Ro8poE3*!pQe(6M`1TySQkgn!Xoc9AE(L{SY~D2 zU@RH(7w6AY{MiD@UEnT$f=L<}zJKe>`oeQ$g-KwZljP7iEKT11cU=f_7(9B#)UgC} zP-@b>Ep0FU0>65FJPx`7*Vc$RH`DdCM@Tkk+-A6?HBe_8shV>{lk?%pRaSQekTdRC*_ zhVBsFIIT^?fdTDII-zBmHr?R;9{iHvK-GEGQA;)~xiUS?hY`R_Qafwr&mrMp6Fq9% zT-qe|2cyjjFWam979+r+Xe%b%-+S3sJ5O!3E1&smHQP1G8GW^~VU5)&?1d8xQ10xP z5f^cCPBRb6^&i_f$4k8Y4*v8if^kt7ud5I!WWEWLs1|9fX;vw@;V6CFzq!ndUdx7i zmzG{>XCclu6o|F}$?1QxH|^(wc_$WD;aw##lzcdm5;pOf^>eJ#JE!BA0yt0|!?+Yh zTkvPTo+T)e7bC>cOXiicQDo z17)lhJy&zia!nS_ugp}MxN>UZZc}Kd4=P3ysh_eyT>Z07hJkKv5&{Yib%B8igjiLy z5VP0QsP?`r(6_7f4sSk75N2$iXwW&Wb}&B~!qqr59UFTqAL++ijjKXM7fgCP*odQ}i0gLVGPjlRR$pN_3H>GXL+d^X zomXIJFYjV6e=K+K+d$fStQBT2op6?Qm34xmv@!1|3(CDgxhhLA7PZd3zD=2H6jb9c zjTlbYXBH&GkjCv=Ot8bzWEEoucDwgmR_LUl>>xDo$?D+ZGS^0VIQe4z8-Zu>h2Uw~ z&-!}Fb}C#>v@kR5q2)!;XAdAH^1<^u13Bds>g)8IKfUfb)JWw)hLs)imk}fSo>eW_ z-bB>Jq=VNbyGC%(I9oC9W~IC~wMfV6gD!1vrhEgJ`dks7c;!d>wDrl_9;5SzFE^!m zKFFpph+&9^`KnjUpYh)2POAVc2>e}BPF;ihYE>Fjj zy`-L%Y$Pl{AB$|d@cq6{8ar7pai%_s!L(eG3t^f1t5C*PF(h&j5P=DN&B*_->OWPu z2{X()`jCw>aYC)l86>dEcJ|zKDx@eB^cWpBFDUu)m&JP?IGj3svoAlHKNPa?k)j|w zZ;jb7ihJ>}6PjAM-=7=5cBrmDs~@NOz`u8EKvc|Q+9`O1%mu2AP7<;zFGqLJwI>-j o9d`+PPmU`qQ@~qXJ>*3Jhb_ZKyuWX1{`yU3pnFB9=n^XYKV?e~-2eap literal 0 HcmV?d00001 diff --git a/lms/static/sass/shared/_header.scss b/lms/static/sass/shared/_header.scss index 116761ddc8..49c9ac250b 100644 --- a/lms/static/sass/shared/_header.scss +++ b/lms/static/sass/shared/_header.scss @@ -19,7 +19,7 @@ header.global { h1.logo { float: left; - margin: 6px 15px 0px 0px; + margin: 0px 15px 0px 0px; padding-right: 20px; position: relative; @@ -46,12 +46,7 @@ header.global { } a { - @include background-image(url('/static/images/header-logo.png')); - background-position: 0 0; - background-repeat: no-repeat; display: block; - height: 31px; - width: 64px; } } diff --git a/lms/templates/footer.html b/lms/templates/footer.html index 85ed6e1769..52c2b45526 100644 --- a/lms/templates/footer.html +++ b/lms/templates/footer.html @@ -6,7 +6,7 @@