diff --git a/brew-formulas.txt b/brew-formulas.txt new file mode 100644 index 0000000000..61e3d33e3a --- /dev/null +++ b/brew-formulas.txt @@ -0,0 +1,8 @@ +readline +sqlite +gdbm +pkg-config +gfortran +python +yuicompressor +node diff --git a/create-dev-env.sh b/create-dev-env.sh new file mode 100755 index 0000000000..a45fc0dba0 --- /dev/null +++ b/create-dev-env.sh @@ -0,0 +1,273 @@ +#!/bin/bash +set -e +trap "ouch" ERR + +ouch() { + printf '\E[31m' + + cat<>$LOG + output "Cloning askbot-devel" + if [[ -d "$BASE/askbot-devel" ]]; then + mv "$BASE/askbot-devel" "${BASE}/askbot-devel.bak.$$" + fi + git clone git@github.com:MITx/askbot-devel >>$LOG + output "Cloning data" + if [[ -d "$BASE/data" ]]; then + mv "$BASE/data" "${BASE}/data.bak.$$" + fi + hg clone ssh://hg-content@gp.mitx.mit.edu/data >>$LOG +} + +PROG=${0##*/} +BASE="$HOME/mitx_all" +PYTHON_DIR="$BASE/python" +RUBY_DIR="$BASE/ruby" +RUBY_VER="1.9.3" +NUMPY_VER="1.6.2" +SCIPY_VER="0.10.1" +BREW_FILE="$BASE/mitx/brew-formulas.txt" +LOG="/var/tmp/install.log" +APT_PKGS="curl git mercurial python-virtualenv build-essential python-dev gfortran liblapack-dev libfreetype6-dev libpng12-dev libxml2-dev libxslt-dev yui-compressor coffeescript" + +if [[ $EUID -eq 0 ]]; then + error "This script should not be run using sudo or as the root user" + usage + exit 1 +fi +ARGS=$(getopt "cvh" "$*") +if [[ $? != 0 ]]; then + usage + exit 1 +fi +eval set -- "$ARGS" +while true; do + case $1 in + -c) + compile=true + shift + ;; + -v) + set -x + verbose=true + shift + ;; + -h) + usage + exit 0 + ;; + --) + shift + break + ;; + esac +done + +cat< $HOME/.rvmrc +fi +mkdir -p $BASE +rm -f $LOG +case `uname -s` in + [Ll]inux) + command -v lsb_release &>/dev/null || { + error "Please install lsb-release." + exit 1 + } + distro=`lsb_release -cs` + case $distro in + lisa|natty|oneiric|precise) + output "Installing ubuntu requirements" + sudo apt-get -y update + sudo apt-get -y install $APT_PKGS + clone_repos + ;; + *) + error "Unsupported distribution - $distro" + exit 1 + ;; + esac + ;; + Darwin) + command -v brew &>/dev/null || { + output "Installing brew" + /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/master/Library/Contributions/install_homebrew.rb)" + } + command -v git &>/dev/null || { + output "Installing git" + brew install git >> $LOG + } + command -v hg &>/dev/null || { + output "Installaing mercurial" + brew install mercurial >> $LOG + } + + clone_repos + + output "Installing OSX requirements" + if [[ ! -r $BREW_FILE ]]; then + error "$BREW_FILE does not exist, needed to install brew deps" + exit 1 + fi + # brew errors if the package is already installed + for pkg in $(cat $BREW_FILE); do + grep $pkg <(brew list) &>/dev/null || { + output "Installing $pkg" + brew install $pkg >>$LOG + } + done + command -v pip &>/dev/null || { + output "Installing pip" + sudo easy_install pip >>$LOG + } + command -v virtualenv &>/dev/null || { + output "Installing virtualenv" + sudo pip install virtualenv virtualenvwrapper >> $LOG + } + command -v coffee &>/dev/null || { + output "Installing coffee script" + curl http://npmjs.org/install.sh | sh + npm install -g coffee-script + } + ;; + *) + error "Unsupported platform" + exit 1 + ;; +esac + +output "Installing rvm and ruby" +curl -sL get.rvm.io | bash -s stable +source $RUBY_DIR/scripts/rvm +rvm install $RUBY_VER +virtualenv "$PYTHON_DIR" +source $PYTHON_DIR/bin/activate +output "Installing gem bundler" +gem install bundler +output "Installing ruby packages" +# hack :( +cd $BASE/mitx || true +bundle install + +cd $BASE + +if [[ -n $compile ]]; then + output "Downloading numpy and scipy" + curl -sL -o numpy.tar.gz http://downloads.sourceforge.net/project/numpy/NumPy/${NUMPY_VER}/numpy-${NUMPY_VER}.tar.gz + curl -sL -o scipy.tar.gz http://downloads.sourceforge.net/project/scipy/scipy/${SCIPY_VER}/scipy-${SCIPY_VER}.tar.gz + tar xf numpy.tar.gz + tar xf scipy.tar.gz + rm -f numpy.tar.gz scipy.tar.gz + output "Compiling numpy" + cd "$BASE/numpy-${NUMPY_VER}" + python setup.py install >>$LOG 2>&1 + output "Compiling scipy" + cd "$BASE/scipy-${SCIPY_VER}" + python setup.py install >>$LOG 2>&1 + cd "$BASE" + rm -rf numpy-${NUMPY_VER} scipy-${SCIPY_VER} +fi + +output "Installing askbot requirements" +pip install -r askbot-devel/askbot_requirements.txt >>$LOG +pip install -r askbot-devel/askbot_requirements_dev.txt >>$LOG +output "Installing MITx requirements" +pip install -r mitx/pre-requirements.txt >> $LOG +pip install -r mitx/requirements.txt >>$LOG + +mkdir "$BASE/log" || true +mkdir "$BASE/db" || true + +cat< self.close_date: + if self.close_date is not None and datetime.datetime.utcnow() > self.close_date: return True return False diff --git a/djangoapps/courseware/modules/seq_module.py b/djangoapps/courseware/modules/seq_module.py index 1c97d6d006..5abe56231c 100644 --- a/djangoapps/courseware/modules/seq_module.py +++ b/djangoapps/courseware/modules/seq_module.py @@ -52,7 +52,7 @@ class Module(XModule): ## Returns a set of all types of all sub-children child_classes = [set([i.tag for i in e.iter()]) for e in self.xmltree] - titles = ["\n".join([i.get("name").strip() for i in e.iter() if i.get("name") != None]) \ + titles = ["\n".join([i.get("name").strip() for i in e.iter() if i.get("name") is not None]) \ for e in self.xmltree] self.contents = self.rendered_children() @@ -86,7 +86,7 @@ class Module(XModule): self.position = 1 - if state != None: + if state is not None: state = json.loads(state) if 'position' in state: self.position = int(state['position']) diff --git a/djangoapps/courseware/modules/video_module.py b/djangoapps/courseware/modules/video_module.py index 95c7102fed..ad26ede81e 100644 --- a/djangoapps/courseware/modules/video_module.py +++ b/djangoapps/courseware/modules/video_module.py @@ -50,7 +50,7 @@ class Module(XModule): self.youtube = xmltree.get('youtube') self.name = xmltree.get('name') self.position = 0 - if state != None: + if state is not None: state = json.loads(state) if 'position' in state: self.position = int(float(state['position'])) diff --git a/djangoapps/courseware/views.py b/djangoapps/courseware/views.py index 228a33461b..a098753728 100644 --- a/djangoapps/courseware/views.py +++ b/djangoapps/courseware/views.py @@ -57,7 +57,7 @@ def profile(request, student_id = None): ''' User profile. Show username, location, etc, as well as grades . We need to allow the user to change some of these settings .''' - if student_id == None: + if student_id is None: student = request.user else: if 'course_admin' not in content_parser.user_groups(request.user): @@ -194,7 +194,7 @@ def index(request, course=None, chapter="Using the System", section="Hints"): else: module_wrapper = dom_module[0] - if module_wrapper == None: + if module_wrapper is None: module = None elif module_wrapper.get("src"): module = content_parser.section_file(user=user, section=module_wrapper.get("src"), coursename=course) @@ -202,7 +202,7 @@ def index(request, course=None, chapter="Using the System", section="Hints"): module = etree.XML(etree.tostring(module_wrapper[0])) # Copy the element out of the tree module_ids = [] - if module: + if module is not None: module_ids = module.xpath("//@id", course=course, chapter=chapter, section=section) diff --git a/djangoapps/simplewiki/views.py b/djangoapps/simplewiki/views.py index 34a81e6b57..167ce27d95 100644 --- a/djangoapps/simplewiki/views.py +++ b/djangoapps/simplewiki/views.py @@ -482,7 +482,7 @@ def check_permissions(request, article, check_read=False, check_write=False, che locked_err = check_locked and article.locked - if revision == None: + if revision is None: revision = article.current_revision deleted_err = check_deleted and not (revision.deleted == 0) if (request.user.is_superuser): diff --git a/install.txt b/install.txt new file mode 100644 index 0000000000..fa82b11a5c --- /dev/null +++ b/install.txt @@ -0,0 +1,78 @@ +This document describes how to set up the MITx development environment +for both Linux (Ubuntu) and MacOS (OSX Lion). + +There is also a script "create-dev-env.sh" that automates these steps. + +1) Make an mitx_all directory and clone the repos + (download and install git and mercurial if you don't have them already) + + mkdir ~/mitx_all + cd ~/mitx_all + git clone git@github.com:MITx/mitx.git + git clone git@github.com:MITx/askbot-devel + hg clone ssh://hg-content@gp.mitx.mit.edu/data + +2) Install OSX dependencies (Mac users only) + + a) Install the brew utility if necessary + /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/master/Library/Contributions/install_homebrew.rb)" + + b) Install the brew package list + cat ~/mitx_all/mitx/brew-formulas.txt | xargs brew install + + c) Install python pip if necessary + sudo easy_install pip + + d) Install python virtualenv if necessary + sudo pip install virtualenv virtualenvwrapper + + e) Install coffee script + curl http://npmjs.org/install.sh | sh + npm install -g coffee-script + +3) Install Ubuntu dependencies (Linux users only) + + sudo apt-get install curl python-virtualenv build-essential python-dev gfortran liblapack-dev libfreetype6-dev libpng12-dev libxml2-dev libxslt-dev yui-compressor coffeescript + + +4) Install rvm, ruby, and libraries + + echo "export rvm_path=$HOME/mitx_all/ruby" > $HOME/.rvmrc + curl -sL get.rvm.io | bash -s stable + source ~/mitx_all/ruby/scripts/rvm + rvm install 1.9.3 + gem install bundler + cd ~/mitx_all/mitx + bundle install + +5) Install python libraries + + source ~/mitx_all/python/bin/activate + cd ~/mitx_all + pip install -r askbot-devel/askbot_requirements.txt + pip install -r askbot-devel/askbot_requirements_dev.txt + pip install -r mitx/pre-requirements.txt + pip install -r mitx/requirements.txt + +6) Create log and db dirs + + mkdir ~/mitx_all/log + mkdir ~/mitx_all/db + +7) Start the dev server + + To start using Django you will need + to activate the local Python and Ruby + environment: + + $ source ~/mitx_all/ruby/scripts/rvm + $ source ~/mitx_all/python/bin/activate + + To initialize and start a local instance of Django: + + $ cd ~/mitx_all/mitx + $ django-admin.py syncdb --settings=envs.dev --pythonpath=. + $ django-admin.py migrate --settings=envs.dev --pythonpath=. + $ django-admin.py runserver --settings=envs.dev --pythonpath=. + + diff --git a/static/coffee/spec/modules/video/video_player_spec.coffee b/static/coffee/spec/modules/video/video_player_spec.coffee index 309afcd002..26f5e3b5ed 100644 --- a/static/coffee/spec/modules/video/video_player_spec.coffee +++ b/static/coffee/spec/modules/video/video_player_spec.coffee @@ -126,6 +126,14 @@ describe 'VideoPlayer', -> it 'trigger pause event', -> expect('pause').toHaveBeenTriggeredOn @player + describe 'when the video is unstarted', -> + beforeEach -> + spyOnEvent @player, 'pause' + @player.onStateChange data: YT.PlayerState.UNSTARTED + + it 'trigger pause event', -> + expect('pause').toHaveBeenTriggeredOn @player + describe 'when the video is ended', -> beforeEach -> spyOnEvent @player, 'ended' diff --git a/static/coffee/src/main.coffee b/static/coffee/src/main.coffee index 733322b9bb..9f3c759a9a 100644 --- a/static/coffee/src/main.coffee +++ b/static/coffee/src/main.coffee @@ -12,6 +12,8 @@ $ -> window.onTouchBasedDevice = -> navigator.userAgent.match /iPhone|iPod|iPad/i + $('body').addClass 'touch-based-device' if onTouchBasedDevice() + $("a[rel*=leanModal]").leanModal() $('#csrfmiddlewaretoken').attr 'value', $.cookie('csrftoken') diff --git a/static/coffee/src/modules/video/video_player.coffee b/static/coffee/src/modules/video/video_player.coffee index 57d7f913b8..28f87b2d53 100644 --- a/static/coffee/src/modules/video/video_player.coffee +++ b/static/coffee/src/modules/video/video_player.coffee @@ -1,5 +1,8 @@ class @VideoPlayer constructor: (@video) -> + # Define a missing constant of Youtube API + YT.PlayerState.UNSTARTED = -1 + @currentTime = 0 @element = $("#video_#{@video.id}") @render() @@ -57,7 +60,7 @@ class @VideoPlayer switch event.data when YT.PlayerState.PLAYING $(@).trigger('play') - when YT.PlayerState.PAUSED + when YT.PlayerState.PAUSED, YT.PlayerState.UNSTARTED $(@).trigger('pause') when YT.PlayerState.ENDED $(@).trigger('ended') diff --git a/static/coffee/src/modules/video/video_speed_control.coffee b/static/coffee/src/modules/video/video_speed_control.coffee index 203e3677a4..6f7631a0ad 100644 --- a/static/coffee/src/modules/video/video_speed_control.coffee +++ b/static/coffee/src/modules/video/video_speed_control.coffee @@ -10,7 +10,9 @@ class @VideoSpeedControl $(@player).bind('speedChange', @onSpeedChange) @$('.video_speeds a').click @changeVideoSpeed if onTouchBasedDevice() - @$('.speeds').click -> $(this).toggleClass('open') + @$('.speeds').click (event) -> + event.preventDefault() + $(this).toggleClass('open') else @$('.speeds').mouseenter -> $(this).addClass('open') diff --git a/static/sass/courseware/_sequence-nav.scss b/static/sass/courseware/_sequence-nav.scss index 0e541e7f07..2be435c350 100644 --- a/static/sass/courseware/_sequence-nav.scss +++ b/static/sass/courseware/_sequence-nav.scss @@ -123,7 +123,7 @@ nav.sequence-nav { background-position: center; } - p { + p { background: #333; color: #fff; display: none; @@ -231,6 +231,10 @@ nav.sequence-nav { } } } + + body.touch-based-device & ol li a:hover p { + display: none; + } } @@ -304,3 +308,4 @@ section.course-content { } } } + diff --git a/templates/video.html b/templates/video.html index 54d6f8fa37..f49b5b56c2 100644 --- a/templates/video.html +++ b/templates/video.html @@ -1,4 +1,4 @@ -% if name is not UNDEFINED and name != None: +% if name is not UNDEFINED and name is not None:

${name}

% endif