From 4d137446227b0b8f68592c65d1a4b4568f479795 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 19 Dec 2012 16:21:37 -0500 Subject: [PATCH 1/9] added new visual status to course listings on edx.org --- lms/static/sass/shared/_course_object.scss | 25 ++++++++++++++++++++++ lms/templates/course.html | 1 + 2 files changed, 26 insertions(+) diff --git a/lms/static/sass/shared/_course_object.scss b/lms/static/sass/shared/_course_object.scss index 374caf4898..2f6ca88a63 100644 --- a/lms/static/sass/shared/_course_object.scss +++ b/lms/static/sass/shared/_course_object.scss @@ -24,6 +24,31 @@ width: 100%; @include transition(all, 0.15s, linear); + .status { + background: $blue; + color: white; + font-size: 10px; + left: 10px; + padding: 2px 10px; + @include border-radius(2px); + position: absolute; + text-transform: uppercase; + top: -6px; + z-index: 100; + } + + .status:after { + border-bottom: 6px solid shade($blue, 50%); + border-right: 6px solid transparent; + content: ""; + display: block; + height: 0; + position: absolute; + right: -6px; + top: 0; + width: 0; + } + a:hover { text-decoration: none; } diff --git a/lms/templates/course.html b/lms/templates/course.html index 50a00f9d31..7392dfcefa 100644 --- a/lms/templates/course.html +++ b/lms/templates/course.html @@ -5,6 +5,7 @@ %> <%page args="course" />
+ New
From 37e0d98fec68f13eb83201df9c217ed364274948 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Thu, 20 Dec 2012 09:32:15 -0500 Subject: [PATCH 2/9] course listings - new html and css for ordering - wip --- lms/static/sass/shared/_course_object.scss | 17 + .../static_templates/_courses-newlisting.html | 301 ++++++++++++++++++ 2 files changed, 318 insertions(+) create mode 100644 lms/templates/static_templates/_courses-newlisting.html diff --git a/lms/static/sass/shared/_course_object.scss b/lms/static/sass/shared/_course_object.scss index 374caf4898..3adcc11534 100644 --- a/lms/static/sass/shared/_course_object.scss +++ b/lms/static/sass/shared/_course_object.scss @@ -13,6 +13,23 @@ } } + .courses-listing { + @include clearfix(); + margin: 0; + padding: 0; + list-style: none; + + .courses-listing-item { + width: flex-grid(4); + margin-right: flex-gutter(); + float: left; + + &:nth-child(3n+3) { + margin-right: 0; + } + } + } + .course { background: rgb(250,250,250); border: 1px solid rgb(180,180,180); diff --git a/lms/templates/static_templates/_courses-newlisting.html b/lms/templates/static_templates/_courses-newlisting.html new file mode 100644 index 0000000000..4d67304fd6 --- /dev/null +++ b/lms/templates/static_templates/_courses-newlisting.html @@ -0,0 +1,301 @@ + \ No newline at end of file From f92266d6595b3a67adae799672aeddbd915f5a7d Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Thu, 20 Dec 2012 09:55:52 -0500 Subject: [PATCH 3/9] course listings - new html and css for ordering - finished sass changes and static markup example --- .../static_templates/_courses-newlisting.html | 582 +++++++++--------- 1 file changed, 291 insertions(+), 291 deletions(-) diff --git a/lms/templates/static_templates/_courses-newlisting.html b/lms/templates/static_templates/_courses-newlisting.html index 4d67304fd6..97985977c1 100644 --- a/lms/templates/static_templates/_courses-newlisting.html +++ b/lms/templates/static_templates/_courses-newlisting.html @@ -1,301 +1,301 @@ \ No newline at end of file +
  • + +
  • + \ No newline at end of file From 4811e73645d5065786a0683c334ce3e61b7ffae4 Mon Sep 17 00:00:00 2001 From: Alexander Kryklia Date: Thu, 20 Dec 2012 17:25:43 +0200 Subject: [PATCH 4/9] enabled rake docs for ubuntu --- rakefile | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rakefile b/rakefile index 3828ad036d..286332c5b8 100644 --- a/rakefile +++ b/rakefile @@ -169,7 +169,7 @@ Dir["common/lib/*"].select{|lib| File.directory?(lib)}.each do |lib| TEST_TASK_DIRS << lib desc "Run tests for common lib #{lib} (without coverage)" - task "fasttest_#{lib}" do + task "fasttest_#{lib}" do sh("nosetests #{lib}") end @@ -309,16 +309,22 @@ task :builddocs do end end -desc "Show doc in browser (mac only for now) TODO add linux support" +desc "Show docs in browser (mac and ubuntu)." task :showdocs do Dir.chdir('docs/build/html') do - sh('open index.html') + if RUBY_PLATFORM.include? 'darwin' # mac os + sh('open index.html') + elsif RUBY_PLATFORM.include? 'linux' # make more ubuntu specific? + sh('sens-browser index.html') # ubuntu + else + raise "\nUndefined how to run browser on your machine. +Please use 'rake builddocs' and then manually open +'mitx/docs/build/html/index.html." + end end end desc "Build docs and show them in browser" task :doc => :builddocs do - Dir.chdir('docs/build/html') do - sh('open index.html') - end + Rake::Task["showdocs"].invoke end From cc76e0518d5f65c432cafcda1c5e9161fa6615b2 Mon Sep 17 00:00:00 2001 From: Alexander Kryklia Date: Thu, 20 Dec 2012 17:28:53 +0200 Subject: [PATCH 5/9] fix --- rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakefile b/rakefile index 286332c5b8..53d7381dd7 100644 --- a/rakefile +++ b/rakefile @@ -315,7 +315,7 @@ task :showdocs do if RUBY_PLATFORM.include? 'darwin' # mac os sh('open index.html') elsif RUBY_PLATFORM.include? 'linux' # make more ubuntu specific? - sh('sens-browser index.html') # ubuntu + sh('sensible-browser index.html') # ubuntu else raise "\nUndefined how to run browser on your machine. Please use 'rake builddocs' and then manually open From 320f1b4141fa46cc93dcd9496c19b5d1584927cb Mon Sep 17 00:00:00 2001 From: ichuang Date: Fri, 21 Dec 2012 13:23:22 +0000 Subject: [PATCH 6/9] update schema for tracking sql logs - larger fields; add hostname --- .../track/migrations/0001_initial.py | 48 +++++++++++++++++ ...t__chg_field_trackinglog_event_type__ch.py | 51 +++++++++++++++++++ .../djangoapps/track/migrations/__init__.py | 0 common/djangoapps/track/models.py | 5 +- common/djangoapps/track/views.py | 4 +- 5 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 common/djangoapps/track/migrations/0001_initial.py create mode 100644 common/djangoapps/track/migrations/0002_auto__add_field_trackinglog_host__chg_field_trackinglog_event_type__ch.py create mode 100644 common/djangoapps/track/migrations/__init__.py diff --git a/common/djangoapps/track/migrations/0001_initial.py b/common/djangoapps/track/migrations/0001_initial.py new file mode 100644 index 0000000000..0546203cf8 --- /dev/null +++ b/common/djangoapps/track/migrations/0001_initial.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'TrackingLog' + db.create_table('track_trackinglog', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('dtcreated', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('username', self.gf('django.db.models.fields.CharField')(max_length=32, blank=True)), + ('ip', self.gf('django.db.models.fields.CharField')(max_length=32, blank=True)), + ('event_source', self.gf('django.db.models.fields.CharField')(max_length=32)), + ('event_type', self.gf('django.db.models.fields.CharField')(max_length=32, blank=True)), + ('event', self.gf('django.db.models.fields.TextField')(blank=True)), + ('agent', self.gf('django.db.models.fields.CharField')(max_length=256, blank=True)), + ('page', self.gf('django.db.models.fields.CharField')(max_length=32, null=True, blank=True)), + ('time', self.gf('django.db.models.fields.DateTimeField')()), + )) + db.send_create_signal('track', ['TrackingLog']) + + + def backwards(self, orm): + # Deleting model 'TrackingLog' + db.delete_table('track_trackinglog') + + + models = { + 'track.trackinglog': { + 'Meta': {'object_name': 'TrackingLog'}, + 'agent': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), + 'dtcreated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'event': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'event_source': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'event_type': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'page': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {}), + 'username': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}) + } + } + + complete_apps = ['track'] \ No newline at end of file diff --git a/common/djangoapps/track/migrations/0002_auto__add_field_trackinglog_host__chg_field_trackinglog_event_type__ch.py b/common/djangoapps/track/migrations/0002_auto__add_field_trackinglog_host__chg_field_trackinglog_event_type__ch.py new file mode 100644 index 0000000000..4c73aa3bfd --- /dev/null +++ b/common/djangoapps/track/migrations/0002_auto__add_field_trackinglog_host__chg_field_trackinglog_event_type__ch.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'TrackingLog.host' + db.add_column('track_trackinglog', 'host', + self.gf('django.db.models.fields.CharField')(default='', max_length=64, blank=True), + keep_default=False) + + + # Changing field 'TrackingLog.event_type' + db.alter_column('track_trackinglog', 'event_type', self.gf('django.db.models.fields.CharField')(max_length=512)) + + # Changing field 'TrackingLog.page' + db.alter_column('track_trackinglog', 'page', self.gf('django.db.models.fields.CharField')(max_length=512, null=True)) + + def backwards(self, orm): + # Deleting field 'TrackingLog.host' + db.delete_column('track_trackinglog', 'host') + + + # Changing field 'TrackingLog.event_type' + db.alter_column('track_trackinglog', 'event_type', self.gf('django.db.models.fields.CharField')(max_length=32)) + + # Changing field 'TrackingLog.page' + db.alter_column('track_trackinglog', 'page', self.gf('django.db.models.fields.CharField')(max_length=32, null=True)) + + models = { + 'track.trackinglog': { + 'Meta': {'object_name': 'TrackingLog'}, + 'agent': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), + 'dtcreated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'event': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'event_source': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'event_type': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'host': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'page': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {}), + 'username': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}) + } + } + + complete_apps = ['track'] \ No newline at end of file diff --git a/common/djangoapps/track/migrations/__init__.py b/common/djangoapps/track/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/common/djangoapps/track/models.py b/common/djangoapps/track/models.py index 401fa2832f..dfdf7a0558 100644 --- a/common/djangoapps/track/models.py +++ b/common/djangoapps/track/models.py @@ -7,11 +7,12 @@ class TrackingLog(models.Model): username = models.CharField(max_length=32,blank=True) ip = models.CharField(max_length=32,blank=True) event_source = models.CharField(max_length=32) - event_type = models.CharField(max_length=32,blank=True) + event_type = models.CharField(max_length=512,blank=True) event = models.TextField(blank=True) agent = models.CharField(max_length=256,blank=True) - page = models.CharField(max_length=32,blank=True,null=True) + page = models.CharField(max_length=512,blank=True,null=True) time = models.DateTimeField('event time') + host = models.CharField(max_length=64,blank=True) def __unicode__(self): s = "[%s] %s@%s: %s | %s | %s | %s" % (self.time, self.username, self.ip, self.event_source, diff --git a/common/djangoapps/track/views.py b/common/djangoapps/track/views.py index 434e75a63f..54bd476799 100644 --- a/common/djangoapps/track/views.py +++ b/common/djangoapps/track/views.py @@ -17,7 +17,7 @@ from track.models import TrackingLog log = logging.getLogger("tracking") -LOGFIELDS = ['username','ip','event_source','event_type','event','agent','page','time'] +LOGFIELDS = ['username','ip','event_source','event_type','event','agent','page','time','host'] def log_event(event): event_str = json.dumps(event) @@ -58,6 +58,7 @@ def user_track(request): "agent": agent, "page": request.GET['page'], "time": datetime.datetime.utcnow().isoformat(), + "host": request.META['SERVER_NAME'], } log_event(event) return HttpResponse('success') @@ -83,6 +84,7 @@ def server_track(request, event_type, event, page=None): "agent": agent, "page": page, "time": datetime.datetime.utcnow().isoformat(), + "host": request.META['SERVER_NAME'], } if event_type.startswith("/event_logs") and request.user.is_staff: # don't log From 3bbfb4851bf8f83e9c1a44e0ef55c5430b8b896b Mon Sep 17 00:00:00 2001 From: Jay Zoldak Date: Fri, 21 Dec 2012 10:25:14 -0500 Subject: [PATCH 7/9] Remove logger setting override from test settings configuration file. --- lms/envs/test.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lms/envs/test.py b/lms/envs/test.py index ef2a343db4..c72c8b98bf 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -44,12 +44,6 @@ STATUS_MESSAGE_PATH = TEST_ROOT / "status_message.json" COURSES_ROOT = TEST_ROOT / "data" DATA_DIR = COURSES_ROOT -LOGGING = get_logger_config(TEST_ROOT / "log", - logging_env="dev", - tracking_filename="tracking.log", - dev_env=True, - debug=True) - COMMON_TEST_DATA_ROOT = COMMON_ROOT / "test" / "data" # Where the content data is checked out. This may not exist on jenkins. GITHUB_REPO_ROOT = ENV_ROOT / "data" From 8ac89c39a785390fedb21a17efa3b4eb0afb5c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s=20Rocha?= Date: Fri, 21 Dec 2012 11:12:21 -0500 Subject: [PATCH 8/9] Use course metadata instead of setting attributes to display new course overlay --- lms/djangoapps/courseware/courses.py | 9 +++++---- lms/templates/course.html | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index 0f039b6cf5..422974cdcf 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -251,11 +251,12 @@ def _sort_courses_and_mark_new(courses): for course in courses: days_to_start = _get_course_days_to_start(course) - # Add values as attributes, so they can be used in templates - setattr(course, '_days_to_start', days_to_start) - setattr(course, 'is_new', days_to_start > 1) + metadata = course.metadata + metadata['days_to_start'] = days_to_start + metadata['is_new'] = course.metadata.get('is_new', days_to_start > 1) - courses = sorted(courses, key=lambda d: d._days_to_start, reverse=True) + key = lambda c: c.metadata['days_to_start'] + courses = sorted(courses, key=key, reverse=True) return courses diff --git a/lms/templates/course.html b/lms/templates/course.html index a2eff572e1..dcf6ab895e 100644 --- a/lms/templates/course.html +++ b/lms/templates/course.html @@ -5,7 +5,7 @@ %> <%page args="course" />
    - %if course.is_new: + %if course.metadata['is_new']: New %endif From 1ac41787a7937ccca2f43329828167512fcda915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s=20Rocha?= Date: Fri, 21 Dec 2012 16:38:17 -0500 Subject: [PATCH 9/9] Fix broken display of courses in university profile --- common/djangoapps/student/views.py | 8 ++++++-- lms/djangoapps/courseware/courses.py | 20 ++------------------ lms/djangoapps/courseware/views.py | 16 ++++++++++++---- lms/templates/course.html | 2 +- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 3acd02e115..06c59d7937 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -40,7 +40,7 @@ from xmodule.modulestore.exceptions import ItemNotFoundError from datetime import date from collections import namedtuple -from courseware.courses import get_courses_by_start_date +from courseware.courses import get_courses from courseware.access import has_access from statsd import statsd @@ -75,7 +75,11 @@ def index(request, extra_context={}, user=None): if domain==False: # do explicit check, because domain=None is valid domain = request.META.get('HTTP_HOST') - courses = get_courses_by_start_date(None, domain=domain) + courses = get_courses(None, domain=domain) + + # Sort courses by how far are they from they start day + key = lambda course: course.metadata['days_to_start'] + courses = sorted(courses, key=key, reverse=True) # Get the 3 most recent news top_news = _get_news(top=3) diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index 422974cdcf..dc530bdebc 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -233,21 +233,7 @@ def get_courses(user, domain=None): courses = branding.get_visible_courses(domain) courses = [c for c in courses if has_access(user, c, 'see_exists')] - return courses - - -def get_courses_by_start_date(user, domain=None): - """ - Returns a list of courses available, sorted by start date - """ - visible_courses = get_courses(user, domain) - courses = _sort_courses_and_mark_new(visible_courses) - - return courses - - -def _sort_courses_and_mark_new(courses): - """Sort by course start date and mark which have not started yet""" + # Add metadata about the start day and if the course is new for course in courses: days_to_start = _get_course_days_to_start(course) @@ -255,9 +241,7 @@ def _sort_courses_and_mark_new(courses): metadata['days_to_start'] = days_to_start metadata['is_new'] = course.metadata.get('is_new', days_to_start > 1) - key = lambda c: c.metadata['days_to_start'] - courses = sorted(courses, key=key, reverse=True) - + courses = sorted(courses, key=lambda course:course.number) return courses diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index dc83061fcd..f6e87dfe9f 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -17,7 +17,7 @@ from django.views.decorators.cache import cache_control from courseware import grades from courseware.access import has_access -from courseware.courses import (get_course_with_access, get_courses_by_start_date) +from courseware.courses import (get_courses, get_course_with_access, get_courses_by_university) import courseware.tabs as tabs from courseware.models import StudentModuleCache from module_render import toc_for_course, get_module, get_instance_module @@ -61,15 +61,18 @@ def user_groups(user): return group_names - @ensure_csrf_cookie @cache_if_anonymous def courses(request): ''' Render "find courses" page. The course selection work is done in courseware.courses. ''' - courses = get_courses_by_start_date(request.user, - domain=request.META.get('HTTP_HOST')) + courses = get_courses(request.user, domain=request.META.get('HTTP_HOST')) + + # Sort courses by how far are they from they start day + key = lambda course: course.metadata['days_to_start'] + courses = sorted(courses, key=key, reverse=True) + return render_to_response("courseware/courses.html", {'courses': courses}) @@ -435,6 +438,11 @@ def university_profile(request, org_id): # Only grab courses for this org... courses = get_courses_by_university(request.user, domain=request.META.get('HTTP_HOST'))[org_id] + + # Sort courses by how far are they from they start day + key = lambda course: course.metadata['days_to_start'] + courses = sorted(courses, key=key, reverse=True) + context = dict(courses=courses, org_id=org_id) template_file = "university_profile/{0}.html".format(org_id).lower() diff --git a/lms/templates/course.html b/lms/templates/course.html index dcf6ab895e..a3217d2da5 100644 --- a/lms/templates/course.html +++ b/lms/templates/course.html @@ -5,7 +5,7 @@ %> <%page args="course" />