Makahiki Manual

This manual is available in both PDF and HTML formats.

Overview

Introduction

_images/kukuicup-header.png

Partial screenshot of the Kukui Cup challenge, built using Makahiki.

Goals

Makahiki is an open source “serious game engine for sustainability”. It provides a framework for creating serious games for the purpose of education and behavioral change regarding energy, water, food, and waste generation and use.

The initial version of Makahiki (Version 1) was developed in support of first Kukui Cup energy challenge held at the University of Hawaii in Fall, 2011. Some of the goals of the Kukui Cup challenge are to support:

  • A synergistic mixture of real-world and virtual world activities.
  • Real-time feedback on energy consumption by residence hall teams.
  • Incentives in the form of prizes and raffle games.
  • Social networks, both physical (residence hall teams) and virtual (Facebook).
  • Activities to raise player consciousness and literacy regarding energy issues.

Makahiki 2 builds upon the prior version with the following new features:

  • The ability to tailor system functionality to support the requirements of different organizations.
  • Support for PaaS (Platform as a Service) facilities such as Heroku. This enables organizations to create and deploy challenges without obtaining physical hardware and its requisite IT support.
  • The ability to extend the framework with new modules to support sustainable resource challenges such as water, food, and waste in addition to energy.
  • The use of HTML5/CSS3 “responsive” design techniques for support of laptop, tablet, and smart phone interfaces.
  • Real-time game analytics to help assess the impact of game mechanics during challenges.
  • A-B testing to support research evaluation of components by deploying alternative versions to subsets of the population. (Under development)

Research Publications

We maintain a online list of research publications on Makahiki.

Contact Us

For more information about this project, please contact the director:

Professor Philip Johnson
Information and Computer Sciences
University of Hawaii
Honolulu, HI 96822
808-956-3489

Of course, the vast majority of work has been done by talented graduate students at the University of Hawaii, including: George Lee, Yongwen Xu, and Robert Brewer.

Guided Tour

Perhaps the best way to introduce Makahiki is through a simple tour of its interface. The following tour was developed using a test instance of the system in Summer, 2012. Not all features of the system will be covered in this tour, and some features may be slightly different in the version of the system you are using.

This guided tour illustrates the laptop user interface. Makahiki is designed in a “responsive” fashion, so the user interface will look slightly different from this on iPads, smart phones, and large screen displays.

Landing

_images/guided-tour-landing.png

The landing page is the first page encountered by new users. So far, challenges built using Makahiki have a “closed” registration model; that is, the users of the system are known in advance and set up during the configuration process. Thus, the landing page has two buttons: one for users who live in a particular place and thus should have access to the system, and one for those who are just visiting and would like to learn more about the system.

Most of the content on this page is configurable, including the University logo, the slogan, the text fields and button contents, and the sponsors.

About

_images/guided-tour-about.png

Users who click on the bottom button on the landing page are taken to this About page, which provides more information about the Challenge. This content is configurable.

Authentication

_images/guided-tour-authentication.png

Users who click on the top button on the landing page are taken to an authentication page. Makahiki supports CAS, LDAP, and internal (Django) authentication mechanisms. The screen shot above shows the University of Hawaii CAS authentication screen.

Site administrators can configure which authentication scheme(s) are used for any particular challenge.

First login sequence

If a user provides acceptable credentials during the authentication process, then the first time they access the system they enter the “first login” process, which is a series of modal dialogs intended to help orient them to the system.

_images/guided-tour-first-login-1.png

The above dialog provides initial information about logging in and requests verification that the system’s internal records about the user are correct.

_images/guided-tour-first-login-terms.png

The above dialog ensures that the user has consented to the terms and conditions of the system. (The terms and conditions are configurable.)

_images/guided-tour-first-login-referral-bonus.png

The next dialog illustrates one of Makahiki’s game mechanics: the referral bonus. If a player gets another player to sign up, both players earn additional points.

The use of the referral bonus game mechanic, and the number of points awarded, is configurable.

_images/guided-tour-first-login-profile.png

The dialog above enables users to customize aspects of their profile.

If Facebook integration is enabled, then users can choose to use their Facebook profile picture. (Facebook integration is not enabled in this configuration.)

_images/guided-tour-first-login-video.png

When first time players get to the above dialog box, they are asked to watch a short, 3 minute video that introduces them to the Kukui Cup. They are notified that they will be quizzed on this material in the next screen.

_images/guided-tour-first-login-video-verification.png

Players answer the question in order to proceed and obtain points for doing so.

_images/guided-tour-first-login-final.png

The above screen is the final one in the first login sequence, which provides some final comments about what happens next and a plug for the Quest mechanism as an additional tool to supporting learning about the system.

Home

After finishing the first login sequence, the players are taken to the following Home page. The system sets a cookie when the player authenticates, and notes that the first login sequence has been completed. Thus, after the first visit, the player will normally go directly to this page when retrieving the challenge URL.

_images/guided-tour-home.png

The user interface components are discussed in the three minute video, so the player should have some familiarity with them when they reach this page for the first time. From top to bottom:

  • The “Info Bar” is a horizontal UI component at the top of every page. It provides status information about the challenge as well as a logout link. (The player will not normally need to logout unless they are accessing the site from a public computer.)
  • The “Nav Bar” is a horizontal UI component below the Info Bar, which provides icons that link to all of the top-level pages in the system. The set of pages in the system is configurable.
  • The “Quest Bar” is a horizontal UI component below the Nav Bar. It provides “Quests” (explained in more detail below).

Those three elements appear on every page. On the home page, below these three components, are enlarged images of the icons in the Nav Bar along with short descriptions of their content.

Quests

Makahiki provides a configurable “Quest Engine”, that enables the definition of quests and the dependencies among them. That enables site developers to create a kind of structured, “just-in-time” documentation for the system. Users learn about the capabilities of the site by performing discrete sequences of actions. Quests have a completion predicate, so if a plauyer has already shown mastery of a certain concept, the Quest will not appear.

The Quest Bar shows the next three quests available for the player. Clicking on the link expands the window to reveal the quest. Once expanded, the window stays that way even as players navigate to other pages so that the Quest description is always accessable while the Player carries out the associated actions.

Here is the expanded window corresponding to the “Learn Secrets of Kukui Cup Masters” quest:

_images/guided-tour-quests.png

Get Nutz

The “Get Nutz” page provides the user interface to the primary “literacy” game, also known as the “Smart Grid Game”. Players gain points by clicking on cells in the Smart Grid widget, which takes them to activities, commitments, events, and excursions.

Here is an example of the Get Nutz page (the name of this page and any other top-level page can be configured by site administrators):

_images/guided-tour-get-nutz.png

The page also provides widgets about upcoming events and a scoreboard showing point leaders.

Clicking on the 30 point purple link in the middle of the smart grid game takes the player to a page explaining that excursion. Here is an example of that page:

_images/guided-tour-excursion.png

This page also provides social details (how many other students have signed up) and enables students to request a reminder by email or text message.

It also implements the “signup bonus” game mechanic. After clicking on the “I want to sign up” link, the page displays the following additional information to the player:

_images/guided-tour-excursion-signup.png

Go Low

The “Go Low” page provides the user interface to two “energy” games, as shown below:

_images/guided-tour-go-low.png

On the left side, the “Daily Energy Goal Game” incentivizes players to reduce their energy usage by awarding them points if they can reduce their team’s energy by a certain percentage below a baseline value. The stoplight visualization tells them whether or not they are currently on track to make the goal.

On the right side, the “Current Power” visualization helps players to see what their current power consumption is in near real-time (typically every 10-15 seconds.)

The page also enables team members to communicate via a shared chat window, and provides a scoreboard widget showing leaders in energy conservation.

This Go Low page is configured with an “automated” Daily Energy Goal Game, in which the energy data is gathered automatically by meters. Administrators are required to set up this communication, typically using the WattDepot system.

The next page shows an alternative approach available in Makahiki when the resource in question cannot be gathered automatically.

News

The “News” page provides information about the state of the challenge and the team of which this player is a member:

_images/guided-tour-news.png

Widgets such as “Lounge Members”, “Most Popular Excursion”, “My Public Commitments”, etc. all provide a sense for the state of the competition and encourage players to participate by learning about what others members are doing.

Prizes

The “Prizes” page provides access to two games: the “Top Scorer” game and the “Raffle” game:

_images/guided-tour-prizes.png

The Top Scorer game, illustrated by the widget on the left, shows the prizes that can be won by top scorers in the competition.

The Raffle Game provides an alternative route to winning. Here, players earn in-game raffle tickets based upon their point score that can be allocated to any of a collection of raffle prizes. The odds of winning are based upon the percentage of their tickets allocated to the prize, which is picked at random at the end of a round by administrators.

The Raffle Game provides an incentive for players to do activities and earn points even if they do not stand a chance of winning one of the Top Scorer prizes.

Profile

The “Profile” page provides access to profile information for this player:

_images/guided-tour-profile.png

The user can set their display name, their picture, and how they wish to be contacted for reminders. It also shows information about their badges and a complete record of how they earned all of the points in the game.

The profile page also allows them to change the theme associated with the site. A variety of themes are available. In this configuration, the default theme is “Forest”, but the user can go to the Profile page to set a different them for their own use. For example, here is the “Wave” theme:

_images/guided-tour-profile-wave.png

And here is the “Space” theme:

_images/guided-tour-profile-space.png

Help

The final page available to players is the Help page, which simply provides access to explanatory material about the system:

_images/guided-tour-help.png

Status (Admin only)

Administrators have access to special pages. One of these is called the “Status” page, which displays a large number of different widgets with various kinds of information about the state of an ongoing challenge. Here is a screenshot of part of the Status page (with the “Bumblebee” theme enabled):

_images/guided-tour-status.png

The Status page is designed to help administrators to monitor the progress of their challenge, detect problems with the system and/or state of play, and intercede to correct them in a timely manner.

Settings (Admin only)

The final page to be shown in this guided tour is the settings page, which is also restricted to Administrators:

_images/guided-tour-settings.png

Administrators use the Settings page to configure the site, design the challenge, manage a running challenge, generate analytics after the challenge is over, and support new development. These capabilities are documented further in Site Configuration.

Architecture

External architecture

Let’s begin by illustrating how Makahiki fits into the broader system context.

_images/system-architecture.png

As the figure above shows, Makahiki interfaces with the outside environment in four different ways.

First, the left side of Makahiki illustrates the primary user interface: that with the players of the challenge implemented by Makahiki.

Second, the top side illustrates a specialized user interface provided for administrators of the system. This interface provides access to real-time game analytics, interfaces to administer the various game components, and access to other admin-only services.

Third, the right side illustrates that Makahiki must obtain real-world environmental data as the challenge progresses in order to provide feedback to users about the impact of their actions. In some cases, environmental data can be input automatically into the system through a combination of “smart” meters and additional services (such as the WattDepot system for energy data collection, storage, and analysis). If that is not possible, then manual meters can be read by administrators on a regular (typically daily) basis and input into Makahiki using and administrator interface.

Fourth, the bottom side illustrates that Makahiki stores its data in a database repository (currently PostgreSQL). To reduce database access and improve performance, Makahiki provides support for caching (currently memcached).

Finally, the figure shows that Makahiki has three major internal components: authentication and page display, widgets, and managers. The next section provides more detail on this internal architecture.

Internal architecture

The following figure provides a perspective on Makahiki’s architecture in terms of three kinds of “components”: Django-related infrastructure, Widgets, and Managers.

_images/system-internal-architecture.png

This categorization is intended to provide the following conceptual understanding.

Managers are modules that provide Makahiki capabilities that do not involve a (player) user interface. They might provide interaction with administrators via the Django admin interface. Managers can implement game mechanic data structures (such as scores, players, and teams) or more generic web service functions (transactions, authorization, etc.)

Widgets are modules that provide Makahiki capabilities that do include a player user interface. Widgets can be roughly characterized in three ways. “Info widgets” provide state information about the challenge to players but little in the way of interaction. “Mechanics widgets” provide game elements such as Quests and Badges. The third category, “game widgets”, or “gamelets”, refer to full-fledged interactive games.

Django components are modules that provide the web service “glue” to hold the rest of the system together.

Site Administration Guide

This guide is divided into sections that follow the phases of the “life cycle” of a Makahiki serious game project:

1. Software Installation. During this phase, you download and install the Makahiki software and related systems.

2. Site Configuration. During this phase, you configure your Makahiki installation to the specifics of your IT infrastructure (authentication, email, etc.)

3. Challenge Design. During this phase, you tailor Makahiki to the specifics of your challenge, specifying the players, the start and end times, the rounds, the games, the Smart Grid Game activities, excursions, and commitments, the prizes, the default theme, and so forth.

4. Challenge Management. During this phase, the challenge is running and players are actively using your system. Management activities include monitoring game play, verifying Smart Grid Game activity submissions, and so forth.

5. Challenge Postmortem. After the challenge is over, this phase focuses on analysis of the data collected with the goal of better understanding what happened and how to improve your challenge design in the future.

Software Installation

The first step in using Makahiki is to install the software. In order to do this, you must make two decisions:

1. Will Makahiki be installed and run locally in your own IT environment, or do you want Makahiki to be hosted and run “in the cloud”, through the Heroku PaaS infrastructure?

2. Do you desire automated, near real-time monitoring of energy data? If so, you will need to also install WattDepot, a system for collection, storage, and analysis of energy data.

The installation process depends upon your answers to these questions. The following sections go into more detail on these issues.

Install Makahiki

Makahiki supports two forms of installation: local (on your own machine) and cloud-based (to the Heroku application hosting service).

Developers of Makahiki will want to install the system locally.

Organizations will want to install Makahiki locally if they wish to host the system themselves. This requires sufficient hardware resources and IT support to do the installation, perform backups, and monitor the system during the challenge and deal with any outages that occur.

Organizations can instead choose to host Makahiki with Heroku. This incurs a cost (we estimate from $50-$100 per month of the challenge), but has the benefit that no hardware or IT resources are required.

Local installation of Makahiki

Installation of a local instance of Makahiki is different depending upon whether you are running on a Unix (Mac OS or Linux) or Windows environment.

The Vagrant installation creates a virtual machine that works on Mac OS X, Linux, or Windows.

Local Virtual Machine Installation on Vagrant

Vagrant is an application for managing virtual machines that enables the same configuration to be applied to more than one machine based on a Vagrantfile. This allows virtual machines used by different developers to have the same settings and environment configured on them automatically.

Vagrant can be installed on Linux, Mac OS X, and Windows.

This virtual machine is for development. It should not be used as a production server.

To install VirtualBox and Vagrant and download the Makahiki source code, use Setting Up the Makahiki and Vagrant Development Environment.

To install Makahiki on Vagrant and start the server, use Quick Start Guide: Makahiki on Vagrant.

If you want to use Eclipse to develop software with Makahiki, use Using Eclipse to Develop With Makahiki on Vagrant.

The rest of these sections are optional. They describe how to make changes to the configuration of Makahiki and the Vagrant virtual machine.

Setting Up the Makahiki and Vagrant Development Environment

These instructions configure a VirtualBox Ubuntu 12.04 LTS 32-bit virtual machine with Vagrant, and download the Makahiki source code.

With the exception of Windows users, this guide assumes that you are using a Bourne-type shell (such as bash), which is the default on Mac OS X and Linux. Using a C-shell variant (like tcsh) is possible but not recommended.

Hardware Requirements

A modern dual core CPU with 4 GB RAM should be sufficient to run the virtual machine.

Host Operating System Recommendations

The host OS is the OS that Vagrant and VirtualBox will be installed on. If your OS is not listed here, make sure that Vagrant and VirtualBox are available for your OS.

  • Windows 7 or 8
  • Mac OS X
  • Recent version of Red Hat Enterprise Linux, CentOS Linux, or Ubuntu Linux
Install VirtualBox

Download VirtualBox for your host OS by following the instructions on the VirtualBox downloads page.

Follow the installation instructions for your operating system in Chapter 02 of the VirtualBox manual. Select Yes when asked to install drivers for USB support and VirtualBox Host-Only Networking.

Install Vagrant

Download the latest Vagrant installer for your host OS.

The latest version of Vagrant with which this installation process has been tested is 1.6.2.

Other versions with which this process has been tested are 1.2.4, 1.3.5, and 1.4.3. The installation process should work correctly with all Vagrant versions from 1.2.4 through 1.6.2.

Follow the Vagrant installation instructions.

Open A Command Line Application

Open a command line terminal on your system. The Windows terminal is called “Command Prompt.” The Mac OS X terminal is called “Terminal.” Most Linux systems with a graphical user interface call their terminal “Terminal.”

Terminals usually begin each input prompt with the directory (also called a “folder”) that is the user’s current location in the file system. This is called the “working directory.” Terminals usually end their input prompt with a special character (e.g., >, #, or $).

When a user types a system command or program-specific command at the input prompt and presses Enter, the operating system runs the program specified by the command.

Note

In the rest of this article, a “>” is used to indicate a generic command prompt on any host OS (Windows, Mac OS X, or Linux). Commands appearing after a “>” prompt in this article should work on all three operating systems. Though some systems automatically append a space after the prompt, you do not need to type a space before a command.

Windows

Open a Command Prompt or type cmd.exe in Run.

An example of the Windows Command Prompt:

_images/example-windows-command-prompt.png

The Windows command prompt opens with a working directory of C:\Users\<username>, where <username> is the username of the current user. A Windows command prompt that has been opened with “Run as Administrator” opens in C:\Windows\system32.

This guide does not require a Command Prompt to be run as an Administrator. However, administrative privileges may be required to resolve security and permissions issues related to Vagrant.

Mac OS X

Open a Terminal. If your default shell is not bash, type bash to temporarily switch to a bash shell.

If you are using a recent version of OS X, you will not need to change the shell unless you changed the default shell in the past. The bash shell has been the default shell since OS X 10.3.

An example of the OS X Terminal:

_images/example-osx-terminal.png

The ~ indicates that the user is in their user home directory.

Linux

Open a Terminal. If you are using a headless OS (an OS that does not have a graphical user interface), you are already in the Terminal.

Though every Linux distribution does this a little differently, most distributions open a terminal with a command prompt of the form:

<username>@<computer_name>:<working_directory>$

An example of a Terminal shell window from Ubuntu Linux:

_images/example-ubuntu-terminal.png

The ~ indicates that the user is in their user home directory. On Ubuntu, this is equivalent to /home/username.

Download the Base Virtual Machine

Download the base virtual machine image precise32 from Vagrant’s servers:

> vagrant box add precise32 http://files.vagrantup.com/precise32.box

Note

It is only necessary to download each base virtual machine (“box”) once per user account on the host OS. Once the “precise32” box has been downloaded, it can be reused by Vagrant to create any virtual machines that specify “precise32” in their Vagrantfiles. If your host OS is Windows and you switch to another user account, you will need to download the “precise32” box again.

Download the Makahiki Source Code

Downloading the Makahiki source code will create the “makahiki” directory.

There are two ways of obtaining the Makahiki source code: downloading it as an archive, or cloning the Git repository.

Note

The “makahiki” directory created by extracting the .zip file or cloning the repository will be the directory Vagrant uses as a reference point for accessing the virtual machine. This guide refers to that directory as the “makahiki directory.”

Download the Archive

Follow these instructions if you do not have Git or Git for Windows and are unable to install them.

  1. Go to https://github.com/csdl/makahiki
  2. Click the button to “Download ZIP.”
  3. Extract the makahiki.zip file that is downloaded.
  4. Move the extracted “makahiki” directory to the directory you want to start the Vagrant virtual machine from.
Clone the Repository

Follow these instructions if you have installed or are going to install Git or Git for Windows.

Windows users can install Git for Windows.

OS X and Linux users should be able to download Git for their operating system. See GitHub’s setup guide for instructions.

After installing Git or Git for Windows on your operating system, go back to your Command Prompt or Terminal.

In the Command Prompt or Terminal, change your working directory to the directory you want to place the Makahiki source code directory in:

> cd <path-to-directory>

For example, if you wanted the source code to be in C:\Users\username\Vagrant, you would use the command cd C:\Users\username\Vagrant to change your working directory.

An example in Windows:

_images/windows-command-prompt-vagrant.png

Then, enter this command in your Command Prompt or Terminal to clone the repository:

> git clone http://github.com/csdl/makahiki.git

Note

If the “git clone” command does not work in the Windows Command Prompt, you will need to use the “git clone” command in the Git for Windows terminal instead.

Install Makahiki On Vagrant

To install Makahiki, continue to Quick Start Guide: Makahiki on Vagrant.

Quick Start Guide: Makahiki on Vagrant

If you have not already installed VirtualBox and Vagrant and downloaded the Makahiki source code, complete Setting Up the Makahiki and Vagrant Development Environment before completing this section.

Note

In this article, a “>” indicates a command prompt on the host OS. Commands appearing after a “>” should work on Windows, OS X, and Linux unless otherwise stated.

Note

The “makahiki>” prompt indicates that the working directory is in the “Makahiki directory” on the host machine. The file path preceding “makahiki” (e.g., “C:\Users\username\Vagrant\makahiki>”) will be different depending on the location of the directory in the file system of the host OS.

If a Command Prompt (Windows) or Terminal (OS X and Linux) shell is not open on your host machine, open one.

Set up Makahiki in the Virtual Machine

In your Command Prompt or Terminal, switch your working directory to the “makahiki” directory that was created in Setting Up the Makahiki and Vagrant Development Environment:

> cd <path-to-makahiki>/makahiki

Replace <path-to-makahiki> with the file system path to the “makahiki” directory. On Windows, if your “makahiki” directory is located at C:\Users\username\Vagrant\makahiki, you would use the command cd C:\Users\username\Vagrant\makahiki here. On Linux, if your “makahiki” directory is at /home/username/vagrant/makahiki, you would use the command cd /home/username/vagrant/makahiki here.

A Windows example:

_images/windows-command-prompt-vagrant-switch.png

The “makahiki” directory was created when you cloned the Git repository in Setting Up the Makahiki and Vagrant Development Environment. It contains the Vagrantfile which defines the settings of the Vagrant virtual machine. It also contains all of Makahiki’s source code.

Use the vagrant up command to start the virtual machine for the first time:

makahiki> vagrant up

Warning

Windows users may see multiple warnings while vagrant up is running for the first time.

  • A Windows Firewall warning about vboxheadless.exe: This application should be allowed.
  • VirtualBox is attempting to make changes to the system: This should be allowed. It is needed for Vagrant / VirtualBox host-only networking to work.

Warning

If your Vagrant version is less than 1.3.0, you are starting your virtual machine for the first time, and you do not want to lose your configuration, start Vagrant with --no-provision:

makahiki> vagrant up --no-provision

In Vagrant versions prior to 1.3.0, each time Vagrant is started with vagrant up, it will run the run_bootstrap.sh provisioning script specified in the Vagrantfile. This runs another script, bootstrap.sh, which:

  • Sets the system locale to en_US.UTF-8
  • Drops the PostgreSQL cluster data directory, erasing all data in all databases
  • Re-initializes the cluster data directory
  • Re-initializes the Makahiki database

The run_bootstrap.sh script logs the output of bootstrap.sh to a file in makahiki/vagrant/logs. This file will be called “ubuntu_x86_<timestamp>.log,” where timestamp is a string in the format yy-mm-dd-HH-MM-SS (year, month, day, hour, minute, second).

When the script finishes running, look at the last few lines of output:

-------------------------------------------------------------------------------
Configuration setup results:
-------------------------------------------------------------------------------
1. Copying locale settings to /etc/bash.bashrc: [Succeeded]
2. Copying settings to pg_hba.conf: [Succeeded]
3. Creating /home/vagrant/makahiki_env.sh: [Succeeded]
4. Appending to /home/vagrant/.bashrc: [Succeeded]
-------------------------------------------------------------------------------

If the value for a task is “Succeeded” or “Already completed,” continue to the next step. If the value for a task is “Failed,” go to Troubleshooting Makahiki on Vagrant.

Connect to the Vagrant Virtual Machine

Start an SSH session with the Ubuntu virtual machine:

makahiki> vagrant ssh

An Ubuntu command prompt will be displayed:

vagrant@precise32:~$
Start the Server

Note

The /vagrant directory that contains /vagrant/makahiki is a special directory that is synchronized with the “makahiki” directory (folder) on your host OS.

  • Any file added to /vagrant on the virtual machine will be added to makahiki on the host machine.
  • Any file added to makahiki on the host machine will be added to /vagrant on the virtual machine.

To start one of the two web servers that Makahiki provides, switch to the /vagrant/makahiki directory:

vagrant@precise32:~$ cd /vagrant/makahiki

The two servers are runserver, which is better for development, and gunicorn, which is better for production use.

To start the runserver server:

vagrant@precise32:/vagrant/makahiki$ ./manage.py runserver 0.0.0.0:8000

Example output of starting runserver:

vagrant@precise32:/vagrant/makahiki$ ./manage.py runserver 0.0.0.0:8000
Validating models...

0 errors found
Django version 1.4, using settings 'settings'
Development server is running at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

To start the gunicorn server:

vagrant@precise32:/vagrant/makahiki$ ./manage.py run_gunicorn -b 0.0.0.0:8000

Example output of starting gunicorn:

vagrant@precise32:/vagrant/makahiki$ ./manage.py run_gunicorn -b 0.0.0.0:8000
Validating models...
0 errors found

Django version 1.4, using settings 'settings'
Server is running
Quit the server with CONTROL-C.
2013-10-11 01:59:41 [1399] [INFO] Starting gunicorn 0.13.4
2013-10-11 01:59:41 [1399] [INFO] Listening at: http://0.0.0.0:8000 (1399)
2013-10-11 01:59:41 [1399] [INFO] Using worker: sync
2013-10-11 01:59:41 [1408] [INFO] Booting worker with pid: 1408
Verify that Makahiki Is Running

Open a browser on the host machine and go to http://192.168.56.4:8000 to see the landing page, which should look similar to this:

_images/kukui-cup-demo-landing.png

In the virtual machine, stop either server with control-c when you are finished:

vagrant@precise32:/vagrant/makahiki$ (type control-c in the shell running the makahiki server process)

If the site is not reachable from your host machine, or your host machine is headless and has no GUI, refer to Running Makahiki on Vagrant and follow the section on Testing the Server Without a Web Browser.

Makahiki Maintenance Tasks

The basic installation of Makahiki is now complete.

To learn how to reset or update the Makahiki database, continue to Running Makahiki on Vagrant.

Exit Your SSH Session

When you are finished working with the Vagrant virtual machine, end your SSH session by typing exit in the SSH terminal:

vagrant@precise32:/vagrant/makahiki$ exit

On your host OS, you will be returned to the terminal that started the SSH session.

Using Eclipse to Develop With Makahiki on Vagrant

Using Eclipse to develop software with Makahiki is optional. However, .project and .pydevproject files are provided for the convenience of Eclipse users in the makahiki/makahiki directory.

This section assumes that the user has followed the instructions in Quick Start Guide: Makahiki on Vagrant to configure the Vagrant virtual machine.

Eclipse is an Integrated Development Environment (IDE) that requires Java. Eclipse is available for Windows, OS X, and Linux at http://eclipse.org.

You will not be able to run Django-based Python files on your host OS. You will need to run them in Vagrant after editing them in Eclipse on your host OS.

Installing Eclipse Prequisites
Prequisites for the Eclipse installation are listed below:
  • Python 2.7.3 or later (but not Python 3): Required

  • Java JRE or JDK (Java 6 or newer): Required

  • Eclipse IDE (Eclipse 4.2 Juno or newer recommended): Required

  • PyDev Eclipse Add-on: Required

  • Configure Line Endings and Character Encodings: Required

  • Eclipse Add-ons: Web, XML, Java EE and OSGi Enterprise Development (Optional)
    • Eclipse Web Developer Tools (HTML/XHTML/CSS editors)
    • JavaScript Development Tools (JavaScript editor)
  • Eclipse Add-ons: Remote System Explorer (Optional)
    • Remote System Explorer End-User Runtime
    • Remote System Explorer User Actions
  • Set Hidden Files and Folders as Visible (Optional)

The following sections describe how to install or configure them.

Prerequisites: Python

Follow the instructions at Python.org to download and install a Python binary on your host OS. To develop software with Makahiki, you must install a version of Python that is 2.7.3 or higher (but not Python 3).

Prerequisites: Eclipse

Eclipse is an Integrated Development Environment (IDE) available from eclipse.org.

Follow the Eclipse.org installation instructions to install Eclipse (and Java if necessary) on your host machine.

Eclipse requires that the Java JRE (Java 6 or later) be installed on the host machine. The full Java JDK (which includes the JRE) is useful for Java development, but it is not required for Makahiki development.

Prerequisites: PyDev

PyDev is an Eclipse add-on that is required for Python development. Follow the Pydev.org installation instructions to install PyDev for your Eclipse installation.

Prerequisites: Configure Line Endings and Character Encodings

It is very important to set these preferences before editing any of the project files or creating new ones.

  1. In Eclipse, go to Window –> Preferences.

  2. Go to Preferences –> General –> Workspace. Click once on Workspace.

  3. In Workspace:
    • Under “Text File Encoding,” select “Other,” then select “UTF-8” from the dropdown menu.
    • Under “New Text File Line Delimiter,” select “Other,” then select “Unix” from the dropdown menu.
  4. Click “Apply” when finished.

Prequisites: Web Development Add-Ons

The “Web, XML, Java EE and OSGi Enterprise Development” set of add-ons is optional. Makahiki uses Django and contains JavaScript, HTML, and CSS files, so general web development tools are useful.

  1. Open Eclipse. In the Help menu, select “Install New Software.”
  2. For the “Work with:” dropdown menu, select the “releases” URL that matches your Eclipse version. For Eclipse 4.2 Juno, for example, this would be “Juno - http://download.eclipse.org/releases/juno.”
  3. In the list of packages that appears below, click on the arrow to the left of “Web, XML, Java EE and OSGi Enterprise Development.” to expand the category. * The “Eclipse Web Developer Tools” provide HTML/XHTML/CSS editors. * The “JavaScript Development Tools” provide a JavaScript (.js) editor.
  4. Check the boxes for the add-ons you want to install.
  5. Click “Next,” then “Next.” You may need to agree to one or more licenses.
  6. Restart Eclipse when prompted. After the restart, any new editors or features will be installed and ready for use.
Prequisites: Remote Systems Explorer

The Remote Systems Explorer addons are optional. They are only required if you plan to connect to the Vagrant virtual machine from within Eclipse.

  1. Open Eclipse. In the Help menu, select “Install New Software.”
  2. For the “Work with:” dropdown menu, select the “releases” URL that matches your Eclipse version. For Eclipse 4.2 Juno, for example, this would be “Juno - http://download.eclipse.org/releases/juno.”
  3. Type “remote” in the search bar and wait for the search to finish. Check the boxes for the add-ons “Remote System Explorer End-User Runtime” and “Remote System Explorer User Actions.”
  4. Click “Next,” then “Next.” You may need to agree to one or more licenses.
  5. Restart Eclipse when prompted. After the restart, any new editors or features will be installed and ready for use.
Prerequisites: Set Hidden Files and Folders as Visible

This step is optional.

  1. Open Eclipse. If you are not in the PyDev perspective, click on the “Open Perspective” button, and select PyDev.
  2. In the “Package Explorer” sidebar, click on the white down-pointing arrow In this menu, click “Customize View.”
  3. In the “Available Customizations” popup that appears, uncheck the checkbox for ”.*resources,” then click “OK.”
  4. The hidden files and folders that start with a ”.” character (e.g., ”.project” and ”.pydevproject”) should now be visible in Eclipse.
Import Makahiki as an Eclipse Project

Your Vagrant virtual machine and its .vagrant folder should be located at the top level of the cloned makahiki repository, where the Vagrantfile is.

Importing the makahiki directory as an Eclipse project when the makahiki directory is also the Vagrant shared directory allows you to modify Makahiki source files on your host machine, then deploy the changes in your Vagrant virtual machine immediately.

  1. Open Eclipse.

  2. When prompted to select a workspace, click “Browse.” In the file system’s browser (Windows Explorer, OS X Finder, etc.), select the directory that you cloned the Makahiki repository into earlier, then click “OK.”

    For example:

    • Makahiki was cloned into: C:/Users/Tester/Vagrant
    • Workspace directory should be: C:/Users/Tester/Vagrant.
  3. Eclipse will open. In the menu, click File –> Import.
    3a. Click the arrow to expand “General,” then select

    “Existing Projects Into Workspace.” Click “Next.”

    3b. Uncheck the “Copy Projects into Workspace” checkbox.

    Select the makahiki/makahiki directory as the root directory.

    For example:

    • Makahiki was cloned into: C:/Users/Tester/Vagrant
    • Project root directory should be: C:/Users/Tester/Vagrant/makahiki/makahiki

    3c. Check the checkbox for “makahiki” when it appears. Click “Finish.”

  4. Assuming that you installed PyDev, you will receive the warning: “It seems that the Python interpreter is not currently configured.” Select “Auto config” if your Python interpreter is on your operating system’s PATH. Otherwise, use “Manual config” to select it manually. These instructions assume you selected “Auto config.”

  5. If you selected “Auto config,” you will get a “Selection needed” popup. The defaults are usually fine. Click “OK” to continue.

  6. You will be shown the “Interpreter - Python” menu. Click “Apply” to configure the Pythonpath for Eclipse.

    If you need to change these libraries later, go to Window –> Preferences –> PyDev –> Interpeter - Python, and select the “Libraries” tab.

Opening an SSH Session in Eclipse

If you have installed the Remote System Explorer addons, you can start an SSH session to the Vagrant virtual machine from within Eclipse. The following steps involve the Remote System Explorer perspective.

In the Perspectives toolbar (upper-left-hand corner), click “Open Perspective.” Select “Remote System Explorer.”

If you want to view your project files, you can switch back to the PyDev perspective, or expand the “Local” –> “Local Files” directory tree in the Remote Systems tab to find the “makahiki” directory.

Start or Resume Vagrant in a Local Shell

If you previously started your Vagrant virtual machine with vagrant up or vagrant resume, you can skip this subsection.

  1. In the “Remote System Explorer” tab, go to Local –> Local Shells. Right-click Local Shells and click “Launch Shell.”

  2. A “Remote Shell” tab will open. It runs the command shell on your host machine, and commands are entered in the “Command” text field. The current directory will be the directory you installed Eclipse into.

    Switch to the top-level “makahiki” directory:

    > cd <path-to-makahiki>/makahiki
    
  3. Check the virtual machine’s status:

    > vagrant status
    
  4. If your Vagrant virtual machine is shut down, start it:

    > vagrant up --no-provision
    

    If your Vagrant virtual machine is suspended instead, resume operation:

    > vagrant resume
    
Define and Start an SSH Session

In the “Remote Systems” sidebar, click the button labeled “Define a connection to remote system.”

  1. In the “New Connection” popup, click “SSH Only” then click “Next.”

  2. Set the “Host name” to 127.0.0.1. Set the “Connection name” to anything you like. Click “Finish.”

  3. The connection you defined will appear in the sidebar. Click the black arrow to the left of it to expand it.

  4. Right-click “SSH Shells” then click on “Properties.”

  5. Click “Subsystem” in the “Properties for Ssh shells” popup. Specify “Port” as “2222,” and “User ID” as “vagrant.” When finished, click “OK.”

  6. Right-click “Ssh Terminals,” then click “Connect.” Use the password “vagrant” when prompted.

  7. If you see a warning similar to the below example, click “Yes” to continue:

    The authenticity of host 'LOCALHOST' can't be established.
    RSA key fingerprint is e6:ad:1e:ee:15:53:7d:a6:ee:7c:aa:04:7a:ad:9a:9a.
    Are you sure you want to continue connecting?
    
  8. If you see a popup similar to the below example, click “Yes” to continue:

    C:\Users\<username>\.ssh\known_hosts does not exist.
    Are you sure you want to create it?
    
  9. In the Remote Systems sidebar, right-click “Ssh Terminals” and click “Launch Terminal.” This will open an SSH session terminal under “Terminals.”

    _images/eclipse-remote-systems-explorer-ssh.png

The SSH session can be used to run Makahiki scripts and the Makahiki web server, like a normal SSH session. Using “exit” or “logout” will close the session, but pressing Enter will launch a new session. Close the “Terminals” tab when you are done.

Note

As of Eclipse Juno, there is a bug in the Terminals display of the Remote Systems Explorer. Pressing backspace will cause the terminal prompt to disappear. Any text before your cursor position will also disappear. The text remains typed in the virtual machine.

Enabling Makahiki Code Completion in Eclipse PyDev
Copying Makahiki Dependencies to the Shared Directory

Assuming that the pip installation completed successfully when the provisioning script was run, the pip packages will be located in /usr/local/lib/python2.7/dist-packages.

Copy the dist-packages directory into the /vagrant/makahiki shared directory:

vagrant@precise32:~$ cd /usr/local/lib/python2.7/dist-packages
vagrant@precise32:/usr/local/lib/python2.7/dist-packages$ ls
-- output omitted --
vagrant@precise32:/usr/local/lib/python2.7/dist-packages$ cd ../
vagrant@precise32:/usr/local/lib/python2.7$ cp -rL dist-packages /vagrant/makahiki/

On your host machine, the dist-packages directory will appear at <path-to-makahiki>/makahiki/makahiki/dist-packages, where <path-to-makahiki> is the file system’s path to your makahiki installation.

Pythonpath and Code Completion Settings in Eclipse PyDev

Open Eclipse. Switch to or open the PyDev perspective if you are not in it.

  1. In the PyDev perspective, click on Window –> Preferences –> PyDev –> Interpreter - Python, then select the “Libraries” tab.

  2. Click on “New Folder.”

  3. In the “New Folder” window, click the white right-pointing arrow to expand the directory tree. In the directory tree, browse to <path-to-makahiki>/makahiki/makahiki/dist-packages. Click on the directory to highlight it, then click “OK.”

  4. In the main “Interpreter - Python” window, click “Apply” to rebuild Eclipse’s System Pythonpath.

  5. In the PyDev perspective, click on Window –> Preferences –> PyDev –> Editor –> Code Completion. These options may be useful:

    • Request completion on ‘.’?
    • Request completion on all letter chars and ‘_’?
  6. To test the code completion, open any Python file. At the top of the file, begin typing this line:

    from django.core.cache import File
    

    When the code completion popup opens, press Control+Space to switch from “templates” to “default completions.” “Default completions” gives you a list of suggested package modules, while “templates” gives you common Python keywords. Use Control+Space to cycle between the two.

If imports are still marked as not found, you may need to refresh the project before changes to the Pythonpath take effect. Right-click the top-level makahiki folder in Eclipse, and click “Refresh.”

Warning

  • Code completion does not always mean that a Python script will run correctly or safely in Eclipse on the host machine (as opposed to the virtual machine).
  • Environment variables may not have the right values on the host OS.
  • Shell commands and system calls may fail if your host OS is different from the virtual machine OS.
  • If your host OS is Linux / Unix-based (especially Ubuntu or any distro that is based on Debian) and has some of the same applications, running any script in Eclipse that makes system calls may result in the script’s effects being applied to your host operating system.
Remote Debugging in Eclipse PyDev

The PyDev addon contains a Remote Debugger feature that allows programs started outside of Eclipse to be debugged from within Eclipse. This allows Python scripts on the virtual machine to be debugged in Eclipse on the host machine.

For more information about the remote debugger, refer to the PyDev remote debugger documentation.

Warning

Using the Remote Debugger requires the process running the script on the virtual machine to be able to communicate with PyDev on port 5678.

Windows users, depending on their settings, may need to disable the Windows Firewall completely for the Remote Debugger to work. Disabling the Windows Firewall requires administrative privileges. It is a security risk and should ideally be done on a machine not connected to any networks (or at least any unsecured and/or public networks).

Similarly, Linux and OS X users may need to change their firewall settings if they want to use this feature. This usually requires administrative privileges on the host machine.

Remote Debugger Demonstration

Run the demonstration class to see the remote debugger in action:

  1. On the host machine, look for the directory you installed Eclipse into (the directory that contains the “eclipse” directory). In this directory, navigate to eclipse/plugins/.

  2. Copy the directory with a name of the form org.python.pydev_<version number X.X.X>.<nine digits representing build date> (e.g., org.python.pydev_2.7.5.2013052819) to the <path-to-makahiki>/makahiki/makahiki directory.

  3. In Eclipse, open the Debug perspective.

  4. In the top button menu bar (below the menu bar that contains “File”), search for a bug icon with a “P” next to it. The mouseover text for the icon is “PyDev: Start the pydev server”:

    _images/eclipse-pydev-server-start-button.png

    Click this. In the Debug tab, icons for the “Debug Server [Python Server]” will appear. In the Console tab, the phrase “Debug Server at port: 5678” will appear.

  5. Switch to the PyDev perspective. Navigate to makahiki/makahiki/remote-debugger-demo.

  6. Open pydevd_demo.py. This is an example file that uses the PyDev debugger.

  7. Look at the two import statements at the beginning of the file. These statements must be added to any file in this project that uses the remote debugger:

    import sys;sys.path.append(os.pardir + os.sep + r'org.python.pydev_2.7.5.2013052819\pysrc')
    import pydevd
    

    Check that the path to org.python.pydev_#.#.#.##########pysrc matches the relative path from pydevd_demo.py to the directory copied into makahiki/vagrant in Step 2. Edit it if it does not.

  8. Look for the “pydevd.settrace().” Each occurrence of pydevd.settrace() acts as a breakpoint when the remote debugger is used.

  9. Switch back to the Debug perspective. Run pydevd_demo.py in Eclipse.

  10. pydevd_demo.py will appear under a item called “MainThread.” Note the value for “i” that appears in the Variables tab. Step through the program using the debugger; “i” will be decremented as the loop runs. Output from the program will appear in the Console tab.

    _images/eclipse-debug-server-demo.png
  11. Leave Eclipse open in the Debug perspective. Open a Command Prompt or Terminal, and SSH into your Vagrant virtual machine:

    > vagrant ssh
    
  12. In Vagrant, switch to /vagrant/vagrant and run pydevd_demo.py:

    vagrant@precise32:~$ cd /vagrant/vagrant
    vagrant@precise32:/vagrant/vagrant$ python pydevd_demo.py
    
  13. You should see the same debugging information appear as when you ran the program locally. If it does not work, you may see Errno 110:

    socket.error: [Errno 110] Connection timed out
    

    If you see Errno 110, check your firewall settings.

  14. When you are finished, right-click the Debug Server and click “Terminate and remove” to stop the server and remove it from the tab.

If this does not work, you may need to set the location of the file to be tested in pydevd_file_utils.py.

  1. Navigate to the org.python.pydev_<version> directory you copied into makahiki/makahiki earlier, then go to the pysrc directory. Open the pydevd_file_utils.py file.
  2. Follow the instructions at the beginning of the file to edit the PATHS_FROM_ECLIPSE_TO_PYTHON variable’s value to match the location of your file on the host machine and on the virtual machine.
Adding Remote Debugging Code to a Python File

To add the remote debugging functionality in pydevd_demo.py to any Python file:

  1. Edit the file so that it includes two import statements: one to import the pysrc directory, and one to import pydevd.

  2. Add pydevd.settrace() wherever you would insert a breakpoint in normal Eclipse debugging. It can have up to 4 parameters set:

    • The first parameter, the IP address, must match the .1 address of the host-only network configured in the Vagrantfile.

    • The port, 5678, is the remote debugger’s default port. To edit this setting, go to Windows –> Preferences –> PyDev –> Debug.
      • Edit “Connect timeout for debugger (ms)” to change the timeout setting.
      • Edit “Port for remote debugger” to change the port. Click “Apply” when finished.
    • stdoutToServer sends standard output to the Eclipse debug server.

    • stderrToServer sends standard error output to the Eclipse debug server.

  3. Start the Debug Server in Eclipse.

  4. Run the Python file that will be debugged.

  5. When you are done debugging, remove the import statements and the calls to pydevd.settrace().

If you experience problems other than Errno 110, you may need to edit PATHS_FROM_ECLIPSE_TO_PYTHON in pydevd_file_utils.py. If this is the case, you will need to change the file paths every time you debug a different file.

Troubleshooting Makahiki on Vagrant

This section contains troubleshooting and configuration instructions for a Makahiki installation on Vagrant. Throughout this guide, a % prompt represents the virtual machine command prompt.

If you were linked here from Quick Start Guide: Makahiki on Vagrant, you should jump to the section specific to your problem.

About nano

These instructions assume the use of the nano text editor, which is installed by default on the precise32 virtual machine configured in Quick Start Guide: Makahiki on Vagrant.

Read the nano documentation if you are unfamiliar with nano. The basic controls are as follows:

  • Arrow keys: Move cursor
  • Control-G (^G) Open Help / Control-X (^X): Exit Help
  • Control-O (^O): Save
  • Control-X (^X): Close
  • Control-W (^W): Search
  • Control-Y (^Y): Page Up
  • Control-V (^V): Page Down
  • Control-K (^K): Cuts entire current line.
  • Control-U (^U): Pastes last line that was cut.
  • Control-C (^C): Shows the current position of the cursor at bottom of screen

If you close a document without saving changes, you will be prompted:

Save modified buffer (ANSWERING "No" WILL DESTROY CHANGES) ?

Y saves, N closes without saving, and ^C is cancel.

When you save a document (e.g., one called test.txt), you will be prompted:

File Name to Write: test.txt

Press Enter to continue, or type to edit the file name.

Troubleshooting bash.bashrc and UTF-8 Encodings

Warning

This troubleshooting process erases all databases in the PostgreSQL installation.

You need to change the system and postgresql database encodings if one of the following applies:

  • You experience a DatabaseError when the initialize_instance.py script runs, with the message character 0x##### of encoding "UTF8" has no equivalent in "LATIN1".

  • The locale command returns a non-UTF-8 encoding setting:

    % locale
    LANG=en_US.LATIN1
    LANGUAGE=en_US.LATIN1
    ...
    LC_ALL=en_US.LATIN1
    

If either of these apply, continue.

Open /etc/bash.bashrc with sudo:

% sudo nano /etc/bash.bashrc

Add these lines to the end of the file:

# UTF-8 locale settings for Makahiki
export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

After you are done editing the file, run these commands:

% sudo locale-gen en_US.UTF-8
% sudo dpkg-reconfigure locales
% sudo pg_dropcluster 9.1 main --stop
% sudo pg_createcluster --locale en_US.UTF8 9.1 main
% sudo cp /vagrant/vagrant/config_examples/pg_hba.conf.ubuntu.makahiki /etc/postgresql/9.1/main/pg_hba.conf
% sudo /etc/init.d/postgresql restart
Troubleshooting PostgreSQL
Check PostgreSQL Local Connections

Begin by verifying the PostgreSQL server authentication settings. At the prompt, type psql -U postgres. If it succeeds, type q to quit:

% psql -U postgres
psql (9.1.9)
Type "help" for help.

postgres=#\q

If this fails, you will need to edit pg_hba.conf.

Edit pg_hba.conf

If you cannot connect to the database with psql -U postgres, check that the pg_hba.conf file has the correct settings applied.

On Ubuntu 12.04 LTS, pg_hba.conf is at /etc/postgresql/9.1/main/pg_hba.conf. Open it in the nano text editor with sudo (root) privileges:

% sudo nano /etc/postgresql/9.1/main/pg_hba.conf

Edit the file to match the examples below:

# Database administrative login by Unix domain socket
local   all             postgres                                trust

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

After you have edited the pg_hba.conf file, restart the Postgresql service:

% sudo /etc/init.d/postgresql restart
Troubleshooting makahiki_env.sh

makahiki_env.sh sets values for Makahiki environment variables MAKAHIKI_DATABASE_URL and MAKAHIKI_ADMIN_INFO. Check that these values have been set:

vagrant@precise32:/vagrant$ echo $MAKAHIKI_DATABASE_URL
postgres://makahiki:makahiki@localhost:5432/makahiki
vagrant@precise32:/vagrant$ echo $MAKAHIKI_ADMIN_INFO
admin:admin

If “echo” returns nothing, source home/vagrant/.bashrc (~/.bashrc) and check again:

vagrant@precise32:/vagrant$ source ~/.bashrc

If MAKAHIKI_DATABASE_URL and MAKAHIKI_ADMIN_INFO are still not set, you need to add them to /home/vagrant/makahiki_env.sh.

Create this file if it does not exist:

vagrant@precise32:~$ touch makahiki_env.sh

Open the file in the nano text editor:

vagrant@precise32:~$ nano makahiki_env.sh

The file should contain the lines shown below:

# Makahiki environment variables
# Syntax: postgres://<db_user>:<db_password>@<db_host>:<db_port>/<db_name>
export MAKAHIKI_DATABASE_URL=postgres://makahiki:makahiki@localhost:5432/makahiki
# Syntax: <admin_name>:<admin_password>
export MAKAHIKI_ADMIN_INFO=admin:admin

These settings are only used to initialize the Makahiki database. If you change the username or password in the Makahiki user interface, these settings will no longer apply.

Note

The username:password combination of admin:admin is meant for use in development. In a production server, the value of MAKAHIKI_ADMIN_INFO would be changed to a more secure value.

When you are done editing makahiki_env.sh, source the .bashrc file. This will source the makahiki_env.sh file, which will set the environment variables:

vagrant@precise32:/vagrant$ source ~/.bashrc
vagrant@precise32:/vagrant$ echo $MAKAHIKI_DATABASE_URL
postgres://makahiki:makahiki@localhost:5432/makahiki
vagrant@precise32:/vagrant$ echo $MAKAHIKI_ADMIN_INFO
admin:admin

If this fails, continue to the next section.

Troubleshooting .bashrc

The provisioning script normally appends this line to the “vagrant” user’s .bashrc file:

% source /home/vagrant/makahiki_env.sh

Open /home/vagrant/.bashrc in the nano editor:

% nano ~/.bashrc

Add the line source /home/vagrant/makahiki_env.sh to the end of the file if it is not there. Save the file and source it for changes to take effect:

% source ~/.bashrc
Running Makahiki on Vagrant

This article describes maintenance tasks for the Makahiki database, and describes the process for starting and stopping the Makahiki web server.

Note

In this article, a “%” prompt indicates that a command can be performed from any working directory in the virtual machine. Directories are specified otherwise.

Initialize Makahiki

The provisioning script that was run when the virtual machine was started for the first time initialized the database. This section describes how to initialize the database again.

Warning

Running the initialize_instance.py script will:

  • Install and/or update all pip-installed packages required by Makahiki.
  • Reinitialize the database contents and perform any needed database migrations.
  • Initialize the system with data.
  • Set up static files.

This script should be run only a single time in production scenarios, because any configuration changes that an administrator makes will be lost if the initialize_instance.py script is used again.

The script initializes the Makahiki database and populates it with default information and users.

If the server is running in your terminal, close it:

(type control-c in the shell running the makahiki server process)

Change to the /vagrant/makahiki directory if you are not in it. (The % sign represents a command prompt and indicates that this can be done from any directory on the virtual machine):

% cd /vagrant/makahiki

Next, run the initialize_instance.py script:

vagrant@precise32:/vagrant/makahiki$ ./scripts/initialize_instance.py --type default

You will need to answer Y to the question Do you wish to continue (Y/n)?.

Example output of the initialize_instance.py script:

vagrant@precise32:/vagrant/makahiki$ ./scripts/initialize_instance.py --type default
installing requirements...
WARNING: This command will reset the database. All existing data will be deleted. This process is irreversible.

Do you wish to continue (Y/n)? Y
resetting the db...
DROP DATABASE
DROP ROLE
CREATE ROLE
CREATE DATABASE
syncing and migrating db...
collecting static and media files...
loading base data...
loading fixture base_badges.json...
loading fixture base_help.json...
loading fixture base_notifications.json...
loading fixture base_pages.json...
loading fixture base_quests.json...
loading fixture base_schedule.json...
loading fixture base_settings.json...
loading fixture smartgrid_library.json...
setting up default data...
set up 1 one-week rounds, starting from today.
loading fixture default_challenge.json...
loading fixture default_designer.json...
loading fixture default_prizes.json...
loading fixture default_smartgrid.json...
loading fixture default_teams.json...
0 test users deleted.
4 test users created.
event dates adjusted to round date.
created initial resource usages for all teams.
created test baselines for all teams.
created goal settings for all teams.
makahiki cache cleared.
vagrant@precise32:/vagrant/makahiki$

If the script experiences errors while connecting to the database, see Troubleshooting Makahiki on Vagrant.

Update the Makahiki Instance

Makahiki is designed to support post-installation updating of your configured system when bug fixes or system enhancements become available.

If the server is running in your terminal, close it:

(type control-c in the shell running the makahiki server process)

Change to the vagrant directory if you are not in it. (The % sign represents a command prompt and indicates that this can be done from any directory on the virtual machine):

% cd /vagrant

Download the updated source code into the Makahiki installation:

vagrant@precise32:/vagrant$ git pull origin master

Change your directory to vagrant/makahiki:

vagrant@precise32:/vagrant$ cd makahiki

Next, run the update_instance.py script:

vagrant@precise32:/vagrant/makahiki$ ./scripts/update_instance.py

This updates the Makahiki instance based on any new files that have been added to the Git repository.

Example output of the update_instance.py script:

vagrant@precise32:/vagrant/makahiki$ ./scripts/update_instance.py
installing requirements...
syncing and migrating db...
collecting static and media files...
vagrant@precise32:/vagrant/makahiki$
Start the Makahiki Server

This guide assumes you are in the directory /vagrant/makahiki on the virtual machine.

Makahiki’s manage.py script provides two web servers: runserver and gunicorn. runserver is better for development, and gunicorn is better for production use.

It is important to bind the server to IP 0.0.0.0 (accepts incoming connections on any IP address) and port 8000 in order to work with the port forwarding settings in the Vagrantfile.

To start the server with manage.py:

vagrant@precise32:/vagrant/makahiki$ ./manage.py runserver 0.0.0.0:8000

Example output of starting runserver:

vagrant@precise32:/vagrant/makahiki$ ./manage.py runserver 0.0.0.0:8000
Validating models...

0 errors found
Django version 1.4, using settings 'settings'
Development server is running at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

To start the server with gunicorn:

vagrant@precise32:/vagrant/makahiki$ ./manage.py run_gunicorn -b 0.0.0.0:8000

Example output of starting gunicorn:

vagrant@precise32:/vagrant/makahiki$ ./manage.py run_gunicorn -b 0.0.0.0:8000
Validating models...
0 errors found

Django version 1.4, using settings 'settings'
Server is running
Quit the server with CONTROL-C.
2013-10-11 01:59:41 [1399] [INFO] Starting gunicorn 0.13.4
2013-10-11 01:59:41 [1399] [INFO] Listening at: http://0.0.0.0:8000 (1399)
2013-10-11 01:59:41 [1399] [INFO] Using worker: sync
2013-10-11 01:59:41 [1408] [INFO] Booting worker with pid: 1408

View the site in your host machine’s web browser at http://192.168.56.4:8000.

Log in with the username and password specified in makahiki_env.sh. The username is “admin” and the password is “admin” unless these settings were changed after installation.

To stop either of the servers, type control-c in the virtual machine terminal.

Testing the Server Without a Web Browser

If you cannot reach the web server from the host machine, you will need to use wget to test the server on the virtual machine:

vagrant@precise32:/vagrant/makahiki$ ./manage.py runserver 0.0.0.0:8000 &
Validating models...

Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
vagrant@precise32:/vagrant/makahiki$ (press "Enter" here)
vagrant@precise32:/vagrant/makahiki$ cd ~/
vagrant@precise32:~$ mkdir test
vagrant@precise32:~/test$ cd test
vagrant@precise32:~/test$ wget http://127.0.0.1:8000
--2013-08-09 11:19:25--  http://127.0.0.1:8000/
Connecting to 127.0.0.1:8000... connected.
HTTP request sent, awaiting response... 302 FOUND
Location: http://127.0.0.1:8000/landing/ [following]
[09/Aug/2013 11:19:26] "GET / HTTP/1.0" 302 0
--2013-08-09 11:19:26--  http://127.0.0.1:8000/landing/
Connecting to 127.0.0.1:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
[09/Aug/2013 11:19:26] "GET /landing/ HTTP/1.0" 200 6181
Saving to: “index.html"

    [ <=>                                   ] 6,181       --.-K/s   in 0s

2013-08-09 11:19:26 (192 MB/s) - “index.html" saved [6181]

If your HTTP response is “200 OK,” the server is running correctly. You can delete the “test” directory when you are done.

Because the server was started in the background with &, you cannot stop it with control-c. You will need to find the PIDs of its processes first:

% ps ax | grep manage.py
21791 tty1     S     0:00 python ./manage.py runserver
21798 tty1     Sl    0:52 /root/.virtualenvs/makahiki/bin/python ./manage.py ru
nserver
21893 tty1     S+    0:00 grep manage.py
% kill -9 21791 21798
%
[1]+  Killed                 ./manage.py runserver  (wd: ~/makahiki/makahiki)
(wd now: <your-working-directory>)

The PID of a given process will be different each time it runs. kill -9 <PID> forces the OS to stop the process with the specified PID. Kill the python ./manage.py runserver and /root/.virtualenvs/makahiki/bin/python ./manage.py runserver processes to stop the server.

Configuring Memcached on Vagrant

The process for configuring Memcached on the Ubuntu virtual machine in Vagrant is different from the process for configuring Memcached on a normal Ubuntu installation.

Check The Memcached Installation

The provisioning script installed Memcached and libmemcached-0.53 on the system. If you plan to configure Memcached, you will need to test the Memcached installation.

In the virtual machine, switch to the /vagrant/makahiki directory and run some commands in the manage.py shell:

vagrant@precise32:~$ sudo service memcached restart
vagrant@precise32:~$ export LD_LIBRARY_PATH_OLD=$LD_LIBRARY_PATH
vagrant@precise32:~$ export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:$LD_LIBRARY_PATH
vagrant@precise32:~$ export MAKAHIKI_USE_MEMCACHED=True
vagrant@precise32:~$ cd /vagrant/makahiki
vagrant@precise32:/vagrant/makahiki$ ./manage.py shell
Python 2.7.3 (default, Apr 10 2013, 05:46:21)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.cache import cache
>>> cache
<django_pylibmc.memcached.PyLibMCCache object at 0x8c93c4c>
>>> cache.set('test','Hello World')
True
>>> cache.get('test')
'Hello World'
>>> exit()
vagrant@precise32:/vagrant/makahiki$ unset MAKAHIKI_USE_MEMCACHED
vagrant@precise32:/vagrant/makahiki$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH_OLD
vagrant@precise32:/vagrant/makahiki$ unset LD_LIBRARY_PATH_OLD
vagrant@precise32:/vagrant/makahiki$ sudo service memcached stop
Stopping memcached: memcached.

If running “manage.py shell” causes the error:

django.core.cache.backends.base.InvalidCacheBackendError: Could not import pylibmc.

then the LD_LIBRARY_PATH may not be set correctly in makahiki_env.sh. This error occurs when MAKAHIKI_USE_MEMCACHED=True but LD_LIBRARY_PATH does not include the location of pylibmc.

If any of the following errors occur, then Memcached is not working:

  • cache prints a blank to the console, or cache is a “django.core.cache.backends.dummy.DummyCache object.”
  • cache.set returns False.
  • cache.get returns False or causes a segmentation fault.

If so, make sure environment variables are set and Memcached is running.

Configuring Memcached For The First Time

Memcached is a backend cache for the Makahiki web server. Configuring memcached is optional.

Run /vagrant/vagrant/makahiki_env_memcached_append.sh to add some code to the end of the /home/vagrant/makahiki_env.sh file:

vagrant@precise32:~$ sh /vagrant/vagrant/makahiki_env_memcached_append.sh

If the file is the same as the one created by the bootstrap.sh script, lines will be appended automatically, with the result [Succeeded].

If the makahiki_env_memcached_append.sh script has been run already but no changes have been made, the script will do nothing and output the result [Already completed].

If you have made other changes to makahiki_env.sh between the time the virtual machine was created and now, the script will ask permission to append to the file instead of copying over it:

WARNING! /home/vagrant/makahiki_env.sh file is different from expected file.
Append settings anyway? (Result may contain duplicate lines.) [Y/n]

If you answer n the script’s result will be [Cancelled]. Answer Y to add these lines to the end of makahiki_env.sh:

export MAKAHIKI_USE_MEMCACHED=True
# Don't add libmemcached paths more than once
if [ ! $LIBMEMCACHED_PATHS_ADDED ];
    then
        export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:$LD_LIBRARY_PATH
        export LIBMEMCACHED_PATHS_ADDED=True
fi

If the operation succeeds, the result will be [Succeeded].

Source /home/vagrant/.bashrc to apply changes:

vagrant@precise32:~$ source /home/vagrant/.bashrc

On Vagrant, the memcached service should run automatically once installed by the provisioning script. If it does not run, start it manually:

vagrant@precise32:~$ sudo service memcached start

On Ubuntu, the memcached service should run automatically at startup.

To test this, shut down the virtual machine, then restart it:

vagrant@precise32:~$ sudo shutdown -h now
-- output omitted --
Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.

> vagrant up --no-provision
-- output omitted --
> vagrant ssh

Warning

Do not use sudo shutdown -r now in Vagrant. This will restart the virtual machine without mounting the /vagrant shared folder.

After the restart, you should be able to test memcached without setting any environment variables:

vagrant@precise32:~$ cd /vagrant/makahiki
vagrant@precise32:/vagrant/makahiki$ ./manage.py shell
Python 2.7.3 (default, Apr 10 2013, 05:46:21)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.cache import cache
>>> cache
<django_pylibmc.memcached.PyLibMCCache object at 0x8c93c4c>
>>> cache == None
False
>>> cache.set('test','Hello World')
True
>>> cache.get('test')
'Hello World'
>>> exit()

If this test works, then the memcached service is running and will be used by Makahiki.

Disabling Memcached

To disable memcached, edit makahiki_env.sh to set MAKAHIKI_USE_MEMCACHED=False and comment out LD_LIBRARY_PATH settings:

export MAKAHIKI_USE_MEMCACHED=False
# Don't add libmemcached paths more than once
#if [ ! $LIBMEMCACHED_PATHS_ADDED ];
#    then
#        export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:$LD_LIBRARY_PATH
#        export LIBMEMCACHED_PATHS_ADDED=True
#fi

Then stop the memcached service, and stop it from running at startup:

vagrant@precise32:~$ sudo service memcached stop
vagrant@precise32:~$ sudo update-rc.d -f memcached disable

The memcached service will no longer be used by Makahiki, and will no longer run at startup.

To test this, shut down the virtual machine, then restart it:

vagrant@precise32:~$ sudo shutdown -h now
-- output omitted --
Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.

> vagrant up --no-provision
-- output omitted --
> vagrant ssh

After starting the new SSH session, test memcached once again:

vagrant@precise32:~$ cd /vagrant/makahiki
vagrant@precise32:/vagrant/makahiki$ ./manage.py shell
Python 2.7.3 (default, Apr 10 2013, 05:46:21)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.cache import cache
>>> cache
<django.core.cache.backends.dummy.DummyCache object at 0x964b72c>
>>> cache.set('test','Hello World') == None
True
>>> exit()
vagrant@precise32:/vagrant/makahiki$

Cache should be a DummyCache, and cache.set('test','Hello World') == None should return True.

Enabling Memcached

Edit makahiki_env.sh to set MAKAHIKI_USE_MEMCACHED=True, and uncomment the LD_LIBRARY_PATH settings:

export MAKAHIKI_USE_MEMCACHED=True
# Don't add libmemcached paths more than once
if [ ! $LIBMEMCACHED_PATHS_ADDED ];
    then
        export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:$LD_LIBRARY_PATH
        export LIBMEMCACHED_PATHS_ADDED=True
fi

Source ~/.bashrc to apply the changes:

vagrant@precise32:~$ source ~/.bashrc

Start the memcached service, and set it to run at startup:

% sudo service memcached start
% sudo update-rc.d -f memcached enable
Configuring Vagrant Settings

This section contains instructions for changing Vagrant settings related to the virtual machine used by Makahiki.

See the Vagrant documentation for more information.

Throughout this guide, a > indicates that a command is performed on the host OS. A % indicates that a command is performed on the virtual machine, and that the working directory in which the command is run does not matter.

Vagrant Commands

Some basic Vagrant commands are listed below:

  • vagrant up: Start the virtual machine. If the virtual machine defined in the Vagrantfile does not exist, it will be created and the provisioning script will be run.
    • vagrant up --provision: Start the virtual machine and force it to run the provisioning script.
  • vagrant reload: Restart the virtual machine. Equivalent to vagrant halt followed by vagrant up.
    • vagrant reload --provision: Restart the virtual machine and force it to run the provisioning script.
  • vagrant suspend: Freeze the current state of the virtual machine.
  • vagrant resume: Reactivate a machine that has been suspended.
  • vagrant halt: Attempt to shut down the virtual machine gracefully.
    • vagrant halt --force: Force a shutdown. This is equivalent to pulling the plug.
  • vagrant status: Show the status of the virtual machine.
  • vagrant destroy: Deletes a virtual machine. The Vagrantfile is not deleted.

Warning

The descriptions above apply only to Vagrant 1.3.0 and later. On Vagrant versions before 1.3.0, the vagrant up and vagrant reload commands worked as follows:

  • vagrant up: Start the virtual machine and run the provisioning script. If the virtual machine defined in the Vagrantfile does not exist, it will be created.
    • vagrant up --no-provision: Start the machine without provisioning it.
  • vagrant reload: Restart the virtual machine and run the provisioning script. Equivalent to vagrant halt followed by vagrant up.
    • vagrant reload --no-provision: Restart the virtual machine without provisioning it.

Note

As of Vagrant 1.4.3, you may see the following warning when running Vagrant commands:

DL is deprecated, please use Fiddle

This is a known issue with Vagrant and will likely be fixed in a future release. The commands will still work correctly. See Vagrant issue 2656.

You can only run commands for a given Vagrant virtual machine if your working directory is the directory that contains the virtual machine’s Vagrantfile.

Vagrant virtual machines are linked to the directory which contains their Vagrantfile. If the same Vagrantfile is copied into another directory, the vagrant up command will create a new virtual machine.

Re-Provisioning Vagrant

When the Vagrant virtual machine was created, a provisioning script was run.

Warning

Running the provisioning script erases all databases in the PostgreSQL installation on the system, including the Makahiki database.

If you want to run the provisioning script again, you can do this in two ways.

Re-provision the Virtual Machine at Startup

In the makahiki/vagrant directory, start the virtual machine with “vagrant up –provision.” This will run the provisioning script designated in the Vagrantfile:

> vagrant up --provision

Note

This error may occur during provisioning:

dpkg-preconfigure: unable to re-open stdin: No such file or directory

This does not affect the provisioning script and can be ignored.

Re-provision a Virtual Machine That is Already Running

Use the vagrant provision command in the host machine:

> vagrant provision
Configure the RAM of the Virtual Machine

The default settings in the Vagrantfile for Makahiki allow the virtual machine to use up to 1536 MB (1.5 GB) of RAM. To change this, you will need to edit the Vagrantfile while the virtual machine is shut down.

In the virtual machine, if the web server is running, stop it by pressing Control-C in the SSH terminal. Then shut down the virtual machine to end the SSH session:

% sudo shutdown -h now

To change the RAM allocated to the Virtualbox VM, edit the vb.customize line in the Vagrantfile by changing the number after the --memory flag:

config.vm.provider :virtualbox do |vb|
  vb.customize ["modifyvm", :id, "--memory", 1536]
end

After saving your changes, restart the VM and start the SSH session:

> vagrant up --no-provision
> vagrant ssh

Note

As of Vagrant 1.3.0, the --no-provision option is redundant because Vagrant no longer automatically runs the provisioning script when vagrant up is run. It is only necessary if your Vagrant version is older than 1.3.0. See the Vagrant changelog for more information.

In the SSH session, switch to /vagrant/makahiki and start the server:

vagrant@precise32:~$ cd /vagrant/makahiki

To start the server with manage.py:

vagrant@precise32:/vagrant/makahiki$ ./manage.py runserver 0.0.0.0:8000

To start the server with gunicorn:

vagrant@precise32:/vagrant/makahiki$ ./manage.py run_gunicorn -b 0.0.0.0:8000
Configure Networking on the Virtual Machine

By default, the Vagrantfile specifies the IP address 192.168.56.4 for the virtual machine’s eth1 interface. This is part of a host-only network. It assumes the host machine has the first usable address in the 192.168.56.0/24 subnet, 192.168.56.1.

If the Makahiki site is unreachable from the host machine after the web server is started, the 192.168.56.0/24 network may not be correct.

To fix this, check the IP addresses assigned to VirtualBox’s networking interfaces.

  1. Open VirtualBox.

  2. Go to File –> Preferences to launch the VirtualBox - Settings window.

  3. In the left sidebar, click Network.

  4. Click on VirtualBox Host-Only Ethernet Adapter once to select it, and click the screwdriver icon (the icon which, when moused over, shows “Edit host-only network.”)

  5. The Host-only Network Details window should show the following:

    IPv4 Address: 192.168.56.1
    IPv4 Network Mask: 255.255.255.0
    

    If the settings are different, you will need to change the settings in the Vagrantfile to match. Continue to the next step.

  6. Open the Vagrantfile in a text editor. Look for the line:

    config.vm.network :private_network, ip: "192.168.56.4"
    
  7. Change the address in quotes after the ip: field to something in the address range specified in Host-only Network Details. For example, if the “IPv4 Address” is 192.168.56.1 and the “IPv4 Network Mask” is 255.255.255.0, the range of usable addresses is 192.168.56.1 - 192.168.56.254. VirtualBox reserves the first usable address, 192.168.56.1, for the host machine. An explanation of IPv4 network addresses is beyond the scope of this guide.

  8. Switch to the directory holding the Vagrantfile. Then, reload the virtual machine configuration:

    > cd <directory-containing-Vagrantfile>
    > vagrant reload --no-provision
    

    Note

    As of Vagrant 1.3.0, the --no-provision option is redundant because Vagrant no longer automatically runs the provisioning script when vagrant reload is run. It is only necessary if your Vagrant version is older than 1.3.0. See the Vagrant changelog for more information.

  9. SSH into the virtual machine and check the network interfaces:

    > vagrant ssh
    Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)
    
    * Documentation:  https://help.ubuntu.com/
    Welcome to your Vagrant-built virtual machine.
    Last login: Thu Aug  8 07:55:06 2013 from 10.0.2.2
    vagrant@precise32:~$ ifconfig
    eth0      Link encap:Ethernet  HWaddr 08:00:27:12:96:98
              inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
              inet6 addr: fe80::a00:27ff:fe12:9698/64 Scope:Link
    -- output omitted --
    eth1      Link encap:Ethernet  HWaddr 08:00:27:fd:05:73
              inet addr:192.168.56.4  Bcast:192.168.56.255  Mask:255.255.255.0
              inet6 addr: fe80::a00:27ff:fefd:573/64 Scope:Link
    -- output omitted --
    lo        Link encap:Local Loopback
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
    -- output omitted --
    vagrant@precise32:~$
    

    The eth0 interface is used for port forwarding. The eth1 interface should match the IP address you just configured. The lo interface is the loopback interface.

  10. Ping the host machine’s “VirtualBox Host Adapter Network Address” from the virtual machine. Press Control-C (^C) to stop:

    vagrant@precise32:~$ ping 192.168.56.1
    PING 192.168.56.1 (192.168.56.1) 56(84) bytes of data.
    64 bytes from 192.168.56.1: icmp_req=1 ttl=128 time=1.49 ms
    64 bytes from 192.168.56.1: icmp_req=2 ttl=128 time=0.710 ms
    64 bytes from 192.168.56.1: icmp_req=3 ttl=128 time=0.609 ms
    64 bytes from 192.168.56.1: icmp_req=4 ttl=128 time=0.685 ms
    ^C
    --- 192.168.56.1 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3000ms
    rtt min/avg/max/mdev = 0.609/0.874/1.493/0.359 ms
    vagrant@precise32:~$
    

    If the ping succeeds, then networking is correctly configured.

  11. Add the new IP address to ALLOWED_HOSTS in settings.py:

    if MACHINE_IS_VAGRANT:
        ALLOWED_HOSTS = ['192.168.56.4']
    

    Change the IP address for ALLOWED_HOSTS to match the new IP address that you configured. For example, if the new address were 192.168.56.8, you would change the ALLOWED_HOSTS line to ALLOWED_HOSTS = ['192.168.56.8'].

From now on, you should use the IP address configured in the Vagrantfile to access the site when the webserver is running.

For more documentation of VirtualBox host-only networking, see Chapter 06 of the VirtualBox manual.

Local installation on Unix

These instructions also assume that you are using a Bourne-type shell (such as bash), which is the default on Mac OS X and Linux. Using a C-shell variant (like tcsh), is possible but not recommended.

Hardware requirements
Our estimated hardware requirements for production use are:
  • CPU: modern dual or quad core
  • RAM: 8 GB
  • Disk space: 10 GB

For development only, a modern dual core CPU with 4 GB should be ok, although the more the better.

Install Python

Install Python 2.7.3 or higher (but not Python 3).

To check that python is installed and has the correct version:

% python --version
  Python 2.7.3
Red Hat Enterprise Linux: Compile and Install Python 2.7.3

As of Red Hat Enterprise Linux (RHEL 6) and CentOS 6, Python 2.6.6 is the default. For Makahiki, Python 2.7.3 will be installed by compiling Python from scratch and performing an altinstall.

Install wget:

% sudo yum install wget

Next, install the packages needed to build and compile C:

% sudo yum groupinstall -y "Development tools"
% sudo yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel

This will take a while.

Next, download and extract the Python 2.7.3 source code:

% wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2
% tar xf Python-2.7.3.tar.bz2

Have the current user take ownership of the extracted directory (replace <username> with your username):

% chown -R <username> Python-2.7.3

Change into the extracted directory:

% cd Python-2.7.3

Configure the path to the altinstall:

% ./configure --prefix=/usr/local

This sets the location of the altinstall to “/usr/local/bin/python2.7.”

To finish the installation, make and install Python to the directory that you configured in the previous step:

% make
% sudo make altinstall

To run Python scripts using the Python 2.7.3 altinstall, you will need to use “python2.7” instead of “python.” Check the Python version:

% python2.7 --version
Python 2.7.3

Next, check that you can use the Python 2.7.3 shell, then exit:

% python2.7
Python 2.7.3 (default, Feb 26 2014, 11:02:10)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()

You have now verified that the altinstall is working.

Install C Compiler

If you are using Mac OS X, install Apple Developer Tools (i.e. Xcode 4). This is required in order to build certain libraries (PIL, etc.) that require GCC (which is bundled with Xcode). Xcode can either be found in your OS X installation DVD, or in the Mac App Store.

If on Linux, in most cases, you will find the C/C++ compiler is already installed in your environment.

To check that C compiler is installed:

% gcc --version

To install gcc on Ubuntu:

% sudo apt-get install gcc

To install gcc on RHEL and CentOS:

% sudo yum install gcc
Install Git

Find a package for your operating system at the GitHub install wiki. We recommend following the GitHub setup instructions at https://help.github.com/articles/set-up-git.

To check that Git is installed:

% git --version
Install Pip

The process to install pip is different for each operating system.

Ubuntu

If you do not have easy_install, download and install it from the setuptools website using sudo apt-get install python-setuptools:

% sudo apt-get install python-setuptools

If easy_install is installed on your system, install pip by typing:

% easy_install pip==1.4.1

Depending on your system configuration, you may have to type sudo easy_install pip==1.4.1.

Check that pip 1.4.1 is installed:

% pip --version
Red Hat Enterprise Linux (RHEL) and CentOS

Install setuptools and pip for the original Python 2.6.6 installation:

% sudo yum install python-setuptools
% sudo easy_install pip==1.4.1

For Python 2.7.3, download and extract setuptools-0.8:

% wget https://pypi.python.org/packages/source/s/setuptools/setuptools-0.8.tar.gz --no-check-certificate
% tar xf setuptools-0.8.tar.gz

Change ownership of the extracted directory by replacing <username> with your username:

% chown -R <username> setuptools-0.8

Change your working directory to the extracted directory and install:

% cd setuptools-0.8
% sudo /usr/local/bin/python2.7 setup.py install

Check that the installation was successful:

% /usr/local/bin/easy_install-2.7 --version
setuptools 0.8

You will install pip into the virtual environment later.

Install Virtual Environment Wrapper

Virtualenvwrapper allows you to install libraries separately from your global Python path.

Ubuntu

Follow the virtualenvwrapper installation instructions through the Quick Start section to install virtualenv and virtualenvwrapper. Once they are installed, create a virtual environment for makahiki as follows:

% mkvirtualenv makahiki

To check that virtual environment wrapper is installed:

% workon makahiki
RHEL and CentOS

Install virtualenvwrapper for Python 2.6.6:

% sudo /usr/bin/pip install virtualenvwrapper

Add these lines to the end of the ~/.bashrc file:

# Virtualenvwrapper settings for makahiki
export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/makahiki
export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib
export VIRTUALENVWRAPPER_VIRTUALENV=/usr/bin/virtualenv
export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages'
source /usr/bin/virtualenvwrapper.sh

Then source this file to apply changes:

% source ~/.bashrc

Create a virtual environment that uses Python 2.7.3:

% mkvirtualenv makahiki -p /usr/local/bin/python2.7

Creating a virtual environment should switch you to the virtual environment. The terminal prompt will be preceded by the name of the virtual environment. On RHEL, this looks like:

(makahiki)[robot@computer makahiki]$

If creating the virtual environment did not switch you to the virtual environment, use “workon makahiki” to switch to it:

% workon makahiki

Check your Python version in the virtualenv:

% python --version
Python 2.7.3

Note

Any commands run with root privileges (sudo python) will use the default Python 2.6.6, not Python 2.7.3.

Next, uninstall the pip version in the virtual environment, and install pip==1.4.1 instead:

% pip uninstall pip
% easy_install pip==1.4.1
Install Python Imaging Library

Makahiki requires the Python Imaging Library (PIL).

Mac OS X

We have found Homebrew to be the most reliable way to install PIL. Once Homebrew is installed, install PIL by typing:

% brew install pil
Ubuntu

In Ubuntu, install PIL by typing:

% sudo apt-get install -y python-imaging python-dev libjpeg-dev

Make sure you have both libjpeg (for JPEG) and zlib (for PNG) in the /usr/lib directory. If not, you can make the symbolic link there.

To make the symbolic links in a 32-bit Ubuntu OS:

% sudo ln -s /usr/lib/i386-linux-gnu/libjpeg.so /usr/lib/libjpeg.so
% sudo ln -s /usr/lib/i386-linux-gnu/libz.so /usr/lib/libz.so

To make the symbolic links in a 64-bit Ubuntu OS:

% sudo ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib/libjpeg.so
% sudo ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/libz.so
RHEL and CentOS

In RHEL and CentOS, install PIL by typing:

% sudo yum install -y python-imaging python-devel libjpeg-devel zlib-devel

Make sure you have both libjpeg (for JPEG) and zlib (for PNG) in the /usr/lib directory. If not, you can make the symbolic link there.

A 32-bit RHEL or CentOS OS should have symbolic links for libz.so and libjpeg.so in /usr/lib created during installation.

If you have a 64-bit RHEL or CentOS OS, you will need to create the symbolic links manually:

% sudo ln -s /usr/lib64/libjpeg.so /usr/lib/libjpeg.so
% sudo ln -s /usr/lib64/libz.so /usr/lib/libz.so
Install PostgreSQL

Makahiki uses PostgreSQL as its standard backend database. We recommend version 9.1.3.

Mac OS X

Note that on Mac OS X, the installer will need to make changes in the sysctl settings and a reboot before installation can proceed.

Ubuntu

On Ubuntu, install the latest version of PostgreSQL 9.1, and install libpq-dev:

% sudo apt-get install -y postgresql-9.1 libpq-dev
RHEL and CentOS

On RHEL and CentOS, install the pgdg91 repository, then install the latest version of Postgresql 9.1 and related packages.

Note

Ignore the following warning when running sudo rpm -i:

warning: /var/tmp/rpm-tmp.Mgcm3P: Header V4 DSA/SHA1 Signature, key ID 442df0f8:NOKEY

On i386 (32-bit) systems:

% sudo rpm -i http://yum.postgresql.org/9.1/redhat/rhel-6-i386/pgdg-redhat91-9.1-5.noarch.rpm
% sudo yum install -y postgresql91-server postgresql91-contrib postgresql91-devel

On x86_64 (64-bit) systems:

% sudo rpm -i http://yum.postgresql.org/9.1/redhat/rhel-6-x86_64/pgdg-redhat91-9.1-5.noarch.rpm
% sudo yum install -y postgresql91-server postgresql91-contrib postgresql91-devel

Next, whether you are on an i386 or x86_64 system, initialize the database and start the server:

% sudo service postgresql-9.1 initdb
% sudo chkconfig postgresql-9.1 on
After Installation

Once installed, use “which” to check that your PostgreSQL installation’s bin/ directory is on $PATH so that pg_config and psql are defined:

% which pg_config
% which psql

RHEL and CentOS users will see errors here. If you are a RHEL or CentOS user, you will add the bin/ directory to the PATH in a later step.

Next, you will need to configure authentication for the “postgres” database user.

During development, a simple way to configure authentication is to make the postgres user “trusted” locally. This means that local processes such as Makahiki can connect to the database server as the user postgres without authentication. To configure this way, edit the pg_hba.conf file and change:

local all postgres ident

to:

local all postgres trust

The first line might be: “local all postgres peer”. Change it to “local all postgres trust”.

If you update the pg_hba.conf file you will have to restart the postgres server.

Ubuntu

The pg_hba.conf file is located in /etc/postgresql/9.1/main/pg_hba.conf and must be opened with sudo. Edit it to match the examples below:

# Database administrative login by Unix domain socket
local   all             postgres                                trust

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

Restart the server after updating pg_hba.conf:

% /etc/init.d/postgresql restart

or:

% sudo /etc/init.d/postgresql restart
RHEL and CentOS

The pg_hba.conf file is located in /var/lib/pgsql/9.1/data/pg_hba.conf and must be opened with sudo. Edit it to match the examples below:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

Restart the server after updating pg_hba.conf:

% sudo service postgresql-9.1 restart
All Platforms

Alternatively, you can create a .pgpass file containing the credentials for the user postgres. See the PostgreSQL documentation for more information on the .pgpass file.

To check that PostgresSQL is installed and configured with “trusted” locally:

% psql -U postgres

It should not prompt you for a password.

This will open the postgres command prompt. Use the command \q to exit.

Install Memcache

Makahiki can optionally use Memcache to improve performance, especially in the production environment. To avoid the need for alternative configuration files, we require local installations to install Memcache and an associated library even if developers aren’t intending to use it.

Mac OS X

On Mac OS X, if you have installed Homebrew, you can install these by typing:

% brew install memcached
% brew install libmemcached
Linux

Linux users will need to download and build libmemcached from source. Start by installing memcached.

Ubuntu users:

% sudo apt-get install -y memcached

RHEL and CentOS users:

% sudo yum install -y memcached

Next, install packages needed to build libmemcached-0.53 from source.

Ubuntu users:

% sudo apt-get install -y build-essential g++ libcloog-ppl-dev libcloog-ppl0

RHEL and CentOS users: If you have been following this guide, you should already have performed a groupinstall of all packages in “Development tools.”

If you did not, use the below command to do it now:

% sudo yum groupinstall -y "Development tools"

Next, for Ubuntu, RHEL, and CentOS, download the source code and extract the archive:

% wget http://launchpad.net/libmemcached/1.0/0.53/+download/libmemcached-0.53.tar.gz
% tar xzvf libmemcached-0.53.tar.gz

Warning

Do not download and extract the source code in a directory that is synchronized with a Windows file system. This will cause the libmemcached-0.53 installation process to fail to create hard links and symbolic links during installation.

Switch into the extracted directory, then configure, make, and make install:

% cd libmemcached-0.53
% ./configure
% make
% sudo make install

Finally, check the location of the libmemcached.so library:

% stat /usr/local/lib/libmemcached.so

If libmemcached.so is found successfully, then the installation is complete.

Download the Makahiki source

You can download the source by cloning or forking the Makahiki Git repository:

% git clone git://github.com/csdl/makahiki.git

This will create the new folder and download the code from the repository.

Workon makahiki

The remaining steps require you to be in the makahiki/ directory and to have activated that virtual environment:

% cd makahiki/
% workon makahiki

If you start a new shell in the midst of this process, you must be sure to invoke workon makahiki and of course cd to the appropriate directory before continuing.

Install required packages
RHEL and CentOS

RHEL and CentOS users will need to add the PostgreSQL libraries to the PATH before installing packages with “pip”:

% export PATH=/usr/pgsql-9.1/bin:$PATH
% which pg_config
/usr/pgsql-9.1/bin/pg_config
% which psql
/usr/pgsql-9.1/bin/psql

Continue to “All Platforms.”

All Platforms

You can install the required Python package for Makahiki by:

% pip install -r requirements.txt

Don’t worry that this command generates lots and lots of output.

Setup environment variables

At a minimum, Makahiki requires two environment variables: MAKAHIKI_DATABASE_URL and MAKAHIKI_ADMIN_INFO.

The following lines show example settings for these two environment variables, preceded by a comment line describing their syntax:

# Syntax: postgres://<db_user>:<db_password>@<db_host>:<db_port>/<db_name>
export MAKAHIKI_DATABASE_URL=postgres://makahiki:makahiki@localhost:5432/makahiki

# Syntax:  <admin_name>:<admin_password>
export MAKAHIKI_ADMIN_INFO=admin:admin

You will want to either add these variables to a login script so they are always available, or you can edit the postactivate file (in Unix, found in $WORKON_HOME/makahiki/bin) so that they are defined whenever you workon makahiki.

After you edit and save postactivate, you will need to workon makahiki for your changes to take effect.

Note that you will want to provide a stronger password for the makahiki admin account if this server is publicly accessible.

Makahiki also utilizes a variety of other environment variables. For complete documentation, see Environment Variables.

Initialize Makahiki

Next, invoke the initialize_instance script, passing it an argument to specify what kind of initial data to load. You need to be in the makahiki/makahiki directory. In most cases, you will want to load the default dataset, as shown next:

% cd makahiki
% ./scripts/initialize_instance.py --type default
This command will:
  • Install and/or update all Python packages required by Makahiki;
  • Reinitialize the database contents and perform any needed database migrations.
  • Initialize the system with data.
  • Set up static files.

Warning

initialize_instance will wipe out all challenge configuration modifications!

The initialize_instance script should be run only a single time in production scenarios, because any subsequent configuration modifications will be lost if initialize_instance is invoked again. Use update_instance (discussed below) to update source code without losing subsequent configuration actions.

You will have to answer ‘Y’ to the question “Do you wish to continue (Y/n)?”

Start the server

Finally, you can start the Makahiki server using either:

% ./manage.py run_gunicorn

or:

% ./manage.py runserver

The first alternative (run_gunicorn) runs a more efficient web server, while the second (runserver) invokes a server that is better for development (for example, Theme Development).

Verify that Makahiki is running

Open a browser and go to http://localhost:8000 to see the landing page, which should look something like this:

_images/guided-tour-landing.png
(Optional) Enable SSL

In order to use SSL for your application, you may want to install a web server that supports SSL. Apache and Nginx are good alternatives. We describe the steps to configure SSL for Nginx to use with Makahiki.

  1. Stop the gunicorn or manage.py processes.

  2. Install Nginx. In CentOS, run:

    % yum install nginx
    
  3. Edit /etc/nginx/conf.d/default.conf (location of the config file might be different):

    server {
        listen       80;
        return 301 https://<server-host-name>:443/;
    }
    server {
        listen       443;
        server_name  <server-host-name>;
    
        ssl                  on;
        ssl_certificate      <location to site-cert.pem>;
        ssl_certificate_key  <location to site-key.pem>;
    
        ssl_session_timeout  5m;
    
        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;
    
        location / {
                proxy_pass_header Server;
                proxy_set_header Host $http_host;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Scheme $scheme;
                proxy_connect_timeout 10;
                proxy_read_timeout 10;
                proxy_pass http://<server-host-name>:8000/;
        }
     }
    
  4. restart Nginx:

    % nginx -s stop
    % nginx
    
  5. start the gunicorn server at port 8000

Configure your Makahiki instance

Now that you have a running Makahiki instance, it is time to configure it for your challenge, as documented in Site Configuration.

Updating your Makahiki instance

Makahiki is designed to support post-installation updating of your configured system when bug fixes or system enhancements become available. Updating an installed Makahiki instance is quite simple, and consists of the following steps.

  1. Bring down the running server in the shell process running Makahiki:

    % (type control-c in the shell running the makahiki server process)
    
  2. In that shell or a new shell, go to your Makahiki installation directory, and ensure the Makahiki virtual environment is set up:

    % cd makahiki
    % workon makahiki
    
  3. Download the updated source code into your Makahiki installation:

    % git pull origin master
    
  4. Run the update_instance script to update your local configuration:

    % ./scripts/update_instance.py
    
  5. Finally, restart your server, using either:

    % ./manage.py run_gunicorn
    

    or:

    % ./manage.py runserver
    
Local Installation on Windows

First off, we must state that native installation of Makahiki on Windows is more complicated and error-prone than on a Unix environment, because Makahiki uses two technologies (Django and Memcached) that are more difficult to install in a Windows environment.

We thus provide documentation for three approaches to installing Makahiki on Windows: dual-booting, virtual machine, and native installation. The first two approaches get around the difficulties of native installation by providing a Unix environment within Windows.

If you intend to modify or enhance the Makahiki software (i.e. you plan to be a developer rather than simply deploy a release of the software), we recommend you use the first two options which provide a unix environment.

Our estimated hardware requirements for development use are:
  • CPU: modern dual or quad core
  • RAM: 4 GB
  • Disk space: 10 GB
Makahiki installation using VirtualBox

You can install Linux on any virtual unix environment such as VirtualBox or Vmware. The advantage of virtual unix environments is availability of pre-configured images that make installation very easy. The disadvantage is the performance penalty of running everything inside a virtual machine. If you find the performance penalty too high after installing a virtual environment, then the solution is to go to a dual boot environment.

The following instructions assume you will use the VirtualBox environment.

Install VirtualBox

Download and install the Oracle VirtualBox software (https://www.virtualbox.org/wiki/Downloads).

Note

Install the corresponding version of the VirtualBox Extension Pack after you install the virtualbox software. This provides support for USB 2.0 etc in your VMs.

Next, you can either use the pre-built Makahiki VirtualBox image or install your own Linux distribution such as Ubuntu on VirtualBox.

Option A: Use the Makahiki VirtualBox Image

To simplify environment setup, we have created a VirtualBox virtual machine image which has Makahiki and related development tools pre-installed.

If you don’t want to use the pre-built Makahiki virtual image, and prefer to install Linux on virtualbox, see the next section “Install Ubuntu on VirtualBox”.

Download the VM Image

To use the Makahiki virtual machine, first download it from the following url:

Note that the VM image is quite large (about 1.2 GB).

Once the download completes, unzip the VM into the default directory for VirtualBox virtual machines. For example, in the Mac OS host, the default virtual machines directory is ~/VirtualBox VMs. If you have not used VirtualBox before, then you can create the default virtualbox vm directory and unzip the Makahiki vm into it.

Start the VM

Once the VirtualBox software and the VM image are installed, locate the Makahiki VM .vbox file, i.e., Makahiki_Ubuntu1204LTS_V1.vbox, and double click it. VirtualBox will start with the Makahiki VM in the list of the VirtualBox managed VMs, as shown in the screenshot here:

_images/virtualbox.png

The Makahiki VM is based on Ubuntu 12.04LTS and has Makahiki dependencies pre-installed. See the “readme.txt” file in the unzipped directory for details of this VM release and also the login info for the VM.

Note

By default, the Makahiki VM is allocated with 2G RAM, which is the recommended configuration for development in Makahiki. If your host machine has limited memory, you can decrease the RAM by changing the “Base Memory” under the System of the settings of the VM.

Double click on the Makahiki VM in the VirtualBox VM manager to start the Makahiki VM, login using the info in the readme.txt file.

Start Makahiki Server

Continue on from the section “2.1.1.1.10. Download the Makahiki source” in the Local installation of Makahiki document to start Makahiki this VM.

Option B: Install Ubuntu on VirtualBox

The following instructions are for installing your own Ubuntu on VirtualBox instead of using the pre-built Makahiki image.

Download Ubuntu 12

Makahiki supports Ubuntu 12. Download the .iso file here. Be sure to select the right option for x86 (32 bit) or x64 (64 bit) based systems (drop down on the right side of the page).

Create a VM

Start the VirtualBox program, then click “New” to create a new virtual machine:

  1. enter the name of the VM and the type as linux and version as ubuntu
  2. select the memory size, recommend at least 2G
  3. select “Create a virtual hard drive now”
  4. select “VDI” as the hard drive file type
  5. select “Dynamically allocated” as the storage option
  6. click finish to create the VM

Now the newly create VM should show up in the VM list.

Setup the CD/DVD drive on the VM
  • Click the storage settings of the VM, then
  • click the CD/DVD drive option, then
  • click the CD icon next to the “IDE Secondary” drop down, then
  • select “choose a virtual CD/DVD file”, and locate the downloaded ubuntu installation iso file.
Install Ubuntu

Power up the VM, the installer should run automatically from Ubuntu installation iso setted up in the CD/DVD.

Follow the Ubuntu installation guide to install the Ubuntu.

Install Guest Addition

After the installation and reboot, you can install the VirtualBox Guest Addition for the VM to get better integration between your VM and the host environment, such as “auto-resize guest display” and “share folders” functionality. To install the Guest Addition, make sure you VM is running, click on the VirtualBox Menu, “Devices” -> “Install Guest Addition...”, It will start the installing process in a new window.

Install Makahiki (via local Unix installation)

Once you have installed the Linux VM, you can now finish the installation of Makahiki by following the document Local installation of Makahiki.

Makahiki installation using dual boot

Warning

Creating a dual boot environment will overwrite the bootstrap on your computer. This can (and most likely will) prevent you from accessing a recovery partition on your computer. While some users have had success restoring their recovery partition after installation, restoration of said partition is neither guaranteed nor supported. If you’re determined to maintain your recovery partition, it is advisable that you find a separate guide to dual booting (as installation details are crucial).

To compensate for the loss of the recovery partition, we suggest using Windows Backup tool to create a system image(full backup) and a System Repair Disk. Should anything go wrong, you can use your System Repair Disk and system image to restore your computer to the state it was in when the image was taken.

Create a Partition

Create a new partition using the Windows Disk Management tool. Ubuntu will require two partitions, one for the OS (~15GB recommended), and one for swap space (~2GB recommended).

Download Ubuntu

Makahiki supports Ubuntu 12.10, the .iso for which can be found here. Be sure to select the right option for x86 (32 bit) or x64 (64 bit) based systems (drop down on the right side of the page).

Download the .iso file, and burn the image to a dvd or make a bootable flash drive.

Install Ubuntu

Follow the Ubuntu installation guide, choosing to “Install Ubuntu Alongside Windows <version>” in Step 4.

Point Ubuntu to the empty partition you designated earlier, and let it install (use default settings). It is recommended that you use the ext2 format for formatting the partition, as it is supported by the Linux OS, and can be accessed in Windows (using Ext2Fsd, a third party program).

After restarting, your computer will load using the GRUB. From here, you can choose to access either your Windows or Ubuntu Operating System.

Mount Windows Drives (Optional)

Optionally, if you wish to be able to interact with the files on your Windows partition, this guide on mounting will walk you through the somewhat complicated process.

Mount Linux Drives in Windows (Optional)

Windows cannot natively read the ext2 file format, however the third party program Ext2Fsd will allow Windows to mount ext2 formatted drives. Ext2Fsd can be found here: <http://www.ext2fsd.com/>`_.

Once you have the Linux VM, follow the document Local installation of Makahiki to install Makahiki in a Linux environment.

Makahiki Native Windows Installation

Warning

Native windows installation should be viewed as “experimental” and should be undertaken only by expert Windows developers.

Install Python

Python 2.7.3 or higher (but not Python 3). It is recommended that you use the 32 bit version.

To check that python is installed and has the correct version:

& python --version
  Python 2.7.3
Install C Compiler

you will need to install Visual Studio 2008 Express Please read and follow this blog post on Django installation on Windows.

Install Git

Find a package for your operating system at the GitHub install wiki. It is recommended that you also configure Git so that it handles line endings from Windows users correctly. See Dealing With Line Endings.

Install Pip

Download and install the binary “setuptools-0.6c11.win32-py2.7.exe ” under the download section of the setuptools website.

Install pip using easy_install:

%  easy_install pip
Install Virtual Environment Wrapper

Virtualenvwrapper allows you to install libraries separately from your global Python path.

In Windows, you will install Virtualenvwrapper for Winows which is the port of Virtualenvwrapper. Follow the “Installation” section to install it in your Windows environment.

Once virtualenv is installed, create a virtual environment for makahiki as follows:

% mkvirtualenv makahiki
Install Python Imaging Library

Makahiki requires the Python Imaging Library (PIL).

You can download and install the pre-build 32bit binary of PIL for windows.

After the PIL is installed, if you want to use the PIL in the virtual environment you just created in the previous step, you need to copy the PIL package from the system python site-packages to your virtual environment. For example, if you have created the virtual environment called “makahiki”, copy the directory “C:\Python27\Lib\site-packages\PIL” to “C:\Users\myuser\Envs\makahiki\Lib\site-packages”. This will make the PIL available in your virtual environment.

Install PostgreSQL

Makahiki uses PostgreSQL as its standard backend database. Once installed, be sure that your PostgreSQL installation’s bin/ directory is on $PATH so that pg_config and psql are defined.

In the development environment, It will be convenient that the user “postgres” is “trusted” locally so that you can connect to the server as the user “postgres” locally without authentication. You could edit the pg_hba.conf file and change “local all postgres ident” to “local all postgres trust”. Or, you may be able to create a .pgpass file containing the credentials. See PostgreSQL documentation for how to bypass the authentication for localhost.

In the Windows environment, you also need to install the psycopg2 for windows in order for the python client to use Postgres. You can download the 32bit binary for the corresponding python version and install to your system.

By default, this will install the package into the system python site-packages. If you want to use it in your virtual environment, which is recommended for Makahiki, you will need to copy the directory “C:\Python27\Lib\site-packages\psycopg2” to the site-packages directory of your virutal environment, for example: “C:\Users\myuser\Envs\makahiki\Lib\site-packages”.

Download the Makahiki source

You can download the source by cloning or forking the Makahiki Git repository:

% git clone git://github.com/csdl/makahiki.git

This will create the new folder and download the code from the repository.

Workon makahiki

The remaining steps require you to be in the makahiki/ directory and to have activated that virtual environment:

% cd makahiki
% workon makahiki

If you start a new shell in the midst of this process, you must be sure to invoke workon makahiki and of course cd to the appropriate directory before continuing.

Install required packages

You can install the required Python package for Makahiki by:

% pip install -r requirements.txt
Setup environment variables

At a minimum, Makahiki requires two environment variables: MAKAHIKI_DATABASE_URL and MAKAHIKI_ADMIN_INFO.

In Windows, these environment variables can be defined this way:

% set MAKAHIKI_DATABASE_URL=postgres://db_user:password@db_host:db_port/db_name

% set MAKAHIKI_ADMIN_INFO=admin:admin_password

You will want to either add these variables to a login script so they are always available, or you can edit the postactivate file in the $WORKON_HOME/makahiki/bin so that they are defined whenever you workon makahiki.

Note that you will want to provide a stronger password for the makahiki admin account if this server is publically accessible.

Makahiki also utilizes a variety of other environment variables. For complete documentation, see Environment Variables.

Initialize Makahiki

Next, invoke the initialize_instance script, passing it an argument to specify what kind of initial data to load. In most cases, you will want to load the default dataset, as shown next:

% scripts/initialize_instance.py --type default
This command will:
  • install or update all Python packages required by Makahiki;
  • Reinitialize the database contents and perform any needed database migrations.
  • Initialize the system with data.
  • Set up static files.

Warning

Invoke initialize_instance only once!

The initialize_instance script should be run only a single time in production scenarios, because any subsequent configuration will be lost if initialize_instance is invoked again. Use update_instance (discussed below) after performing configuration.

Start the server

Finally, you can start the Makahiki server using:

% ./manage.py runserver
Verify that Makahiki is running

Open a browser and go to http://localhost:8000 to see the landing page, which should look something like this:

_images/guided-tour-landing.png
Configure your Makahiki instance

Now that you have a running Makahiki instance, it is time to configure it for your challenge, as documented in Site Configuration.

Updating your Makahiki instance

Makahiki is designed to support post-installation updating of your configured system when bug fixes or system enhancements become available. Updating an installed Makahiki instance is quite simple, and consists of the following steps.

  1. Bring down the running server in the shell process running Makahiki:

    % (type control-c in the shell running the makahiki server process)
    
  2. In that shell or a new shell, go to your Makahiki installation directory, and ensure the Makahiki virtual environment is set up:

    % cd makahiki
    % workon makahiki
    
  3. Download the updated source code into your Makahiki installation:

    % git pull origin master
    
  4. Run the update_instance script to update your local configuration:

    % ./scripts/update_instance.py
    
  5. Finally, restart your server, using:

    % ./manage.py runserver
    
Heroku installation of Makahiki
Install Heroku

Sign up for an account and install the Heroku toolbelt following the instructions in the Heroku Cheat Sheet

This involves:
  • Signing up with the Heroku service
  • Install the Heroku Toolbelt (provides the “git” and “heroku” commands).
  • Logging in to Heroku.
Add your SSH keys to Heroku

You must tell Heroku about your SSH keys. Follow https://devcenter.heroku.com/articles/keys to upload your keys to Heroku.

Verifying your Heroku account

Heroku provides many addons to enhance and manage the apps deployed in Heroku. Makahiki use the free Memcache addon on Heroku for performance enhancement. In order to use any addons, even the free ones, Heroku requires to verify your account by providing your credit card info. The verification process is free and no charge will be made as long as you don’t use the paid addons or exceed your app’s free resource usage allowance. See more about Heroku billing at: https://devcenter.heroku.com/categories/billing

Follow Account Verification page to verify your account.

If you don’t verify your Heroku account, Makahiki will not be able to use Memcache and the “initialize_instance” step later will fail to add the “Memcache” addon to your heroku instance.

Setup Amazon S3

Makahiki on Heroku use Amazon S3 to store static files and support file/image upload due to the limitation of Heroku’s Ephemeral filesystem in hosting static assets. You will need to set up the Amazon S3 for serving the static files in Makahiki heroku instance.

Follow Using AWS S3 to store static assets for details to setup the Amazon S3.

Create a S3 bucket to be used for storing the static files for Makahiki, and record the bucket name you created, the AWW access key id, and the AWS secret access key for use in setting up the environment variables for Heroku.

Note

You will need to sign up for an AWS S3 account with Amazon if you don’t have one. AWS S3 is not a free service and requires a credit card. But if you are a new AWS customer, you can sign up for the AWS Free Usage Tier which will be free for one year. And in general, the charge to S3 after the free period is very inexpensive.

Setup environment variables

To deploy Makahiki on Heroku, you must define several local environment variables that will be used by the initialize_instance script when it configures the Heroku instance.

First, define a local environment variable that specifies the Heroku Makahiki admin account name and password:

% export MAKAHIKI_ADMIN_INFO=admin:Dog4Days56

You will also need to define Amazon S3 information:

% export MAKAHIKI_AWS_ACCESS_KEY_ID=<AWS access key id>
% export MAKAHIKI_AWS_SECRET_ACCESS_KEY=<AWS secret access key>
% export MAKAHIKI_AWS_STORAGE_BUCKET_NAME=<AWS S3 bucket name>

You should have obtained these values in the previous “Setup S3” section.

Download the Makahiki source

To download the Makahiki system, type the following:

% git clone git://github.com/csdl/makahiki.git

This will create a directory called “makahiki” containing the source code for the system.

Initialize Makahiki

Once the above local environment variables are set, you can use the initialize_instance script to create a Heroku application and initialize the application with the default Makahiki data set. All Heroku application names must be unique, so if your organization is “hpu”, then you might call your application “makahiki-hpu”. Use an application name appropriate for your organization.

To initialize your heroku application (for example, “makahiki-hpu”) with the default Makahiki data set, you need to first activate the Makahiki virtual environment and invoke the initialize_instance.py script, similar to the following:

% workon makahiki
% cd makahiki
% scripts/initialize_instance.py --type default --heroku makahiki-hpu
This command will:
  • create the application in Heroku
  • install Heroku Memcache addons
  • set up the Makahiki environments you defined for the application
  • upload the Makahiki source code to Heroku
  • install and/or update all Python packages required by Makahiki
  • initialize the database contents and perform any needed database migrations.
  • initialize the system with data.
  • set up static files.

This command will produce lots of output and may take more than 20 minutes to upload Makahiki to Heroku, depending on your network. After uploading Makahiki you will have to answer ‘Y’ to the question “Do you wish to continue (Y/n)?” during the process.

Warning

initialize_instance will delete any Makahiki challenge configuration actions!

The initialize_instance script should be run only a single time in production scenarios, because any subsequent challenge configuration will be lost if initialize_instance is invoked again. Instead, use update_instance (discussed below) after performing configuration in the production environment.

Note

In an development environment, it is ok to run the initialize_instance multiple times provided that you understand the process will delete your pre-existing instance. In the case that you did not verify the Heroku account or did not setup S3 correctly, the script will fail. You could run the “initialize_instance” script again after you verify the account and/or fix the S3 setup.

If you run the script a second time with the same heroku app name, you may see an error message saying that the heroku application had already been created and the Memcache addon already installed. You can ignore this error message.

Start the server

To start up the server on Heroku, invoke:

% heroku ps:restart --app makahiki-hpu
Verify that Makahiki is running

Open a browser and go to http://<heroku-appname>.herokuapp.com/ (where <heroku-appname> is replaced by your app’s name, for example, makahiki-hpu). This should retrieve the landing page, which should look like:

_images/guided-tour-landing.png
(Optional) Enable SSL

To enable SSL for the Heroku app, run:

% heroku addons:add ssl
Configure your Makahiki instance

Now that you have a running Makahiki instance, it is time to configure it for your challenge, as documented in Site Configuration.

Updating your Makahiki instance

Makahiki is designed to support post-installation updating of your configured system when bug fixes or system enhancements become available. Updating an installed Makahiki instance is quite simple, and consists of the following steps.

  1. Get the updated source code:

    % git pull origin master
    
  2. Run the update_instance script to update your Heroku configuration (make sure the AWS environment variables are set):

    % cd makahiki
    % scripts/update_instance.py --heroku makahiki-hpu
    
  3. Finally, restart your server:

    % heroku ps:restart --app makahiki-hpu
    
Docker installation of Makahiki
Install Docker

Install docker following the instructions in the Docker installation for your OS.

Install Compose

Install compose following the Compose installation.

Download the Makahiki source

To download the Makahiki system, type the following:

% git clone git://github.com/csdl/makahiki.git

This will create a directory called “makahiki” containing the source code for the system.

Setup environment variables

To deploy Makahiki on Docker, you must define several environment variables that will be used by the Docker instance. The environment variables are defined in the file .env in the Makahiki source code root directory.

First, define a local environment variable that specifies the Makahiki admin account name and password:

MAKAHIKI_ADMIN_INFO=admin:Dog4Days56
Create the docker container

Once the above local environment variables are set, run the following command to build the container:

% docker-compose build
This command will:
  • pull a python image to create a container
  • install the dependencies defined in requirements-docker.txt
Initialize the web container

Run the following command to initialize the web container:

 % docker-compose up db
 % docker-compose run web python makahiki/scripts/initialize_instance.py -t default -d

This command will:
 * initialize the database contents and perform any needed database migrations.
 * initialize the system with data.
 * set up static files.
Start the server

To start up the server on Docker, invoke:

% docker-compose up
Verify that Makahiki is running

Open a browser and go to http://<docker-ip>:8000. This should retrieve the landing page, which should look like:

_images/guided-tour-landing.png
Configure your Makahiki instance

Now that you have a running Makahiki instance, it is time to configure it for your challenge, as documented in Site Configuration.

Updating your Makahiki instance

Makahiki is designed to support post-installation updating of your configured system when bug fixes or system enhancements become available. Updating an installed Makahiki instance is quite simple, and consists of the following steps.

  1. Get the updated source code:

    % git pull origin master
    
  2. Run the update_instance script to update your Heroku configuration (make sure the AWS environment variables are set):

    % docker-compose build
    
  3. Finally, restart your server:

    % docker-compose up
    

Install WattDepot

If you plan to have automated collection of energy data as part of your energy challenge, then you will also need to install WattDepot.

Local installation of WattDepot
Hardware requirements
Our estimated hardware requirements (for production use) are:
  • CPU: modern dual or quad core
  • RAM: 8 GB
  • Disk space: 10 GB
WattDepot generic local install instructions

Follow the WattDepot local install instructions

Heroku Installation of WattDepot

Note

Heroku installation of WattDepot is still experimental. Please contact a member of the Makahiki development team if you are interested in this installation option.

WattDepot generic Heroku install instructions

Follow the WattDepot Heroku install instructions

Site Configuration

About site configuration

This section explains how to configure a freshly initialized instance of Makahiki to suit the characteristics of your IT infrastructure. It assumes you have completed the steps to install Makahiki either locally or globally following the instructions in Install Makahiki, that you initialized the instance using the “default” fixture, and that the server is now running.

In this section, all URLs will refer to a locally running instance of Makahiki (i.e. http://127.0.0.1:8000). Please substitute the host and port number of your instance when following the instructions below.

Site configuration differs from challenge design in that it requires “system administration” skills: you must understand IT infrastructure issues such as email transport, authentication, and so forth.

Retrieve the Settings Page

In order to accomplish any online administrative tasks, you must:

  • Login with an account that has administrator privileges
  • Navigate to the “Settings” page, from which you can eventually get to the administrative page of interest.

Note

In addition to the online administrator interface, there are also administative capabilities available through the command line. These are documented in Management Commands.

Log in as admin

To login as an administrator, go to the internal (Django) login page at: http://127.0.0.1:8000/account/login:

_images/configuration-account-login.png

Use the credentials you specified in the MAKAHIKI_ADMIN_INFO environment variable.

Upon successful login, you will be taken to the home page:

_images/configuration-admin-home.png

Note that admin accounts have two additional pages displayed in the Nav Bar: “Status” and “Settings”. “Status” provides real time analytics for use in managing a running competition, as detailed in Challenge Management.

Click on Settings page icon

Click on the Settings icon in the Nav Bar to go to the Settings page:

_images/configuration-settings.png

This page presents a set of buttons providing access to different administrative areas depending upon the type of task to be accomplished. These correspond roughly to the Makahiki “life-cycle phases” described in Site Administration Guide.

Configure authentication
About authentication

In Makahiki, “authentication” refers to the way in which a player logs in to participate in a challenge. In Makahiki, there is currently no way for people to “register” themselves and obtain an account to play a challenge. Instead, the administrator must configure the system in advance of the challenge with the names of all potential players, and the teams to which they are assigned. (This constraint could be removed in a future release.)

Given that the system knows in advance the identities of all potential players of a challenge, the next question is how to verify that a given online user is one of these potential players? That is the goal of authentication, and Makahiki provides a variety of ways to do it.

Note

Authentication is required in Makahiki. If you want the simplest authentication to configure, do internal authentication. However, that means your users will have a separate account and password for the challenge, which is a barrier to participation.

Getting to the authentication page

From the Settings Page, click on the System Administration button to retrieve the following authentication configuration form:

_images/configuration-system-administration-authentication.png

Makahiki currently supports three kinds of authentication: CAS, LDAP, and the internal authentication provided by Django. System administrators must configure at least one form of authentication, though multiple forms are also acceptable.

CAS authentication

To use CAS authentication, you can check the “Use cas auth” checkbox, and fill in the “Cas server url” field. The url is where users access the CAS authentication service, for example, https://login.its.hawaii.edu/cas

You may want to check with the system admin of your organization’s CAS service provider to obtain the url of the service.

You can also modify the CAS login button text by changing the “Cas auth text” field. This text will display as the button text associated with the CAS authentication in the Landing page.

LDAP authentication

Note

Currently Makahiki only support LDAP authentication in local installation. Because the python-ldap software package can not be installed on the Heroku environment (as of this writting), the LDAP authentication of Makahiki is not supported on Heroku.

To use LDAP authentication, you can check the “Use ldap auth” checkbox, and fill in the following additional fields:

  1. Ldap server url”: The url is where users access the LDAP authentication service, for example, ldap://ldap.hawaii.edu:389. You may want to check with the system admin of your organization’s LDAP service provider to obtain the url of the service.
  2. ldap search base”: It is the base entry for the ldap authentication search operation. For example, if all the users in the LDAP directory are located under “ou=users,ou=system”, then the search base will be “ou=users,ou=system”. Again, your organization’s LDAP service admin will be able to provide this information.

You can also modify the LDAP login button text by changing the “Ldap auth text” field. This text will display as the button text associated with the LDAP authentication in the Landing page.

Additionally, in order to use LDAP authentication in Makahiki, You need to install the following two software packages in your local virtual environment:

% pip install python-ldap
% pip install django-auth-ldap

They provides client APIs for Makahiki to access an LDAP directory server.

After the ldap package are installed, you will need to set the following environment variable to enable LDAP authentication:

% export MAKAHIKI_LDAP_BIND_DN = <bind_dn>
% export MAKAHIKI_LDAP_BIND_PASSWORD = <bind_password>

The <bind_dn> is the DN of the special ldap user that have the privilege to bind to and search the ldap directory. <bind_password> is the password of the above special ldap bind user.

By default, if LDAP auth is used, the Makahiki use the ldap user’s “uid” attribute as the username to login and authenticate. If your organization’s LDAP server use “cn” as the unique user identifier, you can set the following environment variable to let Makahiki use the ldap user’s “cn” attribute as the username to login:

%export MAKAHIKI_LDAP_USE_CN = True

After the environment variables are set, the server restart is needed to take into effect for the LDAP configurations.

Internal authentication

To use the built-in Django internal authentication, you can check the “Use internal auth” checkbox.

You can also modify the internal login button text by changing the “Internal auth text” field. This text will display as the button text associated with the internal authentication in the Landing page.

Configure WattDepot
About WattDepot

WattDepot is a software service for collecting, storing, analyzing, and visualizing energy data. One of the capabilities of Makahiki is the display of power being consumed by a team in near real-time, and a record of the amount of power that a team consumed during a challenge. Rather than build into Makahiki support for all the various kinds of power meters and protocols available on the market in order to provide this capability, Makahiki delegates this responsibility to the WattDepot system, which is designed specifically to solve this problem.

Note

Configuration of WattDepot for use in a Makahiki challenge is optional. For example, if you do not want to display power consumption in near real-time, and if you are content to manually enter energy consumption data by each team on a daily basis during the challenge, then you do not have to install WattDepot and configure Makahiki to access energy data from it.

Getting to the WattDepot configuration page

From the Settings Page, click on the System Administration button to retrieve the following WattDepot configuration form (it occurs below the Authentication form):

_images/configuration-system-administration-wattdepot.png
Configuring WattDepot

WattDepot configuration is only necessary if you wish to provide near real-time energy data to players in the challenge.

The configuration setting is rather simple: just the URL to the WattDepot server. However, for WattDepot integration with Makahiki to occur successfully, the following additional constraints must be met:

  • Currently, Makahiki uses the name of a team as name of the Wattdepot source to retrieve the energy data for the team. This requires that the name of the team need to be the same as the source name in Wattdepot. Otherwise, Makahiki will not be able to retrieve the team’s energy data. This limitation may be resolved in the future release of Makahiki.
Configure email
About email

Makahiki uses email in the following ways:

  • Players can elect to be “reminded” about activities they wish to attend. Email is one communication option provided.
  • Makahiki can automatically notify players via email if they have won a prize in the Top Score game or the Raffle Game after a round is over.
  • When an activity submission is rejected, an notification email will be sent to the player.
  • Players can send feedback and ask questions to the system admin in Makahiki, they will be sent via email to the Makahiki system admin.
  • Other system generated email reminders from Makahiki to players.

Note

Configuration of email for use in a Makahiki challenge is optional. However, if you do not enable email, then these communication mechanisms will not be available to players and administrators.

Getting to the email configuration page

From the Settings Page, click on the System Administration button to retrieve the following Email configuration form (it occurs below the WattDepot configuration form):

_images/configuration-system-administration-email.png
Configuring email

To enable the email, you can check the “Email enabled” checkbox, and fill in the following fields:

  1. Contact email”: It is the email of the system admin that user’s feedback or questions will be sent to, or any system generated error messages will be sent to.
  2. Email host”: It is the host name of the email server. for example, smtp.gmail.com
  3. Email port”: It is the port of the email server.
  4. Email use tls”: check this if the email server use TLS.

Additionally, you will need to set the following environment variables in order to complete the email configuration:

% export MAKAHIKI_EMAIL_INFO=<email_user_name>:<password>

On Heroku, you can set the environment variable using:

% heroku config:add MAKAHIKI_EMAIL_INFO=<email_user_name>:<password>

This is the credential of the user that can use the email server configured above. The reason to separate port of the email configuration into environment variable is to avoid putting the credential information in the database.

After the environment variable is set, you will need to restart the server.

Configure Facebook integration (Optional)
About Facebook integration

Makahiki currently integrates with facebook in the following ways:

  1. you can request that your Facebook photo be used as your Makahiki profile picture,
  2. you are given an oppportunity to post to Facebook when the system notifies you of an accomplishment.

To enable the above Facebook integration in Makahiki, the system admin will need to create an Facebook app and configure the app information in Makahiki, as described in the next section.

Configuring Facebook integration

First you will need to create a Facebook app at: https://developers.facebook.com/apps

After you created your app, say, “makahiki-app”, click on the “Website with Faceook Login” setting, enter the URL of your server, for instance, http://localhost:8000, in the “Site URL” field, then click on the “Save Changes” button.

You should see the “App ID” and “App Secret” value of your app under the app name.

Now, you can set the following environment variables to enable facebook integration:

% export MAKAHIKI_USE_FACEBOOK=True
% export MAKAHIKI_FACEBOOK_APP_ID=<your_app_id>
% export MAKAHIKI_FACEBOOK_SECRET_KEY=<your_app_secret_key>

On Heroku, you can set the environment variable using:

% heroku config:add <ENV_KEY>=<ENV_VALUE>

Last, you need to restart the Makahiki server.

If you want to turn off the Facebook integration, you can set the envrionment variable MAKAHIKI_USE_FACEBOOK=False and restart the server.

Configure Memcached
About Memcached

Memcached is a memory object caching daemon that stores objects in memory to reduce the load on a database. This section explains how to configure Makahiki to use memcached as the backend cache for its web server.

Note

Memcached is optional. However, it is recommended that Memcached be configured on production servers.

These instructions assume that you have followed the instructions in Local installation on Unix to configure a Linux installation of Makahiki. It is also assumed that you are using a Bourne-type shell, which is the default on Linux.

Environment Variables

Open the $WORKON_HOME/makahiki/bin/postactivate file. Add these lines to the end:

export MAKAHIKI_USE_MEMCACHED=True
# Don't add libmemcached paths more than once
if [ ! $LIBMEMCACHED_PATHS_ADDED ];
    then
        export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:$LD_LIBRARY_PATH
        export LIBMEMCACHED_PATHS_ADDED=True
fi

Next, workon makahiki to apply the changes:

% workon makahiki

Continue to the next section to start the memcached service.

Start the memcached Service

Next, the memcached service must be started if it is not running:

% sudo service memcached start

On Ubuntu, the memcached service will automatically run at startup. In Red Hat Enterprise Linux or CentOS systems, however, the user must use chkconfig to enable the service to run at startup:

% sudo chkconfig memcached on
Verify Memcached Settings

To test your Memcached settings, switch to the makahiki virtual environment:

% workon makahiki

Then, change to the makahiki/makahiki directory and run the manage.py shell:

% cd ~/makahiki/makahiki
% ./manage.py shell

This will open a Python shell.

In the shell, run the below commands to test whether Memcached is configured and running:

Python 2.7.3 (default, Apr 10 2013, 05:46:21)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.cache import cache
>>> cache
<django_pylibmc.memcached.PyLibMCCache object at 0xa669c0c>
>>> cache.set('test','Hello World')
True
>>> cache.get('test')
'Hello World'
>>> exit()

If your output matches the example output shown above, then Memcached has been successfully configured and started. If your output does not match or you experience errors, continue to the next section.

Troubleshooting

If running manage.py shell causes the error django.core.cache.backends.base.InvalidCacheBackendError: Could not import pylibmc, then the LD_LIBRARY_PATH environment variable may not be set correctly in $WORKON_HOME/makahiki/bin/postactivate. This error occurs when MAKAHIKI_USE_MEMCACHED=True but LD_LIBRARY_PATH does not include the location of pylibmc.

If the manage.py shell starts correctly but one of the following errors occurs when you run the test commands, then memcached is not correctly configured:

  • cache is a DummyCache object
  • cache.set('test','Hello World') returns False
  • cache.get('test') causes a segmentation fault or exits the Python shell

Verify that your postactivate settings for MAKAHIKI_USE_MEMCACHED and LD_LIBRARY PATH match the settings added in these instructions.

If you are testing memcached on your local machine, verify that the makahiki/makahiki/settings.py file specifies the backend cache for location 127.0.0.1 as django_pylibmc.memcached.PyLibMCCache. The settings.py file should include the following lines:

else:
    CACHES = {'default':
                {'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
                 'LOCATION': '127.0.0.1',
                 'BINARY': True,
     }}
Disabling Memcached

In $WORKON_HOME/makahiki/bin/postactivate, set MAKAHIKI_USE_MEMCACHED=False and comment out memcached environment variable settings:

export MAKAHIKI_USE_MEMCACHED=False
# Don't add libmemcached paths more than once
#if [ ! $LIBMEMCACHED_PATHS_ADDED ];
#    then
#        export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:$LD_LIBRARY_PATH
#        export LIBMEMCACHED_PATHS_ADDED=True
#fi

Then workon makahiki to apply changes:

% workon makahiki

Finally, stop the makahiki service, and stop it from running at startup.

Ubuntu users:

% sudo service memcached stop
% sudo update-rc.d -f memcached disable

RHEL and CentOS users:

% sudo service memcached stop
% sudo chkconfig memcached off

The manage.py shell tests should fail now:

% ./manage.py shell
Python 2.7.3 (default, Apr 10 2013, 05:46:21)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.cache import cache
>>> cache
<django.core.cache.backends.dummy.DummyCache object at 0x9ef470c>
>>> cache.set('test','Hello World') == None
True
>>> exit()
Re-enabling Memcached

In $WORKON_HOME/makahiki/bin/postactivate, set MAKAHIKI_USE_MEMCACHED=True and uncomment the memcached environment variable settings:

export MAKAHIKI_USE_MEMCACHED=True
# Don't add libmemcached paths more than once
if [ ! $LIBMEMCACHED_PATHS_ADDED ];
    then
        export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:$LD_LIBRARY_PATH
        export LIBMEMCACHED_PATHS_ADDED=True
fi

Then workon makahiki to apply changes:

% workon makahiki

Finally, start the makahiki service, and set it to run at startup.

Ubuntu users:

% sudo service memcached start
% sudo update-rc.d -f memcached enable

RHEL and CentOS users:

% sudo service memcached start
% sudo chkconfig memcached on

The manage.py shell tests should work correctly now.

Challenge Design

About challenge design

Unlike Software Installation and Site Configuration, challenge design is not intended to need “sys admin” skills. During this phase, the focus is on tailoring the default Makahiki configuration to suit the needs of your specific challenge goals.

Getting to the challenge design page

Go to the Settings Page (see Retrieve the Settings Page), and click on the Challenge Design button to retrieve the page providing the top-level interface to the various aspects of Challenge Design.

_images/configuration-challenge-design.png

As you can see, the page consists of two sections, “Challenge Settings” and “Game Settings”. Challenge settings enables you to set the global properties of the challenge (rounds, scores, users, etc.), while Game Settings enables you to configure the specific games to appear in the challenge and their properties.

Challenge

Design the global settings
About global settings

Makahiki challenges have a few global properties: the name of the challenge, the logo that appears on all pages, and so forth. Also included in the global settings is the text that appears on a few static pages: the Landing Page, About page, and so forth.

Getting to the global settings page

Clicking on Global settings within the Challenge Design Page brings up a page with sections allowing you to specify some global properties of your challenge.

Specify the name, logo, etc.

The first section of the page enables you to configure the basic identify of your challenge: its name, logo, and so forth.

Note

Configuration of this section is optional, if you are satisfied with the default values.

_images/configuration-challenge-design-name.png

Makahiki uses the Name field and the Logo to brand the Challenge. They appear on the Left-hand side of the navigation bar of each page. The domain is used to in the Attendance and Bonus Codes to create the URL the player uses to collect their points. The Team label is used in several widgets, such as energy scoreboard. The Theme is the default theme for the Challenge.

Specify the Landing page text

This form enables you to customize the text that appears on the Landing Page.

Note

Configuration of this section is optional, if you are satisfied with the default values.

_images/configuration-challenge-design-landing-page.png

The system is initialized with text appropriate to the Kukui Cup challenge at the University of Hawaii. You should change this to reflect your own challenge circumstances.

Specify the About page text

This form enables you to customize the text that appears on the About Page.

Note

Configuration of this section is optional, if you are satisfied with the default values.

_images/configuration-challenge-design-about-page.png
Specify the sponsors

This form enables you to specify the Sponsors that appear on the Landing page.

Note

Configuration of this section is optional, if you are satisfied with the default values.

_images/configuration-challenge-design-sponsors.png
Design the rounds
About rounds

Makahiki requires all challenges to have a start date when players can begin logging in to the system and engage in activities, and an end date when the challenge is over and prizes are awarded. In addition, Makahiki allows you to partition the overall challenge into a sequence of “sub-challenges” which can potentially have their own points, prizes, and activities. These capabilities are provided by the “Round” mechanism.

The simplest approach is to define a single round for your challenge. In this case, the start and end dates of the challenge as a whole correspond to the start and end dates of that round.

Alternatively, you could define a challenge with 2, 3, or more rounds. The 2011 University of Hawaii Kukui Cup contained three rounds, each approximately 1 week in length. The 2012 University of Hawaii Kukui Cup contained 5 rounds, varying in length from 2 weeks to 3 months.

The basic reason for defining multiple rounds is to enable players to join the challenge “late” and still feel like they can compete with other players. To facilitate this, you can specify that a round (and its prizes) depend upon only the points accumulated during that round.

Rounds cannot overlap in time. If you try to define a new round that overlaps in time with a pre-existing round, then the system will signal an error.

Rounds also serve another important purpose: they define the time intervals during which players are allowed to login to the system. (Administrators can log in to the system at any time that the system is up.)

It is possible to define rounds such that there are “non-round periods” between the end of one round and the start of another. For example, you could design a challenge in which Round 1 ends on March 15 and Round 2 starts five days later on March 20. The days between those two rounds create a “blackout” period when players are not able to login to the system.

Note

Configuration of the round(s) corresponding to a challenge is required. At a minimum, the round specification provided in the default configuration must be edited to provide the start and end dates for your challenge.

Getting to the round settings page

After clicking on the “Round Settings” link in the Challenge Design page, a page similar to the following appears:

_images/configuration-challenge-admin-round-settings-1.png

In this example, one round is specified. To create a new round, click on the “Add round setting” in the upper right corner.

Configure a round
_images/configuration-challenge-admin-round-settings-2.png

Clicking on a round name takes you to a page containing a form that allows you to edit the round attributes or delete the round entirely.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the point rubric
About the point rubric

An essential part of a Makahiki challenge for players is the earning of points, and there are a variety of “global” actions that result in points for players, including: finishing the startup activity, referring other players, signing up for workshops and excursions, and so forth. (Of course, players also earn points by completing actions in the Smart Grid Game, and the number of points to be awarded for each action can be specified individually.)

The “point rubric” refers to the number of points to be awarded for the various global actions. By changing the number of points awarded for these actions, you change the level of incentive for doing them.

The default point rubric values have been determined through experience with the 2011 and 2012 Kukui Cups, and appear to be generally appropriate when videos earn about 25 points and workshops earn about 50 to 100 points for attendance.

Note

Configuration of the point rubric is optional, as long as you are satisfied with the default values.

Getting to the point rubric settings page

After clicking on the “Point rubrics” link in the Challenge Design page, a page similar to the following should appear:

_images/configuration-challenge-admin-score-settings-2.png

They are the default point rubrics created as part of the system initialization process. You can adjust them individaully to fit your challenge’s specific need.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Players

Design the groups
About groups
Makahiki defines a three level hierarchy consisting of groups, teams, and players.
  • Groups, which collect together a set of teams. Groups are optional.
  • Teams, which collect together a set of players. Teams are required.
  • Players.

For example, a residence hall challenge might consist of three buildings, each with 10 floors, each floor containing 20 residents. You could define a single group for each building, 10 teams for each group corresponding to the 10 floors in each building, and 20 players for each team corresponding to the 20 residents on each floor. Thus, groups correspond to buildings, teams correspond to floors, and players correspond to residents.

Note that definition of groups is only needed if you want to have competition at that level of aggregation. For example, if in a residence hall competition you are only competing at the floor level and not the building level, then you can just define players and teams. Similarly, if you are only competing at the building level and not the floor level, then once again you do not need groups (in this case, teams correspond to buildings).

The default instance defines some sample groups.

Note

Configuration of groups is required. Either you should rename the default groups to be named appropriately for your challenge, or else delete them altogether if your challenge does not involve competition at the group level.

Getting to the group settings page

After clicking on the “Groups Settings” link in the Challenge Design page, a page similar to the following should appear:

_images/configuration-challenge-admin-groups-settings-1.png

In this example, clicking on the “Lehua” instance brings up this page with information about the group. As you can see, there is not much to provide: the name (which can contain spaces and other punctuation) and the slug (which must be a unique ID).

_images/configuration-challenge-admin-groups-settings-2.png

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the teams
About teams
Makahiki defines a three level hierarchy consisting of groups, teams, and players.
  • Groups, which collect together a set of teams. Groups are optional.
  • Teams, which collect together a set of players. Teams are required.
  • Players.

For example, a residence hall challenge might consist of three buildings, each with 10 floors, each floor containing 20 residents. You could define a single group for each building, 10 teams for each group corresponding to the 10 floors in each building, and 20 players for each team corresponding to the 20 residents on each floor. Thus, groups correspond to buildings, teams correspond to floors, and players correspond to residents.

All players are required to be associated with a Team. This constraint might be removed in a future release of the system.

Note

Configuration of teams is required. At the very least, you should rename the two teams to fit your challenge. You might also need to define more than two teams.

Getting to the team settings page

After clicking on the “Teams Settings” link in the Challenge Design page, a page similar to the following should appear:

_images/configuration-challenge-admin-teams-settings-1.png

To define a new team, click the “Add team” button in the upper right corner. To edit a team definition, click the link which brings up a page similar to the following:

_images/configuration-challenge-admin-teams-settings-2.png

Normally, you can leave the team size as 0. An experimental feature of Makahiki is to specify a non-zero size for each team. By specifying a non-zero team size for each team, the system will use the team size to normalize the participations rate, total team points across different teams.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Set up users
About users

Makahiki supports the following types of users:

  • Player. These are the most common type of users who actually play the challenge. All challenges must have some players.
  • Admin. The admin user has access to the Settings and Status page, and has the ability to configure, design, and manage the challenge. All challenges must have at least one Admin.
  • RA. This is a special-purpose role provided for dorm energy challenges, where you might wish special capabilities or game mechanics for RAs. The RA role is optional for challenges.

As part of the installation process (see Install Makahiki), you create an environment variable that defines an initial admin account and username. As a result, every Makahiki installation has at least one admin account. After logging in with this account, it is possible to use this page to create additional users and provide them with admin status. This is quite desirable in order, for example, to distribute the workload of processing Smart Grid Game submissions.

In addition to defining additional admin accounts, the other primary purpose of this page is to create accounts for all players of a challenge. In the current version of Makahiki, the administrator must define all player accounts; it is not possible for users to “register” themselves online and obtain an account to play.

Creating a player requires providing their name, their account name, and the team to which they belong. You can do this individually, or if you need to define many players, you can create and upload a file.

Note

Configuration of users is required. At a minimum, you must delete the default users and add new users corresponding to the players in your challenge.

Getting to the users page

After clicking on the “Users” link in the Challenge Design, a page similar to the following should appear:

_images/configuration-challenge-admin-players-settings-1.png

To add a new player, click the “Add user” button in the upper right corner.

This is a two step processes. You will be asked to input the username and password for the user first, then, the next step will ask you to input the user’s first name, last name, and other user account info.

About the user profile

When a new user is created, a “Profile” is also created for this user, as shown in the “Profile” link in the list. The Profile has more detailed information about the user, such as the display name, team which this user belongs to, and the contact info etc.

The following screen shows an example of a player’s profile settings looks like:

_images/configuration-challenge-admin-players-settings-2.png

Note

When creating a user, you will normally want to specify the team this player belongs to. After you create the user, you can click on the Profile link in the user list, and specify the team in this player’s profile setting page.

Note

By default, the admin user does not belong to any team. You can temporarily assign the admin user to a team for testing purpose. For example, if you want to see Energy usage of a team, you could temporarily change the admin user to that team then go to the “Go Low” page to see the energy usage. Make sure you un-assign the admin from any team once the testing is done, otherwise, the admin will be participating in the challenge as a team member for the team he is assigned to, which may not be what your intent is.

Changing the information associated with an existing user

Due to Django, Makahiki stores information about a user in two places:

  • Click on the “username” link to bring up a page to modify basic information about the user.
  • Click on the “profile” link to bring up a page to modify additional information about the user.
Defining multiple users through file upload

To load a list of users defined in a csv file, the “Bulk create users” button could be used, which will prompt you to upload a CSV file from your local computer.

The format of the csv file is as follows:

team, firstname, lastname, email, username, password

This step will create both the User objects and Profile objects in the system for the users specified in CSV file.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Other settings

Design the Pages
About the page

Makahiki defines a default set of pages for the game website. A page is associated with a nagivation icon and label on the top of the website interface, the icon and introduction text on the website home page, a condition for displaying and hiding the page, as well as the game widgets on the page.

Note

Configuration of the page is optional, as long as you are satisfied with the default values.

Getting to the page settings page

After clicking on the “Page info” link in the Challenge Design page, a page similar to the following should appear:

_images/configuration-challenge-admin-pageinfo-settings-1.png

These are the default page info created as part of the system initialization process. Click on this link to bring up the following page that enables you to configure the individual page:

_images/configuration-challenge-admin-pageinfo-settings-2.png

You can also click on the “Add page info” button to add a new page. If you like to add a new page, you will need to contact the developer to supply a new set of icons for your new page, as well as other development changes to support the new page.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Help Topics
About the help topics

Makahiki includes a set of help contents about the game website, they are presented to players in:

  • A help page that displays the rules of the challenges and frequently asked questions
  • the contextualized help text for each widget when you click on the question mark icon on the top-right corner of each widget.

These help contents are stored in the Makahiki database which could be modified by the challenge desiger.

Note

Configuration of the help topic is optional, as long as you are satisfied with the default values.

Getting to the help topic settings page

After clicking on the “Help topic” link in the Challenge Design page, a page similar to the following should appear:

_images/configuration-challenge-admin-helptopic-settings-1.png

These are the default help topics created as part of the system initialization process. Click on this link to bring up the following page that enables you to change the individual help topic:

_images/configuration-challenge-admin-helptopic-settings-2.png

You can also click on the “Add help topic” button to add a new help topic.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Notice templates
About the notice templates

Makahiki will notify players about a certain system events, such as:

  • A new round has started
  • The commitment is ready for claiming the commitment points
  • The player won a top-score prize
  • The player won a raffle prize

The message text of these notifications could be customized by the challenge desinger via the notice template settings interface.

Note

Configuration of the notice template is optional, as long as you are satisfied with the default values.

Getting to the notice template settings page

After clicking on the “Notice templates” link in the Challenge Design page, a page similar to the following should appear:

_images/configuration-challenge-admin-notice-settings-1.png

These are the default notice templates created as part of the system initialization process. Click on this link to bring up the following page that enables you to change them:

_images/configuration-challenge-admin-notice-settings-2.png

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Resource Blackout Date
About the resource blackout date

During the course of the challenge, there may be some dates that the resource consumption might be an exception comparing to the normals. For example, Students may leave the dorm during the Thanksgivings days and Spring break, the consumption in the dorm during those periods might be very low. It would not represent the normal consumption. If we compare those days to the baseline or include those days in the baseline calculation, the result will be inaccurate. So, to avoid this problem, Makahiki allows the challenge designer to exclude those days from the competition by specifying the “Resource Blackout Dates”.

Note

Configuration of the resource black out dates is optional. By default, there is no black out dates specified.

Getting to the notice template settings page

After clicking on the “Resource blackout dates” link in the Challenge Design page, You will see a list of blackout dates if there is any. You can click on the “Add resource blackout date” button to add a new black out date:

_images/configuration-challenge-admin-resourceblackout-settings-1.png

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Game Design Settings

The following sections document the settings accessable from the “Game Settings” widget.

Specify the games to appear in your challenge
About the games

As a challenge designer, your responsibilities are limited to deciding which of the pre-built games and game mechanics will appear in your challenge. It is the role of developers to actually create entirely new games for use in challenges.

Makahiki currently allows you to create a challenge out of the following games and game mechanics:

Energy Game. This game awards points to players depending upon their ability to lower their energy consumption.

Water Game. This game awards points to players depending upon their ability to lower their water consumption.

Smart Grid Game. This game is the principle interface to the educational component of Makahiki. The SGG awards points to players for successfully completing activities, commitments, excursions, and events.

Top Score Game. This game awards prizes to players and teams for earning the highest number of points during a round.

Raffle Game. This game awards prizes to players if they have allocated their raffle tickets to a particular raffle prize, and that raffle ticket was randomly selected by the system at the end of a round.

Participation Game. This game awards points to players if they can successfully get a certain percentage of their team members to participate in the challenge.

Quest Game Mechanics. This game mechanic provides a way for players to learn about features of the challenge by guiding them through Quests.

Badge Game Mechanics. This game mechanic provides a way for players to earn badges for playing the game in a variety of ways.

Referral Game Mechanics. This game mechanic provides a way for players to earn points by getting other people to participate in the challenge.

Note

Configuration of the set of games is required. Either you will want to disable certain games or game mechanics in order to simplify your challenge, or you will need to configure certain games that are currently enabled (such as the Smart Grid Game).

Getting to the challenge design page

The challenge design page shows the set of games available in Makahiki and whether or not they are currently enabled for use in your challenge via the following widget:

_images/configuration-game-admin-game-display-widget.png

The above image shows that this instance of Makahiki supports nine games. The small green and red icons on the right side indicate whether a game is currently enabled for the challenge. In this case, all of the games but one (Water Game) are enabled.

Changing the settings associated with a game

Clicking on the title of a game will let you enable or disable the game and its widgets. After clicking on the title link in the Game Admin widget, a page similar to the following should appear:

_images/configuration-game-admin-game-settings.png

By default, the game is enabled. You can uncheck the enabled checkbox to disable the game.

A game’s UI is represented by a set of widgets which is visible in the game website. The widgets belong to a game is listed under the “Game Settings” section, as shown from the above screen shot. If you disable the game, all the widgets belong to this game will not be shown in the web page.

Subsequent sections of this guide explain the configuration of each game.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Resource Goal Games
About resource goal games

To understand the design of resource goal games, we believe it will be useful to start by explaining the design of the Energy Goal Game, then show how it has been extended to resources in general.

Design of the energy goal game

The purpose of the Energy Goal Game is to incentivize teams to work together to conserve energy by showing their progress toward a daily goal, which is computed as a percentage reduction from a baseline. So, for example, if a team normally consumes 100 kWh of energy in a day, the Energy Goal Game might award 20 points to every player in the team at the end of the day if that team reduced their consumption by at least 5% (i.e. to 95 kWh or less).

To provide a more visual sense, the following screen image shows the “stoplight” user interface to the Energy Goal Game:

_images/degg-stoplight.png

The stoplight visualization for the Energy Goal Game

As you can see, this interface uses a stoplight metaphor to show at a glance whether or not the team is making the goal. In this case, the stoplight is green, indicating they are currently below the goal.

During the design of the energy goal game, we faced two primary design challenges:

What constitutes “normal” energy consumption? To calculate a goal (i.e. target) energy consumption, it is useful to have some estimate for what normal consumption would be during the challenge period. The traditional way to accomplish this is by monitoring energy consumption data for each team for a period prior to the start of the challenge, and then using this data to estimate what “normal” consumption would have been like during the competition. This process is normally referred to as generating a “baseline”.

We realized that residence hall energy consumption is significantly different on weekends (when many students might leave the building for travel) and weekdays. Thus, it appears important to calculate a separate baseline for each day of the week.

In Makahiki 1, we recommended that challenge designers gather energy data for at least three weeks prior to the start of the challenge, and then calculate the baseline daily energy consumption for each day by averaging the three values obtained for each day of the week.

What is the user interface? Let’s assume that the baseline data collection resulted in an average energy consumption of 100 kWh on Monday for a given team. Let’s also assume that the goal is a 5% reduction, so we want to reward the team for using 95 kWh or less. How do we provide feedback to the team on their progress toward the goal?

One (naive) approach would be to simply divide the average daily consumption by 24 to get the average hourly consumption for the given day, and then compare the actual consumption to this projected consumption. However, the problem with this approach is that residence hall energy consumption is not consistent during the day: in fact, most of the consumption occurs in the evening hours between 8pm and midnight. Thus, this naive approach would lull players into thinking that they were beating the goal for most of the day until late evening, when their consumption would suddenly “catch up” to the goal.

To provide a more accurate sense for progress toward the goal, we recommend that challenge designers not only gather energy data for each day of the week separately, but for each hour of each day of the week separately. That way the stoplight visualization can track the team’s consumption throughout the day, taking into account the typical “demand curve” associated with the team.

Additional goal game interfaces: the scoreboard view

While the stoplight visualization provides good feedback to a team regarding their current progress toward making the current day’s goal, we have found additional perspectives to also be useful.

The following figure shows the Energy Goal Game scoreboard, which shows how teams are faring relative to each other, and can incentivize teams to conserve not only to earn points, but also to do better than other teams:

_images/degg-scoreboard.png

The scoreboard visualization for the Energy Goal Game

Interestingly, the scoreboard shows that the number of times that a team makes their daily energy goal is not perfectly correlated with their average reduction in energy consumption.

Additional goal game interfaces: the Realtime Power meter view

One useful perspective to a team is a realtime power meter visualization that shows the current power usage of a team, as shown by the following figure:

_images/degg-powermeter.png

The power meter visualization

This visualization displays the realtime power consumption which updates in a specified interval. This give players the sense of energy consumption at the moment. For example, someone turns on a high power microwave, they might see a spike in the realtime power meter reflecting the power usage at that moment.

Additional goal game interfaces: the calendar view

Another useful perspective to a team is a historical, calendar-based visualization that shows the results of the energy goal game for each day of the current round, as shown by the following figure:

_images/degg-calendar.png

The calendar visualization for the Energy Goal Game

This visualization is useful for helping teams to see if there are patterns to their ability to make their goal. The above display shows that they have been making their goal more regularly in the recent past, indicating perhaps that they have identified a useful strategy for conservation.

Automated vs. manual data collection

Makahiki supports both automated and manual data collection. With respect to automated energy collection, Makahiki queries a WattDepot server once an hour to get an update on each team’s consumption during the previous hour, and then updates the stoplight visualization. At midnight, Makahiki determines whether the conservation goal was achieved by the team and updates the calendar-based view with the results for that day.

However, not all challenge player communities have meters that are internet-accessible and thus allow this kind of real-time, automated update. Instead, they might have a traditional, analog meter.

The Energy Goal Game can be configured to support manual data collection. To accomplish this, the challenge designers must first tell the system the time each day at which they will read the meters manually. (To make the energy goal game workable, the challenge designers must commit to reading the energy meters for each team at approximately the same time each day so Makahiki can assume the data represents equal, 24 hour intervals. Team meters can be read at different times, but the time must be consistent for each team.)

Then, each day during the challenge, the challenge designers read the meters, then login to the system and update Makahiki with the latest readings. From this, Makahiki can determine which teams made their energy goal for the previous day.

From a user interface perspective, the basic difference is that the stoplight visualization is not available. Instead, the primary interface to the Energy Goal Game is the calendar-based visualization, which shows the results for each day.

From Energy Goal Games to Resource Goal Games

Now that you understand the various interfaces to the Energy Goal Game, and the issues of manual vs. automated data collection, it is simple to understand the concept of “Resource” goal games.

Basically, we realized that once we had support for both automated and manual energy data collection, we were well on our way to supporting Water Goal Games, Food Goal Games, Waste Goal Games, or any other “resource” for which teams are responsible. So, we reorganized the Makahiki code base for the Energy Goal Game to support a family of games, one per resource.

Currently, Makahiki provides built-in support for two resource goal games: energy and water. Each of those games, when enabled, results in a page devoted to that resource in the web application. The default configuration enables support for the Water Goal Game and the Water page.

Extending Makahiki to support an additional resource goal game is straightforward, but requires developer-level capabilities.

The problem with baselines

The preceding discussion makes perfect sense, but there is an important assumption underlying the design of the game. This assumption is that it is possible to collect historical data that can be analyzed and used to compute an accurate prediction of “normal” resource consumption during the challenge period. This is essential, because if you cannot accurately predict “normal” consumption (i.e. what the consumption would have been in the absence of the challenge), you cannot calculate “conservation” in a meaningful way, and thus the achieving of the goal might not reflect actual team behavior.

Our experience with Makahiki has convinced us that this is a significant issue in the design of serious games for sustainability. The issue is too complex to go into here, but for more information, we recommend that challenge designers read our article “Beyond kWh: Myths and fixes for energy competition game design”.

A concrete outcome of this research is that Makahiki now offers two ways to calculate baselines: “fixed” and “dynamic”. The “fixed” baseline approach uses historical data to calculate baselines in the traditional fashion explained above.

Our more experimental approach is called “dynamic” baselines. In this approach, baselines are calculated using the last two weeks of data, even when that data occurs during the actual challenge. As a result, dynamic baselines do not attempt to characterize or predict “normal” behavior, but instead constantly recalibrate themselves to the team’s most recent behavior by asking them to effectively “do a little better than they did before”. At some point, teams will not be able to conserve any more, and they will stop being able to achieve their goal. If their consumption increases from there, the baseline will reset itself and the goal will once again be achievable. Evaluation of this strategy is still ongoing: while it overcomes certain problems with fixed baselines, it has its own trade-offs (such as the fact that a team will always reach a point at which they can no longer make their goal.)

Configure resource goal game settings

There is no link to “resource goal game” in the system. Instead, there are links to the currently implemented games in this “family” of games. At present, there are links to configure the Energy Goal Game and the Water Goal Game in the top-level challenge design page. From there, clicking on Energy Goal settings in the Energy Game admin widget will produce a page similar to the following:

_images/configuration-game-admin-resource-game-goalsetting-1.png

This is the list of energy goal settings for all teams. Clicking on the team name link brings up a form to edit or change the goal settings. You can also add an energy goal game for a new team using the “Add energy goal setting” in the upper right corner.

Once you’ve clicked a team, you get the following configuration page:

_images/configuration-game-admin-resource-game-goalsetting-2.png

Given the discussion above, the settings should now be understandable:

  • Team: Select the team name to be associated with these settings. Normally, you’ll want all teams to have the same settings, but Makahiki allows you to configure each team individually.
  • Goal percent reduction: Specifies the required percentage reduction from the baseline value for the current day in order to earn the points.
  • Goal points. All active players of the team receive this number of points if the conservation goal is met. To be active, a player must have logged in to the system and completed the first login wizard.
  • Baseline method. Choose “Fixed” for the traditional method, “Dynamic” for the experimental dynamic baseline method.
  • Data storage. Only WattDepot is currently supported.
  • Manual entry. Click this checkbox to enable manual entry. Specify the time of day when the data will be entered.
  • Realtime meter interval. How frequently the data storage mechanism will be queried to update the real-time meter.

You can also click on the “Add new goal settings” button in the list page to create the goal settings for a new team.

Note

Every team should have the goal settings. In fact, when you create a team, the default resource (energy and water) goal settings is created for this team. The designer should check the default value to see if they are what they want and if they are consistent across other teams.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Smart Grid Game
About the Smart Grid Game

Makahiki provides the Smart Grid Game (SGG) to support “gamified” delivery of educational experiences. Players use its grid interface to discover “actions” they can perform. Successful completion of an action earns the player a variable number of points depending upon the difficulty of the action, and can potentially “unlock” additional actions in the SGG. There are four types of actions: activities, commitments, events, and creative. As a challenge designer, your task is to design an SGG that contains educational experiences suitable for your players, and also design the “path” that players take through the SGG through the unlocking of new actions.

The following screen image shows a typical Smart Grid Game interface for players:

_images/configuration-game-admin-smartgrid-game-interface.png

This image reveals several important aspects of the SGG:

Levels. Each Smart Grid Game can have from 1 to 7 “Levels”. (More than 7 Levels becomes awkward when viewing the game on a mobile device.) The screen image above has 7 levels. In typical SGG designs, players begin with access only to the first Level. Higher Levels become unlocked for a player either because they completed a lower level or because a Level is designed to unlock automatically when a given date is reached during the challenge.

Actions. The cells underneath a category label provide access to “Actions”. There are several action types: Activity, Commitment, Event, Filler. The color of the cells indicates their action type. In the screen image, each of the five categories has five Action cells, so this Level of this Smart Grid Game has a total of 25 Actions. In order to create a rectangular grid, designers can also create “filler” actions, which occupy a space in the grid but cannot be otherwise manipulated by players. There is one “filler” action in the lower right corner.

State of play. Cells are “decorated” with information that indicates the state of play.

  • If an action is unlocked and thus available for the player, then the cell provides a number indicating the point value of that action if completed. In the image above, unlocked cells indicate actions ranging in value from 5 to 100 points.
  • If an action is not yet unlocked, then instead of a number, it shows a lock icon.
  • If the cell corresponds to an an event that has already occurred, it is labeled as “Expired”.
  • If the action has been submitted or completed by the player, then instead of a point value, the name of the action appears in the cell. For example, the image above shows that this player has completed the “Intro Video” action.
  • Finally, actions are typically in one of three states: submitted, completed, or rejected (in which case the player can resubmit a revised answer to get full credit.) Small icons (orange, green, or red) indicate this state.
About actions
Activity

Activities are the most basic action available in the Smart Grid. In order to get points for an activity, a player must input a response to the system, which is reviewed and approved or disapproved by administrators. These responses can be a short textual answer or an uploaded picture. If a submission is approved, the player receives the points for their submission. Otherwise, the system notifies the player that their submission was not approved, along with a comment (writte by an administrator) explaining why it was rejected. The player can change and resubmit their response and still earn the full point value for that task. The following figure illustrates a sample activity:

_images/action-video.png

Sample activity in the Smart Grid Game

Commitment

Commitments are pledges that the player will carry out a specific action for a specific amount of time (typically 5 days). Examples include: reducing shower time, taking the stairs, and turning off the lights when leaving a room. Unlike activities, commitments are not easily verifiable, and so they are usually designed with fewer points than activities. Furthermore, a player can only enter into five commitments at any given time. After the commitment period is up, the player can declare that they completed the commitment and immediately earn the associated points. They can then enter into another commitment, including the one they just completed. The following figure illustrates a sample commitment:

_images/action-commitment.png

Sample commitment in the Smart Grid Game

Events

Events are actions tied to real world meetings. To help organizers gauge interest in events, players can earn points by signing up in advance. Players that do this (and then actually attend the event) earn a signup bonus (typically 2 points). Players can also set up a reminder that is sent to their email and/or their mobile phone before the meeting takes place. At the event, a challenge administrator provides players with “attendance codes” printed on slips of paper that can be later entered in the system by the player to get their points. (The paper slips provide a form of verification that the player physically attended the event.) Attendance codes are generated by Makahiki and can only be used once. To discourage players from signing up and not attending, a penalty (typically 2 points) is assessed to players who do not submit an attendance code. If the player submits an attendance code for the event after receiving this penalty, the penalty is reversed. The following figure illustrates a sample event:

_images/action-event.png

Sample event in the Smart Grid Game

Creative

Creative actions enable players to exercise their artistic talents. These are often worth a variable number of points, depending upon the effort made by the player and the quality of the outcome (as judged by administrators). Examples of creative activities include: make a poem, make a video, write a letter to the editor, write a song, and create a photo blog. The following figure illustrates a creative activity:

_images/action-creative.png

Sample creative activity in the Smart Grid Game

Designing your Smart Grid Game

Designing the Smart Grid Game is one of the most complicated parts of the Kukui Cup planning process, because the Smart Grid Game is the “portal” through which players get access to the various “actions” (activities, commitments, events, and creatives) of the Kukui Cup: in short, virtually all of the “real world” experiences.

We recommend that you begin by “roughing out” the design of your smart grid game on paper (or, even better, in a spreadsheet). Once you have designed the preliminary set of actions and their locations in the grid, you can implement that design in the system.

Note

We are working on a SGG “designer” interface with drag-and-drop functionality that will greatly simplify this process. We hope to release it in Q2 of 2013.

Step 1: Design your initial content

To design an SGG, the first step is to determine the initial content for your challenge, which means answering the following questions:

  • What are the events (if any) in your challenge?
  • What are the commitments (if any) in your challenge?
  • What are the videos (if any) in your challenge?
  • What are the non-video activities in your challenge?
  • How many points is each activity worth?
  • For video and non-video activities, what are the verification questions?

To help bootstrap your design, we have created an action library of almost 100 actions that you can use for inspiration. They are organized as a Google Spreadsheet with various subsheets to show different perspectives on the information. The following figure shows a screen image of the spreadsheet. Here is a link to the action library.

_images/sgg-library-spreadsheet.png

A screenshot of the action library

The Library versions of these actions are also provided in Makahiki’s Smart Grid Game Designer on the left-hand side, so you don’t have to retype all of the information if you would like to use one or more of these actions in your challenge.

To complete this design step: create a document that provides the titles, descriptions, point values, and verification questions for all of your proposed content. If you are reusing actions from the library, then just list the title and any attributes that you wish to change.

Step 2: Design the “paths” that players take through the SGG

To make your SGG more interesting to players, and more pedagogically sophisticated, you will want to define “paths” through the content. In most cases, when a new player sees the SGG for the first time, there should only be a few actions available to them—possibly only one. All of the rest should be “locked”.

For this design step, start by specifying the initial, “seed” actions in your SGG: those that are always unlocked.

Next, specify the actions that should be unlocked once one or more of the seed actions are successfully completed by players. The content of these new actions can now potentially depend upon the information presented in the initial actions, since the game itself guarantees that players will have completed “dependent” actions before being able to see the new action.

An alternative way to specify that an action should be unlocked is by time and date. For example, you may want to make events and excursions visible to participants starting five days before their actual occurrence. You can also combine the two approaches. For example, you might want to make an event available only to those players who have successfully completed certain actions. In this case, it gets unlocked for a player only if both the date/time has been reached, and the player has completed the actions.

To complete this design step: Augment the document created in Step 1 with the dependencies associated with each action. If an action has no dependencies, it is a “seed” action and will be always unlocked.

Step 3: Decide which activities support the “social bonus”

The social bonus is an optional attribute of any Smart Grid Game action which awards extra points if the player has done the action with someone else. Examples of actions which commonly include a social bonus are: attending an event, recording a song related to energy, or measuring a shower water flow rate.

When a player submits a response for a action that supports the social bonus, the player can provide the email address another player who jointly completed the action. Once the other player also completes the task, the social bonus is awarded. Social bonuses are not bi-directional; if the second player doesn’t provide the first player’s email address, only the first player will get the social bonus.

To complete this design step: Decide which actions should include the social bonus, and augment your document with this information.

Step 4: Design the layout

Now that you have the initial set of actions and their dependencies, it is time to figure out how they should appear in the grid. A spreadsheet program is quite useful in this process, or you can use graph paper, or even a piece of paper in which you have drawn vertical lines to create a grid. In any case, you need to decide on the column labels, and the column of actions underneath each category. If you are designing a game with multiple Levels, then you need to decide on the categories and actions for each level.

Note that you frequently don’t have a “perfect” number of actions to create a rectangular grid. To solve this problem, the SGG allows you to specify “Filler” cells in order to create a rectangular grid. For example, let’s say you want to define a Level with 17 actions. You could create a 4 x 5 grid with your 17 actions and 3 additional “Filler” actions. While the SGG allows you to create grids with a “ragged” bottom edge, we think that a rectangular grid is aestheticly more pleasing. In addition, Filler cells can be later replaced by actual actions, enabling you to easily add content in the middle of a challenge without changing the structure of the grid.

Here are some layout heuristics we have discovered through the design and execution of our own challenges:

  • Initial, unlocked (seed) actions generally go in the first Level, in the first column. The intro video (used during the “first login wizard”) is typically the first action in the upper left corner.
  • For best display on mobile devices, define no more than 5 columns per Level.
  • To simplify addition of actions after the challenge is started, it is useful to always have a few Filler actions on each Level.
  • If you are creating a challenge with multiple rounds, you might want to have one Level per round, and have each Level unlock at the start of its corresponding round.

To complete this design step: Create a grid using a spreadsheet or paper that contains your layout. Each action should appear once and only once on the grid. If you define multiple Levels, you need to create a separate grid for each Level.

Implementing your Smart Grid Game with the Designer

Once you have finished with the design of your Smart Grid Game, it is time to implement it in the system. The Smart Grid Game Designer introduces a new concept Draft Grids. Drafts are Smart Grids that are just for planning or development. They allow you to explore different layouts and paths through the Smart Grid Game. Since the Smart Grid is live, players can see the Smart Grid. If the designer want to change the Smart Grid Game they shouldn’t directly edit the Smart Grid since the players can see any changes in real time.

  • The Library holds the generic actions without any dates or locations. The Library is a resuable set of actions for any Kukui Cup.
  • The Designer holds specific draft grids that can be published to the Smart Grid Game. Designer Actions are more specific than Library Actions since they often have real dates and locations. The Designer Actions should be tailored to your specific KukuiCup. Designers can adjust the Designer Grid, adding or removing actions, columns and levels and players will not see the changes until they are published.

Makahiki has a Smart Grid Game Designer (Designer) to help you build your Smart Grid Game. To get to the Designer click on the “sgg conf” button on the Navigation bar. The right hand most icons shown the figure below.

_images/configuration-game-admin-smartgrid-game-toolbar.png

If there are no Draft grids when you start the Designer Makahiki presents you with the ‘New Draft’ choice dialog shown below when you click on “New Draft.”

_images/configuration-game-admin-smartgrid-game-new-draft.png

Warning

The names of Draft grids cannot contain spaces or uppercase letters.

You can choose from five different example Smart Grid Game templates, Empty Grid, Demo, Kukui Cup/UH12, and test. These templates provide a variety of different Smart Grid Game examples.

  • Empty Grid is a single level empty grid, wide open for your creativity.
  • Demo is a three level grid, with one virtual event.
  • Kukui Cup/UH12 is the grid used in the 2012 Kukui Cup at the University of Hawaii, Manoa. It has seven levels and was designed to run for 9 months.
  • Test is four level grid used in some of the development tests.

Once the draft is created you will see the Designer. Designer has two sections, Designer Widget and the Grid Consistency Checker (GCC) tools.

Designer Widget

The first section is the Smart Grid Game Designer Widget shown in the next figure.

_images/configuration-game-admin-smartgrid-game-designer.png

The Designer Widget has three columns, Library Actions, Designer Grid, and Palette. The Library Actions Column holds a library of Activities, Commitments, and Events. These actions are divided into three tabs, Activities, Cmnts (Commitments), Events, shown in the next figure.

_images/configuration-game-admin-smartgrid-designer-library-actions.png

These are actions we’ve used in previous Kukui Cups and are good examples. Clicking on the name of an action takes you to the admin interface where you can edit the action. Right mouse clicking on the action pops up a menu of choices allowing you to copy the action or pre-view the action. You can drag these library actions into the Designer Grid. When you drag a Library Action into the Designer Grid Makahiki creates a new Designer Action in the current draft. If the Action is an Event you will be asked to provide the event date and location.

_images/configuration-game-admin-smartgrid-designer-grid.png

The Designer Grid has four sections, draft choice, library column names, control buttons, and grid.

  • The Draft choice row allows you to select the draft you want to work on, create a brand new draft, or delete the current draft.
  • The Library Column Names holds the predefined column names we’ve used in previous Kukui Cups. You can drag these columns to the grid activating the column.
  • The control buttons allow you to revert to the current Smart Grid Game or Publish the current draft in the Designer to the Smart Grid Game.
    • Reverting to the current Smart Grid Game erases the contents of the Designer and copies the Smart Grid Game into the current draft.
    • Publishing the Designer runs the GCC checking for any errors in the current draft. A dialog box shows the GCC results. If there are no errors you can publish the draft to the Smart Grid Game. At this point you can decide to use Fillers to fill out the grid or just leave blanks in the grid. The Smart Grid Game is live any players will immediately see the changes to the Smart Grid Game.
  • The Grid represents the Smart Grid Game. Levels are on the left (They are at the top of the Smart Grid Game). Each level has up to eight columns and eight rows holding the grid of actions. Clicking on the column names or grid actions takes you to an editor.

Clicking on the names of the Designer Actions takes you to the admin interface where you can edit the contents of the action. Right mouse clicking on the action pops up a menu allowing you to copy the Designer Action, delete the Designer Action or preview the Designer Action.

The third column of the Designer Widget is the Action Palette. The Action Palette hold Actions that are not currently in the Smart Grid Game, but may be used at a later time. It is also useful for moving an action from one level to another.

_images/configuration-game-admin-smartgrid-designer-palette.png
Grid Consistency Checker (GCC) Tools

The second section is a set of Grid Consistency Checker (GCC) Tools shown in the next figure.

_images/configuration-game-admin-smartgrid-designer-validation.png

The left-hand side of the GCC section shows the results of running the GCC on the current draft.

_images/configuration-game-admin-smartgrid-designer-gcc-errors.png

The Re-Run Grid Consistency Checker button re-runs the GCC, updating the errors and warnings. The Settings button pops up a dialog box allowing you to select which checks the GCC runs.

_images/configuration-game-admin-smartgrid-designer-gcc-settings.png

Generally, you should keep all the checks enabled except ‘Check description URLs’. Check description URLs validates URLs in the Action descriptions checking for valid HTTP return codes. This check is very, very slow.

The right-hand side of the GCC section shows the dependency tree or path through the actions. This panel is scrollable.

_images/configuration-game-admin-smartgrid-designer-dependency.png
Using The Smart Grid Game Designer
Step 1: Design your initial content

To complete this design step: You need to drag the Library Actions into the grid or copy existing Designer Actions in the grid. Then edit the Designer Actions.

There are several different approaches to selecting your content.

  1. You can start with an empty grid, then create the levels and add the columns then drag the library actions into the grid. After the Designer Actions are in place you can edit them.
  2. You can drag your selected content into the palette. Then edit the Designer Actions. Create the levels and columns then later locate the actions in the grid.
  3. Using your content document from Step 1, mark off each action as you drag it into the grid and edit the Designer Action.

In all the approaches above you should ensure that you edit the action so that it matches the titles, descriptions, point values, and verification questions of your proposed content. Clicking the name of the action in the grid takes you to the admin interface where you can edit the contents of the action. Remember to Save your changes.

Step 2: Design the “paths” that players take through the SGG

To complete this design step: Edit the Designer Action’s unlock condition field in the admin interface.

_images/configuration-game-admin-smartgrid-designer-unlock.png

Note

We are working on a SGG dependency editor interface that will greatly simplify the process of creating the “paths”. We hope to release it in Q3 of 2013.

The unlock condition uses the Makahiki Supported Predicates and boolean operators to indicate what actions or conditions must be true to unlock the current action. There are several very useful predicates:

  • submitted_action: This predicate has one parameter the slug for the action must be attempted before unlocking. Attempted means that the player hit the ‘I Did This’ button and submitted their answer. It does not mean that a Challenge Admin approved the answer. The figure above shows two submitted_action predicates.

  • unlock_on_date: This predicate is true if the current date is after the given date.

    unlock_on_date('03/15/13') will evaluate to true after the Fifteenth of March 2013.

  • unlock_on_event: This predicate allows you to unlock an event based upon its event date. The predicate has two optional parameters days and lock_after_days. days should be a negative number and is the number days before the event date to unlock the event. lock_after_days will lock the event after the event date.

    For example if an event had an event date of ‘03/15/13’ and the unlock condition was unlock_on_event(days=-3, lock_after_days=2) the event would be unlocked from 03/12/13 til 03/17/13.

  • approved_action: This predicate is very similar to submitted_action, but is only true when a Challenge Admin has approved the player’s answer.

If in your design an action has no dependencies, its unlock condition should be ‘True’. This makes it a “seed” action and will be always unlocked.

You can use boolean operators to make more complex dependencies. For example:

submitted_action('tweet-link') and unlock_on_date('03/15/13') will only be true after March 15th, 2013 and if the player had submitted the Tweet about Kukui Cup activity.

Note

We do not recommend you to use complex boolean logic since it is very difficult to ensure that it will work properly.

Step 3: Decide which activities support the “social bonus”

To complete this design step: Edit the actions that have the social bonus setting their Social Bonus Points value.

_images/configuration-game-admin-smartgrid-designer-social.png

Be sure to save your changes.

Step 4: Design the layout

To complete this design step: Implement your spreadsheet or paper grid.

First, create the level(s) in your grid.

  • Right mouse click on any of the Levels to get a popup menu. The menu allows you to delete the current level or create a new level.
_images/configuration-game-admin-smartgrid-designer-level-edit.png
  • Deleting a level moves all the actions in the level to the palette.
  • Adding a new level creates an empty level. Just supply the unique new level name and a predicate for the unlock condition.
_images/configuration-game-admin-smartgrid-designer-new-level.png

Second, fill the level(s) based upon your design.

1. Drag a column name to the first row of the Designer Grid. This will enable the column. Column names must be unique per level. Keep dragging column names untill you are satisfied with the columns.

_images/configuration-game-admin-smartgrid-designer-columns.png

2. Drag a Library Activity, Commitment, or Event into the enabled columns. This will create a Designer Activity, Commitment, or Event. When you drag an Event, Makahiki will ask you for the Event date and location.

_images/configuration-game-admin-smartgrid-designer-event-dialog.png

The finished level:

_images/configuration-game-admin-smartgrid-designer-lvl-5.png

3. Edit the Designer Actions by clicking on the action names. Make sure the contents of the actions is what you want. Pay attention to the unlock_conditions from step 2 and the Social Bonus Points from step 3.

4. Check your Designer Grid by running the GCC. Fix any errors. Check the warnings they may be issues or not.

_images/configuration-game-admin-smartgrid-designer-gcc1.png

In this example we have one error. The commitment ‘Use Stairs’ will not unlock since it depends upon the action ‘energy-intuition’, but energy-intuition is not in the grid. We have a couple of options to fix this problem:

  • Change Use Stairs’ unlock condition to be dependent on something in the grid.
  • Add the action ‘energy-intuition’ to the grid.

5. Try to publish your Designer Grid to the Smart Grid Game by pressing the ‘Publish Draft’ button. Makahiki runs the GCC on your grid before publishing the grid. If there are no errors in your grid you will be able to pubulish your grid. If you want fillers in your grid make sure the “Use Fillers” checkbox is checked when you publish. Otherwise the empty grid locaiton will be empty in the Smart Grid Game.

Verifying your Smart Grid Game

Once you have published your SGG, it is good to “playtest” the game. Go through each of the actions, and make sure they display correctly. Complete the initial actions to make sure that new actions get unlocked appropriately.

For large scale challenges, we recommend that you run a prior “pilot” challenge in which you select just a few people to play through the game and look for problems with your design.

Coming Soon Designer play tester.

Design the Top Score Game
About the Top Score Game

The Top Score Game enables you to design a challenge in which prizes are awarded to individuals and teams who earn the most points during the challenge (and/or each round in a challenge). It also enables you to award prizes to the teams that conserved the most energy (or some other resource such as water) during the challenge (and/or each round in the challenge).

If the Top Score Game is enabled, then you can enable both a Leaderboard widget that shows the top players/team in contention for each round, and a Prizes widget that shows the prizes for for each round and the current team/individual in line to win them.

_images/configuration-game-admin-topscore-game-scoreboard.png

Topscore game scoreboard

_images/configuration-game-admin-topscore-game-prize.png

Topscore game prize

Specify a Top Score Prize

After clicking on the “Prizes” link in the Top Score Game window, a page similar to the following should appear:

_images/configuration-game-admin-topscore-game-list.png

This page displays the current Top Score Game prize information for each round.

To add a new prize, click the “Add prize” button in the upper right corner.

Change the Top Score Prize

Clicking on a prize instance brings up a page with information about the prize:

_images/configuration-game-admin-topscore-game-change.png

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Raffle Game
About the Raffle Game

The Raffle Game was designed to solve the problem of incentivizing players who cannot hope to be a top competitor in the Challenge. When several hundred players are competing, only a handful have a realistic chance to be the top scorers for a round. Once a player knows they cannot beat all of the other players, there can be an urge to simply give up.

The Raffle Game is designed to enable all players to have a chance to win a wide variety of prizes, where their odds of winning increase based upon the number points they have earned in the game. The following image shows a screenshot of a raffle game.

_images/configuration-game-admin-raffle-game-screenshot.png

The Raffle Game works in the following way. For every 25 points (by default) that a player earns, they receive one virtual raffle ticket. Players can dynamically allocate their tickets to any raffle prizes they are interested in at any time, up to the end of the raffle. Each round of the competition has its own set of raffle prizes and any unused raffle tickets carry over to the next round. Raffle tickets are independent from a player’s score; allocating a raffle ticket does not affect their rank.

As the screen image above shows, each player can see in real-time how many Raffle Game Tickets they have earned, which prizes they have allocated them to, and the resulting percentage chance they have of winning based upon the tickets allocated by others to that same prize. Of course, these odds can change on a moment-to-moment basis as players allocated and deallocated tickets.

The Raffle Game, in addition to providing an incentive for the non-top players to earn points, also creates an incentive for players to come back to the site on a regular basis to see the updated odds associated with their choices.

Setting up the Raffle Prizes

After clicking on the “Raffle Prizes” link in the Game Admin widget, a page similar to the following should appear:

_images/configuration-game-admin-raffle-game-list.png

This page displays the raffle prize information for each round.

To add a new raffle prize, click the “Add raffle prize” button in the upper right corner.

Change a Raffle Prize

Clicking on a raffle prize instance brings up a page with information about the raffle prize:

_images/configuration-game-admin-raffle-game-change.png

The “Winner” of the raffle prize is normally randomly picked by the system at the end of the round. At the end of the page, you can also see a list of users that allocated raffle tickets for this raffle prize.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Participation Game
About the participation game

One of the current design constraints of the Kukui Cup is that the players associated with each team in a challenge must be specified in advance of a challenge. Thus, as the challenge runs, it is possible to know exactly what percentage of each team’s players are actively playing the game (in the sense that they have logged in at least once).

The Participation Game is designed to incentivize active players on a team to recruit other members of their team to login and try the game. It does this by providing extra points to all active players on a team when the percentage participation by that team reaches certain thresholds (currently 50%, 75%, and 100%).

The current percentage participation by a player’s team is shown in a scoreboard when this game is enabled (as shown in the figure below) and players receive an in-game notification whenever they reach a threshold participation where points are awarded.

_images/challenge-design-game-admin-participation-game-scoreboard.png
Configure the Participation Game

To configure the participation game, click on the “Participation Settings” link in the Game Admin widget. You will see the overview of the participation settings. Clicking on the link will bring you to a page to change the settings:

_images/configuration-game-admin-participation-game.png

You can change the points to award for each participation percentage. Currently, the percentages (50, 75, and 100%) are hardwired into the system.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Quest Game Mechanics
About the Quest Game Mechanic

One fundamental challenge faced by any game is: how do players learn how to play it? This is generally known as the onboarding problem. One way that Makahiki addresses the onboarding problem is through a “first login wizard” in which players (upon their first login) step through a series of dialog boxes including a short video to introduce them to the game.

However, the first login wizard gives only a very basic introduction to the system, and there are many aspects of the game that it does not cover. Players could “stumble” onto these features over time, but with Quests, Makahiki provides a more proactive approach to helping players learn about advanced features of the game.

Quests are made available to the player in a collapsible/expandable window right below the navigation bar. The set of Quests shown to a player can depend upon their game state, so that “simple” Quests can be presented initially and more “complicated” Quests presented as the player gains in expertise. Quests generally guide the player through the various workflows of the Challenge, such as completing a task, signing up for an event, or allocating a raffle ticket.

The system shows a maximum of three Quests at a time. What follows is a screen shot of a Quest window that can display three quests: Learn Secrets of the Kukui Cup Masters, Make a commitment, and Learn about Energy. The first Quest has been clicked on, expanding the window to reveal the description associated with that Quest.

_images/challenge-design-game-admin-quest-example.png

A quest that teaches a player how to use the Smart Grid Game to earn points.

Quests are created by the administrator prior to the Challenge. Administrators have the option of specifying a set of predicates to determine:

  • When the player could be shown a Quest;
  • When the player has performed actions indicating that they have completed the Quest, and it should no longer be shown.

Players can also indicate explicitly that they have completed a Quest.

Completion of a Quest does not currently earn a player any points. The big advantage to this is that Quests do not need to be verifiable, and thus a much broader variety of onboarding experiences can be constructed as Quests. The disadvantage is that some players might not understand why they should do Quests, given that they don’t earn any points for doing them. (Although completing Quests generally does lead to improved game play, which leads to additional points, so there is an indirect incentive for performing Quests.)

Managing Quests

After clicking on the “Quests” link in the Game Admin widget, a page similar to the following should appear:

_images/configuration-game-admin-quest-list.png

This page displays all the quests in the system. When you design a Quest, you provide a priority number, which imposes an ordering on the presentation of Quests.

The algorithm for Quest display is as follows. The three quests with the lowest priority number whose:

  • unlock conditions evaluate to True
  • whose completion conditions evaluate to False
  • have not been explicitly indicated as “uninteresting” by the player are shown to the player.

To add a new quest, click the “Add quest” button in the upper right corner.

Change a Quest

Clicking on a quest instance brings up a page with information about the quest:

_images/configuration-game-admin-quest-change.png

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Badge Game Mechanics
About Badge Game Mechanics

Badges are a common game mechanic, in which players receive recognition for various accomplishments. Makahiki allows the challenge designer to specify the set of badges available in a challenge, and to define new ones. The challenge designer has the option of making badges worth points. Finally, the designer can use the Makahiki predicate system to award a badge automatically (for example, when a player has completed a Level in the Smart Grid Game), or manually award the badge through administrator action (for example, when a player reports a significant bug in the system).

In many systems, each badge has a custom design, but in Makahiki, we decided that the overhead of providing a custom graphic for each badge outweighed the benefits. Providing a custom graphic also would creates complexity with another feature of Makahiki: the ability to create “themes” with different colors (see Theme Development). To facilitate theme development, badges have a common look and feel consisting of a circle and a multi-character ID. Its actual colors are specified by the theme, and can thus vary from theme to theme.

Here is a screen image showing some badges accumulated by a player in a recent challenge:

_images/challenge-design-game-admin-badge-examples.png
Managing badges

After clicking on the “Badges” link in the Game Admin widget, a page similar to the following should appear:

_images/configuration-game-admin-badge-list.png

This page displays all the badges in the system.

To add a new badge, click the “Add badge” button in the upper right corner.

Change a Badge

Clicking on a badge instance brings up a page with information about the badge:

_images/configuration-game-admin-badge-change.png

Note the following:

  • Name: Should be unique within this set of badges.
  • Slug: You can allow the system to generate this; it must also be unique.
  • Label: What appears in the the badge icon; should be unique across all badge labels.
  • Description: What achievment led to the badge award.
  • Hint: What appears in the Badge Library page. You can either specify exactly what earns the badge, or just provide a hint.
  • Points: How many points this badge is worth. Could be zero.
  • Priority: Specifies the order in which the badges appear in the Badge Library page.
  • Award condition: Use “False” to award the badge manually, or else create a predicate to specify when the badge should be awarded to the player.
  • Award trigger: How often the system should check to see if badges should be awarded.
  • Theme: Select one of five possible themes. The examples are based upon the current theme, but the actual display will be based upon whatever the player has selected.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Design the Referral Game Mechanics
About the Referral Bonus

To incentivize players to work together during a challenge, Makahiki provides two types of bonuses: social and referral. The social bonus is discussed in Design the Smart Grid Game. This section presents the referral bonus, in which current players can earn points by getting new people on their team to login to the system and complete the first login process.

When enabled, the referral bonus is implemented as a step in the first login process. The following figure shows this step:

_images/challenge-design-game-admin-referralbonus.png

If the new player was referred to the challenge by another player, they can use this step to input their email address. Once the new player earns 30 points in the competition, both players are awarded a referral bonus of (typically) 10 points. Typically, going through the setup process gives you 25 points, so a threshold of 30 points means the new player has to complete at least one additional task in order to get the referral bonus.

You can disable the referral game mechanics by clicking on the “Referral Game Mechanics” link. If referral game mechanics is disabled, then this window is omitted from the first login wizard and players will not be able to get points by referring other players.

The referral bonus also has a “dynamic bonus” capability. If enabled, then you can vary the amount of points awarded depending upon the participation level of the team associated with the new player. This incentivizes players to not just recruit new players for their own team, but to also recruit players for other teams who might not have much participation.

Configure Referral Settings

If the referral game mechanics is enabled, which is true by default, you will see the “Referral settings” link in the Game Admin widget. After clicking on the “Referral Settings” link , You will see the overview of the referral settings, clicking on any of the links, will bring you to a page to change the settings:

_images/configuration-game-admin-referral.png

By default, only the “Normal” referral points value is used. If you check the “Start dynamic bonus” setting, then the “Super” and “Mega” values are enabled depending upon the team participation rate of the new player.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Challenge Management

About challenge management

Challenge management refers to administrative activities that take place while a challenge is underway. For example, when players submit answers to actions in the Smart Grid Game, an administrator must review the answer and decide whether to award points. Another challenge management activity is the generation and printing of attendance codes to give out to players who have attended an event. There are many such management activities, all of which are (hopefully) documented in this section.

Challenge management tasks

Manage the Resource (Energy or Water) game
Resource usage data

In the case of manual entry of resource usage data, (configured in the resource goal settings page as described above), the resource usage could be input through the “Energy usages” or “Water usage” link. Clicking on the “Add energy usage” link on the list page, a page similar to the following should appear:

_images/execution-manage-resource-game-usage.png

The page is used to enter the usage data and the timestamp for the specific team.

In the case of non-manual entry, the energy data is retrieved automatically from the Wattdepot or eGauge data source and stored here. They should not be modified manually.

Click “Save” when finished

Remember to click the Save button at the bottom of the page when finished to save your changes.

Manage the Smart Grid game
Manage Action submissions

You will need to approve or reject the action submitted from the players. Clicking on the “Action Submissions” link on the smartgrid game admin widget, a page similar to the following should appear:

_images/execution-manage-smartgrid-game-list.png

By default, you will see all submitted actions with the “Pending approval” status. You can click on the link to see the submission details and do the approval there. Or, if the question and answer of the action is simple enough, you can select the action or several actions and use the “Action” dropdown “Approve the selected actions (USE CAUTION)” to approve the selected actions.

You can also go in to the “Change action member” page to look at the full question and answer of the submission, change the “Approval status” and provide the “Admin comment” back to the player.

_images/execution-manage-smartgrid-game-change.png

You will only need to approve the “Activity” type actions, which requires players submitting their answers or responses. For “Commitment” type actions, the system will automatically approve the submission when the player submits after the commitment period ends. For “Event” and “Excursion” type actions, the system will also automatically approve them when the player submits the correct confirmation code.

Manage Attendance codes

For the “Event” and “Excursion” type actions, the attendance codes are used to verify their attendance. You can create and print the codes to be handed out to the player during an event or excursion. To do so, click on the “Actions” link on the smartgrid game admin widget, you will see a list of actionsa page similar to the following should appear:

_images/configuration-game-admin-smartgrid-game-action-list.png

First, you will need to find the event or excursion you would like to manage the attendance code. One way is to use the search box on the top of the page to search by name or title of the event. Other way is to use the “filter” box on the right of the page, for example, click on the “Event” link under the “By type” of the filter box, will list all the event type actions.

Then, click on the link of the event/excursion you want to manage the attendance code, you will see:

_images/configuration-game-admin-smartgrid-game-event.png

On the top right corner of the page, you will see the “View RSVPs” and “View Confirmation codes” button. You can click on the “View RSVPs” to see how many players has signed up for the event/excursion. This will give you a general idea that at least will you need to generate much more confirmation codes than the RSVPs.

Then, click on the “View Confirmation Codes” button on the top right corner of the page. You will see the “Generate codes” button on the upper right corner of the page. By clicking the button, you will be asked how many codes to be generated. Once you click the “Generate” button, the specified number of the codes will be generated for this event/excursion. You will see a page similar to this:

_images/execution-manage-smartgrid-game-code.png

Clicking the “View all codes” on the upper right corner of the page will display a page of all the codes for you to print out and cut into individual coupons.

Manage Bonus points

You can create and print bonus point coupons to be handed out to the player during an event. Clicking on the “Bonus points” link on the smartgrid game admin widget, a page similar to the following should appear:

_images/execution-manage-smartgrid-game-bonus.png

To add a new bonus code, you can click the “Add Bonus point codes” on the upper right corner of the page. It will ask the number of codes to be generated, as well as the value of the code.

Clicking the “View all codes” on the upper right corner of the page will display a page of all the bonus codes for you to print out and cut into individual coupons.

Click “Save” when finished

Remember to click the Save button at the bottom of the page when finished to save your changes.

Manage the Topscore game
Notify the winners

Once the round is end, you may want to notify the winners of the prizes. Under the “Action” dropdown on the top of the prize list page, you will see an action called “Notify winners of the selected prizes”. You can select the prize winners (for prizes of individual categories) you want to notify by checkin the checkbox on the left of the prizes, the select the “Notify winners of the selected prizes” action, and click “go”, the system will send out the notification email to the selected winners. The “Winner Notice Sent” column will be set to “True” once action completed.

Note

Please note that you will only want to click the “notify winner” action after the round has ended.

View the Topscore Game Winner Summary

The “Round Summary” button on the top right corner of the prize list page will show you the summary of the topscore game winners.

Manage the Raffle game
Pick the winners

Once the round is end, you can intruct the system to randomly pick the winners of the raffle prizes. Under the “Action” dropdown on the top of the prize list page, you will see an action called “Pick winners of the selected prizes”. You can select the prize of the ended round by checkin the checkbox on the left of the prizes, then select the “Pick winners of the selected prizes” action, and click “go”, the system will randomly pick a user that had allocated raffle tickets to the prizes. The “Winner” column will be filled after the pick action is completed.

Note

Please note that you will only want to click the “notify winner” action after the round has ended.

Notify the winners

Once winners are picked, you may want to notify the winners of the prizes. Under the “Action” dropdown on the top of the prize list page, you will see an action called “Notify winners of the selected prizes”. You can select the prize winners (for prizes of individual categories) you want to notify by checkin the checkbox on the left of the prizes, the select the “Notify winners of the selected prizes” action, and click “go”, the system will send out the notification email to the selected winners. The “Winner Notice Sent” column will be set to “True” once action completed.

Note

Please note that you will only want to click the “notify winner” action after the round has ended and winners picked.

View the Raffle Game Winner Summary

The “Round Summary” button on the top right corner of the prize list page will show you the summary of the raffle game winners.

Monitoring the challenge

Once you login as an administrator, You can monitor the current state of the challenge by going to the status page.

Click on the “Status” icon in the Nav bar to go to the status page:

_images/execution-monitoring-status.png
You can glance the current state of the following information:
  • Team points
  • Individual points
  • Team participation
  • Resource scoreboard
  • Action submission status
  • Event/Excursion RSVPs
  • Popular actions
  • Popular quests
  • Feedbacks of actions
  • Raffle status
  • Awarded badges
  • Referral status
  • Player stats
  • Resource goal stats

Challenge Postmortem

To be written.

Developer Guide

Makahiki Development Environment

This chapter describes how to setup the Makahiki development environment.

Using the Makahiki VirtualBox Virtual Machine

To facilitate the development environment setup, we create an VirtualBox virtual machine which has the necessary dependencies of the Makahiki and the development tools pre-installed. The advantage of developing using the Makahiki VM is the quick set up without the need of installing all the dependency of Makahiki. The shortcoming is of cause the performance penalty of running everything inside a virtual machine.

If you decide not to use the Makahiki virtual machine, you can skip this step. We assume that you have already gone through the local Makahiki installation successfully, especially, the python virtual environment has been set up.

To use the Makahiki virtual machine, first download it from the following url:

The download may take a while since the VM image is quite large as about 1.2G. In the mean time, you can download and install the Oracle VirtualBox software (https://www.virtualbox.org/wiki/Downloads) if you have not use VirtualBox before.

Note

You may want to install the corresponding version of the VirtualBox Extension Pack after you install the virtualbox software. This provides support for USB 2.0 etc in your VMs.

Once the download completes, unzip the VM into the same directory of the other virtualbox virtual machines. For example, in the Mac OS host, the default virtual machines directory is ~/VirtualBox VMs. If you have not use virtualbox before, you can create the default virtualbox vm directory and unzip the Makahiki vm there.

Once the virtualbox software is installed and the vm files unzipped, locate the Makahiki VM .vbox file, i.e., Makahiki_Ubuntu1204LTS_V1.vbox, and double click, the virtualbox will start and add the makahiki vm in the list of the virtualbox managed vms, as shown in the screenshot here:

_images/virtualbox.png

The Makahiki VM is based on Ubuntu 12.04LTS and has the makahiki dependency pre-installed. See the “readme.txt” file in the unzipped directory for details of this VM release and also the login info for the VM.

Note

By default, the Makahiki VM is allocated with 2G RAM, which is the recommended configuration for development in Makahiki. If your host machine has limitted memory, you can decrease the RAM by changing the “Base Memory” under the System of the settings of the VM.

Double click on the Makahiki VM in the virtualbox VM manager to start the Makahiki VM, login using the info in the readme.txt file.

Using an IDE

Although you can develop without an IDE, but we recommend using an IDE to program effeciently and effectively. Pydev and Pycharm are two excellent IDEs for Python/Django development. The following describes the steps involved in installing and using the Pydev IDE:

  1. Install Eclipse and PyDev.

Note

If you use the Makahiki VirtualBox VM, the Eclipse ad PyDev are already installed in the VM image, you can skip this step.

You want to install a version of Eclipse that includes eGit and WebTools components. The comparison page shows which components are in which versions of Eclipse. You can choose a version with a superset of these components if you like. After you download the install the Eclipse, you want to install the PyDev following the instructions in “Installing with the Update Site“.

  1. Configure the Python Interpreter for PyDev.

Note

If you use the Makahiki VM, you can start the Eclipse by invoking “eclipse” from any path in a shell terminal.

To configure the interpreter for PyDev in Eclipse, start Eclipse, go to the Eclipse menu:

Window -> Preferences -> PyDev -> Interpreter - Python

Choose the interpreter in the virtual environment you have created during the Makahiki Installation. To do that, Click on the “New...” button, and browse and select the python executable under the virtual environment’s bin directory, see screenshot below.

_images/pydev-intepreter.png

On the next screen, click on the “Select All” then “OK”.

Fork the Makahiki source

You may want to fork the Makahiki source to your own Git repository and manage the version control in your own repository. To fork the Makahiki source, go to https://github.com/csdl/makahiki/ and click the “Fork” button. Go to your fork, you will see your repository has the git url like this:

git@github.com:<your-name>/makahiki.git

This is the Git url you will use for your development in Makahiki.

Now, in the Terminal, cd to ~/workspace (you may want to create this directory if it does not exist. This is the default directory where Eclipse will place all the projects.), run the following command to download the forked Makahiki source:

% git clone git@github.com/<your-name>/makahiki.git

This will create a directory called “makahiki” containing the source code for the system.

Workon makahiki

Next, you need to activate the makahiki virtual environment. To do this, type the following in the Terminal:

% workon makahiki

This will set up the python environment, as well as the necessary environment variables in your current shell for developing and running Makahiki. You can examine the environment variables set by the virtual environemnt by looking at the script located at:

~/.virtualenvs/makahiki/bin/postactivate

Note

Always activate the virtual environment by running the workon command before doing any Makahiki development or running Makahiki instance.

Initialize or update the Makahiki instance

If you had not initialized the Makahiki instance, you need to invoke the initialize_instance script, passing it an argument to specify what kind of initial data to load. If you had already initialized the instance, you can run the update_instance script to apply any changes from the newly download makahiki source.

To initialize the instance with default dataset, run:

% scripts/initialize_instance.py -t default

To update the instance from the latest downloaded source, run:

% ./scripts/update_instance.py

Run Makahiki outsite of Eclipse

You can start the Makahiki server using:

% ./manage.py runserver

It will start the makahiki server at http://127.0.0.1:8000.

Import the Makahiki Project into Eclipse

Start Eclipse, go to menu:

File -> Import -> General -> Existing Projects into Workspace

as shown in the following screenshot:

_images/import.png

Next, browse and select the Makahiki source you just clone from github in the previous step. Make sure you select the second makahiki directory which is root directory of the makahiki Django application. It is also where the Makahiki project definition file is located. See screenshot below.

_images/import-makahiki.png

Create a Run Confiugration in Eclipse

To help you start the Makahiki server conveniently, you can create a “Run Configuration” in Eclipse. To do so, select the makahiki project in the “PyDev Package Explorer”, right click to bring up the context menu, select “Run As” and “PyDev Django”, see the screenshot below:

_images/runconfig.png

It will run the makahiki as a Django project and start the makahiki server at http://127.0.0.1:8000. You can also find the output of the run in the Eclipse run console.

You can verify the running server by going to the above url in a brower. Once verify, go to Eclipse menu:

Run -> Run Configurations -> PyDev Django -> makahiki makahiki

You will see a run configuration already created for you from the previous “Run as” command, as shown here:

_images/runconfig-makahiki.png

You just need to change the name of the run configuration to the one you like, such as “Local Makahiki”.

Now you can stop the server from previous “Run As”, and select the newly created run configuration from the menu to start the makahiki server.

Coding Standards

This document contains information to support uniform, high quality, and efficient development of Makahiki.

Automated quality assurance

All code should pass Pylint, PEP 8, and the current set of Makahiki unit tests. To run them individually:

% cd makahiki/
% scripts/run_pylint.sh
% scripts/run_pep8.sh
% python manage.py test

To simplify quality assurance, there is a script called verify.py that runs all of these scripts:

% cd makahiki/
% scripts/verify.py

If all return successfully, then verify.py returns normally and no output is printed. If there are any errors, the output associated with the unsuccessful tools is printed and verify.py returns with an error code.

It is good practice to run verify.py prior to pushing your code to the master branch at github.

Be patient: verify takes 10 seconds or more to complete.

Coverage

To obtain a coverage report on the test cases:

% scripts/coverage.py

The report will be generated into the directory htmlcov/. Open index.html to browse. Click the coverage column to sort, and click on a module to see which lines were tested and which lines were not.

General documentation string standards

Documentation strings should be enclosed in triple double quotes.

Documentation strings should be formatted using reStructuredText format so that they can be easily processed using the Sphinx autodoc extension.

The first line of a documentation string (i.e. the line containing the open triple double quote) should contain a one sentence summary of the purpose of the program unit (module, class, function, variable, etc.)

If one sentence suffices to document the program unit, then the closing triple double quote should appear on the same line.

Otherwise there should be a blank line followed by additional lines of documentation. In this case, the closing triple double quote appears on its own line.

Module documentation

Every module (i.e. .py file) should have a documentation string explaining its purpose and (if relevant) client interface.

The module documentation string should not specify the file name.

For example, here is an example docstring for the apps/pages/views.py module:

"""Provides the top-level rendering functions for all makahiki pages.

This module handles all requests for Makahiki pages.  It handles
authentication and contains the code to dynamically render the custom
configured pages for any particular site.
"""

Function documentation

All functions should have a documentation string explaining its purpose and documenting parameters and any return values.

See the Info field lists page for helpful information on how to format parameter lists and return values appropriately.

For example, here is an example docstring for the index(request) method appearing in the apps/pages/views.py module:

"""Process the request, dynamically generating the page as specified in page_settings.

:param request: The django request object.
:return: The response object for the page.
"""
Note the following:
  • There must be a blank line between the text description and the start of the parameter/return value descriptions.
  • The directives must start and end with a ”:”. Note that this means the param directive includes a trailing ”:” after the param name, and the return directive has a ”:” on both sides.

Variable documentation

All variables should have a documentation string explaining its purpose and who might reference it.

Variables should be documented by a documentation string immediately following the variable declaration. For example:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'dev.db',
        'USER': '',
        'PASSWORD': '',
        }
}
"""Specifies the default database, required by Django."""

Theme Development

A “theme” in Makahiki consists of a specification of the background image (or color), as well as with the background and font colors for various structural elements of the system.

Users have the ability to select themes from the Profile page, making it unnecessary to develop a “perfect” theme for your challenge. We provide a variety of pre-built themes and allow developers to create additional ones, with the hope that all users will find at least one that appeals to them.

Makahiki’s themes are implemented using LESS, which is a kind of enhanced version of CSS that supports variables and other capabilities not available in standard CSS. We choose LESS for themes because that is the language used to implement the Twitter Bootstrap framework, which is also used in Makahiki.

Fortunately, you need to know nothing about Twitter Bootstrap and almost nothing about LESS to create Makahiki themes. Most developers should be able to create themes simply by copying and editing a pre-existing theme file, which is what this page will show you how to do.

The following sections provide a step by step guide to developing a new theme. These sections document the actual steps taken to develop the initial version of the “Google” theme.

Create a local installation

The first step in theme development is to follow the local installation guide to create a running implementation on your computer, as documented in Local installation of Makahiki.

Set environment variables for theme development

To simplify theme development, it is important to set the MAKAHIKI_USE_LESS and MAKAHIKI_DEBUG environment variables to true. When this is done, you can make changes to your theme file, save it, and then simply refresh the page to see the changes.

There are a variety of ways to set these environment variables, but a convenient way is to set them in the ~/.virtualenvs/makahiki/bin/postactivate file. This way, whenever you workon makahiki, the variables will be set. Here, for example, is the contents of my postactivate file:

#!/bin/bash
# This hook is run after this virtualenv is activated.

MAKAHIKI_DATABASE_URL=postgres://makahiki:makahiki@localhost:5432/makahiki
export MAKAHIKI_DATABASE_URL

MAKAHIKI_ADMIN_INFO=admin:admin
export MAKAHIKI_ADMIN_INFO

MAKAHIKI_USE_LESS=True
export MAKAHIKI_USE_LESS

MAKAHIKI_DEBUG=True
export MAKAHIKI_DEBUG

Once you have edited this file, you will need to workon makahiki again to set these variables. To verify they are set correctly, you can do the following:

% printenv | grep MAKAHIKI
MAKAHIKI_DEBUG=True
MAKAHIKI_DATABASE_URL=postgres://makahiki:makahiki@localhost:5432/makahiki
MAKAHIKI_ADMIN_INFO=admin:admin
MAKAHIKI_USE_LESS=True

Create your new theme file

The directory makahiki/static/less contains all of the files that define the Makahiki look and feel. All of the information required to define a new theme is specified in a single file named “theme-<theme_name>.less”. For example, some of the predefined theme files are: “theme-sonora.less”, “theme-wave.less”, and “theme-forest.less”.

To create your new theme file, simply make a copy of a current theme file, naming it with the name of your new theme. To start creating the Google theme, I will do the following:

% cd ~/makahiki2/makahiki/static/less
% cp theme-forest.less theme-google.less

To make the new theme, we will edit variable values in the theme-google.less file to suit our new look and feel.

Add your theme to the installed themes

In order for a new theme to be available to the system, you need to edit the makahiki/settings.py file and add your theme name to the INSTALLED_THEMES variable. Here is what this portion of the settings.py file looks like after I’ve added my new google theme to it:

##########################################################
# INSTALLED Themes. Please keep them in alphabetical order
##########################################################
INSTALLED_THEMES = (
    'theme-bubbles',
    'theme-forest',
    'theme-google',
    'theme-sonora',
    'theme-wave',
)

In other words, add the name of your new theme file, minus the ”.less” extension, to this list.

Verify your theme installation

It should now be possible to select your new theme in the system. To check, bring up the server by invoking the runserver command:

%  manage.py runserver
   Validating models...

   0 errors found
   Django version 1.4, using settings 'settings'
   Development server is running at http://127.0.0.1:8000/
   Quit the server with CONTROL-C.

Then browse to the development server, login, go to the Profile page, and select your new theme from the drop-down list in the My Info widget. Press “Save Changes” to install your new theme. The following figure shows a portion of the Profile page after choosing the brand new google theme:

_images/theme-dev-new-google.png

The newly installed Google theme after selection from the Profile page.

As you can see, there is a theme called “Google”, which the system named by capitalizing the text following “theme-” in the file name, and omitting the “theme-” prefix.

If your theme does not show up in the drop-down menu or if errors occur during display, seek guidance from a Kukui Cup developer.

Otherwise, you have now installed your new theme, and the next step is to actually make it look the way you want to.

Determine your color palette

All themes are based upon a set of complementary colors represented in RGB notation. How you come up with the color palette is up to you. In the case of our new Google theme, we will use the same colors that appear on the Google home page:

_images/theme-dev-google-home.png

To determine those colors, we will use the Color Explorer Image Import page, where you can upload an image and it will determine the RGB colors present in that image for you.

After uploading the google home page image above, Color Explorer indicates the colors as follows:

_images/theme-dev-color-explorer.png

So, the RGB value for Google’s red color is #D41C34, the gold is #E8AC13, and so forth.

Specify your palette in your theme file

Now that we know the colors we want, let’s define them in the theme file. In our case, we will open the file theme-google.less in an editor, and near the top of the file we find LESS variable definitions for the twitter bootstrap and forest theme color palettes:

// Bootstrap color palette
@black:                 #000;
@grayDarker:            #222;
@grayDark:              #333;
@gray:                  #555;
@grayLight:             #999;
@grayLighter:           #eee;
@white:                 #fff;
@blue:                  #049cdb;
@blueDark:              #0064cd;
@green:                 #46a546;
@red:                   #9d261d;
@yellow:                #ffc40d;
@orange:                #f89406;
@pink:                  #c3325f;
@purple:                #7a43b6;

// Forest color palette
@forest-white:          #E9F2E4;
@forest-brightgreen:    #86B04C;
@forest-tan:            #A89B83;
@forest-lighttan:       #EBE8B9;
@forest-green:          #82A367;
@forest-gold:           #A18E4A;
@forest-purple:         #916981;
@forest-brown:          #635A49;
@forest-darkgreen:      #182608;

@forest-sgg-blue:       #671BE0;
@forest-sgg-orange:     #A33B0F;
@forest-sgg-green:      #7E9C08;
@forest-sgg-purple:     #A13B9D;
@forest-sgg-aqua:       #399E99;
@forest-sgg-darkaqua:   #074263;

The Twitter Bootstrap framework defines the first set of color variables, and these colors are occasionally used for UI elements. They are provided in every theme file so that if you want to override the default colors used by Twitter Bootstrap for your theme, you can do so. This is optional and we won’t worry about it.

The second set of definitions specify the colors used in the Forest theme. As you can see, to keep things simple, each theme defines a color palette using its own theme name. The next step is to add our new color palette variable names right below the Forest color palette:

// Bootstrap color palette
@black:                 #000;
@grayDarker:            #222;
@grayDark:              #333;
@gray:                  #555;
@grayLight:             #999;
@grayLighter:           #eee;
@white:                 #fff;
@blue:                  #049cdb;
@blueDark:              #0064cd;
@green:                 #46a546;
@red:                   #9d261d;
@yellow:                #ffc40d;
@orange:                #f89406;
@pink:                  #c3325f;
@purple:                #7a43b6;

// Forest color palette
@forest-white:          #E9F2E4;
@forest-brightgreen:    #86B04C;
@forest-tan:            #A89B83;
@forest-lighttan:       #EBE8B9;
@forest-green:          #82A367;
@forest-gold:           #A18E4A;
@forest-purple:         #916981;
@forest-brown:          #635A49;
@forest-darkgreen:      #182608;

@forest-sgg-blue:       #671BE0;
@forest-sgg-orange:     #A33B0F;
@forest-sgg-green:      #7E9C08;
@forest-sgg-purple:     #A13B9D;
@forest-sgg-aqua:       #399E99;
@forest-sgg-darkaqua:   #074263;

// Google color palette
@google-white:          #FFFFFF;
@google-offwhite:       #E9EEF5;
@google-lightblue:      #8DAAEB;
@google-gold:           #E8AC13;
@google-lightlightblue: #B8CAE0;
@google-darkblue:       #1249E0;
@google-red:            #D41C34;

As you can see, the color palette for the Google theme is smaller than for the Forest theme. That’s fine: there’s no standard number of colors for a palette. You will see below that there are ways to produce new colors by lightening and darkening the palette colors if that is desired.

The following steps will incrementally replace the Forest theme colors for various components of the site with our new Google palette colors.

Define the background theme

The background for a Makahiki site can either be an image or a color. In the Forest theme, and image is used so the use-bkg-image variable is set to true, an image is specified, and the background color variables are commented out:

// Page Background
@use-bkg-image: true;
@page-bkg-image: "../images/forest-theme-background.jpg";

// Since background image is used, these values are not needed.
//@page-bkg-color-start: @forest-gold;
//@page-bkg-color-end: lighten(@forest-gold, 10%);

Images should be stored in makahiki/site_media/static/images. By convention, name them <name>-theme-background.jpg, and make sure they are small in file size (around 50 KB).

The background for the Google theme is (you guessed it), white. So, we change these definitions so that use-bkg-image is false, and provide white as the background color:

// Page Background
@use-bkg-image: false;
// @page-bkg-image: "../images/forest-theme-background.jpg";

@page-bkg-color-start: @google-white;
@page-bkg-color-end: @google-white

Note

Defining gradients with “start” and “end” variables.

Several of the theme color elements (such as page-bkg-color) are specified as pairs of variables with a “-start” and “-end” suffix. This means that it is possible to define that element as a gradient, where the element has the start color at the top, and transitions into the end color at the bottom. If you do not want a gradient, simply specify the same color for both start and end (as is shown above).

Once we’ve made the change and saved the file, all we need to do is refresh the page in a browser to see the change:

_images/theme-dev-google-page-background.png

As you can see, the background is now white.

Define the Navigation Bar theme

The next element of the theme I want to tackle is the navigation bar. I’m going to try making it blue:

// Navbar
@navbar-bkg-color-start: @google-darkblue;
@navbar-bkg-color-end: lighten(@navbar-bkg-color-start, 30%);
@navbar-font-color: @google-white;
@navbar-curr-page-bkg-color: @navbar-bkg-color-end;
@navbar-curr-path-font-color: lighten(@google-gold, 20%);
@navbar-transparency: 0%;

In this case, I will use a gradient for the navigation bar background, where the end color will be the start color lightened by 30%. The variables also enable you to highlight the current page. Since there is no background color, I set transparency to zero. Here’s what the new blue nav bar looks like:

_images/theme-dev-google-navbar.png

Define the Info Bar theme

The top element in the page is called the “Info Bar”. Since Google is a very minimal style, let’s just make it offwhite:

// Infobar
@infobar-bkg-color-start: @google-offwhite;
@infobar-bkg-color-end: @google-offwhite;
@infobar-font-color: @black;
@infobar-feedback-font-color: @black;
@infobar-transparency: 0%;

Here’s the result:

_images/theme-dev-google-infobar.png

Define the Quest Bar theme

We’ll make the Quest Bar the same as the Info Bar:

// Questbar
@questbar-bkg-color-start: @google-offwhite;
@questbar-bkg-color-end: @google-offwhite;
@questbar-font-color: @black;
@questbar-transparency: 0%;

Here’s the result:

_images/theme-dev-google-questbar.png

Define the widget theme

To continue with simplicity mode, I am going to define the widget title background with a light blue top. Subelements of the widget will just use slight variants of these colors:

// Widgets
@widget-title-bkg-color-start: @google-lightblue;
@widget-title-bkg-color-end: @google-lightblue;
@widget-title-font-color: @black;
@widget-title-transparency: 0%;
@widget-body-bkg-color: @google-white;
@widget-body-font-color: @black;
@widget-body-transparency: 0%;
@widget-button-bkg-color: darken(@widget-body-bkg-color, 50%);
@widget-button-font-color: @widget-body-bkg-color;
@widget-table-row-color-1: @widget-body-bkg-color;
@widget-table-row-color-2: lighten(@widget-body-bkg-color, 40%);
@widget-subtitle-bkg-color: lighten(@widget-title-bkg-color-start, 20%);
@widget-subtitle-font-color: @black;

@widget-text-area-bkg-color: @google-offwhite;
@widget-text-area-font-color: @black;

Here’s what the whole profile page looks like at this point:

_images/theme-dev-google-widgets.png

Define the notifications theme

When users accomplish actions or various events occur in the game, the system informs users via dismissable notification windows that appear just below the Quest Bar on all pages.

We’ll make these gold so they stand out:

// Notifications
@notification-bkg-color-start: @google-gold;
@notification-bkg-color-end: @google-gold;
@notification-font-color: @black;
@notification-transparency: 0%;

Define the modal dialog box theme

Modal dialogs are used in various places on the site to focus user attention on a task that must be accomplished immediately before doing anything else.

A quick way to see a modal dialog during theme development is to click into any unfinished action in the Smart Grid Game and press the “I did this” button.

We will make our modal dialogs with a blue title bar and light blue background:

// Modal dialog box
@modal-title-bkg-color-start: @google-darkblue;
@modal-title-bkg-color-end: @google-darkblue;
@modal-title-font-color: @black;
@modal-body-bkg-color: @google-offwhite;
@modal-body-font-color: @black;

Because they are modal, to see the affects of your change, be sure to go back to the Get Nutz page and re-enter the action page. Just re-clicking the “I did this” button will not revised the formatting.

Here’s what the modal dialog looks like:

_images/theme-dev-google-modal.png

Define the Info Box theme

The Home Page contains large versions of the Navigation Bar icons that are annotated with explanatory text. Let’s style these as follows:

// Home Page Infobox
@pageinfobox-bkg-color-start: @google-lightblue;
@pageinfobox-bkg-color-end: @google-lightlightblue;
@pageinfobox-font-color: @black;
@pageinfobox-transparency: 0%;

Now the home page looks like:

_images/theme-dev-google-infobox.png

Define the Smart Grid Game theme

Let’s introduce some color into the Smart Grid Game:

// Smart grid game
@sgg-header-bkg-color: @google-offwhite;
@sgg-header-font-color: @black;
@sgg-entry-font-color: @black;
@sgg-activity-cell-bkg-color: @google-lightblue;
@sgg-commitment-cell-bkg-color: @google-red;
@sgg-event-cell-bkg-color: @google-gold;
@sgg-excursion-cell-bkg-color: @google-darkblue;

And it looks like this:

_images/theme-dev-google-sgg.png

Define the Raffle Game Theme

It is possible to set the Raffle Game entry color. Let’s just make it black:

@prizes-raffle-table-entry-color: @black;

With this result:

_images/theme-dev-google-raffle.png

Define the Badge themes

Makahiki comes with six predefined badge themes, which are specified in terms of a start and end color for the badge background, and a color for the text that appears inside the badge and for the outline color. Here’s what the definitions for the google theme look like:

// Badges
@badge-theme-1-bkg-color-start: @google-lightlightblue;
@badge-theme-1-bkg-color-end: @google-darkblue;
@badge-theme-1-text-color: @google-white;

@badge-theme-2-bkg-color-start: lighten(@google-gold, 40%);
@badge-theme-2-bkg-color-end: darken(@google-gold, 20%);
@badge-theme-2-text-color: @white;

@badge-theme-3-bkg-color-start: @google-lightlightblue;
@badge-theme-3-bkg-color-end: @google-lightblue;
@badge-theme-3-text-color: @google-darkblue;

@badge-theme-4-bkg-color-start: lighten(@google-darkblue, 20%);
@badge-theme-4-bkg-color-end: @google-darkblue;
@badge-theme-4-text-color: @white;

@badge-theme-5-bkg-color-start: @google-red;
@badge-theme-5-bkg-color-end: darken(@google-red, 20%);
@badge-theme-5-text-color: @google-white;

@badge-theme-summary-bkg-color-start: @google-white;
@badge-theme-summary-bkg-color-end: @google-white;
@badge-theme-summary-text-color: @google-darkblue;

To see the results, you have to navigate to the special page “badge-display”, which looks like this:

_images/theme-dev-badge-display.png

Seeing everything at once: the theme-display page

If you want to see virtually all of your theme’s elements in a single page, retrieve the “theme-display” page, which looks like this:

_images/theme-dev-theme-display.png

Cleanup: Delete the prior theme’s variable definitions

Once you have gone through and replaced all references to the old theme’s palette colors, delete these definitions from the top of the file. In this example, I will delete all of the “forest” color definitions.

After deleting, I do a quick search of the file to make sure no strings beginning with “forest-” exist, just to make sure I haven’t left a reference to an undefined theme variable in the file.

Leave the Twitter Bootstrap color definitions in the file, of course.

Create a compiled (CSS) version of your theme

During development of the theme, it is convenient for the page to load the .less file and compute the actual CSS directives on the fly. This allows you to edit the .less files and see the changes simply by reloading the page.

For production use, it is preferable to have a single CSS file containing the results of compiling all the associated .less files. This can be retrieved once and the locally cached file can be then referenced for all pages.

Once you are satisfied with your theme, you can create the compiled version via the compile_less script, which can be invoked as follows:

% scripts/compile_less.py

Note

Installing the lessc compiler

For the above script to run, you must have the lessc compiler installed. On Mac OS X, the following suffices:

$ brew install node
$ curl http://npmjs.org/install.sh | sh
$ npm install --global less

At least, sometimes. During a June, 2012 installation on Lion the installation of node failed. To fix it, I followed the directions in https://github.com/mxcl/homebrew/issues/11216, where it was suggested to:

sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer

If this seems like too much hassle, just inform the Makahiki Development Team that you have developed a new theme and would like it compiled, and one of them will do it for you.

Push your changes

The final step is to use git to add your new theme file and push your changes (including the updated settings.py).

Hello World Widget Development

This quick tutorial demonstrates how to create a simple Hello World widget for Makahiki.

The following sections provide a step by step guide to developing a new widget for Makahiki. These sections document the actual steps taken to develop the Hello World Widget.

Create a local installation

The first step in theme development is to follow the local installation guide to create a running implementation on your computer, as documented in Local installation of Makahiki.

Set environment variables for theme development

To simplify theme development, it is important to set the MAKAHIKI_USE_LESS and MAKAHIKI_DEBUG environment variables to true. When this is done, you can make changes to your theme file, save it, and then simply refresh the page to see the changes.

There are a variety of ways to set these environment variables, but a convenient way is to set them in the ~/.virtualenvs/makahiki/bin/postactivate file. This way, whenever you workon makahiki, the variables will be set. Here, for example, is the contents of my postactivate file:

#!/bin/bash
# This hook is run after this virtualenv is activated.

MAKAHIKI_DATABASE_URL=postgres://makahiki:makahiki@localhost:5432/makahiki
export MAKAHIKI_DATABASE_URL

MAKAHIKI_ADMIN_INFO=admin:admin
export MAKAHIKI_ADMIN_INFO

MAKAHIKI_USE_LESS=True
export MAKAHIKI_USE_LESS

MAKAHIKI_DEBUG=True
export MAKAHIKI_DEBUG

Once you have edited this file, you will need to workon makahiki again to set these variables. To verify they are set correctly, you can do the following:

% printenv | grep MAKAHIKI
MAKAHIKI_DEBUG=True
MAKAHIKI_DATABASE_URL=postgres://makahiki:makahiki@localhost:5432/makahiki
MAKAHIKI_ADMIN_INFO=admin:admin
MAKAHIKI_USE_LESS=True

Create the hello world widget package

The first step to create the hello_world widget is to create the new widget package. Makahiki’s manage.py supplies an easy way to start a new widget. Simply run the following command:

% manage.py startwidget hello_world

The startwidget command will create the base files and directories necessary for building a new widge. The directory structure should look like:

hello_world/
            templates/
                      index.html
            __init__.py
            tests.py
            views.py

__init__.py describes the purpose of the widget. Edit the default description to something like.:

"""The hello_world widget provides an simple example Makahiki widget showing
player's name, team and current point total."""

We’ll go through contents each of the rest of the files next.

The Widget’s User Interface index.html

Makahiki uses Django templates for the User Interface for widgets. Let’s build a simple UI for our Hello World widget. Since we are going to put our widget in an existing page, the widget only needs enough html to show itself.

The startwidget command gives you the following default index.html:

<div class="content-box">
    <div class="content-box-title">
        Widget name
    </div>
    <div class="content-box-contents">
        Widget content
    </div>
</div>

Makahiki provides many different styles and CSS classes. Normally, widgets are contained in a content-box . The context-box is a rounded, shaded box with two parts, content-box-title, and content-box-contents. We just need to edit the index.html file to provide the view for our widget.

Here is the template for our Hello World widget:

<div class="content-box">
      <div class="content-box-title">
          Hello World
          <a href="#" style="float: right">
              <img src="{{ STATIC_URL}}images/icons/icon-help-sm.png" width="20"
                   align="center"
                   title="Click to get help about this window"
                   onclick="toggleHelp(event, 'widget', 'hello-world'); return false;" />
          </a>
      </div>
      <div class="content-box-contents">
          Hello <em>{{ view_objects.hello_world.name }}</em>, you're in team
          <em>{{ view_objects.hello_world.team }}</em> and have
          <em>{{ view_objects.hello_world.points}}</em> points.
      </div>
</div>

Notice the link in the content-box-title it gives us a help icon that uses JavaScript to pop-up a help dialog box. We will add the contents of the dialog later in the tutorial. The content-box-contents is the main body of our widget showing the player’s name, team, and points. The view gets these values from the Django template layer.

Providing data to the UI views.py

Makahiki has a standard way of getting data to all the widgets:

  • When the player/user loads a page the apps.pages.views.index function is called. The index function determines the name of the page and creates a dictionary of view_objects, then calls the function supply_view_objects with the request, page_name and view_objects dictionary.
  • The supply_view_objects function determines which widgets are enabled for the given page. It then loops over each and calls their apps.widgets.<widget-name>.views.supply function with the current request and page_name.

So go get the player’s name, team, and points to the Hello World widget we need to implement the supply function. The startwidget command provides us with an empty supply function:

"""Provides the view of the widget."""


def supply(request, page_name):
    """ supply view_objects for widget rendering."""
    _ = request
    _ = page_name
    return {}

We need to edit the return value to include the keys name, team, and points. Let’s add those keys to the supply function:

"""Provide the view for the Hello_World widget."""


def supply(request, page_name):
    """Supply view_objects contents, which are the player name, team and points."""
    _ = request
    _ = page_name
    return {
        "name": None,
        "team": None,
        "points": None,
    }

Now how do we get the values? We can get the user who made the request from the request. Makahiki provides a user profile that has the player’s name and team. Let’s add that information to the supply function:

"""Provide the view for the Hello_World widget."""


def supply(request, page_name):
    """Supply view_objects contents, which are the player name, team and points."""
    _ = page_name
    profile = request.user.profile
    name = profile.name
    team = profile.team
    return {
        "name": name,
        "team": team,
        "points": None,
    }

Now how are we going to get the player’s points? Makahiki provides a score_mgr that encapsulates scores. The function we want is players_points. Let’s take a look at the supply function again:

"""Provide the view for the Hello_World widget."""
from apps.managers.score_mgr import score_mgr


def supply(request, page_name):
    """Supply view_objects contents, which are the player name, team and points."""
    _ = page_name
    profile = request.user.profile
    name = profile.name
    team = profile.team
    points = score_mgr.player_points(profile)
    return {
        "name": name,
        "team": team,
        "points": points,
    }

Notice: we have to import the score_mgr to be able to use it.

Add your widget to the installed widget apps

In order for a new widget to be available to the system, you need to edit the makahiki/settings.py file and add your widget name to the INSTALLED_WIDGET_APPS variable. Here is what this portion of the settings.py file looks like after I’ve added the new hello_world widget to it:

################################
# INSTALLED Widgets
################################
INSTALLED_WIDGET_APPS = (
  'action_feedback',
  'ask_admin',
  'badge_scoreboard',
  'badges',
  'bonus_points',
  'hello_world',
  'home',
  'resource_goal',
  'resource_goal.energy',
  'resource_goal.water',
  'energy_power_meter',
  'resource_scoreboard',
  'resource_scoreboard.energy',
  'resource_scoreboard.water',
  'my_achievements',
  'my_commitments',
  'my_info',
  'popular_tasks',
  'prizes',
  'quests',
  'raffle',
  'scoreboard',
  'participation',
  'smartgrid',
  'team_members',
  'upcoming_events',
  'wallpost',
  'help.intro',
  'help.faq',
  'help.rule',
  'status',
  'status.prizes',
  'status.rsvps',
  'status.users',
  'status.actions',
  'logging',
  'status.referrals',
  'status.wattdepot',
  'status.twitter',
  'status.badges',
  'status.DEGG',
  'status.DWGG',
  'wallpost.user_wallpost',
  'wallpost.system_wallpost',
)

In other words, add the name of your new widget to this list.

Add the widget to a page

Add the widget to the page in the admin interface. Go to the Admin interface, “Settings” page, and select Page infos. It is in the Internal Admin section.

_images/page-infos.png

The Admin Settings Page.

Select the profile row in the Page Info page. The Page Settings section lists the Widgets for the selected page.

_images/page-settings.png

The default Widgets on the Profile page.

We are going to add the hello-world widget to the left-hand location by pressing Add another Page Setting. Then use the widget dropdown and select the hello-world widget. Leave the Location setting on “Left”. Set the Priority to “2”. Save the profile page setting.

_images/pageinfo-w-hello.png

The Hello World Widget added to the Left-hand column.

Once the widget is added to the Page Settings the Game Designer may enable or disable the widget.

Verify your widget installation

Go to the Profile page, and see the Hello World widget.

The following figure shows a portion of the Profile page after choosing the brand new google theme:

_images/hello-world-widget.png

The newly installed and enabled Hello World Widget.

Enter the help text for the Hello World Widget

We need to add the contents of the Help Dialog for the Hello World Widget. Go back to the Settings page and select Help topics from the Internal Admin section.

Press the “Add Help Topic” button in the upper right-hand corner.

_images/help-topic.png

Add New Help Topic Button.

This will bring up the Add New Help Topic page.

_images/add-help-topic.png

Add New Help Topic Page.

1. Enter the Title for the help topic. In our case enter “Hello World”. The form automatically fills out the Slug field based upon the Title. The slug must match the third parameter in the toggleHelp function call in the index.html help link.:

<img src="{{ STATIC_URL}}images/icons/icon-help-sm.png" width="20"
     align="center"
     title="Click to get help about this window"
     onclick="toggleHelp(event, 'widget', 'hello-world'); return false;" />
  1. Select the “Widget Help” Category from the drop down. This matches the second parameter in the toggleHelp function.
  2. Enter the Help Contents.
  3. Save the Help Topic.
_images/filled-help-topic.png

Filled out Help Topic

  1. Verify the Help Dialog. Go to the Profile page and click the Hello World’s help icon. You should see the help dialog box with our contents.
_images/help-dialog.png

Hello World Widget Help Dialog.

Push your changes

The final step is to use git to add your new widget and push your changes to your GitHub repository.

The following files were modified or added during this tutorial:

  • settings.py
  • apps/widgets/hello_world

The changes to the database, to add the Hello World widget and Help Topic are not permanent. If you re-initialize the database the script will erase the page settings and help topic. To make the changes permanent edit “fixtures/base_pages.json” to add the page_settings item for the Hello World Widget. Here is the entry:

{
    "pk": 114,
    "model": "challenge_mgr.pagesetting",
    "fields": {
        "priority": 2,
        "widget": "hello_world",
        "enabled": true,
        "page": 8,
        "location": "Left"
    }
},

Edit “fixtures/base_help.json” to add the Hello World’s help topic. That entry looks like:

{
    "pk": 51,
    "model": "help.helptopic",
    "fields": {
        "category": "widget",
        "title": "Hello World",
        "parent_topic": null,
        "priority": 0,
        "slug": "hello-world",
        "contents": "Help for the Hello World Widget."
    }
},

Design periodic tasks

About periodic tasks

Various games and game mechanics in Makahiki depend upon periodic updates to the system state. For example, the Energy Goal game requires the system to update the state of a team’s progress toward achieving its daily energy goal once an hour. If students have requested a reminder regarding an event, the system must send that reminder at the prescribed amount of time before the event occurs.

Makahiki provides a “periodic task” system to support the needs of various games and game mechanics to invoke a specific behavior regularly.

Whether or not you need to configure periodic tasks depends upon the specific games and game mechanics you are providing in your challenge.

Getting to the periodic tasks page

After clicking on the “Periodic Task Settings” link in the Challenge Design page, a page similar to the following should appear:

_images/configuration-challenge-admin-scheduler-settings-1.png

This table lists all the defined Periodic Tasks, such as checking the Energy Goals. You may enable, disable, and create new periodic tasks.

Configure a periodic task

_images/configuration-challenge-admin-scheduler-settings-2.png

Clicking on a task name takes you to a page containing a form that allows you to edit the task attributes or delete the task entirely. The important fields are Name - The name of the task you see in the list. Task name - This is the function that is run. In this example ‘apps.widgets.resource_goal.tasks.check_energy’. The “Interval” or “Crontab” fields determine when Makahiki runs the task. In this case it is run every day at 23:55. If the task needs parameters supply them in the Arguments field. Check or uncheck the Enabled field to turn the task on or off.

Note

Remember to click the Save button at the bottom of the page when finished to save your changes.

Testing

This document contains notes on writing and executing tests.

Install Firefox

Because we use Firefox for our browser test, please make sure that Firefox is installed before running the test.

Run the test suite

Now invoke the test suite as follows:

% ./manage.py test

You can also run tests for individual apps by passing in the test modules in those apps as parameters. For example, python manage.py test apps.widgets.scoreboard.tests will run the tests in module apps/widgets/scoreboard/tests.py.

Creating Tests

Test modules are normally named tests.py under the individual apps directory. If there are more than one test modules, they could be named *_tests.py and located under the tests directory of the individual apps.

We use django.test.TransactionTestCase for non-browser test cases, and LiveServerTestCase for browser test cases, which use the selenium test tool.

See django testing for more details in Django testing framework.

Creating Selenium Tests

There are two ways to create Selenium tests; by hand or using the Selenium IDE. If you choose to write them yourself, the Python WebDriver API (http://readthedocs.org/docs/selenium-python/en/latest/api.html) has a list of functions that might be useful when creating tests. While tedious, it will prevent you from running into compatibility errors.

The other way is to use the Selenium IDE plugin for Firefox. Using the Selenium IDE, your actions on the website can be recorded and then exported to Python. Use Firefox and go to [[http://seleniumhq.org/download/]] to download and install the plugin. After it is downloaded, restart Firefox to complete the installation.

In Firefox, go to http://localhost:8000. Start the Selenium IDE by going to Tools->Selenium IDE. By default, it starts recording once you open the IDE. Create your test by navigating through the site as a user would. You have access to additional test assertion commands by right clicking on the page. However, the downside of the IDE is that not all of the Selenium assertions work when exported to the WebDriver format that Django will use.

Once you are done, click on the red “record” icon on the Selenium IDE to stop it from recording. You can then export your test by going to “File->Export Test Case As->Python 2 (WebDriver)”.

Once the test is exported, it still needs to be edited to fit within our framework.

Editing exported Selenium tests to run within our test framework

When the test is exported, it needs to be edited a little to support our test framework. By default, a test comes out something like this.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re

class Test(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://localhost:8000/"
        self.verificationErrors = []

    def test_(self):
        driver = self.driver
        driver.get(self.base_url + "/account/login/")

    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()

Things that need to be changed:

  • Delete the existing imports. Instead, import MakahikiSeleniumTestCase from apps.utils.selenium_helpers and test_utils from apps.test_helpers.
  • Change the Test class to inherit from MakahikiSeleniumTestCase.
  • Remove the setUp and tearDown methods. These are handled for you in MakahikiSeleniumTestCase. Note that MakahikiSeleniumTestCase has a few useful functions, like login(username, password) and logout().
  • After the class definition, add in a few base test fixtures (i.e. fixtures = [“base_pages.json”]). You may want to enter additional fixtures from the fixtures directory. The two fixtures in the example are highly recommended unless you have a specific reason not to include them.
  • Remove the if statement at the end.
  • Put in comments and change the name of the test class.

After this, your test should look something like this:

"""
Tests for the pages module.
"""
from apps.utils.selenium_helpers import MakahikiSeleniumTestCase
from apps.utils import test_utils


class LandingSeleniumTestCase(MakahikiSeleniumTestCase):
    """Selenium tests for the home page."""
    fixtures = ["base_pages.json"]

    def testLogin(self):
        self.login("username", "password")
        self.logout()

Heroku command line in a nutshell

This page provides some hints for monitoring a Makahiki application using the heroku command line.

Help

If you type heroku at the command line without any arguments, it provides simple help:

% heroku

  Usage: heroku COMMAND [--app APP] [command-specific-options]

  Primary help topics, type "heroku help TOPIC" for more details:

    addons    # manage addon resources
    apps      # manage apps (create, destroy)
    auth      # authentication (login, logout)
    config    # manage app config vars
    domains   # manage custom domains
    logs      # display logs for an app
    ps        # manage processes (dynos, workers)
    releases  # view release history of an app
    run       # run one-off commands (console, rake)
    sharing   # manage collaborators on an app

  Additional topics:

    account      # manage heroku account options
    db           # manage the database for an app
    drains       # display syslog drains for an app
    help         # list commands and display help
    keys         # manage authentication keys
    maintenance  # toggle maintenance mode
    pg           # manage heroku postgresql databases
    pgbackups    # manage backups of heroku postgresql databases
    plugins      # manage plugins to the heroku gem
    ssl          # manage ssl certificates for an app
    stack        # manage the stack for an app
    status       # check status of Heroku platform
    update       # update the heroku client
    version      # display version

Logging in

The first time you try to run any command, heroku will request your credentials. For example, let me invoke the apps command:

% heroku apps
  Authentication failure
  Enter your Heroku credentials.
  Email: johnson@hawaii.edu
  Password:
  Authentication successful.
  makahiki-hpu
  makahiki-staging-uh
  makahiki-staging-hpu
  makahiki-staging-ewc
  kukuicup-uh
  wattdepot-uh

All of the following commands take a –app argument, where you specify the application of interest.

Application configuration

To see the environment configuration for your app, run the config command with the application of interest:

% heroku config --app kukuicup-uh
  DATABASE_URL                     => postgres://blahblah/blah
  FACEBOOKMAKAHIKI_FACEBOOK_APP_ID =>
  LANG                             => en_US.UTF-8
  LD_LIBRARY_PATH                  => /app/.heroku/vendor/lib
  LIBRARY_PATH                     => /app/.heroku/vendor/lib
  MAKAHIKI_ADMIN_INFO              => admin:changeme
  MAKAHIKI_AWS_ACCESS_KEY_ID       => blahblah
  MAKAHIKI_AWS_SECRET_ACCESS_KEY   => blahblah
  MAKAHIKI_AWS_STORAGE_BUCKET_NAME => kukuicup-uh
  MAKAHIKI_EMAIL_INFO              => kukuicup@gmail.com:changeme
  MAKAHIKI_FACEBOOK_APP_ID         => blahblah
  MAKAHIKI_FACEBOOK_SECRET_KEY     => blahblah
  MAKAHIKI_USE_FACEBOOK            => True
  MAKAHIKI_USE_HEROKU              => True
  MAKAHIKI_USE_MEMCACHED           => True
  MAKAHIKI_USE_S3                  => True
  MEMCACHE_PASSWORD                => blah/blah
  MEMCACHE_SERVERS                 => mc6.ec2.northscale.net
  MEMCACHE_USERNAME                => blah%40heroku.com
  PATH                             => /app/.heroku/venv/bin:/bin:/usr/local/bin:/usr/bin
  PYTHONHASHSEED                   => random
  PYTHONHOME                       => /app/.heroku/venv/
  PYTHONPATH                       => /app/
  PYTHONUNBUFFERED                 => true
  SCHEDULER_URL                    => http://blahblah@heroku-scheduler.herokuapp.com/
  SHARED_DATABASE_URL              => postgres://blahblah/blah

Sensitive information has been replaced in the above output.

Running manage.py commands

Use the heroku run command to access all of the manage.py commands. For example, here is the invocation of the clear_cache command to clear the memcache contents:

% heroku run --app kukuicup-uh makahiki/manage.py clear_cache
  Running makahiki/manage.py clear_cache attached to terminal... up, run.1
  makahiki cache cleared.

See the logs

To see Heroku’s command line logging, run the logs command:

% heroku logs --app kukuicup-uh
  2012-06-25T23:12:57+00:00 heroku[router]: GET kukuicup-uh.herokuapp.com/log/level/locked/view-lock-close/ dyno=web.1 queue=0 wait=0ms service=226ms status=200 bytes=5
  2012-06-25T23:15:17+00:00 heroku[api]: Add MAKAHIKI_FACEBOOK_SECRET_KEY, FACEBOOKMAKAHIKI_FACEBOOK_APP_ID, MAKAHIKI_USE_FACEBOOK config by johnson@hawaii.edu
  2012-06-25T23:15:17+00:00 heroku[api]: Release v24 created by johnson@hawaii.edu
  2012-06-25T23:15:17+00:00 heroku[web.1]: State changed from up to bouncing
  2012-06-25T23:15:17+00:00 heroku[web.1]: State changed from bouncing to created
   :
   :

See process status

Process status is obtained with the ps command:

% heroku ps --app kukuicup-uh
  Process  State      Command
  -------  ---------  ------------------------------------
  web.1    up for 2m  python makahiki/manage.py run_guni..

To scale an app

When using a single (free) dyno, Heroku puts your app into an inactive state after some number of minutes, requiring a few seconds for response to start it up again upon the next request.

To prevent this, you must add a dyno (incurring charges). Here’s an example of the command:

% heroku ps:scale web=2 --app kukuicup-uh

How a collaborator can push a new app

The configuration instructions show how you can set up your environment to push out a new version of the app. If you are working in a team, then someone else might have done that for you. If you later want to push out a new instance to Heroku, the process is a little different.

First, go to the makahiki directory, workon makahiki, and get the latest version:

% cd <makahaki directory>
% workon makahiki
% git pull origin master

You may want to run tests to make sure the master is appropriate for pushing to Heroku.

Next, find out what remotes you have already. Make sure the app of interest is not already in your remotes:

% git remote -v
  origin git@github.com:csdl/makahiki.git (fetch)
  origin git@github.com:csdl/makahiki.git (push)

Now add the app of interest (in this case, kukuicup-uh) as a remote:

% git remote add kukuicup-uh git@heroku.com:kukuicup-uh.git

Make sure your public keys are available to heroku:

% heroku keys:add
  Found existing public key: /Users/johnson/.ssh/id_rsa.pub
  Uploading SSH public key /Users/johnson/.ssh/id_rsa.pub

Now invoke the script to push the master to Heroku. This also updates requirements, syncs the database, and moves static media to S3:

% scripts/update_instance.py -r kukuicup-uh
  Counting objects: 15, done.
  Delta compression using up to 4 threads.
  Compressing objects: 100% (3/3), done.
  Writing objects: 100% (9/9), 5.96 KiB, done.
  Total 9 (delta 6), reused 9 (delta 6)

  -----> Heroku receiving push
  -----> Python/Django app detected
  -----> Preparing Python interpreter (2.7.2)
  -----> Creating Virtualenv version 1.7
  New python executable in .heroku/venv/bin/python2.7
  Not overwriting existing python script .heroku/venv/bin/python (you must use .heroku/venv/bin/python2.7)
  Installing distribute.....done.
  Installing pip...............done.
           :
  -----> Noticed pylibmc. Bootstrapping libmemcached.
  -----> Activating virtualenv
  -----> Installing dependencies using pip version 1.0.2
           :
  Cleaning up...
  -----> Installing dj-database-url...
  Cleaning up...
  -----> Injecting Django settings...
  -----> Discovering process types
  -----> Compiled slug size is 26.1MB
  -----> Launching... done, v37

  To git@heroku.com:kukuicup-uh.git
  dec36d4..3313850  master -> master

  Running python makahiki/manage.py syncdb attached to terminal... up, run.1
  Syncing...
  Creating tables ...
  Installing custom SQL ...
  Installing indexes ...
  Installed 0 object(s) from 0 fixture(s)

  Synced:
   > apps.lib.avatar
     :
  Migrated:
  - apps.managers.challenge_mgr
     :

Logging and analysis

When complete, this chapter will discuss:
  • The kinds of logging data captured by Makahiki.
  • The kinds of analyses that can be run on the logging data.
  • Exporting and external analysis possibilities.

Enhancement Ideas

This chapter describes some enhancement projects for Makahiki that we believe would be interesting and useful for the framework.

Real-time player awareness

It is not possible in Makahiki to know who is currently “on line” and playing the game. Creating this awareness opens up new social gaming opportunities (performing tasks together), new opportunities for communication (chat windows), and potentially entirely new games (play “against” another online player).

The goal of this enhancement is to extend the framework with a general purpose API that provides the identities of those who are online, and then the development of one or more user interface enhancements to exploit this capability.

Deep Facebook integration

Makahiki currently supports a “shallow” form of Facebook integration: you can request that your Facebook photo be used as your Makahiki profile picture, and you are given an oppportunity to post to Facebook when the system notifies you of an accomplishment.

For this task, expand the current Facebook integration. One way is to deepen the connection between user Facebook pages and their game play. This might involve more automated forms of notification (i.e. the same way Spotify playlists are posted to your Facebook wall), or ways in which your activities on Facebook could impact on your Makahiki challenge status (for example, posting a sustainability video to Facebook, or liking a Sustainability organization could earn you points.)

A different type of enhancement is to allow challenge designers to specify a Facebook page as the official Challenge Facebook information portal, and have the system automatically post information to that Facebook page as the challenge progresses.

Action Library Management System

Makahiki currently ships with over 100 possible “actions” already developed for the Smart Grid Game. However, the current implementation suffers from a number of problems:

  • There is no convenient way to display and peruse the current set of actions. This has led to a duplicate representation of the smart grid game, implemented using a Google Docs spreadsheet linked to Google Sites pages. This approach has a lot of problems: it duplicates content, it does not provide a way to edit or manage content, it is already out of date.
  • The content is intimately tied to the Smart Grid Game implementation. The SGG is just one of many ways that the sustainability content could be presented to players. By separating “content” from the “presentation”, more games can be developed using this content.

For this task, you will enhance Makahiki to provide a “content management system” for “actions”. This involves the following changes to the current system:

  • A new set of database tables must be defined to hold Library actions.
  • Library actions can be “instantiated” (i.e. copied) into the Smart Grid Game. At that point they are assigned a category and a row within the Smart Grid Game.
  • An editor is provided to create action content and preview it in a formatted manner.
  • A new set of pages can be (optionally) made available to allow others to peruse Library content.
  • Library content can be exported and imported into systems in order to support sharing. A public repository can be provided on GitHub. The format is likely JSON.

Reference Guide

Management Commands

Mahahiki implements the following Django management commands to facilitate setup and management of challenges.

Development management

These management commands are used by developers for testing enhancements to the system and debugging.

clear_cache

Invocation: python manage.py clear_cache

Clear all content in the Makahiki cache.

clear_log

Invocation: python manage.py clear_log

Clear all content in the Makahiki log table.

clear_session

Invocation: python manage.py clear_session

Delete all persistent web sessions. Use this to clean up any invalid session references.

setup_test_data

Challenge configuration

These management commands are used to set up a challenge.

load_users
reset_users
verify_quests

Invocation: python manage.py verify_quests

Verifies that all of the existing quest lock and unlock condition strings are valid. Prints out the names of any invalid quest conditions.

verify_smartgrid

Challenge management

These management commands are used by administrators to facilitate the running of a challenge.

award_badge
update_energy_baseline

Invocation: python manage.py update_energy_baseline

update the daily baseline.

Automated management

These management commands are typically invoked automatically during a challenge in order to manage resource and game data.

update_energy_usage

Invocation: python manage.py update_energy_usage

For each team, queries WattDepot server to find out cumulative energy usage from midnight to now. Used for updating the status of the Energy Goal Game.

check_energy_goal

Invocation: python manage.py check_energy_goal

Checks whether or not each team made their energy goal, and awards points to team members if it’s at the end of the day.

check_water_goal

Invocation: python manage.py check_water_goal

Checks whether or not each team made their water goal, and awards points to team members if it’s at the end of the day.

Package Reference Guide

Package: apps.managers

Managers are Makahiki components that do not provide a player-level user interface but implement a functionality (such as caching, authentication, etc.). Managers often implement an admin-level user interface for initialization or customization.

Package apps.managers.auth_mgr

Provides authentication services for Makahiki including administrative logins and CAS authentication.

Module apps.managers.auth_mgr.views

Admin method for logging in as another user.

apps.managers.auth_mgr.views.login(request)[source]

Show the login page and process the login form.

apps.managers.auth_mgr.views.login_as(request, *args, **kwargs)[source]

Admin method for logging in as another user.

apps.managers.auth_mgr.views.logout(request)[source]

simply logout and redirect to landing page

Package apps.managers.cache_mgr

Manages caching data structures.

Module apps.managers.cache_mgr.cache_mgr

Provides utility methods for invalidating various caches.

apps.managers.cache_mgr.cache_mgr.clear()[source]

proxy the call to django cache.clear.

apps.managers.cache_mgr.cache_mgr.delete(key, version=None)[source]

proxy the call to django cache.delete.

apps.managers.cache_mgr.cache_mgr.get_cache(key, default=None, version=None)[source]

proxy the call to django cache.get.

apps.managers.cache_mgr.cache_mgr.info()[source]

return the information about this cache.

apps.managers.cache_mgr.cache_mgr.invalidate_template_cache(fragment_name, *variables)[source]

Invalidates the cache associated with a template. Credit: djangosnippets.org/snippets/1593/

apps.managers.cache_mgr.cache_mgr.set_cache(key, value, timeout=None, version=None)[source]

proxy the call to django cache.set.

Package apps.managers.challenge_mgr

The Challenge manager maintains state information about an entire Challenge, including what widgets are enabled, the round information, and so forth.

Module apps.managers.challenge_mgr.models

Defines the model containing game settings.

class apps.managers.challenge_mgr.models.AboutPage(*args, **kwargs)[source]

Defines the sponsor for this challenge.

Parameters:
  • id (AutoField) – Id
  • challenge_id (ForeignKey) – Challenge
  • about_page_text (TextField) – The text of the about page that explains the challenge. Uses Markdown formatting.
class apps.managers.challenge_mgr.models.ChallengeSetting(*args, **kwargs)[source]

Defines the global settings for the challenge.

Parameters:
  • id (AutoField) – Id
  • domain (CharField) – The domain name of this challenge.
  • logo (ImageField) – The logo of the challenge.
  • name (CharField) – The name of the challenge.
  • theme (CharField) – The default theme for this challenge.
  • team_label (CharField) – The display label for ‘teams’.
  • use_cas_auth (BooleanField) – Use CAS authentication ?
  • cas_server_url (CharField) – The URL for CAS authentication service. Example: https://login.its.hawaii.edu/cas/
  • cas_auth_text (TextField) – A button will appear if there is other auth method(s) selected. This is the text for the CAS auth button. Uses Markdown formatting.
  • use_ldap_auth (BooleanField) – Use LDAP authentication ?
  • ldap_server_url (CharField) – The URL for LDAP authentication service. Example: ldap://localhost:10389
  • ldap_search_base (CharField) – The search base for the ldap service. Example: ou=users,ou=system
  • ldap_auth_text (TextField) – A button will appear if there is other auth method(s) selected. This is the text for the LDAP auth button. Uses Markdown formatting.
  • use_internal_auth (BooleanField) – Use internal authentication ?
  • internal_auth_text (TextField) – A button will appear if there is other auth method(s) selected. This is the text for the internal auth button. Uses Markdown formatting.
  • wattdepot_server_url (CharField) – The URL for Wattdepot service. Example: http://localhost:8194/wattdepot
  • email_enabled (BooleanField) – Enable email ?
  • contact_email (CharField) – The contact email of the admin.
  • email_host (CharField) – The host name of the email server.
  • email_port (IntegerField) – The port of the email server
  • email_use_tls (BooleanField) – Use TLS in the email server ?
  • landing_slogan (TextField) – The slogan text in the landing page. Uses Markdown formatting.
  • landing_introduction (TextField) – The introduction in the landing page. Uses Markdown formatting.
  • landing_participant_text (TextField) – The text of the participant button in the landing page. Uses Markdown formatting.
  • landing_non_participant_text (TextField) – The text of the non participant button in the landing page. Uses Markdown formatting.
about_page_text()[source]

returns the about page text.

is_multi_auth()[source]

returns true if use_cas and either use ldap or internal.

round_info()[source]

returns the info for all rounds.

save(*args, **kwargs)[source]

Custom save method.

class apps.managers.challenge_mgr.models.GameInfo(*args, **kwargs)[source]

Defines the game info.

Parameters:
  • id (AutoField) – Id
  • name (CharField) – The name of the game.
  • enabled (BooleanField) – Enable ?
  • priority (IntegerField) – The priority (ordering) of the game in the admin interface.
save(*args, **kwargs)[source]

Custom save method.

class apps.managers.challenge_mgr.models.GameSetting(*args, **kwargs)[source]

Defines the widgets in a game.

Parameters:
  • id (AutoField) – Id
  • game_id (ForeignKey) – Game
  • widget (CharField) – The name of the widget in the page.
save(*args, **kwargs)[source]

Custom save method.

class apps.managers.challenge_mgr.models.PageInfo(*args, **kwargs)[source]

Defines the page info.

Parameters:
  • id (AutoField) – Id
  • name (CharField) – The name of the page. It is used to determine which navbar icon is used.
  • label (CharField) – The label of the page. It is used on the Home page and the navbar. Should be less than 10 characters long.
  • title (CharField) – The HTML title of the page.
  • introduction (TextField) – This text is shown on the Home page. It should not be more than 3 lines,each line should be less than 25 characters long. Uses Markdown formatting.
  • priority (IntegerField) – The priority (ordering) of the page.
  • url (CharField) – The URL of the page.
  • unlock_condition (CharField) – if the condition is True, the page will be unlocked. Uses Makahiki Predicates.
save(*args, **kwargs)[source]

Custom save method.

class apps.managers.challenge_mgr.models.PageSetting(*args, **kwargs)[source]

Defines widgets in a page.

Parameters:
  • id (AutoField) – Id
  • page_id (ForeignKey) – Page
  • widget (CharField) – The name of the widget in the page.
  • location (CharField) – The location of the widget in the page.
  • priority (IntegerField) – The priority (ordering) of widget in the location of the page.
  • enabled (BooleanField) – Enable ?
save(*args, **kwargs)[source]

Custom save method.

class apps.managers.challenge_mgr.models.RoundSetting(*args, **kwargs)[source]

Defines the round settings for this challenge.

Parameters:
  • id (AutoField) – Id
  • name (CharField) – The name of the round.
  • start (DateTimeField) – The start date of the round.
  • end (DateTimeField) – The end date of the round.
  • round_reset (BooleanField) – Reset the points for this round? if reset, the points from previous roundwill not be carried over to this round.
  • display_scoreboard (BooleanField) – Display the round in scoreboard?
save(*args, **kwargs)[source]

Custom save method.

class apps.managers.challenge_mgr.models.Sponsor(*args, **kwargs)[source]

Defines the sponsor for this challenge.

Parameters:
  • id (AutoField) – Id
  • challenge_id (ForeignKey) – Challenge
  • priority (IntegerField) – The priority of the sponsor
  • name (CharField) – The name of the sponsor.
  • url (CharField) – The url of the sponsor.
  • logo_url (CharField) – The url of the sponsor logo.
  • logo (ImageField) – The logo of the sponsor.
class apps.managers.challenge_mgr.models.UploadImage(*args, **kwargs)[source]

Defines the table for uploaded images.

Parameters:
  • id (AutoField) – Id
  • image (ImageField) – The uploaded image.
Package apps.managers.log_mgr

Provides logging services to track the actions of players (logged in users).

Module apps.managers.log_mgr.middleware

A middleware class to support logging of interactions with logged in users.

class apps.managers.log_mgr.middleware.LoggingMiddleware[source]

Provides logging of logged in user interactions.

process_response(request, response)[source]

Log the actions of logged in users.

apps.managers.log_mgr.middleware.log_request_exception(sender, **kwargs)[source]

log the exception with traceback.

Module apps.managers.log_mgr.urls

Specify the URL pattern to be associated with logging.

Module apps.managers.log_mgr.views

Support logging of AJAX-based interactions.

apps.managers.log_mgr.views.log_ajax(request, obj_type, obj, action)[source]

Simple AJAX view provided to support logging actions.

Note that since the logger intercepts requests and responses, this method just returns a success response.

Package apps.managers.player_mgr

The manager for supporting definition and processing of Players.

Module apps.managers.player_mgr.models
Module apps.managers.player_mgr.middleware
Package apps.managers.resource_mgr

resource manager package.

Module apps.managers.resource_mgr.models

The model for the resource manager.

class apps.managers.resource_mgr.models.EnergyUsage(*args, **kwargs)[source]

Energy usage model.

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – Team
  • date (DateField) – The date when the usage or reading is recorded.
  • time (TimeField) – The time of the day when the usage or reading is recorded.
  • manual_meter_reading (IntegerField) – The daily manual reading of the meter, in the unit defined in ResourceSetting. only needed when manually reading the meter.
  • usage (IntegerField) – The daily usage, if manual_meter_reading is input and the reading from the day before is available, this will be automatically calculated.
  • created_at (DateTimeField) – Created at
  • updated_at (DateTimeField) – Updated at
save(*args, **kwargs)[source]

Custom save method to set fields.

class apps.managers.resource_mgr.models.ResourceBlackoutDate(*args, **kwargs)[source]

defines the blackout dates for the resource related games.

Parameters:
  • id (AutoField) – Id
  • date (DateField) – The date when the resource usage should be ignored.
  • description (CharField) – The description of the date.
class apps.managers.resource_mgr.models.ResourceSetting(*args, **kwargs)[source]

resource settings model.

Parameters:
  • id (AutoField) – Id
  • name (CharField) – The name of the resource.
  • unit (CharField) – The unit of the resource, such as kWh, Gallon, etc.
  • conversion_rate (IntegerField) – The rate of converting the usage data into the unit. For example, 1000 could be specified to convert usage data recorded in Wh to kWh.
  • winning_order (CharField) – The winning order. Ascending indicates the lesser/smaller wins.
save(*args, **kwargs)[source]

Custom save method.

class apps.managers.resource_mgr.models.ResourceUsage(*args, **kwargs)[source]

abstract resource usage model.

Parameters:
  • team_id (ForeignKey) – Team
  • date (DateField) – The date when the usage or reading is recorded.
  • time (TimeField) – The time of the day when the usage or reading is recorded.
  • manual_meter_reading (IntegerField) – The daily manual reading of the meter, in the unit defined in ResourceSetting. only needed when manually reading the meter.
  • usage (IntegerField) – The daily usage, if manual_meter_reading is input and the reading from the day before is available, this will be automatically calculated.
  • created_at (DateTimeField) – Created at
  • updated_at (DateTimeField) – Updated at
class Meta[source]
class apps.managers.resource_mgr.models.WasteUsage(*args, **kwargs)[source]

Water usage model.

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – Team
  • date (DateField) – The date when the usage or reading is recorded.
  • time (TimeField) – The time of the day when the usage or reading is recorded.
  • manual_meter_reading (IntegerField) – The daily manual reading of the meter, in the unit defined in ResourceSetting. only needed when manually reading the meter.
  • usage (IntegerField) – The daily usage, if manual_meter_reading is input and the reading from the day before is available, this will be automatically calculated.
  • created_at (DateTimeField) – Created at
  • updated_at (DateTimeField) – Updated at
save(*args, **kwargs)[source]

Custom save method to set fields.

class apps.managers.resource_mgr.models.WaterUsage(*args, **kwargs)[source]

Water usage model.

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – Team
  • date (DateField) – The date when the usage or reading is recorded.
  • time (TimeField) – The time of the day when the usage or reading is recorded.
  • manual_meter_reading (IntegerField) – The daily manual reading of the meter, in the unit defined in ResourceSetting. only needed when manually reading the meter.
  • usage (IntegerField) – The daily usage, if manual_meter_reading is input and the reading from the day before is available, this will be automatically calculated.
  • created_at (DateTimeField) – Created at
  • updated_at (DateTimeField) – Updated at
save(*args, **kwargs)[source]

Custom save method to set fields.

Package apps.managers.score_mgr

The manager for defining and managing scores.

Module apps.managers.score_mgr.models

The model definition for scores.

class apps.managers.score_mgr.models.PointsTransaction(*args, **kwargs)[source]

Entries that track points awarded to users.

Parameters:
  • id (AutoField) – Id
  • user_id (ForeignKey) – User
  • points (IntegerField) – The points for the transaction. negative number indicates a subtraction
  • transaction_date (DateTimeField) – The date of the transaction
  • message (CharField) – The message of the transcation.
  • object_id (PositiveIntegerField) – Object id
  • content_type_id (ForeignKey) – Content type
class apps.managers.score_mgr.models.ReferralSetting(*args, **kwargs)[source]

Defines the model of the dynamic referral settings.

Parameters:
  • id (AutoField) – Id
  • normal_referral_points (IntegerField) – The point amount for normal referral bonus.
  • super_referral_points (IntegerField) – The point amount for supper referral bonus, when the referral is from a team of participation rate from 20% to 40%
  • mega_referral_points (IntegerField) – The point amount for mega referral bonus, when the referrals is from a team of participation rate les than 20%
  • start_dynamic_bonus (BooleanField) – Start rewarding the dynamic referral bonus. set it to true if you want to reward referral bonus depends on referral’s team participation.
save(*args, **kwargs)[source]

Custom save method.

class apps.managers.score_mgr.models.ScoreSetting(*args, **kwargs)[source]

score settings models.

Parameters:
  • id (AutoField) – Id
  • name (CharField) – The settings label.
  • setup_points (IntegerField) – The point amount for setting up the profile.
  • active_threshold_points (IntegerField) – The point amount for considering an active participant. It is also the threshold point amount for awarding referral bonus.
  • signup_bonus_points (IntegerField) – The point amount for signing up a commitment or event.
  • quest_bonus_points (IntegerField) – The point amount for completing a quest.
  • noshow_penalty_points (IntegerField) – The point amount for no show penalty.
  • feedback_bonus_points (IntegerField) – The point amount for providing action feedback.
save(*args, **kwargs)[source]

Custom save method.

class apps.managers.score_mgr.models.ScoreboardEntry(*args, **kwargs)[source]

Defines the model that tracks user scores.

Parameters:
  • id (AutoField) – Id
  • profile_id (ForeignKey) – Profile
  • round_name (CharField) – The name of the round
  • points (IntegerField) – Points for this round
  • last_awarded_submission (DateTimeField) – Last award time
Package apps.managers.team_mgr

The manager to support definition and management of teams.

Teams can be aggregated into ‘groups’. This allows, for example, a group of teams representing individual floors to be aggregated into a group (their residence hall).

Module apps.managers.team_mgr.models

Defines the model for teams.

class apps.managers.team_mgr.models.Group(*args, **kwargs)[source]

Defines the group that a team belongs to.

Parameters:
  • id (AutoField) – Id
  • name (CharField) – The name of the group.
team_points_leaders(num_results=None, round_name=None)[source]

Returns the top points leaders for the given group.

class apps.managers.team_mgr.models.Post(*args, **kwargs)[source]

Represents a wall post on a user’s wall.

Parameters:
  • id (AutoField) – Id
  • user_id (ForeignKey) – The user who submit the post.
  • team_id (ForeignKey) – The team of the submitter.
  • text (TextField) – The content of the post.
  • style_class (CharField) – The CSS class to apply to this post.
  • created_at (DateTimeField) – The create timestamp
date_string()[source]

Formats the created date into a pretty string.

class apps.managers.team_mgr.models.Team(*args, **kwargs)[source]

Represents the team that a player belongs to.

Parameters:
  • id (AutoField) – Id
  • group_id (ForeignKey) – The group this team belongs to.
  • name (CharField) – The team name
  • size (IntegerField) – The size of the team. It is the total number of residents in the team. Non-zero value will be used to normalize the team total score and participation rate.
  • logo (ImageField) – The logo of the team.
current_round_points()[source]

Returns the number of points for the current round.

current_round_rank()[source]

Gets the ranking of this team during the current round.

points(round_name=None)[source]

Returns the total number of points for the team. Optional parameter for a round.

points_leaders(num_results=None, round_name=None)[source]

Gets the individual points leaders for the team.

rank(round_name=None)[source]

Returns the rank of the team across all groups.

save(*args, **kwargs)[source]

Custom save method.

Module apps.managers.team_mgr.admin

Administrator interface to teams.

class apps.managers.team_mgr.admin.GroupAdmin(model, admin_site)[source]

Group Admin

class apps.managers.team_mgr.admin.PostAdmin(model, admin_site)[source]

Post administrator for teams, overrides delete_selected

delete_selected(request, queryset)[source]

delete selected override

class apps.managers.team_mgr.admin.TeamAdmin(model, admin_site)[source]

Team Admin

Package: apps.widgets

Widgets are Makahiki components that provide a player-level user interface.

Package apps.widgets.ask_admin

The ask_admin widget implements a “send feedback” button and corresponding form.

Module apps.widgets.ask_admin.views

Views handler for ask admin page rendering.

apps.widgets.ask_admin.views.send_feedback(request)[source]

send feedback.

apps.widgets.ask_admin.views.supply(request, page_name)[source]

Supply view_objects for widget rendering, returns form.

Module apps.widgets.ask_admin.forms

Provides a simple text area for users to type their question to the admin.

class apps.widgets.ask_admin.forms.FeedbackForm(data=None, files=None, auto_id=u'id_%s', prefix=None, initial=None, error_class=<class 'django.forms.util.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Ask Admin feedback form.

Package apps.widgets.badges

Provides badges for players.

Module apps.widgets.badges.models
Module apps.widgets.badges.badges
Module apps.widgets.badges.views
Package apps.widgets.energy_power_meter

Implements the Energy Power Meter widget.

Module apps.widgets.energy_power_meter.views

Handle rendering of the Energy Power Meter widget.

apps.widgets.energy_power_meter.views.supply(request, page_name)[source]

Return the view_objects content, which in this case is empty.

The Help Package Hierarchy
Module apps.widgets.help

A set of widgets for storage, retrieval, and display of help topics.

Module apps.widgets.help.models

The model for help topics.

apps.widgets.help.models.HELP_CATEGORIES = (('faq', 'Frequently Asked Questions'), ('rules', 'Rules of the competition'), ('widget', 'Widget Help'))

Defines the available help categories.

class apps.widgets.help.models.HelpTopic(*args, **kwargs)[source]

Represents a help topic in the system.

Parameters:
  • id (AutoField) – Id
  • title (CharField) – The title of the topic.
  • slug (SlugField) – Automatically generated if left blank.
  • category (CharField) – One of the HELP_CATEGORIES.
  • priority (IntegerField) – sorting order within the category. lower priority first
  • contents (TextField) – The content of the help topic. Uses Markdown formatting.
  • parent_topic_id (ForeignKey) – Optional parent topic of this topic.
get_absolute_url(*moreargs, **morekwargs)[source]

Returns the absolute url for a help page.

Module apps.widgets.help.views

Provides the view of a help topic.

apps.widgets.help.views.supply(request, page_name)[source]

supply view_objects for widget rendering.

apps.widgets.help.views.topic(request, *args, **kwargs)[source]

Shows a help topic. This method handles both a regular request and an AJAX request for dialog boxes.

Module apps.widgets.help.faq

Implements the widget providing the FAQ for this challenge.

Module apps.widgets.help.faq.views

Provides the view for the Help FAQ widget

apps.widgets.help.faq.views.supply(request, page_name)[source]

supply view_objects for widget rendering, namely the faq objects.

Module apps.widgets.help.intro

Implements the widget providing an introduction to the challenge.

Module apps.widgets.help.intro.views
Module apps.widgets.help.rule

Implements the help widget for challenge rules.

Module apps.widgets.help.rule.views

The view for the widget to display the rules of the challenge.

apps.widgets.help.rule.views.supply(request, page_name)[source]

supply view_objects for widget rendering.

Package apps.widgets.home

Implements the home page and first login wizard.

Module apps.widgets.home.views
Module apps.widgets.home.forms
Package apps.widgets.my_achievements

Implements My_Achievements, which provides a historical record of how all the points for a player was obtained during a challenge.

Module apps.widgets.my_achievements.views
Package apps.widgets.my_commitments

Implements a widget that displays the player’s current commitments.

Module apps.widgets.my_commitments.views
Package apps.widgets.my_info

Implements the My_Info widget, which displays profile information.

Module apps.widgets.my_info.views
Module apps.widgets.my_info.forms
Package apps.widgets.notifications

Provides the notification service.

apps.widgets.notifications.get_unread_count(user)[source]

Get the number of notifications that are unread.

apps.widgets.notifications.get_unread_notifications(user, limit=None)[source]

Retrieves the user’s unread notifications that are to be displayed on the web. Returns a dictionary containing their alerts, their unread notifications, and if there are more unread notifications.

apps.widgets.notifications.get_user_alert_notifications(user)[source]

Retrieves notifications that should be displayed in an alert.

Module apps.widgets.notifications.models

Model definition for notification service.

class apps.widgets.notifications.models.NoticeTemplate(*args, **kwargs)[source]

Templates for built in notifications.

Parameters:
  • id (AutoField) – Id
  • notice_type (SlugField) – Notice type
  • template (TextField) – Uses Markdown formatting. The available template variables are listed here.
render(context_dict=None)[source]

Renders the message first using Django’s templating system, then using Markdown. The template renderer uses the passed in context to insert variables.

apps.widgets.notifications.models.TYPE_CHOICES = (('round-transition', 'Round Transition'), ('raffle-winner', 'Raffle Winner'), ('prize-winner', 'Prize Winner'), ('commitment-ready', 'Commitment Ready'), ('prize-winner-receipt', 'Prize Winner Receipt Form'), ('raffle-winner-receipt', 'Raffle Winner Receipt Form'))

Possible notification types.

class apps.widgets.notifications.models.UserNotification(*args, **kwargs)[source]

User Notification

Parameters:
  • id (AutoField) – Id
  • recipient_id (ForeignKey) – The recipient of this notification.
  • contents (TextField) – The content of the notification.
  • unread (BooleanField) – Unread
  • updated_at (DateTimeField) – Updated at
  • created_at (DateTimeField) – Created at
  • level (IntegerField) – The notification level, such as INFO or ERROR.
  • display_alert (BooleanField) – If enabled, display the alert dialog box to user.
  • content_type_id (ForeignKey) – Content type
  • object_id (PositiveIntegerField) – Object id
static create_email_notification(recipient_email, subject, message, html_message=None)[source]

Create an email notification.

static create_error_notification(recipient, contents, display_alert=True, content_object=None)[source]

Create an error level notification.

static create_info_notification(recipient, contents, display_alert=False, content_object=None)[source]

Create an info level notification.

static create_success_notification(recipient, contents, display_alert=False, content_object=None)[source]

Create a success notification.

static create_warning_notification(recipient, contents, display_alert=True, content_object=None)[source]

Create a warning level notification.

icon_class

Return the css class for the icon.

is_success

Return true if success.

save(*args, **kwargs)[source]

Custom save method.

style_class

Return the style class

Module apps.widgets.notifications.views

Handle the requests for the notification widget.

apps.widgets.notifications.views.read(request, notification_id)[source]

Handle the read notification request.

apps.widgets.notifications.views.supply(request, page_name)[source]

Supply the view_objects content, which are the last 3 unread notifications.

Package apps.widgets.popular_tasks

The widget displaying the top 10 most popular actions in the Smart Grid Game.

Package apps.widgets.prizes

Implements the prize widget.

Module apps.widgets.prizes.models
Module apps.widgets.prizes.views
Package apps.widgets.quests

quests module.

apps.widgets.quests.MAX_AVAILABLE_QUESTS = 3

The number of quests a user can have at any one time.

Module apps.widgets.quests.models

Defines the Quest Model.

class apps.widgets.quests.models.Quest(*args, **kwargs)[source]

Represents a quest in the database.

Parameters:
  • id (AutoField) – Id
  • name (CharField) – The name of the quest.
  • quest_slug (SlugField) – A unique identifier of the quest. Automatically generated if left blank.
  • description (TextField) – Discription of the quest. It should outline the steps to completing this quest. Uses Markdown formatting.
  • priority (IntegerField) – Quest with lower values (higher priority) will be listed first.
  • unlock_conditions (TextField) – Conditions a user needs to meet in order to have this quest be available (appeared in the Quest widget). Uses Makahiki Predicates.
  • completion_conditions (TextField) – Conditions a user needs to meet in order to complete the quest. Uses Makahiki Predicates.
accept(user)[source]

Lets the user accept the quest. Returns True if successful.

can_add_quest(user)[source]

Returns True if the user can add the quest.

completed_quest(user)[source]

Returns True if the user completed the quest.

opt_out(user)[source]

Lets the user opt out of seeing the quest. Returns True if successful.

class apps.widgets.quests.models.QuestMember(*args, **kwargs)[source]

Represents a user’s participation in a quest. Shouldn’t be in the admin interface, since there shouldn’t be a reason to edit instances.

Parameters:
  • id (AutoField) – Id
  • user_id (ForeignKey) – User
  • quest_id (ForeignKey) – Quest
  • completed (BooleanField) – True if the user completed the quest.
  • opt_out (BooleanField) – True if the user opts out of the quest.
  • created_at (DateTimeField) – Created at
  • updated_at (DateTimeField) – Updated at
delete(*args, **kwargs)[source]

Custom delete method.

save(*args, **kwargs)[source]

Custom save method to create a points transaction after the object is saved.

Module apps.widgets.quests.views

Implemenat view processing for Quests.

apps.widgets.quests.views.accept(request, *args, **kwargs)[source]

Accept the quest.

apps.widgets.quests.views.cancel(request, *args, **kwargs)[source]

cancel the quest

apps.widgets.quests.views.opt_out(request, *args, **kwargs)[source]

opt_out of the quest

apps.widgets.quests.views.supply(request, page_name)[source]

supply the quest view_objects

Module apps.widgets.quests.admin

Quest administrative interface, enabling checking of quest conditions.

class apps.widgets.quests.admin.QuestAdmin(model, admin_site)[source]

Admin

form

alias of QuestAdminForm

class apps.widgets.quests.admin.QuestAdminForm(data=None, files=None, auto_id=u'id_%s', prefix=None, initial=None, error_class=<class 'django.forms.util.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None)[source]

admin form

class Meta[source]

meta

model

alias of Quest

QuestAdminForm.clean_completion_conditions()[source]

Validates the unlock conditions of the quest.

QuestAdminForm.clean_unlock_conditions()[source]

Validates the unlock conditions of the quest.

Module apps.widgets.quests.management.commands.verify_quests

Invocation: python manage.py verify_quests

Verifies that all of the existing quest lock and unlock condition strings are valid. Prints out the names of any invalid quest conditions.

class apps.widgets.quests.management.commands.verify_quests.Command(*args, **kwargs)[source]

command

handle(*args, **options)[source]
Package apps.widgets.raffle

Implements the raffle widget.

Module apps.widgets.raffle.models

Provides the model for the raffle widget.

apps.widgets.raffle.models.POINTS_PER_TICKET = 25

Number of points required to earn a raffle ticket

class apps.widgets.raffle.models.RafflePrize(*args, **kwargs)[source]

RafflePrize model

Parameters:
  • id (AutoField) – Id
  • round_id (ForeignKey) – The round of the raffle prize.
  • title (CharField) – The title of the raffle prize.
  • value (IntegerField) – The value of the raffle prize
  • description (TextField) – Description of the raffle prize. Uses Markdown formatting.
  • image (ImageField) – A picture of the raffle prize.
  • winner_id (ForeignKey) – The winner of the raffle prize. Normally, this is randomly picked by the system at the end of the round.
add_ticket(user)[source]

Adds a ticket from the user if they have one. Throws an exception if they cannot add a ticket.

allocated_tickets(user=None)[source]

Returns the number of tickets allocated to this prize. Takes an optional argument to return the number of tickets allocated by the user.

remove_ticket(user)[source]

Removes an allocated ticket.

class apps.widgets.raffle.models.RaffleTicket(*args, **kwargs)[source]

Raffle ticket model

Parameters:
  • id (AutoField) – Id
  • user_id (ForeignKey) – User
  • raffle_prize_id (ForeignKey) – Raffle prize
  • created_at (DateTimeField) – Created at
  • updated_at (DateTimeField) – Updated at
static available_tickets(user)[source]

Returns the number of raffle tickets the user has available.

static total_tickets(user)[source]

Return the total tickets available for this user.

Module apps.widgets.raffle.views

Handle rendering of the raffle widget.

apps.widgets.raffle.views.add_ticket(request, *args, **kwargs)[source]

Adds a user’s raffle ticket to the prize.

apps.widgets.raffle.views.bulk_round_change(request, *args, **kwargs)[source]

Handle change Round for selected Raffle Prizes from the admin interface.

apps.widgets.raffle.views.notify_winner(request, *args, **kwargs)[source]

Sends an email to the user notifying them that they are a winner.

apps.widgets.raffle.views.pick_winner(request, *args, **kwargs)[source]

Picks the raffle game winners for the raffle deadline that has passed.

apps.widgets.raffle.views.prize_summary(request, round_name)[source]

display summary of the winners.

apps.widgets.raffle.views.raffle_form(request, *args, **kwargs)[source]

Supply the raffle form.

apps.widgets.raffle.views.raffle_prize_list(request)[source]

Generates the raffle prize list and renders to page.

apps.widgets.raffle.views.remove_ticket(request, *args, **kwargs)[source]

Removes a user’s raffle ticket from the prize.

apps.widgets.raffle.views.supply(request, page_name)[source]

Supply the view_objects contents, which provides all raffle data.

Module apps.widgets.raffle.admin

Raffle widget administration

class apps.widgets.raffle.admin.RafflePrizeAdmin(model, admin_site)[source]

raffle admin

change_round(request, queryset)[source]

Change the round for the selected Raffle Prizes.

copy_raffle_prize(request, queryset)[source]

Copies the selected Raffle Prizes.

notice_sent(obj)[source]

return True if the notification had been sent.

notify_winner(request, queryset)[source]

pick winner.

pick_winner(request, queryset)[source]

pick winner.

winner_form(obj)[source]

return the winner and link to pickup form.

class apps.widgets.raffle.admin.RaffleTicketInline(parent_model, admin_site)[source]

SponsorsInline admin.

model

alias of RaffleTicket

Package apps.widgets.resource_goal

Implements the widgets for resource goal games (energy, water, etc.)

Module apps.widgets.resource_goal.models

Energy goal model definition.

class apps.widgets.resource_goal.models.EnergyBaselineDaily(*args, **kwargs)[source]

Daily Team energy baseline Model for a week

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – The team which this baseline is related to.
  • day (IntegerField) – The day in the week
  • usage (IntegerField) – The baseline usage of the day.
  • updated_at (DateTimeField) – Updated at
class apps.widgets.resource_goal.models.EnergyBaselineHourly(*args, **kwargs)[source]

Hourly Team energy baseline Model for a week

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – The team which this baseline is related to.
  • day (IntegerField) – The day in the week.
  • hour (IntegerField) – The hour in the day.
  • usage (IntegerField) – The baseline usage of the day.
  • updated_at (DateTimeField) – Updated at
class apps.widgets.resource_goal.models.EnergyGoal(*args, **kwargs)[source]

Energy goal

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – The team which this goal is related to.
  • date (DateField) – The date of the goal.
  • actual_usage (IntegerField) – The actual usage, cache of the usage in ResourceUsage.
  • baseline_usage (IntegerField) – The baseline usage, cache of the usage in BaselineDaily.
  • goal_usage (IntegerField) – The goal usage, derived from baseline and goal percentage.
  • percent_reduction (IntegerField) – The percentage of reduction over the goal usage, derived from actual and goal usage
  • current_goal_percent_reduction (IntegerField) – The current goal percentage of reduction, calculated from the initial valuein GoalSetting.
  • goal_status (CharField) – The status of the goal.
  • updated_at (DateTimeField) – Updated at
class apps.widgets.resource_goal.models.EnergyGoalSetting(*args, **kwargs)[source]

Energy goal settings.

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – The team which this goal is related to.
  • goal_percent_reduction (IntegerField) – The goal percentage of reduction.
  • baseline_method (CharField) – The method of calculating the baseline.
  • data_storage (CharField) – The storage service of the usage data.
  • wattdepot_source_name (CharField) – The source name in wattdepot server for the team. It defaults to the team name.
  • goal_points (IntegerField) – The amount of points to award for completing a goal.
  • manual_entry (BooleanField) – Manually enter the data?
  • manual_entry_time (TimeField) – The time for manual data entry.
  • realtime_meter_interval (IntegerField) – The refresh interval (in seconds) for the real-time meter display. not applicable when the Manual Entry is checked.
save(*args, **kwargs)[source]

Custom save method to set fields.

class apps.widgets.resource_goal.models.ResourceBaselineDaily(*args, **kwargs)[source]

Daily Team resource baseline Model for a week

Parameters:
  • team_id (ForeignKey) – The team which this baseline is related to.
  • day (IntegerField) – The day in the week
  • usage (IntegerField) – The baseline usage of the day.
  • updated_at (DateTimeField) – Updated at
class Meta[source]
class apps.widgets.resource_goal.models.ResourceBaselineHourly(*args, **kwargs)[source]

Daily Team resource baseline Model for a week

Parameters:
  • team_id (ForeignKey) – The team which this baseline is related to.
  • day (IntegerField) – The day in the week.
  • hour (IntegerField) – The hour in the day.
  • usage (IntegerField) – The baseline usage of the day.
  • updated_at (DateTimeField) – Updated at
class Meta[source]
class apps.widgets.resource_goal.models.ResourceGoal(*args, **kwargs)[source]

Team Resource Goal Model

Parameters:
  • team_id (ForeignKey) – The team which this goal is related to.
  • date (DateField) – The date of the goal.
  • actual_usage (IntegerField) – The actual usage, cache of the usage in ResourceUsage.
  • baseline_usage (IntegerField) – The baseline usage, cache of the usage in BaselineDaily.
  • goal_usage (IntegerField) – The goal usage, derived from baseline and goal percentage.
  • percent_reduction (IntegerField) – The percentage of reduction over the goal usage, derived from actual and goal usage
  • current_goal_percent_reduction (IntegerField) – The current goal percentage of reduction, calculated from the initial valuein GoalSetting.
  • goal_status (CharField) – The status of the goal.
  • updated_at (DateTimeField) – Updated at
class Meta[source]
class apps.widgets.resource_goal.models.ResourceGoalSetting(*args, **kwargs)[source]

Team Resource Goal Setting Model

Parameters:
  • team_id (ForeignKey) – The team which this goal is related to.
  • goal_percent_reduction (IntegerField) – The goal percentage of reduction.
  • baseline_method (CharField) – The method of calculating the baseline.
  • data_storage (CharField) – The storage service of the usage data.
  • wattdepot_source_name (CharField) – The source name in wattdepot server for the team. It defaults to the team name.
  • goal_points (IntegerField) – The amount of points to award for completing a goal.
  • manual_entry (BooleanField) – Manually enter the data?
  • manual_entry_time (TimeField) – The time for manual data entry.
  • realtime_meter_interval (IntegerField) – The refresh interval (in seconds) for the real-time meter display. not applicable when the Manual Entry is checked.
class Meta[source]
class apps.widgets.resource_goal.models.WaterBaselineDaily(*args, **kwargs)[source]

Daily Team water baseline Model for a week

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – The team which this baseline is related to.
  • day (IntegerField) – The day in the week
  • usage (IntegerField) – The baseline usage of the day.
  • updated_at (DateTimeField) – Updated at
class apps.widgets.resource_goal.models.WaterBaselineHourly(*args, **kwargs)[source]

Hourly Team water baseline Model for a week

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – The team which this baseline is related to.
  • day (IntegerField) – The day in the week.
  • hour (IntegerField) – The hour in the day.
  • usage (IntegerField) – The baseline usage of the day.
  • updated_at (DateTimeField) – Updated at
class apps.widgets.resource_goal.models.WaterGoal(*args, **kwargs)[source]

Water goal

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – The team which this goal is related to.
  • date (DateField) – The date of the goal.
  • actual_usage (IntegerField) – The actual usage, cache of the usage in ResourceUsage.
  • baseline_usage (IntegerField) – The baseline usage, cache of the usage in BaselineDaily.
  • goal_usage (IntegerField) – The goal usage, derived from baseline and goal percentage.
  • percent_reduction (IntegerField) – The percentage of reduction over the goal usage, derived from actual and goal usage
  • current_goal_percent_reduction (IntegerField) – The current goal percentage of reduction, calculated from the initial valuein GoalSetting.
  • goal_status (CharField) – The status of the goal.
  • updated_at (DateTimeField) – Updated at
class apps.widgets.resource_goal.models.WaterGoalSetting(*args, **kwargs)[source]

Water goal settings

Parameters:
  • id (AutoField) – Id
  • team_id (ForeignKey) – The team which this goal is related to.
  • goal_percent_reduction (IntegerField) – The goal percentage of reduction.
  • baseline_method (CharField) – The method of calculating the baseline.
  • data_storage (CharField) – The storage service of the usage data.
  • wattdepot_source_name (CharField) – The source name in wattdepot server for the team. It defaults to the team name.
  • goal_points (IntegerField) – The amount of points to award for completing a goal.
  • manual_entry (BooleanField) – Manually enter the data?
  • manual_entry_time (TimeField) – The time for manual data entry.
  • realtime_meter_interval (IntegerField) – The refresh interval (in seconds) for the real-time meter display. not applicable when the Manual Entry is checked.
save(*args, **kwargs)[source]

Custom save method to set fields.

Module apps.widgets.resource_goal.views
Package apps.widgets.scoreboard

Implements the scoreboard widget.

Module apps.widgets.scoreboard.views
Package apps.widgets.smartgrid

Smartgrid widget module.

apps.widgets.smartgrid.MAX_COMMITMENTS = 5

Maximum number of commitments user can have at one time.

apps.widgets.smartgrid.NOSHOW_PENALTY_DAYS = 2

Number of days after event sign up which will incur no show penalty.

apps.widgets.smartgrid.NUM_GOLOW_ACTIONS = 3

Number of go low actions to display.

apps.widgets.smartgrid.SETUP_WIZARD_ACTIVITY = 'intro-video'

Slug of the activity used in the setup wizard.

Module apps.widgets.smartgrid.models
Module apps.widgets.smartgrid.views
Module apps.widgets.smartgrid.forms
Module apps.widgets.smartgrid.admin
Module apps.widgets.smartgrid.management.commands.process_notices
Module apps.widgets.smartgrid.management.commands.send_reminders
Package apps.widgets.team_members

Implements the team member widget.

Module apps.widgets.team_members.views

Provides the view of the team member widget.

apps.widgets.team_members.views.supply(request, page_name)[source]

Supply view_objects content, which is the set of team members.

apps.widgets.team_members.views.team_members(request, *args, **kwargs)[source]

Provide the team members.

Package apps.widgets.upcoming_events

Implements the upcoming event widget.

Module apps.widgets.upcoming_events.views
Package apps.widgets.wallpost

Provide the wall post widget.

Module apps.widgets.wallpost.views

Handles wall post widget request and rendering.

apps.widgets.wallpost.views.DEFAULT_POST_COUNT = 10

Number of posts to load at a time.

apps.widgets.wallpost.views.post(request, *args, **kwargs)[source]

handle the submission of the wall post

handle more post link

apps.widgets.wallpost.views.super_supply(request, page_name, agent)[source]

supply the view_objects.

apps.widgets.wallpost.views.supply(request, page_name)[source]

supply the view_objects.

Package: apps.lib

Provides source code for third party libraries that we needed to adapt for use in Makahiki.

Currently, Makahiki uses adapted versions of the following third party libraries:

Scripts Reference Guide

The page provides a reference guide to the top-level scripts for managing Makahiki.

Installation scripts

initialize_instance
Invocation: scripts/initialize_instance .py -t|–type[=] default|demo|test
-r|–heroku[=] <heroku_app> -d|–docker

Use this script to create an instance with different types of configuration:

[default]: includes the basic configuration. The admin needs to create
the settings for rounds, resources, resource goals, teams and users, prizes, etc. Uses internal authentication.
[test] : includes all of “default” configuration, with more test users
and data. Uses CAS authentication.

if -r or –heroku is specified, it will initialize the instance in the specified heroku app.

Performs the following:
  • installation of any modules in requirements.txt
  • re-create the database and database user
  • Synchronize and migrates the database schemas.
  • Collects and copies the static and media files to the specific location.
  • Loads the default or test configuration of data.
initialize_postgres

Invocation: scripts/initialize_postgres.py

Creates makahiki database and user within postgres database. Assumes that the user postgres is trusted and can login without authentication. This is usually the case by default.

update_instance

Invocation: scripts/update_instance .py -r|–heroku[=] <heroku_app>

Use this script to update an instance:

if -r or –heroku is specified, it will initialize the instance in the specified heroku app.

Performs the following:
  • Updates and/or installation of any modules in requirements.txt
  • Synchronize and migrates the database schemas.
  • Collects and copies the static and media files to the specific location.

Development scripts

compile_less

Invocation: compile_less.py [-v | –verbose]

Compiles all of the LESS style files into CSS.

Compiles all the themes and individual page style sheets, creating CSS files for each theme containing all necessary definitions.

coverage

Invocation: scripts/coverage.py

Runs the tests and computes their coverage. An HTML coverage report is
generated in htmlcov/.
dump_data

Invocation: scripts/dump_data.py

Creates a set of json files in the dumped_data directory containing the current state. This state can be loaded into a new instance using load_data.

verify

Invocation: scripts/verify.py

Runs pep8, pylint, and tests. If all are successful, there is no output and program terminates normally. If any errors, prints output from unsuccessful programs and exits with non-zero error code.

Environment Variables

The page provides a reference guide to the environment variables.

Note

This environment variable documentation is extracted autogmatically from the settings.py file. For this reason, the documentation shows the string “settings.” on the front of each environment variable name. The actual environment variable name is the uppercase string without the “settings.” prefix.

Note

To set the environment variables in a local installation, use OS specific commands. For example, in Unix bash, to set the environment variable MAKAHIKI_EMAIL_INFO:

% export MAKAHIKI_EMAIL_INFO=kukuicup@changeme.com:changeme

To set it in the heroku installation, use the heroku config:add command. For example:

% heroku config:add MAKAHIKI_EMAIL_INFO=kukuicup@changeme.com:changeme

Provides system-level settings and access to environment variables. All variables corresponding to environment variables have documentation for ReadTheDocs.

settings.MAKAHIKI_USE_HEROKU = False

[Optional] If “true”, use Heroku hosting, Otherwise, use local hosting.

settings.MAKAHIKI_DATABASE_URL = ''

[Required if MAKAHIKI_USE_HEROKU is not true] Specify the Database URL. Example: postgres://username:password@db_host:db_port/db_name

settings.MAKAHIKI_ADMIN_INFO = ''

[Required] Specify the makahiki admin account and password. Example: admin:changeme

settings.MAKAHIKI_EMAIL_INFO = ''

[Required if enabling email] Specify the email host user and password. Example: kukuicup@gmail.com:changeme

settings.MAKAHIKI_DEBUG = False

[Optional] If “true”, enable debug mode, with better error messages. Otherwise use production mode.

settings.MAKAHIKI_USE_MEMCACHED = False

[Optional] If “true”, use memcache. Otherwise no caching is used.

settings.MAKAHIKI_USE_S3 = False

[Optional] If “true”, use the Amazon S3 storage facility. Otherwise use local folder.

settings.MAKAHIKI_AWS_ACCESS_KEY_ID = ''

[Required if MAKAHIKI_USE_S3 is true] The Amazon access key ID.

settings.MAKAHIKI_AWS_SECRET_ACCESS_KEY = ''

[Required if MAKAHIKI_USE_S3 is true] The Amazon secret access key.

settings.MAKAHIKI_AWS_STORAGE_BUCKET_NAME = ''

[Required if MAKAHIKI_USE_S3 is true] The Amazon storage bucket name.

settings.MAKAHIKI_USE_LESS = False

[Optional] If “true”, use LESS files to style pages. Otherwise use the latest version of CSS.

settings.MAKAHIKI_LDAP_BIND_DN = ''

[Required for LDAP services] Provide the Bind DN.

settings.MAKAHIKI_LDAP_BIND_PASSWORD = ''

[Required for LDAP services] Provide the Bind password.

settings.MAKAHIKI_LDAP_USE_CN = False

[Optional] If “true”, use the LDAP cn attribute as the username, otherwise use uid attribute.

settings.MAKAHIKI_SECRET_KEY = 'yvzg-s=^gb#)e6l7jq_$%ft=i7jln&izs2@4+3!5%#unumorn-'

[Optional] Specifies the Django secret key setting. See https://docs.djangoproject.com/en/dev/ref/settings/#secret-key

settings.MAKAHIKI_USE_FACEBOOK = False

[Optional] If “true”, use facebook integration.

settings.MAKAHIKI_FACEBOOK_APP_ID = ''

[Required if using Facebook] App ID required for Facebook integration.

settings.MAKAHIKI_FACEBOOK_SECRET_KEY = ''

[Required if using Facebook] Secret key required for Facebook integration.

settings.MAKAHIKI_USE_LOGFILE = False

[Optional] if “true”, use logfile to store application logs.

settings.MAKAHIKI_USE_WATTDEPOT3 = False

[Required if using wattdepot3] wattdepot admin name.

settings.WATTDEPOT_ADMIN_NAME = ''

[Required if using wattdepot3] wattdepot admin password.

Supported Predicates

This section documents the predicates available for evaluating conditions such as unlocking smartgrid levels, actions, quests, badges etc.

Note

This documentation is extracted automatically from the predicate definition source files. For this reason, the documentation shows the full path to the predicates. To use the predicates in a condition string, only the predicate name (without any qualified prefixes) should be used. In addition, the “user” argument need not to be supplied in the condition string. The predicates can be connected using python boolean operators such as “and” or “or” etc.

Example: The following condition string will check for if the current time has reach round 2 and the user has earned 100 points:

reached_round("Round 2") or has_points(100)

Challenge Predicates

Predicates regarding the state of the challenge.

apps.managers.challenge_mgr.predicates.game_enabled(user, game_name)[source]

Returns True if the game is enabled.

apps.managers.challenge_mgr.predicates.reached_round(user, round_name)[source]

Returns True if the current time was past the start of specified round.

Player Predicates

Smart Grid Game Predicates

Indices and tables