Weeks ago, I wanted to upgrade my Cakebox light instance to 2.0.0. Cakebox light is the refactored version of Cakebox original version.

The project is active and some great improvements is expected for [2.0 release](https://github.com/Cakebox/cakebox/issues/156](https://github.com/Cakebox/cakebox/issues/156).
The main improvement is a complete project refactoring in order to split backend and frontend environment.

Written with the great Silex micro-framework and AngularJS, it provide a awesome web interface to browse and watch files, especally vacation movies ;).

Let's clone the 2.0.0 branch.

Currently, cakebox.sh, scripts and webconf examples are outdated and not relevant for the 2.0.0 version so we will have to setup everything manually.
This may be outdated, some corrections below may have already been implemented in the new version.

First problem, authors have really change their way to think about the architecture, and the setup is not easy without any installation instructions. But worse, some files are missing and even if you setup correctly the project, errors will pop-up and nothing will work.

Ok heads up, let's do this.

The architecture is now like this:

  • back (Silex API)

    • config
    • public
      • index.php
    • src
      • Cakebox
        • Controller
          • BetaseriesController.php
          • DirectoryController.php
          • FileController.php
          • MainController.php
        • Service
          • MainService.php
      • bootstrap.php
      • routing.php
    • .composer.json
  • front (AngularJS front)

    • gulp
    • src
      • app
        • about
          • about.html
        • browse
          • browse.controller.js
          • browse.html
        • components
          • ....
        • main
          • main.controller.js
        • play
          • play.controller.js
          • play.html
        • index.config.js
        • index.css
        • index.module.js
      • assets
        • images
          • ...
        • languages
          • locale-en.json
          • locale-fr.json
          • locale-it.json
      • index.css
      • index.html
    • .bower.json
    • gulpfile.js
    • package.json
  • scripts

    • apache2-alias.sh
    • apache2-subdomain.sh
  • webconf-example

    • apache2-alias.conf.example
    • apache2-vhost.conf.example
  • cakebox.sh

Setup the API

I assume you have composer installed globaly.

$ cd back && composer install && composer update
$ cp config/default.php.dist config/default.php

back/config/default.php


<?php

/*
  General configuration of Cakebox
*/
$app["cakebox.root"] = "/Users/Cakebox/videos/"; // Root directory Cakebox have to scan
$app["cakebox.access"] = "/access/"; // Alias used in web server for direct access
$app["cakebox.language"] = "en"; //Language of Cakebox. Could be : fr, en

/*
  Directory settings
*/
$app["directory.ignoreDotFiles"] = true;
$app["directory.ignore"] = "//"; // Regex for files exclusion. For exemple : "/(\.nfo|\.test)$/"

/*
  Web player settings
*/
$app["player.default_type"] = "divx"; // html5 or divx or vlc
$app["player.auto_play"] = "false";

/*
  User rights
*/
$app["rights.canPlayMedia"] = true;
$app["rights.canDownloadFile"] = true;
$app["rights.canArchiveDirectory"] = false;
$app["rights.canDelete"] = false;

/*
  Betaseries account
  NB: Ask API key here http://www.betaseries.com/api/
*/
$app["bs.login"] = "";
$app["bs.passwd"] = "";
$app["bs.apikey"] = "";

Now, we can setup our Apache 2 virtual host

<VirtualHost *:80>
	ServerName api.cakebox.local
	
	DocumentRoot "/Applications/MAMP/htdocs/PHP/cakebox/back/public"

	ServerAlias api.cakebox.local

	<Directory "/Applications/MAMP/htdocs/PHP/cakebox/back/public">
		Options Indexes Includes FollowSymLinks  ExecCGI
		AllowOverride All
		Order allow,deny
        Allow from all
		RewriteEngine On
		RewriteRule ^ index.php [L]
	</Directory>
</VirtualHost>

Check if backend works

$ curl -I http://api.cakebox.local/api/directories?path=
$ HTTP/1.1 200 OK

Setup the frontend

I assume you have NodeJS, Bower and GulpJS installed globaly.

$ cd front && npm install && npm update
$ bower install && bower update
$ gulp build

Setup the Apache 2 virtual host

<VirtualHost *:80>
	ServerName cakebox.local
	
	DocumentRoot "/Applications/MAMP/htdocs/PHP/cakebox/front"

	ServerAlias www.cakebox.local

	<Directory "/Applications/MAMP/htdocs/PHP/cakebox/front">
		Options Indexes Includes FollowSymLinks  ExecCGI MultiViews
		AllowOverride All
		Order allow,deny
        Allow from all
        RewriteEngine On
        #RewriteBase /
        Redirect 301 /api    http://api.cakebox.local/api
	</Directory>
    
	Alias /access /Applications/MAMP/htdocs/cakebox/downloads/
	
    <Directory /Applications/MAMP/htdocs/cakebox/downloads>
        RewriteEngine On
        <IfVersion >= 2.4>
            Require all granted
        </IfVersion>
        <IfVersion < 2.4>
            Order allow,deny
            Allow from all
        </IfVersion>
        Header set Content-Disposition "attachment"
    </Directory>
</VirtualHost>

Check front works

Browse to http://cakebox.local

Problems begin

Everything should work but I get Error -1 (): GET api/directories.
If you check FireBug, I see such errors

XMLHttpRequest cannot load http://api.cakebox.local/api/rights. No 'Access-Control-Allow-Origin' header is present on the requested resource

The API assume that frontend is in the same domain but I do not want to setup that on my MAMP application so a quick workaround is to modify API response.

I used the after application middleware like this

back/src/routing.php

<?php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

...

$app->after(function (Request $request, Response $response) {
    $response->headers->set('Access-Control-Allow-Origin', $_SERVER['HTTP_ORIGIN']);
});

Refresh http://cakebox.local. If you have a file it sould look like this

2015-09-21-my-first-open-source-pull-request

You can't click on your file and some errors occur. The easiest one to solve:

ReferenceError: alertify is not defined

Let's add alertify to our Bower dependencies

front/bower.json

{
  "name": "cakebox",
  "version": "2.0.0",
  "dependencies": {
      "...": "...",
      "alertify": "~0.3.10",
  }
}
$ bower update
$ gulp build

Last error to solve

GET http://api.cakebox.local/api/rights 405 (Method Not Allowed)

If you look in the API source you will see that there is no controller or routing for the /rights endpoint.
So we need to create a controller that respond if the user is allowed to read a file based on backend configuration.

back/src/Cakebox/Controller/RightController.php

<?php

namespace Cakebox\Controller;

use Silex\Application;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Get user permissions
 *
 * @author  Léopold Jacquot <leopold.jacquot[at]gmail[dot]com>
 */
class RightController {

    /**
     * Get user permissions
     *
     * @param Application $app     Silex Application
     * @param Request     $request Request parameters
     *
     * @return JsonResponse Object containing user permissions
     */
    public function get(Application $app, Request $request) {
        $permissions = ['canPlayMedia' => $app['rights.canPlayMedia']];
        return $app->json($permissions, 200);
    }
}

Create associeted routing is the easy part.

back/src/routing.php


<?php

...

/**
 * Rights routes
 */
$app->get('api/rights', 'Cakebox\Controller\RightController::get');

Great, our index works and we can access to our media library BUT again new error popup when we try to access to a movie...

Error: [ng:areq] Argument 'MediaCtrl' is not a function, got undefined

An angular error great... I use jQuery in the day to day work and I have not much experience with Angular, anyway with some VanillaJS skills all will be fine.
This error is simplier than expected, MediaCtrl has been refactored to PlayCtrl but the app config was not updated.

front/src/app/index.config.js

$routeProvider.when('/play/:path*', {
    templateUrl: 'app/play/play.html',                
    controller:  'PlayCtrl'
})
gulp build
GET http://api.cakebox.local/api/player 405 (Method Not Allowed)

That doesn't work... Player controller doesn't exist.

I will not create a player API controller because this value is already returned by the main App controller. We will need to edit the Angular play controller to fetch the value.

front/src/app/play/play.controller.js

(function() {
    'use strict';
    
     angular.module('cakebox')
        .controller('PlayCtrl', function ($scope, $routeParams, $translate, File, Player, Betaseries, App) {
            $scope.app = App.get(null, function(data) {
                $scope.player = data.player;
            });
            /** ... **/
    });
})();

gulp build

Yeah, cakebox light is now ready to works on the 2.0.0 branch!

I do NOT recommand to use the 2.0.0 branch because it's still in developement and some major changement could occur.
I was surprised by the number of missing or incomplete file, and bug. Even if 2.0.0 branch is in developement it's important to prevent breaking or incomplete stuff by not commiting this in a next tagged release branch.
It makes it painful for developers to contribute to it and that's not the point.