mirror of
https://github.com/devfake/flox.git
synced 2024-11-15 06:32:34 +01:00
remove status (#29)
* prepare fixtures * refactor fileparser and add removed status * update fileparser tests
This commit is contained in:
parent
99d1918e8c
commit
a282723e1d
@ -34,6 +34,7 @@
|
|||||||
/*
|
/*
|
||||||
* Scopes
|
* Scopes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function scopeFindByTmdbId($query, $tmdbId)
|
public function scopeFindByTmdbId($query, $tmdbId)
|
||||||
{
|
{
|
||||||
return $query->where('tmdb_id', $tmdbId);
|
return $query->where('tmdb_id', $tmdbId);
|
||||||
|
@ -53,7 +53,12 @@
|
|||||||
return $query->where('tmdb_id', $tmdbId);
|
return $query->where('tmdb_id', $tmdbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeFindEpisode($query, $tmdbId, $episode)
|
public function scopeFindBySrc($query, $src)
|
||||||
|
{
|
||||||
|
return $query->where('src', $src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeFindSpecificEpisode($query, $tmdbId, $episode)
|
||||||
{
|
{
|
||||||
return $query->where('tmdb_id', $tmdbId)
|
return $query->where('tmdb_id', $tmdbId)
|
||||||
->where('season_number', $episode->season_number)
|
->where('season_number', $episode->season_number)
|
||||||
|
@ -169,6 +169,6 @@
|
|||||||
{
|
{
|
||||||
$files = $parser->fetch();
|
$files = $parser->fetch();
|
||||||
|
|
||||||
$parser->store($files);
|
$parser->updateDatabase($files);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,11 @@
|
|||||||
return $query->where('tmdb_id', $tmdbId);
|
return $query->where('tmdb_id', $tmdbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function scopeFindBySrc($query, $src)
|
||||||
|
{
|
||||||
|
return $query->where('src', $src);
|
||||||
|
}
|
||||||
|
|
||||||
public function scopeFindByTitle($query, $title)
|
public function scopeFindByTitle($query, $title)
|
||||||
{
|
{
|
||||||
return $query->where('title', 'like', '%' . $title . '%')
|
return $query->where('title', 'like', '%' . $title . '%')
|
||||||
|
@ -3,27 +3,30 @@
|
|||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\AlternativeTitle;
|
use App\AlternativeTitle;
|
||||||
use App\Episode;
|
use App\Services\Models\EpisodeService;
|
||||||
use App\Services\Models\ItemService;
|
use App\Services\Models\ItemService;
|
||||||
use App\Setting;
|
use App\Setting;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
class FileParser {
|
class FileParser {
|
||||||
|
|
||||||
private $item;
|
const ADDED = 'added';
|
||||||
private $episode;
|
const REMOVED = 'removed';
|
||||||
|
|
||||||
|
private $itemService;
|
||||||
|
private $episodeService;
|
||||||
private $tmdb;
|
private $tmdb;
|
||||||
private $alternativeTitle;
|
private $alternativeTitle;
|
||||||
private $itemCategory;
|
private $itemCategory;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ItemService $item,
|
ItemService $itemService,
|
||||||
Episode $episode,
|
EpisodeService $episodeService,
|
||||||
TMDB $tmdb,
|
TMDB $tmdb,
|
||||||
AlternativeTitle $alternativeTitle
|
AlternativeTitle $alternativeTitle
|
||||||
){
|
){
|
||||||
$this->item = $item;
|
$this->itemService = $itemService;
|
||||||
$this->episode = $episode;
|
$this->episodeService = $episodeService;
|
||||||
$this->tmdb = $tmdb;
|
$this->tmdb = $tmdb;
|
||||||
$this->alternativeTitle = $alternativeTitle;
|
$this->alternativeTitle = $alternativeTitle;
|
||||||
}
|
}
|
||||||
@ -43,31 +46,56 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loop over local files and see if it can find them in database. Otherwise search in TMDb.
|
* Loop over all local files.
|
||||||
*
|
*
|
||||||
* @param $files
|
* @param $files
|
||||||
*/
|
*/
|
||||||
public function store($files)
|
public function updateDatabase($files)
|
||||||
{
|
{
|
||||||
foreach($files as $type => $items) {
|
foreach($files as $type => $items) {
|
||||||
$this->itemCategory = $type;
|
$this->itemCategory = $type;
|
||||||
|
|
||||||
foreach($items as $item) {
|
foreach($items as $item) {
|
||||||
$title = $item->name;
|
$this->handleStatus($item);
|
||||||
|
|
||||||
// See if file is already in our database.
|
|
||||||
if($found = $this->item->findBy('title', $title)) {
|
|
||||||
$this->handleStatus($item, $found->tmdb_id);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise make a new TMDb request.
|
|
||||||
$this->tmdbSearch($title, $item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check which status the file has.
|
||||||
|
*
|
||||||
|
* @param $item
|
||||||
|
* @return bool|mixed|void
|
||||||
|
*/
|
||||||
|
private function handleStatus($item)
|
||||||
|
{
|
||||||
|
switch($item->status) {
|
||||||
|
case self::ADDED:
|
||||||
|
return $this->addItem($item);
|
||||||
|
case self::REMOVED:
|
||||||
|
return $this->removeSrc($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if it can find the item in our database. Otherwise search in TMDb.
|
||||||
|
*
|
||||||
|
* @param $item
|
||||||
|
* @return bool|mixed
|
||||||
|
*/
|
||||||
|
private function addItem($item)
|
||||||
|
{
|
||||||
|
$title = $item->name;
|
||||||
|
|
||||||
|
// See if file is already in our database.
|
||||||
|
if($found = $this->itemService->findBy('title', $title)) {
|
||||||
|
return $this->storeSrc($item, $found->tmdb_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise make a new TMDb request.
|
||||||
|
return $this->tmdbSearch($title, $item);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a new request to TMDb and check against the database. Otherwise create a new item.
|
* Make a new request to TMDb and check against the database. Otherwise create a new item.
|
||||||
*
|
*
|
||||||
@ -91,57 +119,83 @@
|
|||||||
*
|
*
|
||||||
* @param $firstResult
|
* @param $firstResult
|
||||||
* @param $item
|
* @param $item
|
||||||
* @return \Exception|mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function findOrCreateItem($firstResult, $item)
|
private function findOrCreateItem($firstResult, $item)
|
||||||
{
|
{
|
||||||
$tmdbId = $firstResult['tmdb_id'];
|
$tmdbId = $firstResult['tmdb_id'];
|
||||||
|
|
||||||
// Check against our database.
|
// Check against our database.
|
||||||
if($this->item->findBy('tmdb_id', $tmdbId)) {
|
if($this->itemService->findBy('tmdb_id', $tmdbId)) {
|
||||||
return $this->handleStatus($item, $tmdbId);
|
return $this->storeSrc($item, $tmdbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise create a new item from the result.
|
// Otherwise create a new item from the result.
|
||||||
$created = $this->item->create($firstResult);
|
$created = $this->itemService->create($firstResult);
|
||||||
|
|
||||||
return $this->handleStatus($item, $created->tmdb_id);
|
return $this->storeSrc($item, $created->tmdb_id);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Store src from local file into items for movies or episodes for tv shows.
|
||||||
*
|
*
|
||||||
* @param $item
|
* @param $item
|
||||||
* @param $tmdb_id
|
* @param $tmdbId
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function storeSrc($item, $tmdbId)
|
private function storeSrc($item, $tmdbId)
|
||||||
|
{
|
||||||
|
$model = $this->findItem($item, $tmdbId);
|
||||||
|
|
||||||
|
if($model) {
|
||||||
|
return $model->update([
|
||||||
|
'src' => $item->src,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove src for local file in items for movies or episodes for tv shows.
|
||||||
|
*
|
||||||
|
* @param $item
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function removeSrc($item)
|
||||||
|
{
|
||||||
|
$model = $this->findItemBySrc($item);
|
||||||
|
|
||||||
|
if($model) {
|
||||||
|
return $model->update([
|
||||||
|
'src' => null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $item
|
||||||
|
* @param $tmdbId
|
||||||
|
* @return \Illuminate\Support\Collection|mixed
|
||||||
|
*/
|
||||||
|
private function findItem($item, $tmdbId)
|
||||||
{
|
{
|
||||||
if($this->itemCategory == 'tv') {
|
if($this->itemCategory == 'tv') {
|
||||||
$model = $this->episode->findEpisode($tmdbId, $item);
|
return $this->episodeService->findBy('episode', $tmdbId, $item);
|
||||||
} else {
|
|
||||||
$model = $this->item->findBy('tmdb_id', $tmdbId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $model->update([
|
return $this->itemService->findBy('tmdb_id', $tmdbId);
|
||||||
'src' => $item->src,
|
}
|
||||||
]);
|
|
||||||
|
/**
|
||||||
|
* @param $item
|
||||||
|
* @return \Illuminate\Support\Collection|mixed
|
||||||
|
*/
|
||||||
|
private function findItemBySrc($item)
|
||||||
|
{
|
||||||
|
if($this->itemCategory == 'tv') {
|
||||||
|
return $this->episodeService->findBy('src', $item->src);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->itemService->findBy('src', $item->src);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,9 +66,11 @@
|
|||||||
{
|
{
|
||||||
$episode = $this->model->find($id);
|
$episode = $this->model->find($id);
|
||||||
|
|
||||||
return $episode->update([
|
if($episode) {
|
||||||
'seen' => ! $episode->seen,
|
return $episode->update([
|
||||||
]);
|
'seen' => ! $episode->seen,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,4 +88,27 @@
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if we can find a episode by src or tmdb_id.
|
||||||
|
* Or we search a specific episode in our database.
|
||||||
|
*
|
||||||
|
* @param $type
|
||||||
|
* @param $value
|
||||||
|
* @param null $episode
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function findBy($type, $value, $episode = null)
|
||||||
|
{
|
||||||
|
switch($type) {
|
||||||
|
case 'src':
|
||||||
|
return $this->model->findBySrc($value)->first();
|
||||||
|
case 'tmdb_id':
|
||||||
|
return $this->model->findByTmdbId($value)->first();
|
||||||
|
case 'episode':
|
||||||
|
return $this->model->findSpecificEpisode($value, $episode)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if we can find a item by title or tmdb_id in our database.
|
* See if we can find a item by title, tmdb_id or src in our database.
|
||||||
*
|
*
|
||||||
* @param $type
|
* @param $type
|
||||||
* @param $value
|
* @param $value
|
||||||
@ -123,10 +123,15 @@
|
|||||||
*/
|
*/
|
||||||
public function findBy($type, $value)
|
public function findBy($type, $value)
|
||||||
{
|
{
|
||||||
if($type == 'title') {
|
switch($type) {
|
||||||
return $this->model->findByTitle($value)->first();
|
case 'title':
|
||||||
|
return $this->model->findByTitle($value)->first();
|
||||||
|
case 'tmdb_id':
|
||||||
|
return $this->model->findByTmdbId($value)->first();
|
||||||
|
case 'src':
|
||||||
|
return $this->model->findBySrc($value)->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->model->findByTmdbId($value)->first();
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
$this->createMovie();
|
$this->createMovie();
|
||||||
|
|
||||||
$item1 = $this->item->first();
|
$item1 = $this->item->first();
|
||||||
$this->parser->store($this->fpFixtures('movie'));
|
$this->parser->updateDatabase($this->fpFixtures('movie_added'));
|
||||||
$item2 = $this->item->first();
|
$item2 = $this->item->first();
|
||||||
|
|
||||||
$this->assertNull($item1->src);
|
$this->assertNull($item1->src);
|
||||||
@ -48,7 +48,7 @@
|
|||||||
$this->createTv();
|
$this->createTv();
|
||||||
|
|
||||||
$episodes1 = $this->item->with('episodes')->first()->episodes;
|
$episodes1 = $this->item->with('episodes')->first()->episodes;
|
||||||
$this->parser->store($this->fpFixtures('tv'));
|
$this->parser->updateDatabase($this->fpFixtures('tv_added'));
|
||||||
$episodes2 = $this->item->with('episodes')->first()->episodes;
|
$episodes2 = $this->item->with('episodes')->first()->episodes;
|
||||||
|
|
||||||
$episodes1->each(function($episode) {
|
$episodes1->each(function($episode) {
|
||||||
@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
$this->createTmdbMock($this->tmdbFixtures('movie'), $this->tmdbFixtures('alternative_titles_movie'));
|
$this->createTmdbMock($this->tmdbFixtures('movie'), $this->tmdbFixtures('alternative_titles_movie'));
|
||||||
$parser = app(FileParser::class);
|
$parser = app(FileParser::class);
|
||||||
$parser->store($this->fpFixtures('movie'));
|
$parser->updateDatabase($this->fpFixtures('movie_added'));
|
||||||
|
|
||||||
$item = $this->item->first();
|
$item = $this->item->first();
|
||||||
|
|
||||||
@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
$this->createTmdbMock($this->tmdbFixtures('tv'), $this->tmdbFixtures('alternative_titles_tv'));
|
$this->createTmdbMock($this->tmdbFixtures('tv'), $this->tmdbFixtures('alternative_titles_tv'));
|
||||||
$parser = app(FileParser::class);
|
$parser = app(FileParser::class);
|
||||||
$parser->store($this->fpFixtures('tv'));
|
$parser->updateDatabase($this->fpFixtures('tv_added'));
|
||||||
|
|
||||||
$episodes2 = $this->episode->get();
|
$episodes2 = $this->episode->get();
|
||||||
|
|
||||||
@ -120,6 +120,39 @@
|
|||||||
$this->assertNotEquals($setting2->last_fetch_to_file_parser, $setting3->last_fetch_to_file_parser);
|
$this->assertNotEquals($setting2->last_fetch_to_file_parser, $setting3->last_fetch_to_file_parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_should_remove_src_from_movie()
|
||||||
|
{
|
||||||
|
$this->createMovie();
|
||||||
|
$this->parser->updateDatabase($this->fpFixtures('movie_added'));
|
||||||
|
|
||||||
|
$withSrc = $this->item->first();
|
||||||
|
$this->parser->updateDatabase($this->fpFixtures('movie_removed'));
|
||||||
|
$withoutSrc = $this->item->first();
|
||||||
|
|
||||||
|
$this->assertNotNull($withSrc->src);
|
||||||
|
$this->assertNull($withoutSrc->src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_should_remove_src_from_tv_episode()
|
||||||
|
{
|
||||||
|
$this->createTv();
|
||||||
|
$this->parser->updateDatabase($this->fpFixtures('tv_added'));
|
||||||
|
|
||||||
|
$withSrc = $this->item->with('episodes')->first()->episodes;
|
||||||
|
$this->parser->updateDatabase($this->fpFixtures('tv_removed'));
|
||||||
|
$withoutSrc = $this->item->with('episodes')->first()->episodes;
|
||||||
|
|
||||||
|
$withSrc->each(function($episode) {
|
||||||
|
$this->assertNotNull($episode->src);
|
||||||
|
});
|
||||||
|
|
||||||
|
$withoutSrc->each(function($episode) {
|
||||||
|
$this->assertNull($episode->src);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private function createTmdbMock($fixture, $alternativeTitles)
|
private function createTmdbMock($fixture, $alternativeTitles)
|
||||||
{
|
{
|
||||||
$mock = new MockHandler([
|
$mock = new MockHandler([
|
||||||
|
12
backend/tests/fixtures/fp/all.json
vendored
12
backend/tests/fixtures/fp/all.json
vendored
@ -122,6 +122,18 @@
|
|||||||
],
|
],
|
||||||
"status": "added",
|
"status": "added",
|
||||||
"subtitles": "/movies/Warcraft.2016.720p.WEB-DL/Warcraft.2016.720p.WEB-DL.srt"
|
"subtitles": "/movies/Warcraft.2016.720p.WEB-DL/Warcraft.2016.720p.WEB-DL.srt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "removed",
|
||||||
|
"subtitles": "/movies/Warcraft.2016.720p.WEB-DL/Warcraft.2016.720p.WEB-DL.srt"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
16
backend/tests/fixtures/fp/movie_removed.json
vendored
Normal file
16
backend/tests/fixtures/fp/movie_removed.json
vendored
Normal 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": "removed",
|
||||||
|
"subtitles": "/movies/Warcraft.2016.720p.WEB-DL/Warcraft.2016.720p.WEB-DL.srt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
52
backend/tests/fixtures/fp/tv_removed.json
vendored
Normal file
52
backend/tests/fixtures/fp/tv_removed.json
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"tv": [
|
||||||
|
{
|
||||||
|
"name": "Game of Thrones",
|
||||||
|
"season_number": 2,
|
||||||
|
"episode_number": 1,
|
||||||
|
"status": "removed",
|
||||||
|
"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": "removed",
|
||||||
|
"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": "removed",
|
||||||
|
"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": "removed",
|
||||||
|
"extension": "mp4",
|
||||||
|
"filename": "2",
|
||||||
|
"year": null,
|
||||||
|
"subtitles": null,
|
||||||
|
"src": "/tv/Game of Thrones/s1/2.mp4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user