No description, website, or topics provided.
Switch branches/tags
Nothing to show
Clone or download
cgruppioni Remove show_in_app for TextBlocks and Defaults, since those routes do…
…n't exist.

Remove show_in_app for TextBlocks and Defaults, since those routes don't exist.
Latest commit 8a4a835 Dec 7, 2018
Type Name Latest commit message Commit time
Failed to load latest commit information.
app Remove show_in_app for TextBlocks and Defaults, since those routes do… Dec 7, 2018
bin Run `rails webpacker:install` Oct 22, 2018
config Remove show_in_app for TextBlocks and Defaults, since those routes do… Dec 7, 2018
db Render list of casebooks that use a case in rails admin. Aug 23, 2018
lib Add sleep timers to replacement annotation text. Dec 3, 2018
log Added gitkeep for log dir Sep 24, 2013
public Use bootstrap-sass v3 and remove v4 mods Oct 22, 2018
solr reset sunspot/solr config to default Mar 16, 2017
test Annotator lets you create a link annotation even if it doesn't have h… Dec 7, 2018
.babelrc Run `rails webpacker:install` Oct 22, 2018
.coveralls.yml Add coveralls.yml file. Apr 4, 2017
.env.example Add a .env example and load using dotenv gem Aug 21, 2018
.gitignore Revert "Update .gitignore." Oct 26, 2018
.postcssrc.yml Run `rails webpacker:install` Oct 22, 2018
.ruby-gemset canonicalize ruby version and gemset Mar 16, 2017
.ruby-version bump ruby to latest stable minor Apr 5, 2017
.travis.yml Use postgres 9.4 in travis-ci Aug 21, 2018
Gemfile Remove commented out old ckeditor reference. Nov 26, 2018
Gemfile.lock Update CKeditor. No longer point to local copy on harvard-lil github. Nov 26, 2018
Guardfile Add guard-yarn Nov 2, 2018
LICENSE add AGPLv3 as LICENSE file Mar 17, 2017 Add a note about dev environment variables Aug 21, 2018
Rakefile Upgrade to Rails 4.1.1, Annotator upgrade. May 20, 2014 Upgrade to Rails 4.1.1, Annotator upgrade. May 20, 2014
package-lock.json change links in footer Nov 26, 2018
package.json Remove VueContext dependency Nov 2, 2018
test_export.rb add playlist migration script Aug 28, 2017
yarn.lock Modify placement logic to handle multiple ranges Dec 4, 2018


h2o is open-source software designed to replace bulky and expensive law textbooks with an easy-to-use web interface where instructors and students alike can author, organize, view and print public-domain course material.


  1. Live version
  2. Development
  3. Testing
  4. Migration
  5. Contributions
  6. License

Live version   Build Status

Coverage Status

Auto-deploy of the latest master. If the build is green, it's up-to-date.


TODO: These instructions are incomplete for dev platforms other than OS X, and probably lack steps needed on a fresh machine.

Set up RVM

  1. Install RVM (if missing) with \curl -sSL | bash -s stable --auto-dotfiles, then source ~/.bash_profile etc.
  2. Install the project Ruby version (e.g. rvm install $(<.ruby-version))
  3. cd into the h2o directory (or cd . if already there) to create the gemset.

Install gems with Bundler

  1. gem install bundler && bundle install
  2. (If Bundler complains about missing library dependencies, install them and bundle install until it succeeds.)

Install node and npm packages

With Yarn

  1. Installation of yarn is platform-specific. On a Mac: if you already have node installed, brew install yarn --without-node, or brew install yarn to simultaneously install node.
  2. yarn install

With NPM (might not install precisely the same package versions)

  1. Install node if needed (e.g. brew install node)
  2. npm install

Set up the Postgres database

  1. Install postgres ~9.6 (if missing). Note: brew install postgres now installs postgres 10+. To install 9.6.5 via Homebrew, install postgres using the specific version formula (brew install and then run brew switch postgres 9.6.5
  2. Start solr with rails sunspot:solr:start
  3. Create and initialize the database with rake db:setup (or rake db:reset)
  4. Stop solr with rails sunspot:solr:stop

Note: If rake db:setup fails with a message like Sunspot::Solr::Server::NotRunningError, try rails sunspot:solr:run to see why solr failed to start. You may need to update your java installation with brew cask install java

Set Environment Variables

  1. Copy .env.example to .env
  2. Replace the values in .env with your own environment variables

Run Guard

  1. Run guard. It will take several seconds to:
  2. Make sure the bundle is up-to-date;
  3. Start the dev/test Solr server;
  4. Load Spring for fast rails/rake commands;
  5. And finally boot Rails.
  6. (Optionally, install a notifier such as Growl or brew install terminal-notifier for Guard notifications.)
  7. Guard will now be watching the project for changes and will restart Spring/Rails when needed. This can also be done from the guard command line, e.g. reload rails.
  8. When finished, type exit to shut everything down and close Guard.

Configure the local domain

  1. e.g. OS X: echo h2o-dev.local | sudo tee -a /etc/hosts
  2. Go to http://h2o-dev.local:8000


Test design

Since we're going to be heavily refactoring and likely removing a lot of code, the focus for now will be on high-level feature tests which will survive that. cases_test.rb is an example of the test pattern using Minitest and Capybara which exercises the full stack from a user's point of view.


ImageMagick and a global installation of the "Garamond" font are required. On Macs, you can verify the presence of Garamond in Applications > FontBook, and can install ImageMagick via brew install imagemagick.


Test scenarios marked with js: true will be run in a headless WebKit environment via Poltergeist. This requires the PhantomJS binary to be installed, e.g. brew install phantomjs. Headless tests are significantly slower than static tests, so prefer to avoid writing tests (and features!) that require JS when possible.

Guard will not automatically run these tests. This is less than ideal when working on a client-side feature, so you can mark a given test with focus: true to force Guard to run it. If no JS tests are enabled, PhantomJS will not boot, speeding up the whole test suite considerably.

Guard testing

Guard will automatically run all static tests after booting Rails and again after any test or app file is edited. By default, Guard won't run any tests that require JS, since they're so much slower. You can run those tests manually:

  1. bin/rails test runs non-system tests.
  2. bin/rails test:system runs system tests, including JS tests.
  3. bin/rails test test/system/cases_test.rb runs the case feature test, and so on, including JS tests.


Coverage will be generated automatically for all manually-run tests.

TODO: When coverage is a bit higher, add a git commit hook which runs the coverage report and fails if under some value.


Legacy Playlists must be converted into Casebooks. To convert all un-migrated, use this rake task:

bin/rails h2o:migrate_playlists

Any Playlists that don't have a Casebook with a matching created_at date will be migrated.

You can also migrate individual playlists from the rails console:

bin/rails c

> Migrate::Playlist.find(52410).migrate
=> #<Content::Casebook ... >

> Migrate::Playlist.find([11494, 5456, 1496]).map &:migrate
=> [#<Content::Casebook id: ...>, ...]

Importing Data

If importing data from another installation of H2O into your local database, you may need to create an h2oadmin role in postgres first (e.g., psql postgres, followed by CREATE ROLE h2oadmin;. Note the terminating semi-colon).

Be advised that depending on the source of the data, some local rake tasks (e.g. db:reset) may subsequently fail with spurious warnings about affecting production data, regardless of the current value of RAILS_ENV.


Contributions to this project should be made in individual forks and then merged by pull request. Here's an outline:

  1. Fork and clone the project.
  2. Make a branch for your feature: git branch feature-1
  3. Commit your changes with git add and git commit. (git diff --staged is handy here!)
  4. Push your branch to your fork: git push origin feature-1
  5. Submit a pull request to the upstream master through GitHub.

Whenever possible, pull requests should be fast-forwarded (i.e., Rebase and Merged). This creates a nice, linear record of commits, without ugly merge commits that lose context and history.

In order to fast-forward a pull request, upstream/master shouldn't have any commits that aren't also on the fork in the same order— in other words, they have to agree about the history of the repo. This is a problem if upstream has changed since you created your branch!

Rather than creating a merge commit which reconciles the changes, you'll want to rebase your branch to upstream/master. Rebasing simply means that you stash your new commits temporarily, fast-forward your local repo to the updated upstream/master, and then apply your changes on top, pretending that your commits are the most recent changes.

In general, GitHub can automatically rebase a pull request, but if there are any conflicts you'll need to resolve them manually with this process:

  1. Add the upstream repository with git remote add upstream
  2. Fetch the latest changes with git fetch upstream
  3. Rebase your branch to upstream: git rebase upstream/master
  4. (You can do both of these in one step with git pull upstream master --rebase)
  5. If upstream/master has changes that conflict with your commits, you'll need to amend them at this time.
  6. Push and pull request.

In the case of particularly ugly conflicts, rebasing can be more trouble than it's worth to preserve history, and a big merge commit will be the best option, but that should be avoided whenever possible. Rebasing your local branch to upstream/master frequently is the best way to avoid headaches later on.


This codebase is Copyright 2017 The President and Fellows of Harvard College and is licensed under the open-source AGPLv3 for public use and modification. See LICENSE for details.