

# Prerequisites

[Melange](MelangeIntro.md) is a web application written in Python 2.7 that runs on
[Google App Engine](http://code.google.com/appengine/).

# TL;DR

You should read the text below, but if you want a quick refresher on how to get running, here's the TL;DR.

## Prerequisites

### Platform / Operating System

Melange development is known to work on several versions of Debian/Ubuntu on x86\_64.
  * Ubuntu 12.04 (precise)
  * Ubuntu 14.04 (trusty)
  * Debian 7.4 (wheezy)

Other OSes may or may not work without many tweaks.  For best results, please use one of the above, or one closely related.

### Packages

Building, testing, and running Melange depends on installation of a few system packages:
  * git
  * libxml2-dev
  * libxslt-dev
  * python (version 2.7)
  * python-dev
  * python-lxml
  * virtualenv (version 1.10 or later)
  * libpng12-dev
  * libjpeg-dev
  * libwebp-dev
  * libyaml-dev
  * xvfb
  * zlib1g-dev
  * firefox or iceweasel
  * make


This might work for you:
```
sudo apt-get install libxml2-dev libxslt-dev python-dev python-lxml python-virtualenv xvfb zlib1g-dev firefox make libpng12-dev libwebp-dev libjpeg-dev libyaml-dev
```

## Setting up

If you do not yet have a melange directory set up, run the following commands.

```
git clone https://melange.googlesource.com/soc
cd soc
make setup
```

NOTE: There might be some errors that look like - "Bad argument -- expected name or tuple" during the documentation generation. It's a known issue in epydoc [#343](https://sourceforge.net/p/epydoc/bugs/363/). The build works just fine.

## Running locally

If you want to run melange locally, run the following command

```
make localserver
```

It will listen on port 8080.

## Creating an AppEngine instance

If you do not already have an AppEngine instance, follow these steps, otherwise you can skip this part.

  * Go to http://www.appspot.com and sign in with a Google Account
  * Click "Create an application"
  * Verify your account if prompted
  * In the "Create an Application" page, fill in an identifier (cannot be changed), you will need this later on when deploying
  * Fill in a title (can be changed later)
  * Set the "Authentication Options" on either "Open to all Google Accounts users (default)" or "Restricted to the following Google Apps domain".
  * Hit "Create Application"

## Deploying to your own instance

Assuming you have an AppEngine instance called 'your-melange-instance'

```
scripts/gen_app_yaml.py -o devvin -f your-melange-instance &&
thirdparty/google_appengine/appcfg.py update build
```


## Running the test suite

If you want to run the test suite, run the following

```
bin/run-tests
```

This will run, by default, all types of tests. This is the same as running

```
bin/run-tests -t js,pyunit
```

So, using ` -t ` switch it's possible to choose a list of comma-separated types of tests to run.

To run only pyunit tests:

```
bin/run-tests -t pyunit
```

To run only js tests:

```
bin/run-tests -t js
```

To run only functional tests(Headless):

```
bin/run-tests -t functional
```

To run only functional tests(In a browser):

```
bin/run-tests -t functional --browsers-gui
```

# Checking Out the Code

To check out Melange source code run the following command:

Using Git repository:

```
git clone https://melange.googlesource.com/soc
```

# Setting up your Client
Change directories into the working directory (the one created by checking out the code). Google App Engine requires a file `app.yaml` in the application directory. For now, you can create a dummy `app.yaml` file by running:
```
scripts/gen_app_yaml.py local-devel -o devvin
```

# Running the Code Locally
You can start the server on your computer by running:

```
thirdparty/google_appengine/dev_appserver.py build
```

You should now be able to see the running server at http://localhost:8080/ .  Congrats!  You've got Melange running!

(If you want to run on a different port, you can use the `--port` argument.  Other arguments are described [here](http://code.google.com/appengine/docs/thedevwebserver.html).)

(Since you are starting from scratch, you will probably want some sample data.
You can use programmatically-generated sample data to save yours fingers for code. First you need to login, visit http://localhost:8080/login for the same. After login visit http://localhost:8080/seed_db to have Melange generate data for you.)

# Running on and Deploying to App Engine's cluster
If you want to run an instance of Melange on Google's App Engine infrastructure, there are a few more steps to make sure it deploys the right data to the right place.

## Set the application name
In `app/app.yaml` there's an application name that in the above steps was set to fake-application-name.  After registering an application on Google App Engine, use any text editor to change the line that starts with `application: fake-application-name` to instead read `application: <your-instance-name>`. You can also run the script again:

```
scripts/gen_app_yaml.py -o devvin -f proper-application-name 
```

## Building With Paver

Because
[Tiny MCE](http://code.google.com/p/soc/source/browse/#svn/trunk/app/tiny_mce)
(and possibly some other third-party content and JavaScript incorporated
into Melange) is large,
[zipserve](http://code.google.com/p/googleappengine/source/browse/#svn/trunk/google/appengine/ext/zipserve)
is used to combine this content into `.zip` archive files (to avoid
file-count limits in Google App Engine).  A side effect of this is that,
for Tiny MCE to work in the `textarea` controls on your local working copy,
launched with `thirdparty/google_appengine`, you still need to run a build script
to produce these <tt>.zip</tt> files at least once.

To do this, you will need to execute the `bin/paver` script, using the following command

```
bin/paver build
```

This script will create a `build/` directory at the same level as the
`app/` directory (and the `scripts/` directory) in the `hg` working copy.

## Deploying to Google App Engine

Once you have your application configured correctly and you have
executed the `paver` script found in the `bin` folder,
you are ready to deploy your Melange image to your specific Google
App Engine instance.

You can run the contents of the `build/` directory, in
order to test what would actually be uploaded by `appcfg.py upload`
to Google App Engine by using:

```
bin/gae_develop build
```

Once you are satisfied that `build/` contains everything needed, you can deploy
to your Google App Engine instance with:

```
thirdparty/google_appengine/appcfg.py update build
```

# Contributing

There are a number of ways that you can contribute to the Melange project.

## CLA

You must sign the Google CLA before we can accept any patches from you.

Please visit: https://cla.developers.google.com/

## Discussion

If you are interested in contributing to the Melange project, please join our
[general discussion mailing list](MailingListsGuidelines#General_discussion_list.md).
Also,feel free to join us [on IRC](IrcChannelGuidelines.md).


## Bug Hunting and Feature Requests

If you are (or were) a mentor or student participant in GSoC or GCI but do not have the time to contribute patches to Melange, we can still use your help.  While a great deal of code is already done, some parts of the web application are not entirely bug free yet, or feature complete.
Please consider writing up a feature request, or bug report. Please be precise when you file a [New Issue](http://tinyurl.com/new-issue).

## Patches

[Patches](ContributionReviews#Patches.md) to the code are also welcome,
[even from non-committers](ContributionReviews#Suggested_patches_from_casual_contributors.md).  Please see the [Gerrit](Gerrit.md) page for the best way to submit patches.

The code that is used for showing pages can be found in app/soc/modules/`<module_name>`/views.