1
0
mirror of https://github.com/devfake/flox.git synced 2024-11-14 22:22:39 +01:00

Fetch files (added) (#22)

* move to local scope

* start file parser

* flatten controller

* update tests

* composer update

* Update tests, include episodes

* store src for tv episodes

* simplify fixtures

* refactor

* refactor episode and alternative title

* refactor item category

* fix typo and remove exception
This commit is contained in:
Viktor Geringer 2017-01-06 09:40:27 +01:00 committed by Tim Meier
parent 1d55c164c4
commit 7d7553088c
23 changed files with 1147 additions and 555 deletions

View File

@ -2,6 +2,7 @@
namespace App;
use App\Services\TMDB;
use Illuminate\Database\Eloquent\Model;
class AlternativeTitle extends Model {
@ -9,4 +10,23 @@
public $timestamps = false;
protected $fillable = ['title', 'tmdb_id', 'country'];
/**
* Store all alternative titles for tv shows and movies.
*
* @param $item
* @param TMDB $tmdb
*/
public function store($item, TMDB $tmdb)
{
$alternativeTitles = $tmdb->getAlternativeTitles($item);
foreach($alternativeTitles as $title) {
$this->firstOrCreate([
'title' => $title->title,
'tmdb_id' => $item['tmdb_id'],
'country' => $title->iso_3166_1,
]);
}
}
}

View File

@ -2,6 +2,7 @@
namespace App;
use App\Services\TMDB;
use Illuminate\Database\Eloquent\Model;
class Episode extends Model {
@ -18,4 +19,45 @@
'season_tmdb_id',
'created_at'
];
/**
* Save all episodes of each season.
*
* @param $seasons
* @param $tmdbId
*/
public function store($tmdbId, TMDB $tmdb)
{
$seasons = $tmdb->tvEpisodes($tmdbId);
foreach($seasons as $season) {
foreach($season->episodes as $episode) {
$this->create([
'season_tmdb_id' => $season->id,
'episode_tmdb_id' => $episode->id,
'season_number' => $episode->season_number,
'episode_number' => $episode->episode_number,
'name' => $episode->name,
'tmdb_id' => $tmdbId,
'created_at' => time(),
]);
}
}
}
/*
* Scopes
*/
public function scopeFindByTmdbId($query, $tmdbId)
{
return $query->where('tmdb_id', $tmdbId);
}
public function scopeFindEpisode($query, $tmdbId, $episode)
{
return $query->where('tmdb_id', $tmdbId)
->where('season_number', $episode->season_number)
->where('episode_number', $episode->episode_number);
}
}

View File

@ -57,7 +57,7 @@
public function episodes($tmdb_id)
{
return [
'episodes' => Episode::where('tmdb_id', $tmdb_id)->get()->groupBy('season_number'),
'episodes' => Episode::findByTmdbId($tmdb_id)->get()->groupBy('season_number'),
'spoiler' => Setting::first()->episode_spoiler_protection
];
}
@ -76,9 +76,7 @@
}
// We don't have an smart search driver and return an simple 'like' query.
return $this->item->where('title', 'LIKE', '%' . $title . '%')
->orWhere('original_title', 'LIKE', '%' . $title . '%')
->get();
return $this->item->findByTitle($title)->get();
}
/**
@ -106,13 +104,11 @@
* @param TMDB $tmdb
* @return Item
*/
public function add(TMDB $tmdb)
public function add(TMDB $tmdb, Storage $storage, Episode $episode, AlternativeTitle $alternativeTitle)
{
$data = Input::get('item');
$this->storage->createPosterFile($data['poster']);
return $this->createItem($data, $tmdb);
return $this->item->store($data, $tmdb, $storage, $episode, $alternativeTitle);
}
/**
@ -140,74 +136,6 @@
AlternativeTitle::where('tmdb_id', $tmdb_id)->delete();
}
/**
* Create the new movie.
*
* @param $data
* @return Item
*/
private function createItem($data, TMDB $tmdb)
{
$tmdbId = $data['tmdb_id'];
$mediaType = $data['media_type'];
$item = $this->item->create([
'tmdb_id' => $tmdbId,
'title' => $data['title'],
'media_type' => $mediaType,
'original_title' => $data['original_title'],
'poster' => $data['poster'],
'rating' => 1,
'released' => $data['released'],
'genre' => $data['genre'],
'created_at' => time(),
]);
if($mediaType == 'tv') {
$this->createEpisodes($tmdbId, $tmdb);
}
$this->addAlternativeTitles($item, $tmdb);
return $item;
}
/**
* Update alternative titles for all tv shows and movies or specific item.
* For old versions of flox or hold all alternative titles up to date.
*
* @param TMDB $tmdb
*/
public function updateAlternativeTitles(TMDB $tmdb, $tmdbID = null)
{
set_time_limit(3000);
$items = $tmdbID ? Item::where('tmdb_id', $tmdbID)->get() : Item::all();
$items->each(function($item) use ($tmdb) {
$this->addAlternativeTitles($item, $tmdb);
});
}
/**
* Store all alternative titles for tv shows and movies.
*
* @param $item
* @param TMDB $tmdb
*/
private function addAlternativeTitles($item, TMDB $tmdb)
{
$alternativeTitles = $tmdb->getAlternativeTitles($item);
foreach($alternativeTitles as $title) {
AlternativeTitle::firstOrCreate([
'title' => $title->title,
'tmdb_id' => $item['tmdb_id'],
'country' => $title->iso_3166_1,
]);
}
}
/**
* Set an episode as seen/unseen.
*
@ -224,45 +152,25 @@
}
}
public function updateAlternativeTitles(TMDB $tmdb, AlternativeTitle $alternativeTitle, $tmdbID = null)
{
return $this->item->updateAlternativeTitles($tmdb, $alternativeTitle, $tmdbID);
}
/**
* Toggle all episodes of an season as seen/unseen.
*/
public function toggleSeason()
{
$tmdb_id = Input::get('tmdb_id');
$tmdbId = Input::get('tmdb_id');
$season = Input::get('season');
$seen = Input::get('seen');
$episodes = Episode::where('tmdb_id', $tmdb_id)->where('season_number', $season)->get();
$episodes = Episode::where('tmdb_id', $tmdbId)->where('season_number', $season)->get();
foreach($episodes as $episode) {
$episode->seen = $seen;
$episode->save();
}
}
/**
* Save all episodes of each season.
*
* @param $seasons
* @param $tmdbId
*/
protected function createEpisodes($tmdbId, TMDB $tmdb)
{
$seasons = $tmdb->tvEpisodes($tmdbId);
foreach($seasons as $season) {
foreach($season->episodes as $episode) {
$new = new Episode();
$new->season_tmdb_id = $season->id;
$new->episode_tmdb_id = $episode->id;
$new->season_number = $episode->season_number;
$new->episode_number = $episode->episode_number;
$new->name = $episode->name;
$new->tmdb_id = $tmdbId;
$new->created_at = time();
$new->save();
}
}
}
}
}

View File

@ -5,6 +5,7 @@
use App\Episode;
use App\Http\Requests\ImportRequest;
use App\Item;
use App\Services\FileParser;
use App\Services\Storage;
use App\Services\TMDB;
use App\Setting;
@ -160,4 +161,16 @@
'episode_spoiler_protection' => Input::get('spoiler'),
]);
}
/**
* Call flox-file-parser.
*
* @param FileParser $parser
*/
public function fetchFiles(FileParser $parser)
{
$files = $parser->fetch();
$parser->store($files);
}
}

View File

@ -2,6 +2,8 @@
namespace App;
use App\Services\Storage;
use App\Services\TMDB;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
@ -24,6 +26,61 @@
'genre',
];
/**
* Create the new movie / tv show.
*
* @param $data
* @return Item
*/
public function store($data, TMDB $tmdb, Storage $storage, Episode $episode, AlternativeTitle $alternativeTitle)
{
$tmdbId = $data['tmdb_id'];
$mediaType = $data['media_type'];
$item = $this->create([
'tmdb_id' => $tmdbId,
'title' => $data['title'],
'media_type' => $mediaType,
'original_title' => $data['original_title'],
'poster' => $data['poster'],
'rating' => 1,
'released' => $data['released'],
'genre' => $data['genre'],
'created_at' => time(),
]);
$storage->createPosterFile($data['poster']);
if($mediaType == 'tv') {
$episode->store($tmdbId, $tmdb);
}
$alternativeTitle->store($item, $tmdb);
return $item;
}
/**
* Update alternative titles for all tv shows and movies or specific item.
* For old versions of flox or to keep all alternative titles up to date.
*
* @param TMDB $tmdb
*/
public function updateAlternativeTitles(TMDB $tmdb, AlternativeTitle $alternativeTitle, $tmdbID = null)
{
set_time_limit(3000);
$items = $tmdbID ? $this->searchTmdbId($tmdbID)->get() : $this->all();
$items->each(function($item) use ($tmdb, $alternativeTitle) {
$alternativeTitle->store($item, $tmdb);
});
}
/*
* Relations
*/
public function episodes()
{
return $this->hasMany(Episode::class, 'tmdb_id', 'tmdb_id');
@ -41,4 +98,22 @@
->where('seen', true)
->latest();
}
/*
* Scopes
*/
public function scopeFindByTmdbId($query, $tmdbId)
{
return $query->where('tmdb_id', $tmdbId);
}
public function scopeFindByTitle($query, $title)
{
return $query->where('title', 'like', '%' . $title . '%')
->orWhere('original_title', 'like', '%' . $title . '%')
->orWhereHas('alternativeTitles', function($query) use ($title) {
$query->where('title', 'like', '%' . $title . '%');
});
}
}

View File

@ -2,31 +2,155 @@
namespace App\Services;
use App\AlternativeTitle;
use App\Episode;
use App\Item;
use Illuminate\Database\Eloquent\Collection;
class FileParser {
protected $response;
private $item;
private $episode;
private $tmdb;
private $storage;
private $alternativeTitle;
private $itemCategory;
public function __construct()
public function __construct(Item $item, Episode $episode, TMDB $tmdb, Storage $storage, AlternativeTitle $alternativeTitle)
{
$this->response = $this->parseMediaFiles();
$this->item = new Item();
$this->item = $item;
$this->episode = $episode;
$this->tmdb = $tmdb;
$this->storage = $storage;
$this->alternativeTitle = $alternativeTitle;
}
public function parseMediaFiles()
/**
* Make a request to flox-file-parser and get local files data.
*
* @return array
*/
public function fetch()
{
return file_get_contents(base_path('tests/fixtures/media_files.json'));
return json_decode(
file_get_contents(base_path('tests/fixtures/Files/all.json'))
);
}
public function getTmdbId($title)
/**
* Loop over local files and see if it can find them in database. Otherwise search in TMDb.
*
* @param $files
*/
public function store($files)
{
$item = $this->item->where('title', $title)->orWhere('original_title', $title)->first(['id', 'tmdb_id']);
foreach($files as $type => $items) {
$this->itemCategory = $type;
if( ! $item) {
return null;
foreach($items as $item) {
$title = $item->name;
// See if file is already in our database.
if($found = $this->foundInDatabase($title, 'title')) {
$this->handleStatus($item, $found->tmdb_id);
continue;
}
// Otherwise make a new TMDb request.
$this->tmdbSearch($title, $item);
}
}
return $item->tmdb_id;
}
/**
* Make a new request to TMDb and check against the database. Otherwise create a new item.
*
* @param $title
* @param $item
* @return bool|\Exception|mixed
*/
private function tmdbSearch($title, $item)
{
$result = $this->tmdb->search($title);
if( ! $result) {
return false;
}
return $this->findOrCreateItem($result[0], $item);
}
/**
* Check tmdb_id against the database or create a new item.
*
* @param $firstResult
* @param $item
* @return \Exception|mixed
*/
private function findOrCreateItem($firstResult, $item)
{
$tmdbId = $firstResult['tmdb_id'];
// Check against our database.
if($this->foundInDatabase($tmdbId, 'tmdb_id')) {
return $this->handleStatus($item, $tmdbId);
}
// Otherwise create a new item from the result.
$created = $this->item->store($firstResult, $this->tmdb, $this->storage, $this->episode, $this->alternativeTitle);
return $this->handleStatus($item, $created->tmdb_id);
}
/**
* See if we can find a item by title or tmdb_id in our database.
*
* @param $indicator
* @return Collection
*/
public function foundInDatabase($value, $type)
{
if($type == 'title') {
return $this->item->findByTitle($value)->first();
}
return $this->item->findByTmdbId($value)->first();
}
/**
* Check which status the file has.
* Create new src if the status is 'added'.
* Update src if status is 'updated'.
* Remove src if status is 'removed'.
*
* @param $item
* @param $tmdb_id
* @return mixed
*/
public function handleStatus($item, $tmdbId)
{
if($item->status == 'added') {
return $this->storeSrc($item, $tmdbId);
}
}
/**
* Store src from local file into items for movies or episodes for tv shows.
*
* @param $item
* @param $tmdb_id
*/
private function storeSrc($item, $tmdbId)
{
if($this->itemCategory == 'tv') {
$model = $this->episode->findEpisode($tmdbId, $item);
} else {
$model = $this->item->findByTmdbId($tmdbId);
}
return $model->update([
'src' => $item->src,
]);
}
}

View File

@ -13,8 +13,8 @@
"doctrine/dbal": "^2.5"
},
"require-dev": {
"mockery/mockery": "^0.9.7",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~5.0",
"symfony/css-selector": "3.1.*",
"symfony/dom-crawler": "3.1.*"

565
backend/composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,18 @@
'rating' => 1,
'genre' => '',
'released' => time(),
'created_at' => time(),
'created_at' => time(),
'src' => null,
];
});
$factory->define(App\Episode::class, function(Faker\Generator $faker) {
return [
'name' => $faker->name,
'season_tmdb_id' => 1,
'episode_tmdb_id' => 1,
'created_at' => time(),
'src' => null,
];
});
@ -30,4 +41,4 @@
return [
'media_type' => 'tv',
];
});
});

View File

@ -18,6 +18,8 @@
Route::post('/import', 'SettingController@import');
Route::get('/check-update', 'SettingController@checkUpdate');
// todo: POST
Route::get('/fetch-files', 'SettingController@fetchFiles');
Route::get('/sync-scout', 'SettingController@syncScout');
Route::patch('/update-genre', 'SettingController@updateGenre');

View File

@ -1,5 +1,14 @@
<?php
use App\AlternativeTitle;
use App\Episode;
use App\Item;
use App\Services\Storage;
use App\Services\TMDB;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use App\Services\FileParser;
@ -8,40 +17,142 @@
use DatabaseMigrations;
protected $response;
private $item;
private $parser;
private $tmdb;
private $storage;
private $episode;
private $alternativeTitle;
public function setUp()
{
parent::setUp();
$this->createFactory();
$this->response = file_get_contents(__DIR__ . '/fixtures/media_files.json');
$this->parser = new FileParser();
$this->item = new Item();
$this->tmdb = new TMDB(new Client());
$this->storage = new Storage();
$this->episode = new Episode();
$this->alternativeTitle = new AlternativeTitle();
$this->parser = new FileParser($this->item, $this->episode, $this->tmdb, $this->storage, $this->alternativeTitle);
}
/** @test */
public function it_can_parse_tmdb_id_by_name()
public function it_can_find_item_in_database()
{
$tmdbId = $this->parser->getTmdbId('Breaking Bad');
$this->createMovie();
$this->assertEquals(1396, $tmdbId);
$itemFromTitle = $this->parser->foundInDatabase('Warcraft', 'title');
$itemFromId = $this->parser->foundInDatabase(68735, 'tmdb_id');
$this->assertEquals(68735, $itemFromTitle->tmdb_id);
$this->assertEquals(68735, $itemFromId->tmdb_id);
}
/** @test */
public function it_returns_null_if_tmdb_id_not_found_by_name()
public function it_should_store_src_if_movie_found_in_database()
{
$tmdbId = $this->parser->getTmdbId('Not Found');
$this->createMovie();
$this->assertNull($tmdbId);
$item = $this->item->first();
$this->assertNull($item->src);
$this->parser->store($this->fixtureFilesMovie);
$item = $this->item->first();
$this->assertNotNull($item->src);
}
private function createFactory()
/** @test */
public function it_should_store_src_for_episodes_if_tv_found_in_database()
{
factory(App\Item::class)->create([
'title' => 'Breaking Bad',
'original_title' => 'Breaking Bad',
'tmdb_id' => 1396,
'media_type' => 'tv',
$this->createTv();
$episodes = $this->item->with('episodes')->first()->episodes;
foreach($episodes as $episode) {
$this->assertNull($episode->src);
}
$this->parser->store($this->fixtureFilesTv);
$episodes = $this->item->with('episodes')->first()->episodes;
foreach($episodes as $episode) {
$this->assertNotNull($episode->src);
}
}
/** @test */
public function it_should_create_movie_and_store_src_if_not_found_in_database()
{
$items = $this->item->get();
$this->assertCount(0, $items);
$tmdbMock = $this->createTmdbMock($this->fixtureTmdbMovie, $this->fixtureAlternativeTitleMovie);
$parser = new FileParser($this->item, $this->episode, $tmdbMock, $this->storage, $this->alternativeTitle);
$parser->store($this->fixtureFilesMovie);
$this->seeInDatabase('items', [
'title' => 'Warcraft: The Beginning'
]);
$item = $this->item->first();
$this->assertNotNull($item->src);
}
/** @test */
public function it_should_create_tv_with_episodes_and_store_src_if_not_found_in_database()
{
$items = $this->item->get();
$episodes = $this->episode->get();
$this->assertCount(0, $items);
$this->assertCount(0, $episodes);
$tmdbMock = $this->createTmdbMock($this->fixtureTmdbTv, $this->fixtureAlternativeTitleTv);
$parser = new FileParser($this->item, $this->episode, $tmdbMock, $this->storage, $this->alternativeTitle);
$parser->store($this->fixtureFilesTv);
$this->seeInDatabase('items', [
'title' => 'Game of Thrones'
]);
$episodes = $this->episode->get();
$this->assertCount(4, $episodes);
foreach($episodes as $episode) {
$this->assertNotNull($episode->src);
}
}
private function createTmdbMock($fixture, $alternativeTitles)
{
$mock = new MockHandler([
new Response(200, ['X-RateLimit-Remaining' => [40]], $fixture),
new Response(200, ['X-RateLimit-Remaining' => [40]], $alternativeTitles),
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
// Mock this to avoid unknown requests to TMDb (get seasons and then get episodes for each season)
$tmdb = $this->getMockBuilder(TMDB::class)
->setConstructorArgs([$client])
->setMethods(['tvEpisodes'])
->getMock();
$tmdb->method('tvEpisodes')->willReturn($this->fixtureTmdbEpisodes);
return $tmdb;
}
}

View File

@ -1,25 +1,88 @@
<?php
abstract class TestCase extends Illuminate\Foundation\Testing\TestCase
{
/**
* The base URL to use while testing the application.
*
* @var string
*/
abstract class TestCase extends Illuminate\Foundation\Testing\TestCase {
protected $baseUrl = 'http://localhost';
/**
* Creates the application.
*
* @return \Illuminate\Foundation\Application
*/
protected $fixtureFilesAll;
protected $fixtureFilesMovie;
protected $fixtureFilesTv;
protected $fixtureAlternativeTitleMovie;
protected $fixtureAlternativeTitleTv;
protected $fixtureTmdbMovie;
protected $fixtureTmdbTv;
protected $fixtureTmdbEpisodes;
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$this->assignFixtures();
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
$app = require __DIR__ . '/../bootstrap/app.php';
return $app;
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
return $app;
}
}
private function assignFixtures()
{
$this->fixtureFilesAll = json_decode(file_get_contents(__DIR__ . '/fixtures/Files/all.json'));
$this->fixtureFilesMovie = json_decode(file_get_contents(__DIR__ . '/fixtures/Files/movie.json'));
$this->fixtureFilesTv = json_decode(file_get_contents(__DIR__ . '/fixtures/Files/tv.json'));
$this->fixtureAlternativeTitleMovie = file_get_contents(__DIR__ . '/fixtures/Tmdb/alternative_titles_movie.json');
$this->fixtureAlternativeTitleTv = file_get_contents(__DIR__ . '/fixtures/Tmdb/alternative_titles_tv.json');
$this->fixtureTmdbMovie = file_get_contents(__DIR__ . '/fixtures/Tmdb/movie.json');
$this->fixtureTmdbTv = file_get_contents(__DIR__ . '/fixtures/Tmdb/tv.json');
$this->fixtureTmdbEpisodes = json_decode(file_get_contents(__DIR__ . '/fixtures/Tmdb/episodes.json'));
}
protected function createMovie()
{
factory(App\Item::class)->create([
'title' => 'Warcraft: The Beginning',
'original_title' => 'Warcraft',
'tmdb_id' => 68735,
'media_type' => 'movie',
]);
}
protected function createTv()
{
factory(App\Item::class)->create([
'title' => 'Game of Thrones',
'original_title' => 'Game of Thrones',
'tmdb_id' => 1399,
'media_type' => 'tv',
]);
foreach([1, 2] as $season) {
foreach([1, 2] as $episode) {
factory(App\Episode::class)->create([
'tmdb_id' => 1399,
'season_number' => $season,
'episode_number' => $episode,
]);
}
}
}
protected function getMovie()
{
return factory(App\Item::class)->states('movie')->make([
'title' => 'Findet Nemo',
'tmdb_id' => 12,
]);
}
protected function getTv()
{
return factory(App\Item::class)->states('tv')->make([
'title' => 'Dragonball Z',
'tmdb_id' => 12971
]);
}
}

View File

@ -1,44 +1,25 @@
<?php
use App\AlternativeTitle;
use App\Http\Controllers\ItemController;
use App\Item;
use App\Services\Storage;
use App\Services\TMDB;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Facades\Input;
use GuzzleHttp\Psr7\Response;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class AlternativeTitleTest extends TestCase {
use DatabaseMigrations;
protected $movie;
protected $tv;
protected $movieFixture;
protected $tvFixture;
public function setUp()
{
parent::setUp();
$this->createFactories();
$this->createFixtures();
}
/** @test */
public function it_can_store_alternative_titles_for_movies()
{
Input::replace(['item' => $this->movie]);
$tmdbMock = $this->createTmdbMock($this->fixtureAlternativeTitleMovie);
$movie = $this->getMovie();
$tmdbMock = $this->createTmdb($this->movieFixture);
$itemController = new ItemController(new Item(), new Storage());
$itemController->add($tmdbMock);
$alternativeTitle = new AlternativeTitle();
$alternativeTitle->store($movie, $tmdbMock);
$this->assertCount(4, AlternativeTitle::all());
@ -50,18 +31,11 @@
/** @test */
public function it_can_store_alternative_titles_for_tv_shows()
{
Input::replace(['item' => $this->tv]);
$tmdbMock = $this->createTmdbMock($this->fixtureAlternativeTitleTv);
$tv = $this->getTv();
$tmdbMock = $this->createTmdb($this->tvFixture);
$itemControllerMock = $this->getMockBuilder(ItemController::class)
->setConstructorArgs([new Item(), new Storage()])
->setMethods(['createEpisodes'])
->getMock();
$itemControllerMock->method('createEpisodes')->willReturn(null);
$itemControllerMock->add($tmdbMock);
$alternativeTitle = new AlternativeTitle();
$alternativeTitle->store($tv, $tmdbMock);
$this->assertCount(3, AlternativeTitle::all());
@ -70,13 +44,10 @@
]);
}
private function createTmdb($fixture)
private function createTmdbMock($fixture)
{
$mock = new MockHandler([
new Response(200, [
'Content-Type' => 'application/json',
'X-RateLimit-Remaining' => [40],
], $fixture),
new Response(200, ['X-RateLimit-Remaining' => [40]], $fixture),
]);
$handler = HandlerStack::create($mock);
@ -84,23 +55,4 @@
return new TMDB($client);
}
private function createFactories()
{
$this->movie = factory(App\Item::class)->states('movie')->make([
'title' => 'Findet Nemo',
'tmdb_id' => 12
]);
$this->tv = factory(App\Item::class)->states('tv')->make([
'title' => 'Dragonball Z',
'tmdb_id' => 12971
]);
}
private function createFixtures()
{
$this->movieFixture = file_get_contents(__DIR__ . '/../fixtures/alternative_titles_movie.json');
$this->tvFixture = file_get_contents(__DIR__ . '/../fixtures/alternative_titles_tv.json');
}
}

127
backend/tests/fixtures/Files/all.json vendored Normal file
View File

@ -0,0 +1,127 @@
{
"tv": [
{
"name": "Breaking Bad",
"season_number": 1,
"episode_number": 1,
"extension": "mkv",
"year": null,
"filename": "1",
"status": "added",
"tags": [],
"subtitles": "/tv/Breaking Bad/S1/1.srt",
"src": "/tv/Breaking Bad/S1/1.mkv"
},
{
"name": "Breaking Bad",
"season_number": 1,
"episode_number": 2,
"extension": "mkv",
"tags": [],
"status": "added",
"filename": "2",
"year": null,
"subtitles": "/tv/Breaking Bad/S1/2.srt",
"src": "/tv/Breaking Bad/S1/2.mkv"
},
{
"name": "Breaking Bad",
"season_number": 2,
"episode_number": 1,
"status": "added",
"extension": "mp4",
"tags": [],
"year": null,
"filename": "1",
"subtitles": "/tv/Breaking Bad/s2/1.srt",
"src": "/tv/Breaking Bad/s2/1.mp4"
},
{
"name": "Breaking Bad",
"season_number": 2,
"episode_number": 2,
"tags": [],
"extension": "mkv",
"year": null,
"status": "added",
"filename": "2",
"subtitles": "/tv/Breaking Bad/s2/2.srt",
"src": "/tv/Breaking Bad/s2/2.mkv"
},
{
"name": "Game of Thrones",
"season_number": 2,
"episode_number": 1,
"status": "added",
"extension": "mkv",
"tags": [],
"year": null,
"filename": "1",
"subtitles": null,
"src": "/tv/Game of Thrones/S2/1.mkv"
},
{
"name": "Game of Thrones",
"season_number": 2,
"episode_number": 2,
"tags": [],
"status": "added",
"extension": "mkv",
"year": null,
"filename": "2",
"subtitles": null,
"src": "/tv/Game of Thrones/S2/2.mkv"
},
{
"name": "Game of Thrones",
"season_number": 1,
"episode_number": 1,
"extension": "mkv",
"status": "added",
"filename": "1",
"tags": [],
"subtitles": null,
"year": null,
"src": "/tv/Game of Thrones/s1/1.mkv"
},
{
"name": "Game of Thrones",
"season_number": 1,
"tags": [],
"episode_number": 2,
"status": "added",
"extension": "mp4",
"filename": "2",
"year": null,
"subtitles": null,
"src": "/tv/Game of Thrones/s1/2.mp4"
}
],
"movies": [
{
"name": "starwars episode vi return of the jedi",
"extension": "mp4",
"filename": "StarWars.Episode.VI.Return.of.The.Jedi.1080p.BDRip",
"src": "/movies/Star Wars/StarWars Episode VI Return of The Jedi 1080p BDRip/StarWars.Episode.VI.Return.of.The.Jedi.1080p.BDRip.mp4",
"tags": [
"hd",
"1080p"
],
"year": null,
"status": "added",
"subtitles": null
},
{
"name": "warcraft",
"extension": "mkv",
"filename": "Warcraft.2016.720p.WEB-DL",
"src": "/movies/Warcraft.2016.720p.WEB-DL/Warcraft.2016.720p.WEB-DL.mkv",
"year": 2016,
"tags": [
"720p"
],
"status": "added",
"subtitles": "/movies/Warcraft.2016.720p.WEB-DL/Warcraft.2016.720p.WEB-DL.srt"
}
]
}

16
backend/tests/fixtures/Files/movie.json vendored Normal file
View File

@ -0,0 +1,16 @@
{
"movies": [
{
"name": "warcraft",
"extension": "mkv",
"filename": "Warcraft.2016.720p.WEB-DL",
"src": "/movies/Warcraft.2016.720p.WEB-DL/Warcraft.2016.720p.WEB-DL.mkv",
"year": 2016,
"tags": [
"720p"
],
"status": "added",
"subtitles": "/movies/Warcraft.2016.720p.WEB-DL/Warcraft.2016.720p.WEB-DL.srt"
}
]
}

52
backend/tests/fixtures/Files/tv.json vendored Normal file
View File

@ -0,0 +1,52 @@
{
"tv": [
{
"name": "Game of Thrones",
"season_number": 2,
"episode_number": 1,
"status": "added",
"extension": "mkv",
"tags": [],
"year": null,
"filename": "1",
"subtitles": null,
"src": "/tv/Game of Thrones/S2/1.mkv"
},
{
"name": "Game of Thrones",
"season_number": 2,
"episode_number": 2,
"tags": [],
"status": "added",
"extension": "mkv",
"year": null,
"filename": "2",
"subtitles": null,
"src": "/tv/Game of Thrones/S2/2.mkv"
},
{
"name": "Game of Thrones",
"season_number": 1,
"episode_number": 1,
"extension": "mkv",
"status": "added",
"filename": "1",
"tags": [],
"subtitles": null,
"year": null,
"src": "/tv/Game of Thrones/s1/1.mkv"
},
{
"name": "Game of Thrones",
"season_number": 1,
"tags": [],
"episode_number": 2,
"status": "added",
"extension": "mp4",
"filename": "2",
"year": null,
"subtitles": null,
"src": "/tv/Game of Thrones/s1/2.mp4"
}
]
}

View File

@ -0,0 +1,36 @@
{
"1": {
"id": 123,
"episodes": [
{
"episode_number": 1,
"name": "name",
"id": 123,
"season_number": 1
},
{
"episode_number": 2,
"name": "name",
"id": 123,
"season_number": 1
}
]
},
"2": {
"id": 123,
"episodes": [
{
"episode_number": 1,
"name": "name",
"id": 123,
"season_number": 2
},
{
"episode_number": 2,
"name": "name",
"id": 123,
"season_number": 2
}
]
}
}

51
backend/tests/fixtures/Tmdb/movie.json vendored Normal file
View File

@ -0,0 +1,51 @@
{
"page": 1,
"results": [
{
"poster_path": "/jVT1MYp58SSzXc6BKetkGxVS3Ze.jpg",
"release_date": "2016-05-25",
"original_title": "Warcraft",
"genre_ids": [
14
],
"id": 68735,
"media_type": "movie",
"original_language": "en",
"title": "Warcraft: The Beginning"
},
{
"poster_path": "/1rxgOwMNwpVP0Hj8R0zhW1CJLfh.jpg",
"release_date": "2015-01-01",
"original_title": "World of Warcraft - Geschichte eines Kult-Spiels",
"genre_ids": [
99
],
"id": 391584,
"media_type": "movie",
"original_language": "de",
"title": "World of Warcraft - Geschichte eines Kult-Spiels"
},
{
"poster_path": "/Y6M5JsoYPrtbTnOY1bCOx3IuDi.jpg",
"release_date": "2014-11-08",
"original_title": "World of Warcraft: Looking For Group",
"genre_ids": [
99
],
"id": 301865,
"media_type": "movie",
"original_language": "en",
"title": "World of Warcraft: Looking For Group"
},
{
"poster_path": "/fivN0U4HXUMXKtyYfi5S8zdhHTg.jpg",
"release_date": "2010-12-07",
"original_title": "World of Warcraft - Cataclysm - Behind the Scenes",
"genre_ids": [],
"id": 205729,
"media_type": "movie",
"original_language": "en",
"title": "World of Warcraft - Cataclysm - Behind the Scenes"
}
]
}

45
backend/tests/fixtures/Tmdb/tv.json vendored Normal file
View File

@ -0,0 +1,45 @@
{
"page": 1,
"results": [
{
"poster_path": "/jIhL6mlT7AblhbHJgEoiBIOUVl1.jpg",
"id": 1399,
"media_type": "tv",
"first_air_date": "2011-04-17",
"genre_ids": [
10765,
10759,
18
],
"name": "Game of Thrones",
"original_name": "Game of Thrones"
},
{
"poster_path": "/8y1LSfnb8Dfd3XPIrxlpvZ4e8d.jpg",
"release_date": "2011-05-13",
"original_title": "Game of Thrones: Complete History and Lore",
"genre_ids": [
16,
14,
28,
12
],
"id": 269623,
"media_type": "movie",
"original_language": "en",
"title": "Game of Thrones: Complete History and Lore"
},
{
"poster_path": null,
"release_date": "2015-02-08",
"original_title": "Game of Thrones: A Day in the Life",
"genre_ids": [
99
],
"id": 340200,
"media_type": "movie",
"original_language": "en",
"title": "Game of Thrones: A Day in the Life"
}
]
}

View File

@ -1,67 +0,0 @@
{
"tv": [
{
"title": "Breaking Bad",
"seasons": [
{
"episodes": [
{
"episode_number": 1,
"src": "/vagrant/flox-file-parser/app/fixtures/tv/Breaking Bad/s01/01.mkv"
},
{
"episode_number": 2,
"src": "/vagrant/flox-file-parser/app/fixtures/tv/Breaking Bad/s01/02.mkv"
}
],
"season_number": 1
},
{
"episodes": [
{
"episode_number": 1,
"src": "/vagrant/flox-file-parser/app/fixtures/tv/Breaking Bad/s02/01.mkv"
},
{
"episode_number": 2,
"src": "/vagrant/flox-file-parser/app/fixtures/tv/Breaking Bad/s02/02.mkv"
}
],
"season_number": 2
}
]
},
{
"title": "Game of Thrones",
"seasons": [
{
"episodes": [
{
"episode_number": 1,
"src": "/vagrant/flox-file-parser/app/fixtures/tv/Game of Thrones/s01/01.mkv"
},
{
"episode_number": 2,
"src": "/vagrant/flox-file-parser/app/fixtures/tv/Game of Thrones/s01/02.mkv"
}
],
"season_number": 1
},
{
"episodes": [
{
"episode_number": 1,
"src": "/vagrant/flox-file-parser/app/fixtures/tv/Game of Thrones/s02/01.mkv"
},
{
"episode_number": 2,
"src": "/vagrant/flox-file-parser/app/fixtures/tv/Game of Thrones/s02/02.mkv"
}
],
"season_number": 2
}
]
}
],
"movies": {}
}

View File

@ -2,7 +2,7 @@
"private": true,
"scripts": {
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
"dev": "webpack -w"
"dev": "webpack -w --progress --hide-modules"
},
"dependencies": {
"axios": "^0.15.2",