Spectre
=====

# Development

`go build && ./spectre`

Visit http://localhost:8000/

# Authorization

Spectre uses JWT for authorization. For POST/PUT/DELETE requests, you must include an "Authorization" header including the "iss", "aud", "exp", "nbf" claims. The "audience" claim must match the Spectre channel name.

# API

## Channels

When a channel is not Spectre broadcasting, `playhead` is null and `active` is false. When a channel starts Spectre broadcasting, the contents of `playhead` are generated, and `active` is set to true.

```
{
  "id": 27953914,
  "enabled": true,
  "active_playlist_id": 3,
  "active": true,
  "playlists": [
    {
      "id": 3,
      "channel_id": 27953914,
      "playlist": {
        "vod_ids": [
          9400642,
          9452866,
          9987767,
          10720338
        ]
      },
      "version": 1
    }
  ],
  "playhead": {
    "playlist_id": 3,
    "active_vod_index": 0,
    "remaining_seconds_in_active_vod": 954.956214697,
    "vods": [
      {
        "duration": 819.09999999,
        "id": 9400642,
        "transition_segments": null
      },
      {
        "duration": 651.399999993,
        "id": 9452866,
        "transition_segments": null
      },
      {
        "duration": 679.531999995,
        "id": 9987767,
        "transition_segments": null,
      },
      {
        "duration": 1503.732999986,
        "id": 10720338,
        "transition_segments": null
      }
    ]
  }
}
```

### Get info about a channel

`GET /channels/:channel_id`

### Edit info about a channel

`PUT /channels/:channel_id`

Name   |Type|Description
-------|----|--------------------
enabled|bool|True if spectre is enabled

Example
```
curl -X PUT -d '{"enabled":true}' http://spectre-0.prod.us-west2.justin.tv/v1/channels/27953914
```

## Playlists

### Get a channel's playlist

`GET /channels/:channel_id/playlists/:playlist_id`

### Create a channel's playlist

`POST /channels/:channel_id/playlists`

Example
```
curl -X POST -d '{"playlist":{"vod_ids":[1323,1234]}}' http://spectre-0.prod.us-west2.justin.tv/v1/channels/27953914/playlists
```

**Parameters**

Name    |Type  |Description
--------|------|--------------------
playlist|string|JSON of the playlist

### Update a channel's playlist

`PUT /channels/:channel_id/playlists/:playlist_id`

**Parameters**

Name  |Type  |Description
------|------|-----------
module|string|Module name

Example
```
curl -X PUT -d '{"playlist":{"vod_ids":[1323,1234]}}' http://localhost:8000/v1/channels/27953914/playlists/7
```

### Delete a channel's playlist

`DELETE /channels/:channel_id/playlists/:playlist_id`

## Video files

### Get the manifest file for the time that represents the currently live portion

`GET /:stream_id/:format/(py-)?index-live.m3u8`

### Get a video chunk

`GET /:stream_id/:format/index-:index.ts`

# Database

Setting up a local database for testing (OSX):

## Install postgres

`brew install postgres`

## Start the postgres instance

`pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start`

## Create spectre db

`createdb spectre`

## Create a spectre role

First log in to the database using `psql postgres`
Then run the SQL command: `create role spectre createdb superuser login`

## Dump the production db to a file

NOTE: This command should be run with caution as it performs a query against the *production* database. It only performs a read query, but on a large database this may take a long time to run. Currently, the spectre DB is pretty small (thousands of rows), and it will execute pretty quickly.

`pg_dump -h spectre-production.cbywgl1h5pos.us-west-2.rds.amazonaws.com -d spectre -U spectre > /tmp/spectre.sql`

## Import the sql dump to your local database

`psql spectre < /tmp/spectre.sql`

## Setup API to connect to your local DB instance.

Unfortunately this is hard-coded in `main.go`. Edit the `PgConnInfo` string to point to `localhost`.

## Updating the database

To update, simply drop the `spectre` database using `drop database spectre` when connected to the *localhost* db instance. Then follow steps above.

## Spectre Monitor

If running the Spectre Monitor with a local database, be sure to add the `-dry-run` option so that no mutating changes are propagated to Usher.

# Unit Tests

The Monitor uses [vektra/mockery](https://github.com/vektra/mockery) to generate mocks for the unit tests. See documentation on the Github page to see how to re-generate the mocks. The steps should be straightforward:

1. `go get github.com/vektra/mockery`
2. `mockery -name <Interface> -recursive` e.g. `mockery -name Usher -recursive`
